diff --git a/library/common/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java b/library/common/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java index 4d00ee7748..7418877626 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java @@ -111,12 +111,8 @@ public class DecoderInputBuffer extends Buffer { @BufferReplacementMode private final int bufferReplacementMode; private final int paddingSize; - /** - * Creates a new instance for which {@link #isFlagsOnly()} will return true. - * - * @return A new flags only input buffer. - */ - public static DecoderInputBuffer newFlagsOnlyInstance() { + /** Returns a new instance that's not able to hold any data. */ + public static DecoderInputBuffer newNoDataInstance() { return new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED); } @@ -200,14 +196,6 @@ public class DecoderInputBuffer extends Buffer { data = newData; } - /** - * Returns whether the buffer is only able to hold flags, meaning {@link #data} is null and - * its replacement mode is {@link #BUFFER_REPLACEMENT_MODE_DISABLED}. - */ - public final boolean isFlagsOnly() { - return data == null && bufferReplacementMode == BUFFER_REPLACEMENT_MODE_DISABLED; - } - /** * Returns whether the {@link C#BUFFER_FLAG_ENCRYPTED} flag is set. */ diff --git a/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java index 92b7e20658..37db0c5544 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java @@ -21,6 +21,8 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer.InsufficientCapacityException; import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; +import com.google.android.exoplayer2.source.SampleStream.ReadFlags; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MediaClock; import java.io.IOException; @@ -225,8 +227,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { * @param formats The enabled formats. * @param startPositionUs The start position of the new stream in renderer time (microseconds). * @param offsetUs The offset that will be added to the timestamps of buffers read via {@link - * #readSource(FormatHolder, DecoderInputBuffer, boolean)} so that decoder input buffers have - * monotonically increasing timestamps. + * #readSource} so that decoder input buffers have monotonically increasing timestamps. * @throws ExoPlaybackException If an error occurs. */ protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) @@ -383,20 +384,17 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { * @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. - * @param formatRequired Whether the caller requires that the format of the stream be read even if - * it's not changing. A sample will never be read if set to true, however it is still possible - * for the end of stream or nothing to be read. - * @return The status of read, one of {@link SampleStream.ReadDataResult}. - * @throws InsufficientCapacityException If the {@code buffer} is not a {@link - * DecoderInputBuffer#isFlagsOnly() flags-only} buffer and has insufficient capacity to hold + * @param readFlags Flags controlling the behavior of this read operation. + * @return The {@link ReadDataResult result} of the read operation. + * @throws InsufficientCapacityException If the {@code buffer} has insufficient capacity to hold * the data of a sample being read. The buffer {@link DecoderInputBuffer#timeUs timestamp} and * flags are populated if this exception is thrown, but the read position is not advanced. */ - @SampleStream.ReadDataResult + @ReadDataResult protected final int readSource( - FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) { - @SampleStream.ReadDataResult - int result = Assertions.checkNotNull(stream).readData(formatHolder, buffer, formatRequired); + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { + @ReadDataResult + int result = Assertions.checkNotNull(stream).readData(formatHolder, buffer, readFlags); if (result == C.RESULT_BUFFER_READ) { if (buffer.isEndOfStream()) { readingPositionUs = C.TIME_END_OF_SOURCE; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java index 0f4ccbd56a..e7b20ff605 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.audio; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_DRM_SESSION_CHANGED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static java.lang.Math.max; import android.os.Handler; @@ -45,7 +46,7 @@ import com.google.android.exoplayer2.decoder.SimpleOutputBuffer; import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.ExoMediaCrypto; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.MediaClock; @@ -189,7 +190,7 @@ public abstract class DecoderAudioRenderer< eventDispatcher = new EventDispatcher(eventHandler, eventListener); this.audioSink = audioSink; audioSink.setListener(new AudioSinkListener()); - flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance(); + flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance(); decoderReinitializationState = REINITIALIZATION_STATE_NONE; audioTrackNeedsConfigure = true; } @@ -273,7 +274,7 @@ public abstract class DecoderAudioRenderer< // We don't have a format yet, so try and read one. FormatHolder formatHolder = getFormatHolder(); flagsOnlyBuffer.clear(); - @SampleStream.ReadDataResult int result = readSource(formatHolder, flagsOnlyBuffer, true); + @ReadDataResult int result = readSource(formatHolder, flagsOnlyBuffer, FLAG_REQUIRE_FORMAT); if (result == C.RESULT_FORMAT_READ) { onInputFormatChanged(formatHolder); } else if (result == C.RESULT_BUFFER_READ) { @@ -438,7 +439,7 @@ public abstract class DecoderAudioRenderer< } FormatHolder formatHolder = getFormatHolder(); - switch (readSource(formatHolder, inputBuffer, /* formatRequired= */ false)) { + switch (readSource(formatHolder, inputBuffer, /* readFlags= */ 0)) { case C.RESULT_NOTHING_READ: return false; case C.RESULT_FORMAT_READ: diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index 80d5cc0866..b3e235b4ec 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -23,6 +23,9 @@ import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_YES_WITHOUT_RECONFIGURATION; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_YES_WITH_FLUSH; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_YES_WITH_RECONFIGURATION; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_OMIT_SAMPLE_DATA; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_PEEK; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkState; import static java.lang.Math.max; @@ -57,6 +60,8 @@ import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; +import com.google.android.exoplayer2.source.SampleStream.ReadFlags; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.MimeTypes; @@ -294,7 +299,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { private final MediaCodecSelector mediaCodecSelector; private final boolean enableDecoderFallback; private final float assumedMinimumCodecOperatingRate; - private final DecoderInputBuffer flagsOnlyBuffer; + private final DecoderInputBuffer noDataBuffer; private final DecoderInputBuffer buffer; private final DecoderInputBuffer bypassSampleBuffer; private final BatchBuffer bypassBatchBuffer; @@ -388,7 +393,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { this.mediaCodecSelector = checkNotNull(mediaCodecSelector); this.enableDecoderFallback = enableDecoderFallback; this.assumedMinimumCodecOperatingRate = assumedMinimumCodecOperatingRate; - flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance(); + noDataBuffer = DecoderInputBuffer.newNoDataInstance(); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED); bypassSampleBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT); bypassBatchBuffer = new BatchBuffer(); @@ -816,7 +821,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { renderToEndOfStream(); return; } - if (inputFormat == null && !readToFlagsOnlyBuffer(/* requireFormat= */ true)) { + if (inputFormat == null && !readSourceOmittingSampleData(FLAG_REQUIRE_FORMAT)) { // We still don't have a format and can't make progress without one. return; } @@ -837,9 +842,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer { decoderCounters.skippedInputBufferCount += skipSource(positionUs); // We need to read any format changes despite not having a codec so that drmSession can be // updated, and so that we have the most recent format should the codec be initialized. We - // may also reach the end of the stream. Note that readSource will not read a sample into a - // flags-only buffer. - readToFlagsOnlyBuffer(/* requireFormat= */ false); + // may also reach the end of the stream. FLAG_PEEK is used because we don't want to advance + // the source further than skipSource has already done. + readSourceOmittingSampleData(FLAG_PEEK); } decoderCounters.ensureUpdated(); } catch (IllegalStateException e) { @@ -972,16 +977,24 @@ public abstract class MediaCodecRenderer extends BaseRenderer { return new MediaCodecDecoderException(cause, codecInfo); } - /** Reads into {@link #flagsOnlyBuffer} and returns whether a {@link Format} was read. */ - private boolean readToFlagsOnlyBuffer(boolean requireFormat) throws ExoPlaybackException { + /** + * Reads from the source when sample data is not required. If a format or an end of stream buffer + * is read, it will be handled before the call returns. + * + * @param readFlags Additional {@link ReadFlags}. {@link SampleStream#FLAG_OMIT_SAMPLE_DATA} is + * added internally, and so does not need to be passed. + * @return Whether a format was read and processed. + */ + private boolean readSourceOmittingSampleData(@SampleStream.ReadFlags int readFlags) + throws ExoPlaybackException { FormatHolder formatHolder = getFormatHolder(); - flagsOnlyBuffer.clear(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, flagsOnlyBuffer, requireFormat); + noDataBuffer.clear(); + @ReadDataResult + int result = readSource(formatHolder, noDataBuffer, readFlags | FLAG_OMIT_SAMPLE_DATA); if (result == C.RESULT_FORMAT_READ) { onInputFormatChanged(formatHolder); return true; - } else if (result == C.RESULT_BUFFER_READ && flagsOnlyBuffer.isEndOfStream()) { + } else if (result == C.RESULT_BUFFER_READ && noDataBuffer.isEndOfStream()) { inputStreamEnded = true; processEndOfStream(); } @@ -1248,8 +1261,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { int adaptiveReconfigurationBytes = buffer.data.position(); FormatHolder formatHolder = getFormatHolder(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, buffer, /* formatRequired= */ false); + @ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */ 0); if (hasReadStreamToEnd()) { // Notify output queue of the last buffer's timestamp. @@ -2264,8 +2276,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { bypassSampleBuffer.clear(); while (true) { bypassSampleBuffer.clear(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, bypassSampleBuffer, /* formatRequired= */ false); + @ReadDataResult int result = readSource(formatHolder, bypassSampleBuffer, /* readFlags= */ 0); switch (result) { case C.RESULT_FORMAT_READ: onInputFormatChanged(formatHolder); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java index 5ae7cca66c..7adfaa78b3 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java @@ -27,7 +27,7 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.RendererCapabilities; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; import java.util.ArrayList; @@ -125,7 +125,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback { if (!inputStreamEnded && pendingMetadataCount < MAX_PENDING_METADATA_COUNT) { buffer.clear(); FormatHolder formatHolder = getFormatHolder(); - @SampleStream.ReadDataResult int result = readSource(formatHolder, buffer, false); + @ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */ 0); if (result == C.RESULT_BUFFER_READ) { if (buffer.isEndOfStream()) { inputStreamEnded = true; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java index 650e055f0b..464bf497fe 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java @@ -299,7 +299,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public int readData( - FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) { + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { if (isPendingInitialDiscontinuity()) { return C.RESULT_NOTHING_READ; } @@ -307,7 +307,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM); return C.RESULT_BUFFER_READ; } - @ReadDataResult int result = childStream.readData(formatHolder, buffer, requireFormat); + @ReadDataResult int result = childStream.readData(formatHolder, buffer, readFlags); if (result == C.RESULT_FORMAT_READ) { Format format = Assertions.checkNotNull(formatHolder.format); if (format.encoderDelay != 0 || format.encoderPadding != 0) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/EmptySampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/EmptySampleStream.java index fe574cf597..4c4916bf2b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/EmptySampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/EmptySampleStream.java @@ -35,8 +35,8 @@ public final class EmptySampleStream implements SampleStream { } @Override - public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired) { + public int readData( + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM); return C.RESULT_BUFFER_READ; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java index 860d9a3b95..2eac56f5fa 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java @@ -440,8 +440,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public int readData( - FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) { - int readResult = sampleStream.readData(formatHolder, buffer, formatRequired); + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { + int readResult = sampleStream.readData(formatHolder, buffer, readFlags); if (readResult == C.RESULT_BUFFER_READ) { buffer.timeUs = max(0, buffer.timeUs + timeOffsetUs); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java index 66af0e5eee..791dd72479 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java @@ -39,6 +39,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.icy.IcyHeaders; import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener; +import com.google.android.exoplayer2.source.SampleStream.ReadFlags; import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.DataSource; @@ -478,13 +479,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; int sampleQueueIndex, FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired) { + @ReadFlags int readFlags) { if (suppressRead()) { return C.RESULT_NOTHING_READ; } maybeNotifyDownstreamFormat(sampleQueueIndex); int result = - sampleQueues[sampleQueueIndex].read(formatHolder, buffer, formatRequired, loadingFinished); + sampleQueues[sampleQueueIndex].read(formatHolder, buffer, readFlags, loadingFinished); if (result == C.RESULT_NOTHING_READ) { maybeStartDeferredRetry(sampleQueueIndex); } @@ -947,9 +948,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } @Override - public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired) { - return ProgressiveMediaPeriod.this.readData(track, formatHolder, buffer, formatRequired); + public int readData( + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { + return ProgressiveMediaPeriod.this.readData(track, formatHolder, buffer, readFlags); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java index e1faa6e39e..b0b04fb568 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java @@ -15,6 +15,9 @@ */ package com.google.android.exoplayer2.source; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_OMIT_SAMPLE_DATA; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_PEEK; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static com.google.android.exoplayer2.util.Assertions.checkArgument; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static java.lang.Math.max; @@ -36,6 +39,7 @@ import com.google.android.exoplayer2.drm.DrmSessionEventListener; import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager.DrmSessionReference; import com.google.android.exoplayer2.extractor.TrackOutput; +import com.google.android.exoplayer2.source.SampleStream.ReadFlags; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.util.Assertions; @@ -380,20 +384,6 @@ public class SampleQueue implements TrackOutput { return mayReadSample(getRelativeIndex(readPosition)); } - /** Equivalent to {@link #read}, except it never advances the read position. */ - public final int peek( - FormatHolder formatHolder, - DecoderInputBuffer buffer, - boolean formatRequired, - boolean loadingFinished) { - int result = - peekSampleMetadata(formatHolder, buffer, formatRequired, loadingFinished, extrasHolder); - if (result == C.RESULT_BUFFER_READ && !buffer.isEndOfStream() && !buffer.isFlagsOnly()) { - sampleDataQueue.peekToBuffer(buffer, extrasHolder); - } - return result; - } - /** * Attempts to read from the queue. * @@ -403,18 +393,12 @@ public class SampleQueue 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. If a {@link - * DecoderInputBuffer#isFlagsOnly() flags-only} buffer is passed and a sample is read, then - * only the buffer {@link DecoderInputBuffer#timeUs timestamp} and flags will be populated, - * and the read position will not be advanced. - * @param formatRequired Whether the caller requires that the format of the stream be read even if - * it's not changing. A sample will never be read if set to true, however it is still possible - * for the end of stream or nothing to be read. + * C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. + * @param readFlags Flags controlling the behavior of this read operation. * @param loadingFinished True if an empty queue should be considered the end of the stream. * @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or * {@link C#RESULT_BUFFER_READ}. - * @throws InsufficientCapacityException If the {@code buffer} is not a {@link - * DecoderInputBuffer#isFlagsOnly() flags-only} buffer and has insufficient capacity to hold + * @throws InsufficientCapacityException If the {@code buffer} has insufficient capacity to hold * the data of a sample being read. The buffer {@link DecoderInputBuffer#timeUs timestamp} and * flags are populated if this exception is thrown, but the read position is not advanced. */ @@ -422,13 +406,27 @@ public class SampleQueue implements TrackOutput { public int read( FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired, + @ReadFlags int readFlags, boolean loadingFinished) { int result = - peekSampleMetadata(formatHolder, buffer, formatRequired, loadingFinished, extrasHolder); - if (result == C.RESULT_BUFFER_READ && !buffer.isEndOfStream() && !buffer.isFlagsOnly()) { - sampleDataQueue.readToBuffer(buffer, extrasHolder); - readPosition++; + peekSampleMetadata( + formatHolder, + buffer, + /* formatRequired= */ (readFlags & FLAG_REQUIRE_FORMAT) != 0, + loadingFinished, + extrasHolder); + if (result == C.RESULT_BUFFER_READ && !buffer.isEndOfStream()) { + boolean peek = (readFlags & FLAG_PEEK) != 0; + if ((readFlags & FLAG_OMIT_SAMPLE_DATA) == 0) { + if (peek) { + sampleDataQueue.peekToBuffer(buffer, extrasHolder); + } else { + sampleDataQueue.readToBuffer(buffer, extrasHolder); + } + } + if (!peek) { + readPosition++; + } } return result; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleStream.java index b426adbc20..6f061a9cd0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleStream.java @@ -30,7 +30,43 @@ import java.lang.annotation.RetentionPolicy; */ public interface SampleStream { - /** Return values of {@link #readData(FormatHolder, DecoderInputBuffer, boolean)}. */ + /** + * Flags that can be specified when calling {@link #readData}. Possible flag values are {@link + * #FLAG_PEEK}, {@link #FLAG_REQUIRE_FORMAT} and {@link #FLAG_OMIT_SAMPLE_DATA}. + */ + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef( + flag = true, + value = {FLAG_PEEK, FLAG_REQUIRE_FORMAT, FLAG_OMIT_SAMPLE_DATA}) + @interface ReadFlags {} + /** Specifies that the read position should not be advanced if a sample buffer is read. */ + int FLAG_PEEK = 1; + /** + * Specifies that if a sample buffer would normally be read next, the format of the stream should + * be read instead. In detail, the effect of this flag is as follows: + * + * + */ + int FLAG_REQUIRE_FORMAT = 1 << 1; + /** + * Specifies that {@link DecoderInputBuffer#data}, {@link DecoderInputBuffer#supplementalData} and + * {@link DecoderInputBuffer#cryptoInfo} should not be populated when reading a sample buffer. + * + *

This flag is useful for efficiently reading or (when combined with {@link #FLAG_PEEK}) + * peeking sample metadata. It can also be used for efficiency by a caller wishing to skip a + * sample buffer. + */ + int FLAG_OMIT_SAMPLE_DATA = 1 << 2; + + /** Return values of {@link #readData}. */ @Documented @Retention(RetentionPolicy.SOURCE) @IntDef({C.RESULT_NOTHING_READ, C.RESULT_FORMAT_READ, C.RESULT_BUFFER_READ}) @@ -38,10 +74,9 @@ public interface SampleStream { /** * Returns whether data is available to be read. - *

- * Note: If the stream has ended then a buffer with the end of stream flag can always be read from - * {@link #readData(FormatHolder, DecoderInputBuffer, boolean)}. Hence an ended stream is always - * ready. + * + *

Note: If the stream has ended then a buffer with the end of stream flag can always be read + * from {@link #readData}. Hence an ended stream is always ready. * * @return Whether data is available to be read. */ @@ -66,21 +101,15 @@ public interface SampleStream { * @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. If a {@link - * DecoderInputBuffer#isFlagsOnly() flags-only} buffer is passed and a sample is read, then - * only the buffer {@link DecoderInputBuffer#timeUs timestamp} and flags will be populated, - * and the read position will not be advanced. - * @param formatRequired Whether the caller requires that the format of the stream be read even if - * it's not changing. A sample will never be read if set to true, however it is still possible - * for the end of stream or nothing to be read. - * @return The status of read, one of {@link ReadDataResult}. - * @throws InsufficientCapacityException If the {@code buffer} is not a {@link - * DecoderInputBuffer#isFlagsOnly() flags-only} buffer and has insufficient capacity to hold + * C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer. + * @param readFlags Flags controlling the behavior of this read operation. + * @return The {@link ReadDataResult result} of the read operation. + * @throws InsufficientCapacityException If the {@code buffer} has insufficient capacity to hold * the data of a sample being read. The buffer {@link DecoderInputBuffer#timeUs timestamp} and * flags are populated if this exception is thrown, but the read position is not advanced. */ @ReadDataResult - int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired); + int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags); /** * Attempts to skip to the keyframe before the specified position, or to the end of the stream if @@ -90,5 +119,4 @@ public interface SampleStream { * @return The number of samples that were skipped. */ int skipData(long positionUs); - } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java index 447a3e3ad5..35e5e6f8c0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java @@ -292,8 +292,8 @@ public final class SilenceMediaSource extends BaseMediaSource { @Override public int readData( - FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) { - if (!sentFormat || formatRequired) { + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { + if (!sentFormat || (readFlags & FLAG_REQUIRE_FORMAT) != 0) { formatHolder.format = FORMAT; sentFormat = true; return C.RESULT_FORMAT_READ; @@ -307,14 +307,14 @@ public final class SilenceMediaSource extends BaseMediaSource { buffer.timeUs = getAudioPositionUs(positionBytes); buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME); - if (buffer.isFlagsOnly()) { - return C.RESULT_BUFFER_READ; - } - int bytesToWrite = (int) min(SILENCE_SAMPLE.length, bytesRemaining); - buffer.ensureSpaceForWrite(bytesToWrite); - buffer.data.put(SILENCE_SAMPLE, /* offset= */ 0, bytesToWrite); - positionBytes += bytesToWrite; + if ((readFlags & FLAG_OMIT_SAMPLE_DATA) == 0) { + buffer.ensureSpaceForWrite(bytesToWrite); + buffer.data.put(SILENCE_SAMPLE, /* offset= */ 0, bytesToWrite); + } + if ((readFlags & FLAG_PEEK) == 0) { + positionBytes += bytesToWrite; + } return C.RESULT_BUFFER_READ; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java index 9aeac9ca25..26438dbb77 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java @@ -349,31 +349,39 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public int readData( - FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) { + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { maybeNotifyDownstreamFormat(); if (streamState == STREAM_STATE_END_OF_STREAM) { buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); return C.RESULT_BUFFER_READ; - } else if (requireFormat || streamState == STREAM_STATE_SEND_FORMAT) { + } + + if ((readFlags & FLAG_REQUIRE_FORMAT) != 0 || streamState == STREAM_STATE_SEND_FORMAT) { formatHolder.format = format; streamState = STREAM_STATE_SEND_SAMPLE; return C.RESULT_FORMAT_READ; - } else if (loadingFinished) { - if (sampleData != null) { - buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME); - buffer.timeUs = 0; - if (buffer.isFlagsOnly()) { - return C.RESULT_BUFFER_READ; - } - buffer.ensureSpaceForWrite(sampleSize); - buffer.data.put(sampleData, 0, sampleSize); - } else { - buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); - } + } + + if (!loadingFinished) { + return C.RESULT_NOTHING_READ; + } + + if (sampleData == null) { + buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); streamState = STREAM_STATE_END_OF_STREAM; return C.RESULT_BUFFER_READ; } - return C.RESULT_NOTHING_READ; + + buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME); + buffer.timeUs = 0; + if ((readFlags & FLAG_OMIT_SAMPLE_DATA) == 0) { + buffer.ensureSpaceForWrite(sampleSize); + buffer.data.put(sampleData, 0, sampleSize); + } + if ((readFlags & FLAG_PEEK) == 0) { + streamState = STREAM_STATE_END_OF_STREAM; + } + return C.RESULT_BUFFER_READ; } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index c81204e3d2..f7c25e616e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -381,8 +381,8 @@ public class ChunkSampleStream implements SampleStream, S } @Override - public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired) { + public int readData( + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { if (isPendingReset()) { return C.RESULT_NOTHING_READ; } @@ -395,7 +395,7 @@ public class ChunkSampleStream implements SampleStream, S } maybeNotifyPrimaryTrackFormatChanged(); - return primarySampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished); + return primarySampleQueue.read(formatHolder, buffer, readFlags, loadingFinished); } @Override @@ -862,8 +862,8 @@ public class ChunkSampleStream implements SampleStream, S } @Override - public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired) { + public int readData( + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { if (isPendingReset()) { return C.RESULT_NOTHING_READ; } @@ -875,7 +875,7 @@ public class ChunkSampleStream implements SampleStream, S return C.RESULT_NOTHING_READ; } maybeNotifyDownstreamFormat(); - return sampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished); + return sampleQueue.read(formatHolder, buffer, readFlags, loadingFinished); } public void release() { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java index cbfd43775f..3177a70131 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java @@ -29,7 +29,7 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.RendererCapabilities; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; @@ -273,7 +273,7 @@ public final class TextRenderer extends BaseRenderer implements Callback { return; } // Try and read the next subtitle from the source. - @SampleStream.ReadDataResult int result = readSource(formatHolder, nextInputBuffer, false); + @ReadDataResult int result = readSource(formatHolder, nextInputBuffer, /* readFlags= */ 0); if (result == C.RESULT_BUFFER_READ) { if (nextInputBuffer.isEndOfStream()) { inputStreamEnded = true; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java index 894dd6bf4c..436fa00530 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.video; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_DRM_SESSION_CHANGED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static java.lang.Math.max; import android.os.Handler; @@ -41,7 +42,7 @@ import com.google.android.exoplayer2.decoder.DecoderReuseEvaluation; import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.ExoMediaCrypto; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.TimedValueQueue; @@ -165,7 +166,7 @@ public abstract class DecoderVideoRenderer extends BaseRenderer { joiningDeadlineMs = C.TIME_UNSET; clearReportedVideoSize(); formatQueue = new TimedValueQueue<>(); - flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance(); + flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance(); eventDispatcher = new EventDispatcher(eventHandler, eventListener); decoderReinitializationState = REINITIALIZATION_STATE_NONE; outputMode = C.VIDEO_OUTPUT_MODE_NONE; @@ -183,7 +184,7 @@ public abstract class DecoderVideoRenderer extends BaseRenderer { // We don't have a format yet, so try and read one. FormatHolder formatHolder = getFormatHolder(); flagsOnlyBuffer.clear(); - @SampleStream.ReadDataResult int result = readSource(formatHolder, flagsOnlyBuffer, true); + @ReadDataResult int result = readSource(formatHolder, flagsOnlyBuffer, FLAG_REQUIRE_FORMAT); if (result == C.RESULT_FORMAT_READ) { onInputFormatChanged(formatHolder); } else if (result == C.RESULT_BUFFER_READ) { @@ -745,7 +746,7 @@ public abstract class DecoderVideoRenderer extends BaseRenderer { } FormatHolder formatHolder = getFormatHolder(); - switch (readSource(formatHolder, inputBuffer, /* formatRequired= */ false)) { + switch (readSource(formatHolder, inputBuffer, /* readFlags= */ 0)) { case C.RESULT_NOTHING_READ: return false; case C.RESULT_FORMAT_READ: diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java index 287c62521e..6eaa2812c9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java @@ -24,7 +24,7 @@ import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; @@ -94,8 +94,7 @@ public final class CameraMotionRenderer extends BaseRenderer { while (!hasReadStreamToEnd() && lastTimestampUs < positionUs + SAMPLE_WINDOW_DURATION_US) { buffer.clear(); FormatHolder formatHolder = getFormatHolder(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, buffer, /* formatRequired= */ false); + @ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */ 0); if (result != C.RESULT_BUFFER_READ || buffer.isEndOfStream()) { return; } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaPeriodTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaPeriodTest.java index 4a756ccf9f..6847d4a518 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaPeriodTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/MergingMediaPeriodTest.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.source; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM; import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample; import static com.google.common.truth.Truth.assertThat; @@ -93,11 +94,11 @@ public final class MergingMediaPeriodTest { FormatHolder formatHolder = new FormatHolder(); DecoderInputBuffer inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); - assertThat(streams[1].readData(formatHolder, inputBuffer, /* formatRequired= */ true)) + assertThat(streams[1].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT)) .isEqualTo(C.RESULT_FORMAT_READ); assertThat(formatHolder.format).isEqualTo(childFormat12); - assertThat(streams[2].readData(formatHolder, inputBuffer, /* formatRequired= */ true)) + assertThat(streams[2].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT)) .isEqualTo(C.RESULT_FORMAT_READ); assertThat(formatHolder.format).isEqualTo(childFormat21); } @@ -134,20 +135,20 @@ public final class MergingMediaPeriodTest { FormatHolder formatHolder = new FormatHolder(); DecoderInputBuffer inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); - streams[0].readData(formatHolder, inputBuffer, /* formatRequired= */ true); - streams[1].readData(formatHolder, inputBuffer, /* formatRequired= */ true); + streams[0].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT); + streams[1].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT); FakeMediaPeriodWithSelectTracksPosition childMediaPeriod1 = (FakeMediaPeriodWithSelectTracksPosition) mergingMediaPeriod.getChildPeriod(0); assertThat(childMediaPeriod1.selectTracksPositionUs).isEqualTo(0); - assertThat(streams[0].readData(formatHolder, inputBuffer, /* formatRequired= */ false)) + assertThat(streams[0].readData(formatHolder, inputBuffer, /* readFlags= */ 0)) .isEqualTo(C.RESULT_BUFFER_READ); assertThat(inputBuffer.timeUs).isEqualTo(123_000L); FakeMediaPeriodWithSelectTracksPosition childMediaPeriod2 = (FakeMediaPeriodWithSelectTracksPosition) mergingMediaPeriod.getChildPeriod(1); assertThat(childMediaPeriod2.selectTracksPositionUs).isEqualTo(3000L); - assertThat(streams[1].readData(formatHolder, inputBuffer, /* formatRequired= */ false)) + assertThat(streams[1].readData(formatHolder, inputBuffer, /* readFlags= */ 0)) .isEqualTo(C.RESULT_BUFFER_READ); assertThat(inputBuffer.timeUs).isEqualTo(456_000 - 3000); } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java index db9eee2ba2..8ce5c999f7 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java @@ -20,6 +20,8 @@ import static com.google.android.exoplayer2.C.BUFFER_FLAG_KEY_FRAME; import static com.google.android.exoplayer2.C.RESULT_BUFFER_READ; import static com.google.android.exoplayer2.C.RESULT_FORMAT_READ; import static com.google.android.exoplayer2.C.RESULT_NOTHING_READ; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_OMIT_SAMPLE_DATA; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_PEEK; import static com.google.common.truth.Truth.assertThat; import static java.lang.Long.MAX_VALUE; import static java.lang.Long.MIN_VALUE; @@ -208,14 +210,11 @@ public final class SampleQueueTest { sampleQueue.format(FORMAT_1); clearFormatHolderAndInputBuffer(); int result = - sampleQueue.peek( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + sampleQueue.read(formatHolder, inputBuffer, FLAG_PEEK, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); // formatHolder should be populated. assertThat(formatHolder.format).isEqualTo(FORMAT_1); - result = - sampleQueue.peek( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + result = sampleQueue.read(formatHolder, inputBuffer, FLAG_PEEK, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_NOTHING_READ); } @@ -454,7 +453,7 @@ public final class SampleQueueTest { int result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); assertReadEncryptedSample(/* sampleIndex= */ 0); @@ -463,13 +462,13 @@ public final class SampleQueueTest { assertThat(formatHolder.drmSession).isNull(); result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isNull(); assertReadEncryptedSample(/* sampleIndex= */ 2); result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); } @@ -484,7 +483,7 @@ public final class SampleQueueTest { int result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); assertReadEncryptedSample(/* sampleIndex= */ 0); @@ -493,13 +492,13 @@ public final class SampleQueueTest { assertThat(formatHolder.drmSession).isNull(); result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockPlaceholderDrmSession); assertReadEncryptedSample(/* sampleIndex= */ 2); result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); assertThat(formatHolder.drmSession).isSameInstanceAs(mockDrmSession); assertReadEncryptedSample(/* sampleIndex= */ 3); @@ -527,7 +526,7 @@ public final class SampleQueueTest { int result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); // Fill cryptoInfo.iv with non-zero data. When the 8 byte initialization vector is written into @@ -537,7 +536,7 @@ public final class SampleQueueTest { result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_BUFFER_READ); // Assert cryptoInfo.iv contains the 8-byte initialization vector and that the trailing 8 bytes @@ -1558,7 +1557,11 @@ public final class SampleQueueTest { private void assertReadNothing(boolean formatRequired) { clearFormatHolderAndInputBuffer(); int result = - sampleQueue.read(formatHolder, inputBuffer, formatRequired, /* loadingFinished= */ false); + sampleQueue.read( + formatHolder, + inputBuffer, + formatRequired ? SampleStream.FLAG_REQUIRE_FORMAT : 0, + /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_NOTHING_READ); // formatHolder should not be populated. assertThat(formatHolder.format).isNull(); @@ -1576,7 +1579,11 @@ public final class SampleQueueTest { private void assertReadEndOfStream(boolean formatRequired) { clearFormatHolderAndInputBuffer(); int result = - sampleQueue.read(formatHolder, inputBuffer, formatRequired, /* loadingFinished= */ true); + sampleQueue.read( + formatHolder, + inputBuffer, + formatRequired ? SampleStream.FLAG_REQUIRE_FORMAT : 0, + /* loadingFinished= */ true); assertThat(result).isEqualTo(RESULT_BUFFER_READ); // formatHolder should not be populated. assertThat(formatHolder.format).isNull(); @@ -1597,7 +1604,11 @@ public final class SampleQueueTest { private void assertReadFormat(boolean formatRequired, Format format) { clearFormatHolderAndInputBuffer(); int result = - sampleQueue.read(formatHolder, inputBuffer, formatRequired, /* loadingFinished= */ false); + sampleQueue.read( + formatHolder, + inputBuffer, + formatRequired ? SampleStream.FLAG_REQUIRE_FORMAT : 0, + /* loadingFinished= */ false); assertThat(result).isEqualTo(RESULT_FORMAT_READ); // formatHolder should be populated. assertThat(formatHolder.format).isEqualTo(format); @@ -1641,24 +1652,51 @@ public final class SampleQueueTest { byte[] sampleData, int offset, int length) { - // Check that peeks yields the expected values. - clearFormatHolderAndInputBuffer(); + // Check that peek whilst omitting data yields the expected values. + formatHolder.format = null; + DecoderInputBuffer flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance(); int result = - sampleQueue.peek( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); - assertBufferReadResult( + sampleQueue.read( + formatHolder, + flagsOnlyBuffer, + FLAG_OMIT_SAMPLE_DATA | FLAG_PEEK, + /* loadingFinished= */ false); + assertSampleBufferReadResult( + flagsOnlyBuffer, result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted); + + // Check that peek yields the expected values. + clearFormatHolderAndInputBuffer(); + result = sampleQueue.read(formatHolder, inputBuffer, FLAG_PEEK, /* loadingFinished= */ false); + assertSampleBufferReadResult( result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted, sampleData, offset, length); // Check that read yields the expected values. clearFormatHolderAndInputBuffer(); result = sampleQueue.read( - formatHolder, inputBuffer, /* formatRequired= */ false, /* loadingFinished= */ false); - assertBufferReadResult( + formatHolder, inputBuffer, /* readFlags= */ 0, /* loadingFinished= */ false); + assertSampleBufferReadResult( result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted, sampleData, offset, length); } - private void assertBufferReadResult( + private void assertSampleBufferReadResult( + DecoderInputBuffer inputBuffer, + int result, + long timeUs, + boolean isKeyFrame, + boolean isDecodeOnly, + boolean isEncrypted) { + assertThat(result).isEqualTo(RESULT_BUFFER_READ); + // formatHolder should not be populated. + assertThat(formatHolder.format).isNull(); + // inputBuffer should be populated with metadata. + assertThat(inputBuffer.timeUs).isEqualTo(timeUs); + assertThat(inputBuffer.isKeyFrame()).isEqualTo(isKeyFrame); + assertThat(inputBuffer.isDecodeOnly()).isEqualTo(isDecodeOnly); + assertThat(inputBuffer.isEncrypted()).isEqualTo(isEncrypted); + } + + private void assertSampleBufferReadResult( int result, long timeUs, boolean isKeyFrame, @@ -1667,14 +1705,9 @@ public final class SampleQueueTest { byte[] sampleData, int offset, int length) { - assertThat(result).isEqualTo(RESULT_BUFFER_READ); - // formatHolder should not be populated. - assertThat(formatHolder.format).isNull(); - // inputBuffer should be populated. - assertThat(inputBuffer.timeUs).isEqualTo(timeUs); - assertThat(inputBuffer.isKeyFrame()).isEqualTo(isKeyFrame); - assertThat(inputBuffer.isDecodeOnly()).isEqualTo(isDecodeOnly); - assertThat(inputBuffer.isEncrypted()).isEqualTo(isEncrypted); + assertSampleBufferReadResult( + inputBuffer, result, timeUs, isKeyFrame, isDecodeOnly, isEncrypted); + // inputBuffer should be populated with data. inputBuffer.flip(); assertThat(inputBuffer.data.limit()).isEqualTo(length); byte[] readData = new byte[length]; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java index 66fcd280c6..1abe48a047 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/EventSampleStream.java @@ -98,9 +98,9 @@ import java.io.IOException; } @Override - public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean formatRequired) { - if (formatRequired || !isFormatSentDownstream) { + public int readData( + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { + if ((readFlags & FLAG_REQUIRE_FORMAT) != 0 || !isFormatSentDownstream) { formatHolder.format = upstreamFormat; isFormatSentDownstream = true; return C.RESULT_FORMAT_READ; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java index 65a83a4829..5efc452134 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java @@ -360,8 +360,7 @@ public final class PlayerEmsgHandler implements Handler.Callback { private MetadataInputBuffer dequeueSample() { buffer.clear(); int result = - sampleQueue.read( - formatHolder, buffer, /* formatRequired= */ false, /* loadingFinished= */ false); + sampleQueue.read(formatHolder, buffer, /* readFlags= */ 0, /* loadingFinished= */ false); if (result == C.RESULT_BUFFER_READ) { buffer.flip(); return buffer; diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java index 11f4b37c67..348290eb69 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/EventSampleStreamTest.java @@ -58,7 +58,7 @@ public final class EventSampleStreamTest { } /** - * Tests that {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} will + * Tests that {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} will * return format for the first call. */ @Test @@ -106,7 +106,7 @@ public final class EventSampleStreamTest { } /** - * Tests that {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} will + * Tests that {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} will * return sample data after the first call. */ @Test @@ -127,8 +127,8 @@ public final class EventSampleStreamTest { /** * Tests that {@link EventSampleStream#skipData(long)} will skip until the given position, and the - * next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call will - * return sample data from that position. + * next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return + * sample data from that position. */ @Test public void skipDataThenReadDataReturnDataFromSkippedPosition() { @@ -153,7 +153,7 @@ public final class EventSampleStreamTest { /** * Tests that {@link EventSampleStream#seekToUs(long)} (long)} will seek to the given position, - * and the next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call + * and the next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call * will return sample data from that position. */ @Test @@ -179,8 +179,8 @@ public final class EventSampleStreamTest { /** * Tests that {@link EventSampleStream#updateEventStream(EventStream, boolean)} will update the * underlying event stream, but keep the read timestamp, so the next {@link - * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call will return sample - * data from after the last read sample timestamp. + * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return sample data + * from after the last read sample timestamp. */ @Test public void updateEventStreamContinueToReadAfterLastReadSamplePresentationTime() { @@ -213,8 +213,8 @@ public final class EventSampleStreamTest { /** * Tests that {@link EventSampleStream#updateEventStream(EventStream, boolean)} will update the * underlying event stream, but keep the timestamp the stream has skipped to, so the next {@link - * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call will return sample - * data from the skipped position. + * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return sample data + * from the skipped position. */ @Test public void skipDataThenUpdateStreamContinueToReadFromSkippedPosition() { @@ -246,8 +246,8 @@ public final class EventSampleStreamTest { * Tests that {@link EventSampleStream#skipData(long)} will only skip to the point right after it * last event. A following {@link EventSampleStream#updateEventStream(EventStream, boolean)} will * update the underlying event stream and keep the timestamp the stream has skipped to, so the - * next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call will - * return sample data from the skipped position. + * next {@link EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return + * sample data from the skipped position. */ @Test public void skipDataThenUpdateStreamContinueToReadDoNotSkippedMoreThanAvailable() { @@ -280,8 +280,8 @@ public final class EventSampleStreamTest { /** * Tests that {@link EventSampleStream#updateEventStream(EventStream, boolean)} will update the * underlying event stream, but keep the timestamp the stream has seek to, so the next {@link - * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call will return sample - * data from the seek position. + * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return sample data + * from the seek position. */ @Test public void seekToUsThenUpdateStreamContinueToReadFromSeekPosition() { @@ -312,8 +312,8 @@ public final class EventSampleStreamTest { /** * Tests that {@link EventSampleStream#updateEventStream(EventStream, boolean)} will update the * underlying event stream, but keep the timestamp the stream has seek to, so the next {@link - * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, boolean)} call will return sample - * data from the seek position. + * EventSampleStream#readData(FormatHolder, DecoderInputBuffer, int)} call will return sample data + * from the seek position. */ @Test public void seekToThenUpdateStreamContinueToReadFromSeekPositionEvenSeekMoreThanAvailable() { @@ -343,7 +343,7 @@ public final class EventSampleStreamTest { private int readData(EventSampleStream sampleStream) { inputBuffer.clear(); - return sampleStream.readData(formatHolder, inputBuffer, false); + return sampleStream.readData(formatHolder, inputBuffer, /* readFlags= */ 0); } private EventMessage newEventMessageWithId(int id) { diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java index c820038b80..53d9b0cd9e 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStream.java @@ -70,13 +70,14 @@ import java.io.IOException; } @Override - public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) { + public int readData( + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { if (sampleQueueIndex == HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_NO_MAPPING_NON_FATAL) { buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); return C.RESULT_BUFFER_READ; } return hasValidSampleQueueIndex() - ? sampleStreamWrapper.readData(sampleQueueIndex, formatHolder, buffer, requireFormat) + ? sampleStreamWrapper.readData(sampleQueueIndex, formatHolder, buffer, readFlags) : C.RESULT_NOTHING_READ; } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index df1c598be5..3986995389 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -48,6 +48,7 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.SampleQueue; import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener; import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadFlags; import com.google.android.exoplayer2.source.SequenceableLoader; import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroupArray; @@ -569,8 +570,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; chunkSource.maybeThrowError(); } - public int readData(int sampleQueueIndex, FormatHolder formatHolder, DecoderInputBuffer buffer, - boolean requireFormat) { + public int readData( + int sampleQueueIndex, + FormatHolder formatHolder, + DecoderInputBuffer buffer, + @ReadFlags int readFlags) { if (isPendingReset()) { return C.RESULT_NOTHING_READ; } @@ -602,7 +606,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } int result = - sampleQueues[sampleQueueIndex].read(formatHolder, buffer, requireFormat, loadingFinished); + sampleQueues[sampleQueueIndex].read(formatHolder, buffer, readFlags, loadingFinished); if (result == C.RESULT_FORMAT_READ) { Format format = Assertions.checkNotNull(formatHolder.format); if (sampleQueueIndex == primarySampleQueueIndex) { diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerAudioRenderer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerAudioRenderer.java index c0fc23bb78..c5be7dc029 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerAudioRenderer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerAudioRenderer.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.transformer; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkState; import static java.lang.Math.min; @@ -31,7 +32,7 @@ import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.AudioProcessor.AudioFormat; import com.google.android.exoplayer2.audio.SonicAudioProcessor; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import java.io.IOException; import java.nio.ByteBuffer; @@ -273,8 +274,8 @@ import java.nio.ByteBuffer; } decoderInputBuffer.clear(); - @SampleStream.ReadDataResult - int result = readSource(getFormatHolder(), decoderInputBuffer, /* formatRequired= */ false); + @ReadDataResult + int result = readSource(getFormatHolder(), decoderInputBuffer, /* readFlags= */ 0); switch (result) { case C.RESULT_BUFFER_READ: mediaClock.updateTimeForTrackType(getTrackType(), decoderInputBuffer.timeUs); @@ -373,8 +374,7 @@ import java.nio.ByteBuffer; } FormatHolder formatHolder = getFormatHolder(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, decoderInputBuffer, /* formatRequired= */ true); + @ReadDataResult int result = readSource(formatHolder, decoderInputBuffer, FLAG_REQUIRE_FORMAT); if (result != C.RESULT_FORMAT_READ) { return false; } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerVideoRenderer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerVideoRenderer.java index 621dab6f5c..bbc135448d 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerVideoRenderer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerVideoRenderer.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.transformer; +import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import androidx.annotation.Nullable; @@ -24,7 +25,7 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import java.nio.ByteBuffer; @RequiresApi(18) @@ -59,8 +60,7 @@ import java.nio.ByteBuffer; if (!formatRead) { FormatHolder formatHolder = getFormatHolder(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, buffer, /* formatRequired= */ true); + @ReadDataResult int result = readSource(formatHolder, buffer, FLAG_REQUIRE_FORMAT); if (result != C.RESULT_FORMAT_READ) { return; } @@ -102,8 +102,7 @@ import java.nio.ByteBuffer; */ private boolean readAndTransformBuffer() { buffer.clear(); - @SampleStream.ReadDataResult - int result = readSource(getFormatHolder(), buffer, /* formatRequired= */ false); + @ReadDataResult int result = readSource(getFormatHolder(), buffer, /* readFlags= */ 0); if (result == C.RESULT_FORMAT_READ) { throw new IllegalStateException("Format changes are not supported."); } else if (result == C.RESULT_NOTHING_READ) { diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java index de0bc99fe2..c0b6335ae8 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeRenderer.java @@ -25,7 +25,7 @@ import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.drm.DrmSession; -import com.google.android.exoplayer2.source.SampleStream; +import com.google.android.exoplayer2.source.SampleStream.ReadDataResult; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; @@ -92,8 +92,7 @@ public class FakeRenderer extends BaseRenderer { if (!hasPendingBuffer) { FormatHolder formatHolder = getFormatHolder(); buffer.clear(); - @SampleStream.ReadDataResult - int result = readSource(formatHolder, buffer, /* formatRequired= */ false); + @ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */ 0); if (result == C.RESULT_FORMAT_READ) { DrmSession.replaceSession(currentDrmSession, formatHolder.drmSession); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java index 52f0f29193..f3f235cd2f 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java @@ -43,7 +43,7 @@ import java.util.List; */ public class FakeSampleStream implements SampleStream { - /** Item to customize a return value of {@link FakeSampleStream#readData}. */ + /** Item to customize a return value of {@link SampleStream#readData}. */ public static final class FakeSampleStreamItem { /** Item that designates the end of stream has been reached. */ @@ -265,12 +265,12 @@ public class FakeSampleStream implements SampleStream { @Override public int readData( - FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) { - int result = sampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished); + FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) { + int result = sampleQueue.read(formatHolder, buffer, readFlags, loadingFinished); if (result == C.RESULT_FORMAT_READ) { downstreamFormat = checkNotNull(formatHolder.format); } - if (result == C.RESULT_BUFFER_READ && !buffer.isFlagsOnly()) { + if (result == C.RESULT_BUFFER_READ && (readFlags & FLAG_OMIT_SAMPLE_DATA) == 0) { maybeNotifyDownstreamFormat(buffer.timeUs); } return result;