Commit e594eccd by andrewlewis Committed by Oliver Woodman

Merge SampleSourceTrackRenderer into TrackRenderer.

TrackRenderer and SampleSourceTrackRenderer both now use a TrackStream
so they can be merged.

(This may also be useful for adding playlist support, in case TrackStreams need
to be replaced during playback.)
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=119743228
parent c2beffc6
...@@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer; ...@@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.MediaClock; import com.google.android.exoplayer.MediaClock;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.audio.AudioTrack; import com.google.android.exoplayer.audio.AudioTrack;
...@@ -35,8 +34,7 @@ import java.util.List; ...@@ -35,8 +34,7 @@ import java.util.List;
/** /**
* Decodes and renders audio using the native Flac decoder. * Decodes and renders audio using the native Flac decoder.
*/ */
public final class LibflacAudioTrackRenderer extends SampleSourceTrackRenderer public final class LibflacAudioTrackRenderer extends TrackRenderer implements MediaClock {
implements MediaClock {
/** /**
* Interface definition for a callback to be notified of {@link LibflacAudioTrackRenderer} events. * Interface definition for a callback to be notified of {@link LibflacAudioTrackRenderer} events.
......
...@@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer; ...@@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.MediaClock; import com.google.android.exoplayer.MediaClock;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.audio.AudioTrack; import com.google.android.exoplayer.audio.AudioTrack;
...@@ -35,8 +34,7 @@ import java.util.List; ...@@ -35,8 +34,7 @@ import java.util.List;
/** /**
* Decodes and renders audio using the native Opus decoder. * Decodes and renders audio using the native Opus decoder.
*/ */
public final class LibopusAudioTrackRenderer extends SampleSourceTrackRenderer public final class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClock {
implements MediaClock {
/** /**
* Interface definition for a callback to be notified of {@link LibopusAudioTrackRenderer} events. * Interface definition for a callback to be notified of {@link LibopusAudioTrackRenderer} events.
......
...@@ -36,17 +36,12 @@ public final class DummyTrackRenderer extends TrackRenderer { ...@@ -36,17 +36,12 @@ public final class DummyTrackRenderer extends TrackRenderer {
} }
@Override @Override
protected void checkForReset() throws ExoPlaybackException {
throw new IllegalStateException();
}
@Override
protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
throw new IllegalStateException(); throw new IllegalStateException();
} }
@Override @Override
protected void maybeThrowError() { protected void reset(long positionUs) throws ExoPlaybackException {
throw new IllegalStateException(); throw new IllegalStateException();
} }
......
...@@ -102,6 +102,11 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -102,6 +102,11 @@ import java.util.concurrent.atomic.AtomicInteger;
this.state = ExoPlayer.STATE_IDLE; this.state = ExoPlayer.STATE_IDLE;
this.durationUs = C.UNKNOWN_TIME_US; this.durationUs = C.UNKNOWN_TIME_US;
this.bufferedPositionUs = C.UNKNOWN_TIME_US; this.bufferedPositionUs = C.UNKNOWN_TIME_US;
for (int i = 0; i < renderers.length; i++) {
renderers[i].setIndex(i);
}
standaloneMediaClock = new StandaloneMediaClock(); standaloneMediaClock = new StandaloneMediaClock();
pendingSeekCount = new AtomicInteger(); pendingSeekCount = new AtomicInteger();
enabledRenderers = new TrackRenderer[0]; enabledRenderers = new TrackRenderer[0];
......
...@@ -40,7 +40,7 @@ import java.util.List; ...@@ -40,7 +40,7 @@ import java.util.List;
* An abstract {@link TrackRenderer} that uses {@link MediaCodec} to decode samples for rendering. * An abstract {@link TrackRenderer} that uses {@link MediaCodec} to decode samples for rendering.
*/ */
@TargetApi(16) @TargetApi(16)
public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer { public abstract class MediaCodecTrackRenderer extends TrackRenderer {
/** /**
* Interface definition for a callback to be notified of {@link MediaCodecTrackRenderer} events. * Interface definition for a callback to be notified of {@link MediaCodecTrackRenderer} events.
......
...@@ -260,9 +260,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -260,9 +260,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
} }
@Override @Override
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs, protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException {
boolean joining) throws ExoPlaybackException { super.onEnabled(formats, joining);
super.onEnabled(formats, trackStream, positionUs, joining);
adaptiveMaxWidth = Format.NO_VALUE; adaptiveMaxWidth = Format.NO_VALUE;
adaptiveMaxHeight = Format.NO_VALUE; adaptiveMaxHeight = Format.NO_VALUE;
if (formats.length > 1) { if (formats.length > 1) {
......
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer;
import com.google.android.exoplayer.util.Assertions;
import java.io.IOException;
/**
* Base class for {@link TrackRenderer} implementations that render samples obtained from a
* {@link SampleSource}.
*/
public abstract class SampleSourceTrackRenderer extends TrackRenderer {
private TrackStream trackStream;
@Override
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException {
this.trackStream = Assertions.checkNotNull(trackStream);
reset(positionUs);
}
@Override
protected final void checkForReset() throws ExoPlaybackException {
long resetPositionUs = trackStream.readReset();
if (resetPositionUs != TrackStream.NO_RESET) {
reset(resetPositionUs);
return;
}
}
@Override
protected final void maybeThrowError() throws IOException {
trackStream.maybeThrowError();
}
@Override
protected void onDisabled() {
trackStream = null;
}
// Methods to be called by subclasses.
/**
* Reads from the enabled upstream source.
*
* @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
*/
protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return trackStream.readData(formatHolder, buffer);
}
/**
* Returns whether the upstream source is ready.
*
* @return True if the source is ready. False otherwise.
*/
protected final boolean isSourceReady() {
return trackStream.isReady();
}
// Abstract methods.
/**
* Invoked when a reset is encountered, and also when the renderer is enabled.
*
* @param positionUs The playback position in microseconds.
* @throws ExoPlaybackException If an error occurs handling the reset.
*/
protected abstract void reset(long positionUs) throws ExoPlaybackException;
}
...@@ -162,27 +162,6 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -162,27 +162,6 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
} }
/** /**
* Returns the extent to which the renderer supports a given format.
* <p>
* The returned value is the bitwise OR of two properties:
* <ul>
* <li>The level of support for the format itself. One of {@code}link #FORMAT_HANDLED},
* {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <li>The level of support for adapting from the format to another format of the same mimeType.
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul>
* The individual properties can be retrieved by performing a bitwise AND with
* {@link #FORMAT_SUPPORT_MASK} and {@link #ADAPTIVE_SUPPORT_MASK} respectively.
*
* @param format The format.
* @return The extent to which the renderer is capable of supporting the given format.
* @throws ExoPlaybackException If an error occurs.
*/
protected abstract int supportsFormat(Format format) throws ExoPlaybackException;
/**
* Enable the renderer to consume from the specified {@link TrackStream}. * Enable the renderer to consume from the specified {@link TrackStream}.
* *
* @param formats The enabled formats. * @param formats The enabled formats.
...@@ -196,7 +175,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -196,7 +175,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
Assertions.checkState(state == STATE_DISABLED); Assertions.checkState(state == STATE_DISABLED);
state = STATE_ENABLED; state = STATE_ENABLED;
stream = trackStream; stream = trackStream;
onEnabled(formats, trackStream, positionUs, joining); onEnabled(formats, joining);
reset(positionUs);
} }
/** /**
...@@ -205,13 +185,10 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -205,13 +185,10 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* The default implementation is a no-op. * The default implementation is a no-op.
* *
* @param formats The enabled formats. * @param formats The enabled formats.
* @param trackStream The track stream from which the renderer should consume.
* @param positionUs The player's current position.
* @param joining Whether this renderer is being enabled to join an ongoing playback. * @param joining Whether this renderer is being enabled to join an ongoing playback.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs, protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException {
boolean joining) throws ExoPlaybackException {
// Do nothing. // Do nothing.
} }
...@@ -239,6 +216,22 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -239,6 +216,22 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
} }
/** /**
* Attempts to read and process a pending reset from the {@link TrackStream}.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @throws ExoPlaybackException If an error occurs.
*/
/* package */ final void checkForReset() throws ExoPlaybackException {
long resetPositionUs = stream.readReset();
if (resetPositionUs != TrackStream.NO_RESET) {
reset(resetPositionUs);
return;
}
}
/**
* Stops the renderer. * Stops the renderer.
* *
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
...@@ -281,44 +274,73 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -281,44 +274,73 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
// Do nothing. // Do nothing.
} }
// Methods to be called by subclasses.
/** /**
* Whether the renderer is ready for the {@link ExoPlayer} instance to transition to * Throws an error that's preventing the renderer from making progress or buffering more data at
* {@link ExoPlayer#STATE_ENDED}. The player will make this transition as soon as {@code true} is * this point in time.
* returned by all of its {@link TrackRenderer}s.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}. * {@link #STATE_ENABLED}.
* *
* @return Whether the renderer is ready for the player to transition to the ended state. * @throws IOException An error that's preventing the renderer from making progress or buffering
* more data.
*/ */
protected abstract boolean isEnded(); protected final void maybeThrowError() throws IOException {
stream.maybeThrowError();
}
/** /**
* Whether the renderer is able to immediately render media from the current position. * Reads from the enabled upstream source.
* <p> *
* If the renderer is in the {@link #STATE_STARTED} state then returning true indicates that the * @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
* renderer has everything that it needs to continue playback. Returning false indicates that */
* the player should pause until the renderer is ready. protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
* <p> return stream.readData(formatHolder, buffer);
* If the renderer is in the {@link #STATE_ENABLED} state then returning true indicates that the }
* renderer is ready for playback to be started. Returning false indicates that it is not.
/**
* Returns whether the upstream source is ready.
*
* @return True if the source is ready. False otherwise.
*/
protected final boolean isSourceReady() {
return stream.isReady();
}
// Abstract methods.
/**
* Returns the extent to which the renderer supports a given format.
* <p> * <p>
* This method may be called when the renderer is in the following states: * The returned value is the bitwise OR of two properties:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}. * <ul>
* <li>The level of support for the format itself. One of {@code}link #FORMAT_HANDLED},
* {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <li>The level of support for adapting from the format to another format of the same mimeType.
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul>
* The individual properties can be retrieved by performing a bitwise AND with
* {@link #FORMAT_SUPPORT_MASK} and {@link #ADAPTIVE_SUPPORT_MASK} respectively.
* *
* @return True if the renderer is ready to render media. False otherwise. * @param format The format.
* @return The extent to which the renderer is capable of supporting the given format.
* @throws ExoPlaybackException If an error occurs.
*/ */
protected abstract boolean isReady(); protected abstract int supportsFormat(Format format) throws ExoPlaybackException;
/** /**
* Attempts to read and process a pending reset from the {@link TrackStream}. * Invoked when a reset is encountered, and also when the renderer is enabled.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}. * {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* *
* @throws ExoPlaybackException If an error occurs. * @param positionUs The playback position in microseconds.
* @throws ExoPlaybackException If an error occurs handling the reset.
*/ */
protected abstract void checkForReset() throws ExoPlaybackException; protected abstract void reset(long positionUs) throws ExoPlaybackException;
/** /**
* Incrementally renders the {@link TrackStream}. * Incrementally renders the {@link TrackStream}.
...@@ -339,16 +361,35 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -339,16 +361,35 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
throws ExoPlaybackException; throws ExoPlaybackException;
/** /**
* Throws an error that's preventing the renderer from making progress or buffering more data at * Whether the renderer is able to immediately render media from the current position.
* this point in time. * <p>
* If the renderer is in the {@link #STATE_STARTED} state then returning true indicates that the
* renderer has everything that it needs to continue playback. Returning false indicates that
* the player should pause until the renderer is ready.
* <p>
* If the renderer is in the {@link #STATE_ENABLED} state then returning true indicates that the
* renderer is ready for playback to be started. Returning false indicates that it is not.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}. * {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* *
* @throws IOException An error that's preventing the renderer from making progress or buffering * @return True if the renderer is ready to render media. False otherwise.
* more data.
*/ */
protected abstract void maybeThrowError() throws IOException; protected abstract boolean isReady();
/**
* Whether the renderer is ready for the {@link ExoPlayer} instance to transition to
* {@link ExoPlayer#STATE_ENDED}. The player will make this transition as soon as {@code true} is
* returned by all of its {@link TrackRenderer}s.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @return Whether the renderer is ready for the player to transition to the ended state.
*/
protected abstract boolean isEnded();
// ExoPlayerComponent implementation.
@Override @Override
public void handleMessage(int what, Object object) throws ExoPlaybackException { public void handleMessage(int what, Object object) throws ExoPlaybackException {
......
...@@ -19,7 +19,6 @@ import com.google.android.exoplayer.DecoderInputBuffer; ...@@ -19,7 +19,6 @@ import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Assertions;
...@@ -36,7 +35,7 @@ import java.io.IOException; ...@@ -36,7 +35,7 @@ import java.io.IOException;
* *
* @param <T> The type of the metadata. * @param <T> The type of the metadata.
*/ */
public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer implements Callback { public final class MetadataTrackRenderer<T> extends TrackRenderer implements Callback {
/** /**
* An interface for components that process metadata. * An interface for components that process metadata.
......
...@@ -20,7 +20,6 @@ import com.google.android.exoplayer.ExoPlaybackException; ...@@ -20,7 +20,6 @@ import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.ParserException; import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Assertions;
...@@ -44,7 +43,7 @@ import java.util.List; ...@@ -44,7 +43,7 @@ import java.util.List;
* {@link TextRenderer}. * {@link TextRenderer}.
*/ */
@TargetApi(16) @TargetApi(16)
public final class TextTrackRenderer extends SampleSourceTrackRenderer implements Callback { public final class TextTrackRenderer extends TrackRenderer implements Callback {
private static final int MSG_UPDATE_OVERLAY = 0; private static final int MSG_UPDATE_OVERLAY = 0;
...@@ -99,9 +98,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement ...@@ -99,9 +98,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
} }
@Override @Override
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs, protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException {
boolean joining) throws ExoPlaybackException { super.onEnabled(formats, joining);
super.onEnabled(formats, trackStream, positionUs, joining);
parser = parserFactory.createParser(formats[0]); parser = parserFactory.createParser(formats[0]);
parser.start(); parser.start();
} }
...@@ -120,9 +118,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement ...@@ -120,9 +118,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
} }
nextInputBuffer = null; nextInputBuffer = null;
clearTextRenderer(); clearTextRenderer();
if (parser != null) { parser.flush();
parser.flush();
}
} }
@Override @Override
...@@ -215,10 +211,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement ...@@ -215,10 +211,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
nextSubtitle.release(); nextSubtitle.release();
nextSubtitle = null; nextSubtitle = null;
} }
if (parser != null) { parser.release();
parser.release(); parser = null;
parser = null;
}
nextInputBuffer = null; nextInputBuffer = null;
clearTextRenderer(); clearTextRenderer();
super.onDisabled(); super.onDisabled();
......
...@@ -20,7 +20,6 @@ import com.google.android.exoplayer.DecoderInputBuffer; ...@@ -20,7 +20,6 @@ import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.text.Cue; import com.google.android.exoplayer.text.Cue;
...@@ -39,7 +38,7 @@ import java.util.TreeSet; ...@@ -39,7 +38,7 @@ import java.util.TreeSet;
/** /**
* A {@link TrackRenderer} for EIA-608 closed captions in a media stream. * A {@link TrackRenderer} for EIA-608 closed captions in a media stream.
*/ */
public final class Eia608TrackRenderer extends SampleSourceTrackRenderer implements Callback { public final class Eia608TrackRenderer extends TrackRenderer implements Callback {
private static final int MSG_INVOKE_RENDERER = 0; private static final int MSG_INVOKE_RENDERER = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment