From af546b8eda50d03b7851b0207c1a087363b1b194 Mon Sep 17 00:00:00 2001 From: claincly Date: Wed, 2 Aug 2023 11:28:53 +0000 Subject: [PATCH] Fix decoder is queued buffer with timestamp TIME_END_OF_SOURCE ExoPlayer queues the EOS buffer to the decoder with offset/size/timestamp all equal to zero, and a EOS flag. https://github.com/androidx/media/commit/69769c77b326570671daf924862ec9399830b61c set TIME_END_OF_SOURCE on the EOS buffer from the extractor. Queueing the EOS buffer to the decoder with TIME_END_OF_SOURCE causes some decoders to output wrong timestamps in its output. This CL replicates what ExoPlayer does in Transformer. PiperOrigin-RevId: 553104213 --- .../media3/transformer/DefaultCodec.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultCodec.java b/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultCodec.java index 3ca57a6312..97ce47a5dd 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultCodec.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultCodec.java @@ -209,20 +209,30 @@ public final class DefaultCodec implements Codec { int offset = 0; int size = 0; + int flags = 0; if (inputBuffer.data != null && inputBuffer.data.hasRemaining()) { offset = inputBuffer.data.position(); size = inputBuffer.data.remaining(); } - int flags = 0; + long timestampUs = inputBuffer.timeUs; + if (inputBuffer.isEndOfStream()) { inputStreamEnded = true; flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM; - if (isVideo && isDecoder) { - DebugTraceUtil.logEvent(DebugTraceUtil.EVENT_DECODER_RECEIVE_EOS, C.TIME_END_OF_SOURCE); + + if (isDecoder) { + if (isVideo) { + DebugTraceUtil.logEvent(DebugTraceUtil.EVENT_DECODER_RECEIVE_EOS, C.TIME_END_OF_SOURCE); + } + // EOS buffer on the decoder input should never carry data. + checkState(inputBuffer.data == null || !inputBuffer.data.hasRemaining()); + offset = 0; + size = 0; + timestampUs = 0; } } try { - mediaCodec.queueInputBuffer(inputBufferIndex, offset, size, inputBuffer.timeUs, flags); + mediaCodec.queueInputBuffer(inputBufferIndex, offset, size, timestampUs, flags); } catch (RuntimeException e) { Log.d(TAG, "MediaCodec error", e); throw createExportException(e);