From 796781d4c365e31a196c96e0588e4ff5ff0e3bf0 Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 3 Oct 2023 08:46:18 -0700 Subject: [PATCH] Move decode-only handling out of MetadataDecoder interface logic The interface requires the implementation to return null if the decode-only flag is set. So instead of setting the flag and returning null, we can simply not call the method and assume it's null. The only reason where this wouldn't work is if the metadata format has keyframe-like logic and requires previous metadata to decode the next one. This is not something we came across before and it seems ignorable. If that feature is needed in the future, we should instead add a method to MetadataDecoder to set the first output timestamp. #minor-release PiperOrigin-RevId: 570399838 --- RELEASENOTES.md | 2 ++ .../media3/exoplayer/metadata/MetadataRenderer.java | 6 ++---- .../media3/extractor/metadata/MetadataDecoder.java | 3 +-- .../extractor/metadata/SimpleMetadataDecoder.java | 7 ++----- .../metadata/SimpleMetadataDecoderTest.java | 12 ------------ 5 files changed, 7 insertions(+), 23 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 56a597d916..ae2ea8ffd5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -11,6 +11,8 @@ * Video: * Text: * Metadata: + * `MetadataDecoder.decode` will no longer be called for "decode-only" + samples as the implementation must return null anyway. * DRM: * Effect: * Muxers: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java index f80d7a6062..2cc29733ba 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java @@ -238,11 +238,9 @@ public final class MetadataRenderer extends BaseRenderer implements Callback { if (result == C.RESULT_BUFFER_READ) { if (buffer.isEndOfStream()) { inputStreamEnded = true; - } else { + } else if (buffer.timeUs >= getLastResetPositionUs()) { + // Ignore metadata before start position. buffer.subsampleOffsetUs = subsampleOffsetUs; - if (buffer.timeUs < getLastResetPositionUs()) { - buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY); - } buffer.flip(); @Nullable Metadata metadata = castNonNull(decoder).decode(buffer); if (metadata != null) { diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/MetadataDecoder.java b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/MetadataDecoder.java index fc456a1943..b8e475a2e5 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/MetadataDecoder.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/MetadataDecoder.java @@ -32,8 +32,7 @@ public interface MetadataDecoder { * ByteBuffer#hasArray()} is true. * * @param inputBuffer The input buffer to decode. - * @return The decoded metadata object, or {@code null} if the metadata could not be decoded or if - * {@link MetadataInputBuffer#isDecodeOnly()} was set on the input buffer. + * @return The decoded metadata object, or {@code null} if the metadata could not be decoded. */ @Nullable Metadata decode(MetadataInputBuffer inputBuffer); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/SimpleMetadataDecoder.java b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/SimpleMetadataDecoder.java index 6345df54c2..7919ef18dc 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/SimpleMetadataDecoder.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/SimpleMetadataDecoder.java @@ -21,10 +21,7 @@ import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import java.nio.ByteBuffer; -/** - * A {@link MetadataDecoder} base class that validates input buffers and discards any for which - * {@link MetadataInputBuffer#isDecodeOnly()} is {@code true}. - */ +/** A {@link MetadataDecoder} base class that validates input buffers. */ @UnstableApi public abstract class SimpleMetadataDecoder implements MetadataDecoder { @@ -34,7 +31,7 @@ public abstract class SimpleMetadataDecoder implements MetadataDecoder { ByteBuffer buffer = Assertions.checkNotNull(inputBuffer.data); Assertions.checkArgument( buffer.position() == 0 && buffer.hasArray() && buffer.arrayOffset() == 0); - return inputBuffer.isDecodeOnly() ? null : decode(inputBuffer, buffer); + return decode(inputBuffer, buffer); } /** diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/SimpleMetadataDecoderTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/SimpleMetadataDecoderTest.java index 58f21bb22c..000809ee16 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/SimpleMetadataDecoderTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/SimpleMetadataDecoderTest.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import androidx.annotation.Nullable; -import androidx.media3.common.C; import androidx.media3.common.Metadata; import androidx.test.ext.junit.runners.AndroidJUnit4; import java.nio.ByteBuffer; @@ -72,17 +71,6 @@ public class SimpleMetadataDecoderTest { assertThat(decoder.decodeWasCalled).isFalse(); } - @Test - public void decode_decodeOnlyBuffer_notPassedToDecodeInternal() { - TestSimpleMetadataDecoder decoder = new TestSimpleMetadataDecoder(); - MetadataInputBuffer decodeOnlyBuffer = new MetadataInputBuffer(); - decodeOnlyBuffer.data = ByteBuffer.wrap(new byte[8]); - decodeOnlyBuffer.setFlags(C.BUFFER_FLAG_DECODE_ONLY); - - assertThat(decoder.decode(decodeOnlyBuffer)).isNull(); - assertThat(decoder.decodeWasCalled).isFalse(); - } - @Test public void decode_returnsDecodeInternalResult() { TestSimpleMetadataDecoder decoder = new TestSimpleMetadataDecoder();