mirror of
https://github.com/androidx/media.git
synced 2025-05-16 12:09:50 +08:00
Allow ChunkSource an opportunity to fail preparation.
When ChunkSource implementations implement multi-track for DASH and SS, format selection will move inside of ChunkSource. If we, for example, fail to query the decoder to determine which tracks are playable, we need an opportunity to fail (i.e. say we're not prepared, so that maybeThrowError is called, from which we can throw). This may go away in the future if we remove the distinct preparation step and treat tracks/formats as things that can change dynamically, but for now this is what we have. Issue #514.
This commit is contained in:
parent
d49d5a1765
commit
38f2413290
@ -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.
|
||||
* <p>
|
||||
@ -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.
|
||||
* <p>
|
||||
* 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)}.
|
||||
* <p>
|
||||
* 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)}.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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}.
|
||||
* <p>
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user