From 782f5b2a0e3f59be62e4a41cae3910cd29b1692f Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 25 Jul 2023 17:01:07 +0100 Subject: [PATCH] Fix last sample detection issues 1. For codecs that change timestamps, we need to use greater or equal instead of just equal for comparison. 2. We should only make this comparison once a value has been set. 3. The largest queue timestamp isn't updated before using it for this detection, meaning that we also mark the second-to-last sample as the last one. PiperOrigin-RevId: 550901978 --- .../exoplayer/mediacodec/MediaCodecRenderer.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java index 83cdeef82a..b611612f33 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java @@ -1305,11 +1305,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer { return true; } - if (hasReadStreamToEnd() || buffer.isLastSample()) { - // Notify output queue of the last buffer's timestamp. - lastBufferInStreamPresentationTimeUs = largestQueuedPresentationTimeUs; - } - if (result == C.RESULT_NOTHING_READ) { return false; } @@ -1397,6 +1392,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer { waitingForFirstSampleInFormat = false; } largestQueuedPresentationTimeUs = max(largestQueuedPresentationTimeUs, presentationTimeUs); + if (hasReadStreamToEnd() || buffer.isLastSample()) { + // Notify output queue of the last buffer's timestamp. + lastBufferInStreamPresentationTimeUs = largestQueuedPresentationTimeUs; + } buffer.flip(); if (buffer.hasSupplementalData()) { handleInputBufferSupplementalData(buffer); @@ -1915,11 +1914,12 @@ public abstract class MediaCodecRenderer extends BaseRenderer { && outputBufferInfo.presentationTimeUs == 0 && (outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0 && largestQueuedPresentationTimeUs != C.TIME_UNSET) { - outputBufferInfo.presentationTimeUs = largestQueuedPresentationTimeUs; + outputBufferInfo.presentationTimeUs = lastBufferInStreamPresentationTimeUs; } isDecodeOnlyOutputBuffer = outputBufferInfo.presentationTimeUs < getLastResetPositionUs(); isLastOutputBuffer = - lastBufferInStreamPresentationTimeUs == outputBufferInfo.presentationTimeUs; + lastBufferInStreamPresentationTimeUs != C.TIME_UNSET + && lastBufferInStreamPresentationTimeUs <= outputBufferInfo.presentationTimeUs; updateOutputFormatForTime(outputBufferInfo.presentationTimeUs); }