diff --git a/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java b/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java
index ece0392d9c..f74fb4f523 100644
--- a/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java
+++ b/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java
@@ -43,6 +43,7 @@ import org.junit.runners.Parameterized.Parameters;
/** End to end parameterized instrumentation tests for {@link Mp4Muxer}. */
@RunWith(Parameterized.class)
public class Mp4MuxerEndToEndParameterizedAndroidTest {
+ // Video Codecs
private static final String H263_3GP = "bbb_176x144_128kbps_15fps_h263.3gp";
private static final String H264_MP4 = "sample_no_bframes.mp4";
private static final String H264_WITH_NON_REFERENCE_B_FRAMES_MP4 =
@@ -52,9 +53,14 @@ public class Mp4MuxerEndToEndParameterizedAndroidTest {
private static final String H265_HDR10_MP4 = "hdr10-720p.mp4";
private static final String H265_WITH_METADATA_TRACK_MP4 = "h265_with_metadata_track.mp4";
private static final String AV1_MP4 = "sample_av1.mp4";
+ private static final String MPEG4_MP4 = "bbb_176x144_192kbps_15fps_mpeg4.mp4";
+ // Contains CSD in vpcC format.
+ private static final String VP9_MP4 = "bbb_800x640_768kbps_30fps_vp9.mp4";
+ // Contains CSD in CodecPrivate format.
+ private static final String VP9_WEB = "bbb_642x642_768kbps_30fps_vp9.webm";
+ // Audio Codecs
private static final String AMR_NB_3GP = "bbb_mono_8kHz_12.2kbps_amrnb.3gp";
private static final String AMR_WB_3GP = "bbb_mono_16kHz_23.05kbps_amrwb.3gp";
- private static final String MPEG4_MP4 = "bbb_176x144_192kbps_15fps_mpeg4.mp4";
private static final String OPUS_OGG = "bbb_6ch_8kHz_opus.ogg";
private static final String VORBIS_OGG = "bbb_1ch_16kHz_q10_vorbis.ogg";
@@ -68,9 +74,11 @@ public class Mp4MuxerEndToEndParameterizedAndroidTest {
H265_HDR10_MP4,
H265_WITH_METADATA_TRACK_MP4,
AV1_MP4,
+ MPEG4_MP4,
+ VP9_MP4,
+ VP9_WEB,
AMR_NB_3GP,
AMR_WB_3GP,
- MPEG4_MP4,
OPUS_OGG,
VORBIS_OGG);
}
diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
index 76ac437491..202cadf243 100644
--- a/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
+++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
@@ -38,6 +38,7 @@ import androidx.media3.muxer.FragmentedMp4Writer.SampleMetadata;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Bytes;
+import com.google.common.primitives.Ints;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -542,6 +543,8 @@ import java.util.List;
return av1CBox(format);
case MimeTypes.VIDEO_MP4V:
return esdsBox(format);
+ case MimeTypes.VIDEO_VP9:
+ return vpcCBox(format);
default:
throw new IllegalArgumentException("Unsupported format: " + mimeType);
}
@@ -592,6 +595,9 @@ import java.util.List;
contents.putShort((short) -1); // pre_defined
contents.put(codecSpecificBox);
+ if (format.colorInfo != null && fourcc.equals("vp09")) {
+ contents.put(smDmBox(format.colorInfo));
+ }
contents.put(paspBox());
@@ -1264,6 +1270,110 @@ import java.util.List;
return BoxUtils.wrapIntoBox("av1C", ByteBuffer.wrap(csd0));
}
+ /** Returns the vpcC box as per VP Codec ISO Media File Format Binding v1.0. */
+ private static ByteBuffer vpcCBox(Format format) {
+ // For VP9, the CodecPrivate or vpcCBox data is packed into csd-0.
+ checkArgument(!format.initializationData.isEmpty(), "csd-0 is not found in the format");
+ byte[] csd0 = format.initializationData.get(0);
+ checkArgument(csd0.length > 3, "csd-0 for vp9 is invalid.");
+ int versionAndFlags = 1 << 24; // version (value 1, 8 bits) + flag (value 0, 24 bits)
+ if (Ints.fromByteArray(csd0) == versionAndFlags) {
+ // CSD is already in vpcC format.
+ return BoxUtils.wrapIntoBox("vpcC", ByteBuffer.wrap(csd0));
+ }
+
+ ByteBuffer contents = ByteBuffer.allocate(MAX_FIXED_LEAF_BOX_SIZE);
+
+ contents.putInt(versionAndFlags);
+ // Default value of videoRange is 0.
+ int videoRange = format.colorInfo != null ? format.colorInfo.colorRange : 0;
+ ByteBuffer codecPrivateContent = parseVp9CodecPrivateFromCsd(csd0, videoRange);
+ contents.put(codecPrivateContent);
+
+ // The default values for optional fields as per the : Vp9 webm spec
+ int colourPrimaries = 1;
+ int transferCharacteristics = 1;
+ int matrixCoefficients = 1;
+
+ if (format.colorInfo != null) {
+ colourPrimaries = MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.get(videoRange).get(0);
+ transferCharacteristics =
+ MEDIAFORMAT_TRANSFER_TO_MP4_TRANSFER.get(format.colorInfo.colorTransfer);
+ matrixCoefficients = MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.get(videoRange).get(1);
+ }
+
+ contents.put((byte) colourPrimaries);
+ contents.put((byte) transferCharacteristics);
+ contents.put((byte) matrixCoefficients);
+ contents.putShort((short) 0); // codecInitializationDataSize must be 0 for VP9
+ // codecInitializationData is not used for VP9 so skipped writing to contents
+ contents.flip();
+ return BoxUtils.wrapIntoBox("vpcC", contents);
+ }
+
+ /**
+ * Parses a Vp9 CodecPrivate as per Vp9
+ * spec
+ */
+ private static ByteBuffer parseVp9CodecPrivateFromCsd(byte[] csd0, int videoFullRange) {
+ // The default values.
+ byte profile = 0;
+ byte level = 10;
+ byte bitDepth = 8;
+ byte chromaSubsampling = 0;
+ // Each feature is defined by the binary format of ID (1 byte), length (1 byte), and data (1
+ // byte).
+ for (int i = 0; i < csd0.length; i += 3) {
+ int id = csd0[i];
+ int dataIndex = i + 2;
+ switch (id) {
+ case 1:
+ profile = csd0[dataIndex];
+ break;
+ case 2:
+ level = csd0[dataIndex];
+ break;
+ case 3:
+ bitDepth = csd0[dataIndex];
+ break;
+ case 4:
+ chromaSubsampling = csd0[dataIndex];
+ break;
+ default:
+ break;
+ }
+ }
+ ByteBuffer content = ByteBuffer.allocate(3);
+ content.put(profile);
+ content.put(level);
+ // 4 bits of bitDepth + 3 bits of chromaSubsampling + 1 bit of videoRange
+ byte combined = (byte) ((bitDepth << 4) | (chromaSubsampling << 1) | videoFullRange);
+ content.put(combined);
+ content.flip();
+ return content;
+ }
+
+ /**
+ * Returns smDm box as per SmDm box
+ * in Vp9 spec
+ */
+ private static ByteBuffer smDmBox(ColorInfo colorInfo) {
+ byte[] hdrStaticInfo = colorInfo.hdrStaticInfo;
+ if (hdrStaticInfo != null) {
+ ByteBuffer contents = ByteBuffer.allocate(MAX_FIXED_LEAF_BOX_SIZE);
+ contents.putInt(0x00); // version and flag.
+ contents.put(hdrStaticInfo);
+ contents.flip();
+ return BoxUtils.wrapIntoBox("SmDm", contents);
+ } else {
+ // No HDR info
+ return ByteBuffer.allocate(0);
+ }
+ }
+
/** Returns the pasp box. */
private static ByteBuffer paspBox() {
ByteBuffer contents = ByteBuffer.allocate(8);
@@ -1352,6 +1462,8 @@ import java.util.List;
return "av01";
case MimeTypes.VIDEO_MP4V:
return "mp4v-es";
+ case MimeTypes.VIDEO_VP9:
+ return "vp09";
default:
throw new IllegalArgumentException("Unsupported format: " + mimeType);
}
diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
index 7ee7e1134d..00d23635ff 100644
--- a/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
+++ b/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
@@ -411,6 +411,52 @@ public class BoxesTest {
MuxerTestUtil.getExpectedDumpFilePath("video_sample_entry_box_mpeg4"));
}
+ @Test
+ public void createVideoSampleEntryBox_forVp09WithCodecPrivate_matchesExpected()
+ throws IOException {
+ Format format =
+ FAKE_VIDEO_FORMAT
+ .buildUpon()
+ .setSampleMimeType(MimeTypes.VIDEO_VP9)
+ .setColorInfo(
+ new ColorInfo.Builder()
+ .setColorSpace(C.COLOR_SPACE_BT2020)
+ .setColorTransfer(C.COLOR_TRANSFER_ST2084)
+ .setColorRange(C.COLOR_RANGE_FULL)
+ .build())
+ .setInitializationData(
+ ImmutableList.of(BaseEncoding.base16().decode("01010102010A030108040100")))
+ .build();
+
+ ByteBuffer videoSampleEntryBox = Boxes.videoSampleEntry(format);
+
+ DumpableMp4Box dumpableBox = new DumpableMp4Box(videoSampleEntryBox);
+ DumpFileAsserts.assertOutput(
+ context,
+ dumpableBox,
+ MuxerTestUtil.getExpectedDumpFilePath("video_sample_entry_box_vp09_codec_private_as_csd"));
+ }
+
+ @Test
+ public void createVideoSampleEntryBox_forVp09WithVpcBoxAsCsd_matchesExpected()
+ throws IOException {
+ Format format =
+ FAKE_VIDEO_FORMAT
+ .buildUpon()
+ .setSampleMimeType(MimeTypes.VIDEO_VP9)
+ .setInitializationData(
+ ImmutableList.of(BaseEncoding.base16().decode("01000000010A810510060000")))
+ .build();
+
+ ByteBuffer videoSampleEntryBox = Boxes.videoSampleEntry(format);
+
+ DumpableMp4Box dumpableBox = new DumpableMp4Box(videoSampleEntryBox);
+ DumpFileAsserts.assertOutput(
+ context,
+ dumpableBox,
+ MuxerTestUtil.getExpectedDumpFilePath("video_sample_entry_box_vp09_vpc_as_csd"));
+ }
+
@Test
public void createVideoSampleEntryBox_withUnknownVideoFormat_throws() {
// The video format contains an unknown MIME type.
diff --git a/libraries/test_data/src/test/assets/media/mp4/bbb_642x642_768kbps_30fps_vp9.webm b/libraries/test_data/src/test/assets/media/mp4/bbb_642x642_768kbps_30fps_vp9.webm
new file mode 100644
index 0000000000..488474eab0
Binary files /dev/null and b/libraries/test_data/src/test/assets/media/mp4/bbb_642x642_768kbps_30fps_vp9.webm differ
diff --git a/libraries/test_data/src/test/assets/media/mp4/bbb_800x640_768kbps_30fps_vp9.mp4 b/libraries/test_data/src/test/assets/media/mp4/bbb_800x640_768kbps_30fps_vp9.mp4
new file mode 100644
index 0000000000..3e858f4f82
Binary files /dev/null and b/libraries/test_data/src/test/assets/media/mp4/bbb_800x640_768kbps_30fps_vp9.mp4 differ
diff --git a/libraries/test_data/src/test/assets/muxerdumps/bbb_642x642_768kbps_30fps_vp9.webm.dump b/libraries/test_data/src/test/assets/muxerdumps/bbb_642x642_768kbps_30fps_vp9.webm.dump
new file mode 100644
index 0000000000..01563094d7
--- /dev/null
+++ b/libraries/test_data/src/test/assets/muxerdumps/bbb_642x642_768kbps_30fps_vp9.webm.dump
@@ -0,0 +1,386 @@
+seekMap:
+ isSeekable = true
+ duration = 2966600
+ getPosition(0) = [[timeUs=0, position=400052]]
+ getPosition(1) = [[timeUs=0, position=400052], [timeUs=1000000, position=578564]]
+ getPosition(1483300) = [[timeUs=1000000, position=578564], [timeUs=2000000, position=671623]]
+ getPosition(2966600) = [[timeUs=2000000, position=671623]]
+numberOfTracks = 1
+track 0:
+ total output bytes = 378802
+ sample count = 90
+ format 0:
+ id = 1
+ sampleMimeType = video/x-vnd.on2.vp9
+ maxInputSize = 115022
+ width = 642
+ height = 642
+ frameRate = 30.33776
+ colorInfo:
+ colorSpace = 1
+ colorRange = 2
+ colorTransfer = 3
+ lumaBitdepth = 8
+ chromaBitdepth = 8
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
+ sample 0:
+ time = 0
+ flags = 1
+ data = length 114992, hash A3D5A08F
+ sample 1:
+ time = 33322
+ flags = 0
+ data = length 2468, hash 13B2A74F
+ sample 2:
+ time = 66666
+ flags = 0
+ data = length 285, hash 64DF3C60
+ sample 3:
+ time = 100000
+ flags = 0
+ data = length 1334, hash EF02F3C
+ sample 4:
+ time = 133322
+ flags = 0
+ data = length 2352, hash FDAD734
+ sample 5:
+ time = 166666
+ flags = 0
+ data = length 1571, hash E688A7F6
+ sample 6:
+ time = 200000
+ flags = 0
+ data = length 10186, hash E91C70E6
+ sample 7:
+ time = 233322
+ flags = 0
+ data = length 64, hash 6A5CADCE
+ sample 8:
+ time = 266666
+ flags = 0
+ data = length 170, hash 3F5CD758
+ sample 9:
+ time = 300000
+ flags = 0
+ data = length 434, hash 8EAF8EFD
+ sample 10:
+ time = 333322
+ flags = 0
+ data = length 10785, hash 2147D70F
+ sample 11:
+ time = 366666
+ flags = 0
+ data = length 198, hash 793ADD71
+ sample 12:
+ time = 400000
+ flags = 0
+ data = length 392, hash 876BEAB1
+ sample 13:
+ time = 433322
+ flags = 0
+ data = length 344, hash 1D21D8E3
+ sample 14:
+ time = 466666
+ flags = 0
+ data = length 511, hash 9EF86789
+ sample 15:
+ time = 500000
+ flags = 0
+ data = length 1691, hash 64A2CFC9
+ sample 16:
+ time = 533322
+ flags = 0
+ data = length 3531, hash 2F4BC758
+ sample 17:
+ time = 566666
+ flags = 0
+ data = length 1893, hash EB4F09A4
+ sample 18:
+ time = 600000
+ flags = 0
+ data = length 1949, hash 2BFBE13A
+ sample 19:
+ time = 633322
+ flags = 0
+ data = length 1733, hash 70297D15
+ sample 20:
+ time = 666666
+ flags = 0
+ data = length 5425, hash 67A0C461
+ sample 21:
+ time = 700000
+ flags = 0
+ data = length 1465, hash 518C0216
+ sample 22:
+ time = 733322
+ flags = 0
+ data = length 2092, hash C8E96C86
+ sample 23:
+ time = 766666
+ flags = 0
+ data = length 1806, hash 49AED175
+ sample 24:
+ time = 800000
+ flags = 0
+ data = length 2372, hash 50E1B3DE
+ sample 25:
+ time = 833322
+ flags = 0
+ data = length 2848, hash 81944F49
+ sample 26:
+ time = 866666
+ flags = 0
+ data = length 1731, hash 4FB77DFA
+ sample 27:
+ time = 900000
+ flags = 0
+ data = length 1255, hash 520D4D74
+ sample 28:
+ time = 933322
+ flags = 0
+ data = length 1105, hash 70BBC24D
+ sample 29:
+ time = 966666
+ flags = 0
+ data = length 1530, hash 34703EB
+ sample 30:
+ time = 1000000
+ flags = 1
+ data = length 24672, hash 6A73E1D6
+ sample 31:
+ time = 1033322
+ flags = 0
+ data = length 427, hash 27408059
+ sample 32:
+ time = 1066666
+ flags = 0
+ data = length 811, hash 5BAB2B22
+ sample 33:
+ time = 1100000
+ flags = 0
+ data = length 1032, hash 87641FD4
+ sample 34:
+ time = 1133322
+ flags = 0
+ data = length 1158, hash B893D7A5
+ sample 35:
+ time = 1166666
+ flags = 0
+ data = length 1754, hash 8EDA2113
+ sample 36:
+ time = 1200000
+ flags = 0
+ data = length 2938, hash E9932D77
+ sample 37:
+ time = 1233322
+ flags = 0
+ data = length 885, hash C416AB8D
+ sample 38:
+ time = 1266666
+ flags = 0
+ data = length 2621, hash 78F8F394
+ sample 39:
+ time = 1300000
+ flags = 0
+ data = length 1318, hash 170350C7
+ sample 40:
+ time = 1333322
+ flags = 0
+ data = length 11967, hash 1FA8B0D6
+ sample 41:
+ time = 1366666
+ flags = 0
+ data = length 983, hash 878A4991
+ sample 42:
+ time = 1400000
+ flags = 0
+ data = length 1741, hash 71859E1C
+ sample 43:
+ time = 1433322
+ flags = 0
+ data = length 1526, hash E6C4BB78
+ sample 44:
+ time = 1466666
+ flags = 0
+ data = length 1162, hash B68FE43
+ sample 45:
+ time = 1500000
+ flags = 0
+ data = length 1791, hash 5E4761BA
+ sample 46:
+ time = 1533322
+ flags = 0
+ data = length 842, hash 3BEFF0ED
+ sample 47:
+ time = 1566666
+ flags = 0
+ data = length 2280, hash 621FDA5B
+ sample 48:
+ time = 1600000
+ flags = 0
+ data = length 771, hash 10148E9D
+ sample 49:
+ time = 1633322
+ flags = 0
+ data = length 2287, hash 378FD24D
+ sample 50:
+ time = 1666666
+ flags = 0
+ data = length 12364, hash 62F8D157
+ sample 51:
+ time = 1700000
+ flags = 0
+ data = length 603, hash 90CE01C1
+ sample 52:
+ time = 1733322
+ flags = 0
+ data = length 2735, hash 4A09B408
+ sample 53:
+ time = 1766666
+ flags = 0
+ data = length 4273, hash 1ACEF207
+ sample 54:
+ time = 1800000
+ flags = 0
+ data = length 2328, hash 896CB28C
+ sample 55:
+ time = 1833322
+ flags = 0
+ data = length 1277, hash 403D85ED
+ sample 56:
+ time = 1866666
+ flags = 0
+ data = length 661, hash 784C76E
+ sample 57:
+ time = 1900000
+ flags = 0
+ data = length 1958, hash 516FEA38
+ sample 58:
+ time = 1933322
+ flags = 0
+ data = length 1795, hash 20C4D425
+ sample 59:
+ time = 1966666
+ flags = 0
+ data = length 2099, hash C7737C7B
+ sample 60:
+ time = 2000000
+ flags = 1
+ data = length 40947, hash 8C900E8A
+ sample 61:
+ time = 2033322
+ flags = 0
+ data = length 1824, hash 854EA8B5
+ sample 62:
+ time = 2066666
+ flags = 0
+ data = length 2055, hash D9F95484
+ sample 63:
+ time = 2100000
+ flags = 0
+ data = length 1139, hash F84F6B49
+ sample 64:
+ time = 2133322
+ flags = 0
+ data = length 2037, hash F899CC3E
+ sample 65:
+ time = 2166666
+ flags = 0
+ data = length 1522, hash 7565D736
+ sample 66:
+ time = 2200000
+ flags = 0
+ data = length 1800, hash 1725430B
+ sample 67:
+ time = 2233322
+ flags = 0
+ data = length 1005, hash DC4D8922
+ sample 68:
+ time = 2266666
+ flags = 0
+ data = length 1463, hash 581A0280
+ sample 69:
+ time = 2300000
+ flags = 0
+ data = length 1455, hash CCE7936E
+ sample 70:
+ time = 2333322
+ flags = 0
+ data = length 14616, hash CA237B8A
+ sample 71:
+ time = 2366666
+ flags = 0
+ data = length 1206, hash 73C99329
+ sample 72:
+ time = 2400000
+ flags = 0
+ data = length 2044, hash 1921147C
+ sample 73:
+ time = 2433322
+ flags = 0
+ data = length 2705, hash AFC2037
+ sample 74:
+ time = 2466666
+ flags = 0
+ data = length 3221, hash FB57C2EF
+ sample 75:
+ time = 2500000
+ flags = 0
+ data = length 2372, hash C13C3B82
+ sample 76:
+ time = 2533322
+ flags = 0
+ data = length 1965, hash 6EBF308C
+ sample 77:
+ time = 2566666
+ flags = 0
+ data = length 1607, hash F7FFC0D4
+ sample 78:
+ time = 2600000
+ flags = 0
+ data = length 776, hash DFDA0FAF
+ sample 79:
+ time = 2633322
+ flags = 0
+ data = length 928, hash 5292C536
+ sample 80:
+ time = 2666666
+ flags = 0
+ data = length 7550, hash CC4A367
+ sample 81:
+ time = 2700000
+ flags = 0
+ data = length 472, hash 533072E3
+ sample 82:
+ time = 2733322
+ flags = 0
+ data = length 782, hash 60075E02
+ sample 83:
+ time = 2766666
+ flags = 0
+ data = length 947, hash 2FE71731
+ sample 84:
+ time = 2800000
+ flags = 0
+ data = length 1175, hash 96A1046A
+ sample 85:
+ time = 2833322
+ flags = 0
+ data = length 1335, hash BE9DD156
+ sample 86:
+ time = 2866666
+ flags = 0
+ data = length 1556, hash A4F75A
+ sample 87:
+ time = 2900000
+ flags = 0
+ data = length 2497, hash B99B8D9A
+ sample 88:
+ time = 2933322
+ flags = 0
+ data = length 1867, hash DA0AEBC4
+ sample 89:
+ time = 2966666
+ flags = 536870912
+ data = length 2363, hash 9F799805
+tracksEnded = true
diff --git a/libraries/test_data/src/test/assets/muxerdumps/bbb_800x640_768kbps_30fps_vp9.mp4.dump b/libraries/test_data/src/test/assets/muxerdumps/bbb_800x640_768kbps_30fps_vp9.mp4.dump
new file mode 100644
index 0000000000..2196db2751
--- /dev/null
+++ b/libraries/test_data/src/test/assets/muxerdumps/bbb_800x640_768kbps_30fps_vp9.mp4.dump
@@ -0,0 +1,504 @@
+seekMap:
+ isSeekable = true
+ duration = 3966600
+ getPosition(0) = [[timeUs=0, position=400052]]
+ getPosition(1) = [[timeUs=0, position=400052]]
+ getPosition(1983300) = [[timeUs=0, position=400052]]
+ getPosition(3966600) = [[timeUs=0, position=400052]]
+numberOfTracks = 1
+track 0:
+ total output bytes = 305806
+ sample count = 120
+ format 0:
+ id = 1
+ sampleMimeType = video/x-vnd.on2.vp9
+ maxInputSize = 100600
+ width = 800
+ height = 640
+ frameRate = 30.25261
+ colorInfo:
+ colorRange = 2
+ lumaBitdepth = 8
+ chromaBitdepth = 8
+ metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000]
+ sample 0:
+ time = 0
+ flags = 1
+ data = length 100570, hash F3505584
+ sample 1:
+ time = 33322
+ flags = 0
+ data = length 424, hash 351B7D98
+ sample 2:
+ time = 66655
+ flags = 0
+ data = length 968, hash CF97CA51
+ sample 3:
+ time = 100000
+ flags = 0
+ data = length 663, hash 5A9391FB
+ sample 4:
+ time = 133322
+ flags = 0
+ data = length 2344, hash 821F66F2
+ sample 5:
+ time = 166655
+ flags = 0
+ data = length 936, hash 9BA91F74
+ sample 6:
+ time = 200000
+ flags = 0
+ data = length 13724, hash 2AD413FC
+ sample 7:
+ time = 233322
+ flags = 0
+ data = length 87, hash 7A6DB23E
+ sample 8:
+ time = 266655
+ flags = 0
+ data = length 5818, hash 4BF1F91E
+ sample 9:
+ time = 300000
+ flags = 0
+ data = length 83, hash 7D4FE7E1
+ sample 10:
+ time = 333322
+ flags = 0
+ data = length 1073, hash 199BF05D
+ sample 11:
+ time = 366655
+ flags = 0
+ data = length 220, hash CD334AE5
+ sample 12:
+ time = 400000
+ flags = 0
+ data = length 249, hash C67C3DDC
+ sample 13:
+ time = 433322
+ flags = 0
+ data = length 120, hash 1177A230
+ sample 14:
+ time = 466655
+ flags = 0
+ data = length 159, hash AAD4B224
+ sample 15:
+ time = 500000
+ flags = 0
+ data = length 295, hash EF6900EA
+ sample 16:
+ time = 533322
+ flags = 0
+ data = length 2595, hash A23E20BF
+ sample 17:
+ time = 566655
+ flags = 0
+ data = length 1352, hash 312088B3
+ sample 18:
+ time = 600000
+ flags = 0
+ data = length 1544, hash E247E9B3
+ sample 19:
+ time = 633322
+ flags = 0
+ data = length 997, hash 99499D33
+ sample 20:
+ time = 666655
+ flags = 0
+ data = length 3525, hash 6588E6CE
+ sample 21:
+ time = 700000
+ flags = 0
+ data = length 1147, hash 3E9394F4
+ sample 22:
+ time = 733322
+ flags = 0
+ data = length 2040, hash 7C298FC4
+ sample 23:
+ time = 766655
+ flags = 0
+ data = length 1035, hash B31D7CA3
+ sample 24:
+ time = 800000
+ flags = 0
+ data = length 4952, hash 6C44AC2E
+ sample 25:
+ time = 833322
+ flags = 0
+ data = length 2136, hash D67B928
+ sample 26:
+ time = 866655
+ flags = 0
+ data = length 2647, hash 84319CF8
+ sample 27:
+ time = 900000
+ flags = 0
+ data = length 1548, hash 208E98A
+ sample 28:
+ time = 933322
+ flags = 0
+ data = length 2000, hash CEFB8707
+ sample 29:
+ time = 966655
+ flags = 0
+ data = length 594, hash C3795B6A
+ sample 30:
+ time = 1000000
+ flags = 0
+ data = length 8431, hash B5C47EB7
+ sample 31:
+ time = 1033322
+ flags = 0
+ data = length 455, hash CAE64BA3
+ sample 32:
+ time = 1066655
+ flags = 0
+ data = length 1319, hash 65E675D8
+ sample 33:
+ time = 1100000
+ flags = 0
+ data = length 505, hash F1847234
+ sample 34:
+ time = 1133322
+ flags = 0
+ data = length 530, hash DB450768
+ sample 35:
+ time = 1166655
+ flags = 0
+ data = length 331, hash D036DEA4
+ sample 36:
+ time = 1200000
+ flags = 0
+ data = length 4760, hash EDD70E31
+ sample 37:
+ time = 1233322
+ flags = 0
+ data = length 423, hash 95903FFF
+ sample 38:
+ time = 1266655
+ flags = 0
+ data = length 745, hash 5A6EBD10
+ sample 39:
+ time = 1300000
+ flags = 0
+ data = length 328, hash CE70CDBB
+ sample 40:
+ time = 1333322
+ flags = 0
+ data = length 5210, hash 2649A66E
+ sample 41:
+ time = 1366655
+ flags = 0
+ data = length 511, hash 419A4CA1
+ sample 42:
+ time = 1400000
+ flags = 0
+ data = length 452, hash 75825F28
+ sample 43:
+ time = 1433322
+ flags = 0
+ data = length 752, hash 10304F3D
+ sample 44:
+ time = 1466655
+ flags = 0
+ data = length 1198, hash A566BB01
+ sample 45:
+ time = 1500000
+ flags = 0
+ data = length 265, hash 78D51330
+ sample 46:
+ time = 1533322
+ flags = 0
+ data = length 537, hash CB719119
+ sample 47:
+ time = 1566655
+ flags = 0
+ data = length 359, hash 58A020C9
+ sample 48:
+ time = 1600000
+ flags = 0
+ data = length 2661, hash EBFD5510
+ sample 49:
+ time = 1633322
+ flags = 0
+ data = length 292, hash 6D9C5866
+ sample 50:
+ time = 1666655
+ flags = 0
+ data = length 1504, hash 91DC43F2
+ sample 51:
+ time = 1700000
+ flags = 0
+ data = length 267, hash 8F85CA3
+ sample 52:
+ time = 1733322
+ flags = 0
+ data = length 884, hash B28A5CBC
+ sample 53:
+ time = 1766655
+ flags = 0
+ data = length 1913, hash 31AF6E83
+ sample 54:
+ time = 1800000
+ flags = 0
+ data = length 2542, hash E89FB333
+ sample 55:
+ time = 1833322
+ flags = 0
+ data = length 1148, hash EB767F66
+ sample 56:
+ time = 1866655
+ flags = 0
+ data = length 3704, hash 7A975D4
+ sample 57:
+ time = 1900000
+ flags = 0
+ data = length 983, hash FBDB84D7
+ sample 58:
+ time = 1933322
+ flags = 0
+ data = length 1656, hash 41E53FEE
+ sample 59:
+ time = 1966655
+ flags = 0
+ data = length 1939, hash 3250B82D
+ sample 60:
+ time = 2000000
+ flags = 0
+ data = length 11450, hash 7B1889AC
+ sample 61:
+ time = 2033322
+ flags = 0
+ data = length 2056, hash A0CB367D
+ sample 62:
+ time = 2066655
+ flags = 0
+ data = length 2353, hash 53046A1
+ sample 63:
+ time = 2100000
+ flags = 0
+ data = length 1006, hash 44DDB4F2
+ sample 64:
+ time = 2133322
+ flags = 0
+ data = length 5342, hash 83F3F3AC
+ sample 65:
+ time = 2166655
+ flags = 0
+ data = length 955, hash 7AB9C26
+ sample 66:
+ time = 2200000
+ flags = 0
+ data = length 3268, hash E0E082C9
+ sample 67:
+ time = 2233322
+ flags = 0
+ data = length 644, hash E8B6DC7B
+ sample 68:
+ time = 2266655
+ flags = 0
+ data = length 2392, hash 1BF32E27
+ sample 69:
+ time = 2300000
+ flags = 0
+ data = length 593, hash 5DB64C00
+ sample 70:
+ time = 2333322
+ flags = 0
+ data = length 6948, hash 7895B079
+ sample 71:
+ time = 2366655
+ flags = 0
+ data = length 899, hash 5FFDFE17
+ sample 72:
+ time = 2400000
+ flags = 0
+ data = length 3788, hash 5A21D2E1
+ sample 73:
+ time = 2433322
+ flags = 0
+ data = length 1710, hash 89E8A39C
+ sample 74:
+ time = 2466655
+ flags = 0
+ data = length 3327, hash 3310ECDB
+ sample 75:
+ time = 2500000
+ flags = 0
+ data = length 2906, hash 8E0C412C
+ sample 76:
+ time = 2533322
+ flags = 0
+ data = length 4414, hash 11696B53
+ sample 77:
+ time = 2566655
+ flags = 0
+ data = length 2317, hash 657538A3
+ sample 78:
+ time = 2600000
+ flags = 0
+ data = length 1553, hash 5193D6AF
+ sample 79:
+ time = 2633322
+ flags = 0
+ data = length 468, hash 4376D976
+ sample 80:
+ time = 2666655
+ flags = 0
+ data = length 4568, hash E91D1E8F
+ sample 81:
+ time = 2700000
+ flags = 0
+ data = length 497, hash F4F1CD13
+ sample 82:
+ time = 2733322
+ flags = 0
+ data = length 610, hash 42AEFB70
+ sample 83:
+ time = 2766655
+ flags = 0
+ data = length 641, hash 5423E04A
+ sample 84:
+ time = 2800000
+ flags = 0
+ data = length 1165, hash F8637120
+ sample 85:
+ time = 2833322
+ flags = 0
+ data = length 314, hash ACEF2A81
+ sample 86:
+ time = 2866655
+ flags = 0
+ data = length 636, hash 5F2BB532
+ sample 87:
+ time = 2900000
+ flags = 0
+ data = length 647, hash B2729383
+ sample 88:
+ time = 2933322
+ flags = 0
+ data = length 3039, hash 2B1F361
+ sample 89:
+ time = 2966655
+ flags = 0
+ data = length 860, hash 9C0B862A
+ sample 90:
+ time = 3000000
+ flags = 0
+ data = length 8781, hash A2D4BE4D
+ sample 91:
+ time = 3033322
+ flags = 0
+ data = length 499, hash B9F70F2C
+ sample 92:
+ time = 3066655
+ flags = 0
+ data = length 1542, hash 1BA1174E
+ sample 93:
+ time = 3100000
+ flags = 0
+ data = length 695, hash 745CADCE
+ sample 94:
+ time = 3133322
+ flags = 0
+ data = length 586, hash 5742B4C3
+ sample 95:
+ time = 3166655
+ flags = 0
+ data = length 301, hash 9E00FE47
+ sample 96:
+ time = 3200000
+ flags = 0
+ data = length 4798, hash 67C484EB
+ sample 97:
+ time = 3233322
+ flags = 0
+ data = length 254, hash 71B22CF8
+ sample 98:
+ time = 3266655
+ flags = 0
+ data = length 461, hash DCB4FA15
+ sample 99:
+ time = 3300000
+ flags = 0
+ data = length 265, hash BB81E6E0
+ sample 100:
+ time = 3333322
+ flags = 0
+ data = length 2271, hash 66DAC7CC
+ sample 101:
+ time = 3366655
+ flags = 0
+ data = length 465, hash 16572B00
+ sample 102:
+ time = 3400000
+ flags = 0
+ data = length 525, hash 793F2DDA
+ sample 103:
+ time = 3433322
+ flags = 0
+ data = length 447, hash A96D7744
+ sample 104:
+ time = 3466655
+ flags = 0
+ data = length 2278, hash 462CE42B
+ sample 105:
+ time = 3500000
+ flags = 0
+ data = length 457, hash 13A273E0
+ sample 106:
+ time = 3533322
+ flags = 0
+ data = length 501, hash AE03F76E
+ sample 107:
+ time = 3566655
+ flags = 0
+ data = length 172, hash 75792E00
+ sample 108:
+ time = 3600000
+ flags = 0
+ data = length 464, hash C40933BB
+ sample 109:
+ time = 3633322
+ flags = 0
+ data = length 175, hash C46C8660
+ sample 110:
+ time = 3666655
+ flags = 0
+ data = length 1463, hash 44138497
+ sample 111:
+ time = 3700000
+ flags = 0
+ data = length 251, hash 8C44DDB
+ sample 112:
+ time = 3733322
+ flags = 0
+ data = length 1178, hash B96F4269
+ sample 113:
+ time = 3766655
+ flags = 0
+ data = length 320, hash B00BFAD9
+ sample 114:
+ time = 3800000
+ flags = 0
+ data = length 386, hash CAAB54FC
+ sample 115:
+ time = 3833322
+ flags = 0
+ data = length 322, hash 63896DFB
+ sample 116:
+ time = 3866655
+ flags = 0
+ data = length 583, hash 757FF234
+ sample 117:
+ time = 3900000
+ flags = 0
+ data = length 169, hash 281BE891
+ sample 118:
+ time = 3933322
+ flags = 0
+ data = length 540, hash CBDFC083
+ sample 119:
+ time = 3966655
+ flags = 536870912
+ data = length 842, hash D0C087E5
+tracksEnded = true
diff --git a/libraries/test_data/src/test/assets/muxerdumps/video_sample_entry_box_vp09_codec_private_as_csd.dump b/libraries/test_data/src/test/assets/muxerdumps/video_sample_entry_box_vp09_codec_private_as_csd.dump
new file mode 100644
index 0000000000..fed803b243
--- /dev/null
+++ b/libraries/test_data/src/test/assets/muxerdumps/video_sample_entry_box_vp09_codec_private_as_csd.dump
@@ -0,0 +1,2 @@
+vp09 (141 bytes):
+ Data = length 133, hash 86CBFAF0
diff --git a/libraries/test_data/src/test/assets/muxerdumps/video_sample_entry_box_vp09_vpc_as_csd.dump b/libraries/test_data/src/test/assets/muxerdumps/video_sample_entry_box_vp09_vpc_as_csd.dump
new file mode 100644
index 0000000000..67fc14f243
--- /dev/null
+++ b/libraries/test_data/src/test/assets/muxerdumps/video_sample_entry_box_vp09_vpc_as_csd.dump
@@ -0,0 +1,2 @@
+vp09 (122 bytes):
+ Data = length 114, hash 339A8731