diff --git a/library/src/main/java/com/google/android/exoplayer/SampleSource.java b/library/src/main/java/com/google/android/exoplayer/SampleSource.java index e42cea77d6..0243387c78 100644 --- a/library/src/main/java/com/google/android/exoplayer/SampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/SampleSource.java @@ -66,6 +66,14 @@ public interface SampleSource { */ public interface SampleSourceReader { + /** + * If the source is currently having difficulty preparing or loading samples, then this method + * throws the underlying error. Otherwise does nothing. + * + * @throws IOException The underlying error. + */ + public void maybeThrowError() throws IOException; + /** * Prepares the source. *
@@ -75,12 +83,14 @@ public interface SampleSource { * success. * * @param positionUs The player's current playback position. - * @return True if the source was prepared successfully, false otherwise. + * @return True if the source was prepared, false otherwise. */ public boolean prepare(long positionUs); /** * Returns the number of tracks exposed by the source. + *
+ * This method should only be called after the source has been prepared. * * @return The number of tracks. */ @@ -96,7 +106,7 @@ public interface SampleSource { * performed using the formats obtained when reading the media stream through calls to * {@link #readData(int, long, MediaFormatHolder, SampleHolder, boolean)}. *
- * This method should not be called until after the source has been successfully prepared. + * This method should only be called after the source has been prepared. * * @param track The track index. * @return The format of the specified track. @@ -107,32 +117,18 @@ public interface SampleSource { * Enable the specified track. This allows the track's format and samples to be read from * {@link #readData(int, long, MediaFormatHolder, SampleHolder, boolean)}. *
- * This method should not be called until after the source has been successfully prepared. + * This method should only be called after the source has been prepared, and when the specified + * track is disabled. * * @param track The track to enable. * @param positionUs The player's current playback position. */ public void enable(int track, long positionUs); - /** - * Disable the specified track. - *
- * This method should not be called until after the source has been successfully prepared. - * - * @param track The track to disable. - */ - public void disable(int track); - - /** - * If the source is currently having difficulty preparing or loading samples, then this method - * throws the underlying error. Otherwise does nothing. - * - * @throws IOException The underlying error. - */ - public void maybeThrowError() throws IOException; - /** * Indicates to the source that it should still be buffering data for the specified track. + *
+ * This method should only be called when the specified track is enabled. * * @param track The track to continue buffering. * @param positionUs The current playback position. @@ -144,7 +140,7 @@ public interface SampleSource { /** * Attempts to read either a sample, a new format or or a discontinuity from the source. *
- * This method should not be called until after the source has been successfully prepared. + * This method should only be called when the specified track is enabled. *
* Note that where multiple tracks are enabled, {@link #NOTHING_READ} may be returned if the * next piece of data to be read from the {@link SampleSource} corresponds to a different track @@ -168,7 +164,7 @@ public interface SampleSource { /** * Seeks to the specified time in microseconds. *
- * This method should not be called until after the source has been successfully prepared. + * This method should only be called when at least one track is enabled. * * @param positionUs The seek position in microseconds. */ @@ -177,7 +173,7 @@ public interface SampleSource { /** * Returns an estimate of the position up to which data is buffered. *
- * This method should not be called until after the source has been successfully prepared. + * This method should only be called when at least one track is enabled. * * @return An estimate of the absolute position in microseconds up to which data is buffered, * or {@link TrackRenderer#END_OF_TRACK_US} if data is buffered to the end of the stream, @@ -185,6 +181,15 @@ public interface SampleSource { */ public long getBufferedPositionUs(); + /** + * Disable the specified track. + *
+ * This method should only be called when the specified track is enabled. + * + * @param track The track to disable. + */ + public void disable(int track); + /** * Releases the {@link SampleSourceReader}. *
diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java index 95e8e5ac0d..9099284e70 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java @@ -131,6 +131,8 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load Assertions.checkState(state == STATE_INITIALIZED || state == STATE_PREPARED); if (state == STATE_PREPARED) { return true; + } else if (!chunkSource.prepare()) { + return false; } loader = new Loader("Loader:" + chunkSource.getFormat(0).mimeType); state = STATE_PREPARED; diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java index 7d46af3d70..5f07b04168 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java @@ -30,8 +30,27 @@ import java.util.List; */ public interface ChunkSource { + /** + * If the source is currently having difficulty preparing or providing chunks, then this method + * throws the underlying error. Otherwise does nothing. + * + * @throws IOException The underlying error. + */ + void maybeThrowError() throws IOException; + + /** + * Prepares the source. + *
+ * The method can be called repeatedly until the return value indicates success. + * + * @return True if the source was prepared, false otherwise. + */ + boolean prepare(); + /** * Returns the number of tracks exposed by the source. + *
+ * This method should only be called after the source has been prepared. * * @return The number of tracks. */ @@ -40,7 +59,7 @@ public interface ChunkSource { /** * Gets the format of the specified track. *
- * May be called when the source is disabled or enabled. + * This method should only be called after the source has been prepared. * * @param track The track index. * @return The format of the track. @@ -51,6 +70,8 @@ public interface ChunkSource { * Adaptive video {@link ChunkSource} implementations must return a copy of the provided * {@link MediaFormat} with the maximum video dimensions set. Other implementations can return * the provided {@link MediaFormat} directly. + *
+ * This method should only be called after the source has been prepared. * * @param format The format to be copied or returned. * @return A copy of the provided {@link MediaFormat} with the maximum video dimensions set, or @@ -59,21 +80,19 @@ public interface ChunkSource { MediaFormat getWithMaxVideoDimensions(MediaFormat format); /** - * Called when the source is enabled. + * Enable the source for the specified track. + *
+ * This method should only be called after the source has been prepared, and when the source is + * disabled. * * @param track The track index. */ void enable(int track); - /** - * Called when the source is disabled. - * - * @param queue A representation of the currently buffered {@link MediaChunk}s. - */ - void disable(List extends MediaChunk> queue); - /** * Indicates to the source that it should still be checking for updates to the stream. + *
+ * This method should only be called when the source is enabled. * * @param playbackPositionUs The current playback position. */ @@ -88,6 +107,8 @@ public interface ChunkSource { * with the next {@link Chunk} to load. The next chunk may be a {@link MediaChunk} to be added to * the queue, or another {@link Chunk} type (e.g. to load initialization data), or null if the * source is not able to provide a chunk in its current state. + *
+ * This method should only be called when the source is enabled. * * @param queue A representation of the currently buffered {@link MediaChunk}s. * @param seekPositionUs If the queue is empty, this parameter must specify the seek position. If @@ -103,17 +124,11 @@ public interface ChunkSource { void getChunkOperation(List extends MediaChunk> queue, long seekPositionUs, long playbackPositionUs, ChunkOperationHolder out); - /** - * If the source is currently having difficulty providing chunks, then this method throws the - * underlying error. Otherwise does nothing. - * - * @throws IOException The underlying error. - */ - void maybeThrowError() throws IOException; - /** * Invoked when the {@link ChunkSampleSource} has finished loading a chunk obtained from this * source. + *
+ * This method should only be called when the source is enabled. * * @param chunk The chunk whose load has been completed. */ @@ -122,10 +137,21 @@ public interface ChunkSource { /** * Invoked when the {@link ChunkSampleSource} encounters an error loading a chunk obtained from * this source. + *
+ * This method should only be called when the source is enabled. * * @param chunk The chunk whose load encountered the error. * @param e The error. */ void onChunkLoadError(Chunk chunk, Exception e); + /** + * Disables the source. + *
+ * This method should only be called when the source is enabled. + * + * @param queue A representation of the currently buffered {@link MediaChunk}s. + */ + void disable(List extends MediaChunk> queue); + } diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java index 5e8dc638ee..5bb43be5b5 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java @@ -61,6 +61,15 @@ public final class MultiTrackChunkSource implements ChunkSource, ExoPlayerCompon return allSources.length; } + @Override + public boolean prepare() { + boolean prepared = true; + for (int i = 0; i < allSources.length; i++) { + prepared &= allSources[i].prepare(); + } + return prepared; + } + @Override public int getTrackCount() { return selectedSource.getTrackCount(); diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java index 53ae76fe34..3faea8b21a 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java @@ -54,6 +54,11 @@ public final class SingleSampleChunkSource implements ChunkSource { this.mediaFormat = mediaFormat; } + @Override + public boolean prepare() { + return true; + } + @Override public int getTrackCount() { return 1; diff --git a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java index 551aa79e1d..5941c27dc2 100644 --- a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java @@ -290,6 +290,11 @@ public class DashChunkSource implements ChunkSource { ? format.copyWithMaxVideoDimension(maxWidth, maxHeight) : format; } + @Override + public boolean prepare() { + return true; + } + @Override public int getTrackCount() { return 1; diff --git a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java index 5f182b0a35..5fb69c0574 100644 --- a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java @@ -186,6 +186,11 @@ public class SmoothStreamingChunkSource implements ChunkSource { ? format.copyWithMaxVideoDimension(maxWidth, maxHeight) : format; } + @Override + public boolean prepare() { + return true; + } + @Override public int getTrackCount() { return 1;