diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/ExoPlayerTest.java index 0357fe8dad..1197139b01 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -514,13 +514,14 @@ public final class ExoPlayerTest extends TestCase { @Override public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) { - if (readFormat) { + if (buffer == null || !readFormat) { + formatHolder.format = format; + readFormat = true; + return C.RESULT_FORMAT_READ; + } else { buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM); return C.RESULT_BUFFER_READ; } - formatHolder.format = format; - readFormat = true; - return C.RESULT_FORMAT_READ; } @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/BaseRenderer.java b/library/src/main/java/com/google/android/exoplayer2/BaseRenderer.java index 514bbca8f4..99ed1b8a74 100644 --- a/library/src/main/java/com/google/android/exoplayer2/BaseRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/BaseRenderer.java @@ -251,11 +251,11 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { * {@link C#RESULT_BUFFER_READ} is only returned if {@link #setCurrentStreamFinal()} has been * called. {@link C#RESULT_NOTHING_READ} is returned otherwise. * - * @see SampleStream#readData(FormatHolder, DecoderInputBuffer) * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format. * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the * end of the stream. If the end of the stream has been reached, the - * {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. + * {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. May be null if the + * caller requires that the format of the stream be read even if it's not changing. * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or * {@link C#RESULT_BUFFER_READ}. */ diff --git a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index ba4a729f78..f0f37f963a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -610,6 +610,7 @@ import java.io.IOException; enabledRenderers = new Renderer[0]; rendererMediaClock = null; rendererMediaClockSource = null; + playingPeriodHolder = null; } // Update the holders. diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java index 75497e59c1..b3bcd97048 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java @@ -265,7 +265,8 @@ public final class DefaultTrackOutput implements TrackOutput { * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format. * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the * end of the stream. If the end of the stream has been reached, the - * {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. + * {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. May be null if the + * caller requires that the format of the stream be read even if it's not changing. * @param loadingFinished True if an empty queue should be considered the end of the stream. * @param decodeOnlyUntilUs If a buffer is read, the {@link C#BUFFER_FLAG_DECODE_ONLY} flag will * be set if the buffer's timestamp is less than this value. @@ -751,7 +752,8 @@ public final class DefaultTrackOutput implements TrackOutput { * about the sample, but not its data. The size and absolute position of the data in the * rolling buffer is stored in {@code extrasHolder}, along with an encryption id if present * and the absolute position of the first byte that may still be required after the current - * sample has been read. + * sample has been read. May be null if the caller requires that the format of the stream be + * read even if it's not changing. * @param downstreamFormat The current downstream {@link Format}. If the format of the next * sample is different to the current downstream format then a format will be read. * @param extrasHolder The holder into which extra sample information should be written. @@ -761,14 +763,14 @@ public final class DefaultTrackOutput implements TrackOutput { public synchronized int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, Format downstreamFormat, BufferExtrasHolder extrasHolder) { if (queueSize == 0) { - if (upstreamFormat != null && upstreamFormat != downstreamFormat) { + if (upstreamFormat != null && (buffer == null || upstreamFormat != downstreamFormat)) { formatHolder.format = upstreamFormat; return C.RESULT_FORMAT_READ; } return C.RESULT_NOTHING_READ; } - if (formats[relativeReadIndex] != downstreamFormat) { + if (buffer == null || formats[relativeReadIndex] != downstreamFormat) { formatHolder.format = formats[relativeReadIndex]; return C.RESULT_FORMAT_READ; } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java b/library/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java index 33aeef754d..b18eabf493 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java @@ -235,6 +235,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb if (pendingDiscontinuity) { return C.RESULT_NOTHING_READ; } + if (buffer == null) { + return stream.readData(formatHolder, null); + } if (sentEos) { buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM); return C.RESULT_BUFFER_READ; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java b/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java index 39374acb33..5ee70cd2ed 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java @@ -44,11 +44,17 @@ public interface SampleStream { /** * Attempts to read from the stream. + *
+ * If no data is available then {@link C#RESULT_NOTHING_READ} is returned. If the format of the + * media is changing or if {@code buffer == null} then {@code formatHolder} is populated and + * {@link C#RESULT_FORMAT_READ} is returned. Else {@code buffer} is populated and + * {@link C#RESULT_BUFFER_READ} is returned. * * @param formatHolder A {@link FormatHolder} to populate in the case of reading a format. * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the * end of the stream. If the end of the stream has been reached, the - * {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. + * {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. May be null if the + * caller requires that the format of the stream be read even if it's not changing. * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or * {@link C#RESULT_BUFFER_READ}. */ diff --git a/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java b/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java index b32956fd95..c78bb5371b 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java @@ -206,13 +206,13 @@ import java.util.Arrays; @Override public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) { - if (streamState == STREAM_STATE_END_OF_STREAM) { - buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); - return C.RESULT_BUFFER_READ; - } else if (streamState == STREAM_STATE_SEND_FORMAT) { + if (buffer == null || streamState == STREAM_STATE_SEND_FORMAT) { formatHolder.format = format; streamState = STREAM_STATE_SEND_SAMPLE; return C.RESULT_FORMAT_READ; + } else if (streamState == STREAM_STATE_END_OF_STREAM) { + buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); + return C.RESULT_BUFFER_READ; } Assertions.checkState(streamState == STREAM_STATE_SEND_SAMPLE); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java index c63cf3e5a4..04fe8a093c 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java @@ -26,7 +26,7 @@ import java.io.IOException; /* package */ final class HlsSampleStream implements SampleStream { public final int group; - + private final HlsSampleStreamWrapper sampleStreamWrapper; public HlsSampleStream(HlsSampleStreamWrapper sampleStreamWrapper, int group) {