diff --git a/libraries/common/src/main/java/androidx/media3/common/Format.java b/libraries/common/src/main/java/androidx/media3/common/Format.java index 188a7f25d8..046a86fe51 100644 --- a/libraries/common/src/main/java/androidx/media3/common/Format.java +++ b/libraries/common/src/main/java/androidx/media3/common/Format.java @@ -196,6 +196,9 @@ public final class Format { private @C.CryptoType int cryptoType; + // Extra custom data added to the class. + @Nullable private Object customData; + /** Creates a new instance with default values. */ public Builder() { labels = ImmutableList.of(); @@ -273,6 +276,8 @@ public final class Format { this.tileCountVertical = format.tileCountVertical; // Provided by the source. this.cryptoType = format.cryptoType; + // Extra custom data added to the class. + this.customData = format.customData; } /** @@ -729,6 +734,20 @@ public final class Format { return this; } + // Extra custom data added to the class. + + /** + * Sets the opaque object {@link Format#customData}. The default value is null. + * + * @param customData The {@link Format#customData}. + * @return The builder. + */ + @CanIgnoreReturnValue + public Builder setCustomData(@Nullable Object customData) { + this.customData = customData; + return this; + } + // Build. public Format build() { @@ -985,6 +1004,12 @@ public final class Format { */ @UnstableApi public final @C.CryptoType int cryptoType; + /** + * An extra opaque object that can be added to the {@link Format} to provide additional information + * that can be passed through the player. + */ + @UnstableApi @Nullable public final Object customData; + // Lazily initialized hashcode. private int hashCode; @@ -1060,6 +1085,8 @@ public final class Format { } else { cryptoType = builder.cryptoType; } + // Extra custom data added to the class. + customData = builder.customData; } /** Returns a {@link Format.Builder} initialized with the values of this instance. */ @@ -1234,6 +1261,8 @@ public final class Format { result = 31 * result + tileCountVertical; // Provided by the source. result = 31 * result + cryptoType; + // Extra custom data added to the class. + result = 31 * result + (customData == null ? 0 : customData.hashCode()); hashCode = result; } return hashCode; @@ -1284,7 +1313,8 @@ public final class Format { && Util.areEqual(metadata, other.metadata) && Util.areEqual(colorInfo, other.colorInfo) && Util.areEqual(drmInitData, other.drmInitData) - && initializationDataEquals(other); + && initializationDataEquals(other) + && Util.areEqual(customData, other.customData); } /** @@ -1382,6 +1412,9 @@ public final class Format { Joiner.on(',').appendTo(builder, Util.getRoleFlagStrings(format.roleFlags)); builder.append("]"); } + if (format.customData != null) { + builder.append(", customData=").append(format.customData); + } return builder.toString(); } diff --git a/libraries/common/src/test/java/androidx/media3/common/FormatTest.java b/libraries/common/src/test/java/androidx/media3/common/FormatTest.java index e95ee68631..a216276b71 100644 --- a/libraries/common/src/test/java/androidx/media3/common/FormatTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/FormatTest.java @@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import android.os.Bundle; +import androidx.media3.common.util.Util; import androidx.media3.test.utils.FakeMetadataEntry; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; @@ -35,6 +36,36 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public final class FormatTest { + public static class ExoCustomData { + public final String extraMetadata; + public final int customInt; + + public ExoCustomData(String extraMetadata, int customInt) { + this.extraMetadata = extraMetadata; + this.customInt = customInt; + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + (extraMetadata == null ? 0 : extraMetadata.hashCode()); + result = 31 * result + customInt; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + ExoCustomData other = (ExoCustomData) obj; + return Util.areEqual(extraMetadata, other.extraMetadata) && customInt == other.customInt; + } + } + @Test public void buildUponFormat_createsEqualFormat() { Format testFormat = createTestFormat(); @@ -116,7 +147,16 @@ public final class FormatTest { .build()); } - private static Format createTestFormat() { + @Test + public void copyFormat_copiesCustomData() { + Format format = createTestFormat().buildUpon().setCustomData(new ExoCustomData("CustomData", 100)).build(); + + Format copy = format.buildUpon().build(); + assertThat(format.customData).isEqualTo(copy.customData); + assertThat(format.customData).isEqualTo(new ExoCustomData("CustomData", 100)); + } + +private static Format createTestFormat() { byte[] initData1 = new byte[] {1, 2, 3}; byte[] initData2 = new byte[] {4, 5, 6}; List initializationData = new ArrayList<>(); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java index 12b4860c13..5a40f90214 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java @@ -449,6 +449,7 @@ public abstract class DecoderAudioRenderer< .setEncoderDelay(encoderDelay) .setEncoderPadding(encoderPadding) .setMetadata(inputFormat.metadata) + .setCustomData(inputFormat.customData) .setId(inputFormat.id) .setLabel(inputFormat.label) .setLabels(inputFormat.labels) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java index 24d4cf307b..e3329d2739 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java @@ -573,6 +573,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media .setEncoderDelay(format.encoderDelay) .setEncoderPadding(format.encoderPadding) .setMetadata(format.metadata) + .setCustomData(format.customData) .setId(format.id) .setLabel(format.label) .setLabels(format.labels)