diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer/ext/flac/LibflacAudioTrackRenderer.java b/extensions/flac/src/main/java/com/google/android/exoplayer/ext/flac/LibflacAudioTrackRenderer.java index 3d3410ba67..f0f6d6d143 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer/ext/flac/LibflacAudioTrackRenderer.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer/ext/flac/LibflacAudioTrackRenderer.java @@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.Format; import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.MediaClock; -import com.google.android.exoplayer.SampleSourceTrackRenderer; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.audio.AudioTrack; @@ -35,8 +34,7 @@ import java.util.List; /** * Decodes and renders audio using the native Flac decoder. */ -public final class LibflacAudioTrackRenderer extends SampleSourceTrackRenderer - implements MediaClock { +public final class LibflacAudioTrackRenderer extends TrackRenderer implements MediaClock { /** * Interface definition for a callback to be notified of {@link LibflacAudioTrackRenderer} events. diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java index d34c24a852..a652fd7390 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java @@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.Format; import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.MediaClock; -import com.google.android.exoplayer.SampleSourceTrackRenderer; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.audio.AudioTrack; @@ -35,8 +34,7 @@ import java.util.List; /** * Decodes and renders audio using the native Opus decoder. */ -public final class LibopusAudioTrackRenderer extends SampleSourceTrackRenderer - implements MediaClock { +public final class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClock { /** * Interface definition for a callback to be notified of {@link LibopusAudioTrackRenderer} events. diff --git a/library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java index 1e0783a3c2..8f223fc33d 100644 --- a/library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java @@ -35,18 +35,13 @@ public final class DummyTrackRenderer extends TrackRenderer { throw new IllegalStateException(); } - @Override - protected void checkForReset() throws ExoPlaybackException { - throw new IllegalStateException(); - } - @Override protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { throw new IllegalStateException(); } @Override - protected void maybeThrowError() { + protected void reset(long positionUs) throws ExoPlaybackException { throw new IllegalStateException(); } diff --git a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java index 85791bf392..293ee8ff11 100644 --- a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java @@ -102,6 +102,11 @@ import java.util.concurrent.atomic.AtomicInteger; this.state = ExoPlayer.STATE_IDLE; this.durationUs = 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(); pendingSeekCount = new AtomicInteger(); enabledRenderers = new TrackRenderer[0]; diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java index c4224f56b8..b9460e4999 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java @@ -40,7 +40,7 @@ import java.util.List; * An abstract {@link TrackRenderer} that uses {@link MediaCodec} to decode samples for rendering. */ @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. diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java index eeda1b3a3b..67c68ae9eb 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java @@ -260,9 +260,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { } @Override - protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs, - boolean joining) throws ExoPlaybackException { - super.onEnabled(formats, trackStream, positionUs, joining); + protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException { + super.onEnabled(formats, joining); adaptiveMaxWidth = Format.NO_VALUE; adaptiveMaxHeight = Format.NO_VALUE; if (formats.length > 1) { diff --git a/library/src/main/java/com/google/android/exoplayer/SampleSourceTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/SampleSourceTrackRenderer.java deleted file mode 100644 index e105dbd9b1..0000000000 --- a/library/src/main/java/com/google/android/exoplayer/SampleSourceTrackRenderer.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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; - -} diff --git a/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java index 282e537418..36cbf0819e 100644 --- a/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java @@ -161,27 +161,6 @@ public abstract class TrackRenderer implements ExoPlayerComponent { return ADAPTIVE_NOT_SUPPORTED; } - /** - * Returns the extent to which the renderer supports a given format. - *
- * The returned value is the bitwise OR of two properties: - *
+ * 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. * @@ -281,44 +274,73 @@ public abstract class TrackRenderer implements ExoPlayerComponent { // Do nothing. } - /** - * 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. - *
- * 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(); + // Methods to be called by subclasses. /** - * Whether the renderer is able to immediately render media from the current position. - *
- * 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. - *
- * 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. + * Throws an error that's preventing the renderer from making progress or buffering more data at + * this point in time. *
* This method may be called when the renderer is in the following states: - * {@link #STATE_ENABLED}, {@link #STATE_STARTED}. + * {@link #STATE_ENABLED}. * - * @return True if the renderer is ready to render media. False otherwise. + * @throws IOException An error that's preventing the renderer from making progress or buffering + * more data. */ - protected abstract boolean isReady(); + protected final void maybeThrowError() throws IOException { + stream.maybeThrowError(); + } /** - * Attempts to read and process a pending reset from the {@link TrackStream}. - *
- * This method may be called when the renderer is in the following states: - * {@link #STATE_ENABLED}, {@link #STATE_STARTED}. + * Reads from the enabled upstream source. * + * @see TrackStream#readData(FormatHolder, DecoderInputBuffer) + */ + protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) { + return stream.readData(formatHolder, buffer); + } + + /** + * 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. + *
+ * The returned value is the bitwise OR of two properties: + *
+ * This method may be called when the renderer is in the following states: + * {@link #STATE_ENABLED}, {@link #STATE_STARTED}. + * + * @param positionUs The playback position in microseconds. + * @throws ExoPlaybackException If an error occurs handling the reset. + */ + protected abstract void reset(long positionUs) throws ExoPlaybackException; /** * Incrementally renders the {@link TrackStream}. @@ -339,16 +361,35 @@ public abstract class TrackRenderer implements ExoPlayerComponent { throws ExoPlaybackException; /** - * Throws an error that's preventing the renderer from making progress or buffering more data at - * this point in time. + * Whether the renderer is able to immediately render media from the current position. + *
+ * 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. + *
+ * 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. *
* 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 - * more data. + * @return True if the renderer is ready to render media. False otherwise. */ - 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. + *
+ * 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
public void handleMessage(int what, Object object) throws ExoPlaybackException {
diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java
index 4a0e51eee9..d2f7845dd0 100644
--- a/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java
+++ b/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java
@@ -19,7 +19,6 @@ import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder;
-import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.util.Assertions;
@@ -36,7 +35,7 @@ import java.io.IOException;
*
* @param