diff --git a/libraries/common/src/main/java/androidx/media3/common/C.java b/libraries/common/src/main/java/androidx/media3/common/C.java index 264566024f9..fb9fd6827b5 100644 --- a/libraries/common/src/main/java/androidx/media3/common/C.java +++ b/libraries/common/src/main/java/androidx/media3/common/C.java @@ -179,7 +179,8 @@ private C() {} /** * Represents an audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE}, * {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link - * #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link + * #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_20BIT}, {@link + * #ENCODING_PCM_20BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link * #ENCODING_PCM_24BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_32BIT}, {@link * #ENCODING_PCM_32BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_PCM_DOUBLE}, * {@link #ENCODING_MP3}, {@link #ENCODING_AC3}, {@link #ENCODING_E_AC3}, {@link @@ -195,6 +196,8 @@ private C() {} ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, ENCODING_PCM_16BIT_BIG_ENDIAN, + ENCODING_PCM_20BIT, + ENCODING_PCM_20BIT_BIG_ENDIAN, ENCODING_PCM_24BIT, ENCODING_PCM_24BIT_BIG_ENDIAN, ENCODING_PCM_32BIT, @@ -224,7 +227,8 @@ private C() {} /** * Represents a PCM audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE}, * {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link - * #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link + * #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_20BIT}, {@link + * #ENCODING_PCM_20BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link * #ENCODING_PCM_24BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_32BIT}, {@link * #ENCODING_PCM_32BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_PCM_DOUBLE}. */ @@ -237,6 +241,8 @@ private C() {} ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, ENCODING_PCM_16BIT_BIG_ENDIAN, + ENCODING_PCM_20BIT, + ENCODING_PCM_20BIT_BIG_ENDIAN, ENCODING_PCM_24BIT, ENCODING_PCM_24BIT_BIG_ENDIAN, ENCODING_PCM_32BIT, @@ -258,6 +264,26 @@ private C() {} /** Like {@link #ENCODING_PCM_16BIT}, but with the bytes in big endian order. */ @UnstableApi public static final int ENCODING_PCM_16BIT_BIG_ENDIAN = 0x10000000; + /** + * PCM encoding with 20 bits per sample. + * + *
Note that this is not generally supported or used and just exists to signal that a + * compressed audio track contains 20-bit PCM resolution. A decoder for said track should convert + * the audio to the closest higher format (such as {@link #ENCODING_PCM_24BIT}) instead of + * attempting to output 20-bit PCM. + */ + @UnstableApi public static final int ENCODING_PCM_20BIT = 0x80000000; + + /** + * Like {@link #ENCODING_PCM_20BIT} but with the bytes in big endian order. + * + *
Note that this is not generally supported or used and just exists to signal that a + * compressed audio track contains 20-bit PCM resolution. A decoder for said track should convert + * the audio to the closest higher format (such as {@link #ENCODING_PCM_24BIT}) instead of + * attempting to output 20-bit PCM. + */ + @UnstableApi public static final int ENCODING_PCM_20BIT_BIG_ENDIAN = 0x90000000; + /** PCM encoding with 24 bits per sample. */ public static final int ENCODING_PCM_24BIT = AudioFormat.ENCODING_PCM_24BIT_PACKED; diff --git a/libraries/common/src/main/java/androidx/media3/common/util/MediaFormatUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/MediaFormatUtil.java index a103d297e30..a4f68f96d46 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/MediaFormatUtil.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/MediaFormatUtil.java @@ -504,6 +504,8 @@ private static void maybeSetPcmEncoding( break; case Format.NO_VALUE: case C.ENCODING_PCM_16BIT_BIG_ENDIAN: + case C.ENCODING_PCM_20BIT: + case C.ENCODING_PCM_20BIT_BIG_ENDIAN: case C.ENCODING_PCM_24BIT_BIG_ENDIAN: case C.ENCODING_PCM_32BIT_BIG_ENDIAN: case C.ENCODING_PCM_DOUBLE: diff --git a/libraries/common/src/main/java/androidx/media3/common/util/Util.java b/libraries/common/src/main/java/androidx/media3/common/util/Util.java index 75291e1e773..b8f6ebefb50 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/Util.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/Util.java @@ -2380,6 +2380,10 @@ public static Format getPcmFormat(AudioProcessor.AudioFormat audioFormat) { /** * Converts a sample bit depth to a corresponding little-endian integer PCM encoding constant. * + *
Note that this method does not support encodings which are not a multiple of bytes, such as + * 20-bit PCM, as those cannot be handled in the same way as linear PCM encodings which are + * multiples of bytes. It's recommended to convert such a PCM format to the closest higher format. + * * @param bitDepth The bit depth. Supported values are 8, 16, 24 and 32. * @return The corresponding encoding. One of {@link C#ENCODING_PCM_8BIT}, {@link * C#ENCODING_PCM_16BIT}, {@link C#ENCODING_PCM_24BIT} and {@link C#ENCODING_PCM_32BIT}. If @@ -2393,6 +2397,10 @@ public static Format getPcmFormat(AudioProcessor.AudioFormat audioFormat) { /** * Converts a sample bit depth and byte order to a corresponding integer PCM encoding constant. * + *
Note that this method does not support encodings which are not a multiple of bytes, such as + * 20-bit PCM, as those cannot be handled in the same way as linear PCM encodings which are + * multiples of bytes. It's recommended to convert such a PCM format to the closest higher format. + * * @param bitDepth The bit depth. Supported values are 8, 16, 24 and 32. * @param byteOrder The byte order. * @return The corresponding integer PCM encoding. If the bit depth is unsupported then {@link @@ -2424,6 +2432,10 @@ public static Format getPcmFormat(AudioProcessor.AudioFormat audioFormat) { /** * Returns whether {@code encoding} is one of the linear PCM encodings. * + *
Note that this will return false for encodings which are not a multiple of bytes, such as + * 20-bit PCM, as those cannot be handled in the same way as linear PCM encodings which are + * multiples of bytes. It's recommended to convert such a PCM format to the closest higher format. + * * @param encoding The encoding of the audio data. * @return Whether the encoding is one of the PCM encodings. */ @@ -2443,6 +2455,10 @@ public static boolean isEncodingLinearPcm(@C.Encoding int encoding) { /** * Returns whether {@code encoding} is high resolution (> 16-bit) PCM. * + *
Note that this will return false for encodings which are not a multiple of bytes, such as + * 20-bit PCM, as those cannot be handled in the same way as linear PCM encodings which are + * multiples of bytes. It's recommended to convert such a PCM format to the closest higher format. + * * @param encoding The encoding of the audio data. * @return Whether the encoding is high resolution PCM. */ @@ -2616,28 +2632,31 @@ public static int getPcmFrameSize(@C.PcmEncoding int pcmEncoding, int channelCou } /** - * Returns the byte depth for audio with the specified encoding. + * Returns the bit depth for audio with the specified encoding. * * @param pcmEncoding The encoding of the audio data. - * @return The byte depth of the audio. + * @return The bit depth of the audio. */ @UnstableApi - public static int getByteDepth(@C.PcmEncoding int pcmEncoding) { + public static int getBitDepth(@C.PcmEncoding int pcmEncoding) { switch (pcmEncoding) { case C.ENCODING_PCM_8BIT: - return 1; + return 8; case C.ENCODING_PCM_16BIT: case C.ENCODING_PCM_16BIT_BIG_ENDIAN: - return 2; + return 16; + case C.ENCODING_PCM_20BIT: + case C.ENCODING_PCM_20BIT_BIG_ENDIAN: + return 20; case C.ENCODING_PCM_24BIT: case C.ENCODING_PCM_24BIT_BIG_ENDIAN: - return 3; + return 24; case C.ENCODING_PCM_32BIT: case C.ENCODING_PCM_32BIT_BIG_ENDIAN: case C.ENCODING_PCM_FLOAT: - return 4; + return 32; case C.ENCODING_PCM_DOUBLE: - return 8; + return 64; case C.ENCODING_INVALID: case Format.NO_VALUE: default: @@ -2645,6 +2664,28 @@ public static int getByteDepth(@C.PcmEncoding int pcmEncoding) { } } + /** + * Returns the byte depth for audio with the specified encoding. + * + *
This will throw for encodings which are not a multiple of bytes, such as 20-bit PCM. + * + * @param pcmEncoding The encoding of the audio data. + * @return The byte depth of the audio. + * @see #getBitDepth(int) + */ + @UnstableApi + public static int getByteDepth(@C.PcmEncoding int pcmEncoding) { + int bitDepth = getBitDepth(pcmEncoding); + if ((bitDepth % C.BITS_PER_BYTE) != 0) { + throw new IllegalArgumentException( + "Bit depth " + + bitDepth + + " cannot be represented as byte" + + " depth. Use getBitDepth() instead."); + } + return bitDepth / C.BITS_PER_BYTE; + } + /** Returns the {@link C.AudioUsage} corresponding to the specified {@link C.StreamType}. */ @UnstableApi public static @C.AudioUsage int getAudioUsageForStreamType(@C.StreamType int streamType) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index 666e2023739..e6d655386a4 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -1828,6 +1828,8 @@ private FormatConfig getFormatConfig(Format format, int preferredBufferSize) { return OpusUtil.parseOggPacketAudioSampleCount(buffer); case C.ENCODING_PCM_16BIT: case C.ENCODING_PCM_16BIT_BIG_ENDIAN: + case C.ENCODING_PCM_20BIT: + case C.ENCODING_PCM_20BIT_BIG_ENDIAN: case C.ENCODING_PCM_24BIT: case C.ENCODING_PCM_24BIT_BIG_ENDIAN: case C.ENCODING_PCM_32BIT: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/util/EventLogger.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/util/EventLogger.java index f893b3fbe06..579911efcf7 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/util/EventLogger.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/util/EventLogger.java @@ -821,6 +821,10 @@ private static String encodingAsString(@C.Encoding int encoding) { return "pcm-16"; case C.ENCODING_PCM_16BIT_BIG_ENDIAN: return "pcm-16be"; + case C.ENCODING_PCM_20BIT: + return "pcm-20"; + case C.ENCODING_PCM_20BIT_BIG_ENDIAN: + return "pcm-20be"; case C.ENCODING_PCM_24BIT: return "pcm-24"; case C.ENCODING_PCM_24BIT_BIG_ENDIAN: diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java index a5b29baf1f5..3925227f24f 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java @@ -163,6 +163,8 @@ public static int getMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) return OpusUtil.MAX_BYTES_PER_SECOND; case C.ENCODING_PCM_16BIT: case C.ENCODING_PCM_16BIT_BIG_ENDIAN: + case C.ENCODING_PCM_20BIT: + case C.ENCODING_PCM_20BIT_BIG_ENDIAN: case C.ENCODING_PCM_24BIT: case C.ENCODING_PCM_24BIT_BIG_ENDIAN: case C.ENCODING_PCM_32BIT: diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/WavUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/WavUtil.java index 169a20f2346..f03044625fc 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/WavUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/WavUtil.java @@ -72,6 +72,7 @@ public static int getTypeForPcmEncoding(@C.PcmEncoding int pcmEncoding) { switch (pcmEncoding) { case C.ENCODING_PCM_8BIT: case C.ENCODING_PCM_16BIT: + case C.ENCODING_PCM_20BIT: case C.ENCODING_PCM_24BIT: case C.ENCODING_PCM_32BIT: return TYPE_PCM; @@ -79,6 +80,7 @@ public static int getTypeForPcmEncoding(@C.PcmEncoding int pcmEncoding) { return TYPE_FLOAT; // TYPE_PCM is little endian so big endian formats don't match. case C.ENCODING_PCM_16BIT_BIG_ENDIAN: + case C.ENCODING_PCM_20BIT_BIG_ENDIAN: case C.ENCODING_PCM_24BIT_BIG_ENDIAN: case C.ENCODING_PCM_32BIT_BIG_ENDIAN: case C.ENCODING_INVALID: diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/BoxParser.java b/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/BoxParser.java index 0f750556e1a..05fd681034e 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/BoxParser.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/BoxParser.java @@ -2376,7 +2376,13 @@ private static void parseAudioSampleEntry( sampleRate = parsedAlacConfig[0]; channelCount = parsedAlacConfig[1]; int bitDepth = parsedAlacConfig[2]; - pcmEncoding = Util.getPcmEncoding(bitDepth); + // getPcmEncoding() does not support encodings which are not a multiple of bytes, such as + // 20-bit PCM, as those cannot be handled in the same way as linear PCM encodings which are + // multiples of bytes. These formats are also not supported by any part of media3's PCM + // handling pipeline. The reason this constant exists is to be able to signal that the + // compressed audio (in this case, ALAC) has 20-bit PCM precision, but a decoder is expected + // to output a supported format such as 24-bit PCM instead. + pcmEncoding = bitDepth == 20 ? C.ENCODING_PCM_20BIT : Util.getPcmEncoding(bitDepth); initializationData = ImmutableList.of(initializationDataBytes); } else if (childAtomType == Mp4Box.TYPE_iacb) { parent.setPosition( diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/mp4/Mp4ExtractorParameterizedTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/mp4/Mp4ExtractorParameterizedTest.java index f3b5078cb1f..3550b3d193a 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/mp4/Mp4ExtractorParameterizedTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/mp4/Mp4ExtractorParameterizedTest.java @@ -308,6 +308,11 @@ public void mp4SampleWithAlac() throws Exception { assertExtractorBehavior("media/mp4/sample_alac.mp4", /* peekLimit= */ 50); } + @Test + public void mp4SampleWithAlac20Bit() throws Exception { + assertExtractorBehavior("media/mp4/sample_alac_20bit.mp4", /* peekLimit= */ 4096); + } + @Test public void mp4SampleWithFixedRechunkAndNoElst() throws Exception { assertExtractorBehavior("media/mp4/sample_fixed_rechunk_no_elst.mp4", /* peekLimit= */ 44); diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.0.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.0.dump new file mode 100644 index 00000000000..372b96033b0 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.0.dump @@ -0,0 +1,74 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 40135 + sample count = 12 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 0 + flags = 1 + data = length 1952, hash 298B8810 + sample 1: + time = 92879 + flags = 1 + data = length 3898, hash 7734D643 + sample 2: + time = 185759 + flags = 1 + data = length 3923, hash 8AAC13A1 + sample 3: + time = 278639 + flags = 1 + data = length 3917, hash CFEBDF3E + sample 4: + time = 371519 + flags = 1 + data = length 3880, hash CCDB7EB5 + sample 5: + time = 464399 + flags = 1 + data = length 3830, hash 7FB90D6E + sample 6: + time = 557278 + flags = 1 + data = length 3845, hash 4481CE0F + sample 7: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 8: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 9: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 10: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 11: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.1.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.1.dump new file mode 100644 index 00000000000..441cc5d4c4c --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.1.dump @@ -0,0 +1,62 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 30362 + sample count = 9 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 278639 + flags = 1 + data = length 3917, hash CFEBDF3E + sample 1: + time = 371519 + flags = 1 + data = length 3880, hash CCDB7EB5 + sample 2: + time = 464399 + flags = 1 + data = length 3830, hash 7FB90D6E + sample 3: + time = 557278 + flags = 1 + data = length 3845, hash 4481CE0F + sample 4: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 5: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 6: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 7: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 8: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.2.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.2.dump new file mode 100644 index 00000000000..0c388563b68 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.2.dump @@ -0,0 +1,46 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 14890 + sample count = 5 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 1: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 2: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 3: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 4: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.3.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.3.dump new file mode 100644 index 00000000000..7494147e8b9 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.3.dump @@ -0,0 +1,30 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 8 + sample count = 1 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.0.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.0.dump new file mode 100644 index 00000000000..372b96033b0 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.0.dump @@ -0,0 +1,74 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 40135 + sample count = 12 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 0 + flags = 1 + data = length 1952, hash 298B8810 + sample 1: + time = 92879 + flags = 1 + data = length 3898, hash 7734D643 + sample 2: + time = 185759 + flags = 1 + data = length 3923, hash 8AAC13A1 + sample 3: + time = 278639 + flags = 1 + data = length 3917, hash CFEBDF3E + sample 4: + time = 371519 + flags = 1 + data = length 3880, hash CCDB7EB5 + sample 5: + time = 464399 + flags = 1 + data = length 3830, hash 7FB90D6E + sample 6: + time = 557278 + flags = 1 + data = length 3845, hash 4481CE0F + sample 7: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 8: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 9: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 10: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 11: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.1.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.1.dump new file mode 100644 index 00000000000..441cc5d4c4c --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.1.dump @@ -0,0 +1,62 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 30362 + sample count = 9 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 278639 + flags = 1 + data = length 3917, hash CFEBDF3E + sample 1: + time = 371519 + flags = 1 + data = length 3880, hash CCDB7EB5 + sample 2: + time = 464399 + flags = 1 + data = length 3830, hash 7FB90D6E + sample 3: + time = 557278 + flags = 1 + data = length 3845, hash 4481CE0F + sample 4: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 5: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 6: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 7: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 8: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.2.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.2.dump new file mode 100644 index 00000000000..0c388563b68 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.2.dump @@ -0,0 +1,46 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 14890 + sample count = 5 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 1: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 2: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 3: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 4: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.3.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.3.dump new file mode 100644 index 00000000000..7494147e8b9 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.3.dump @@ -0,0 +1,30 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 8 + sample count = 1 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.unknown_length.dump new file mode 100644 index 00000000000..372b96033b0 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.unknown_length.dump @@ -0,0 +1,74 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 40135 + sample count = 12 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 0 + flags = 1 + data = length 1952, hash 298B8810 + sample 1: + time = 92879 + flags = 1 + data = length 3898, hash 7734D643 + sample 2: + time = 185759 + flags = 1 + data = length 3923, hash 8AAC13A1 + sample 3: + time = 278639 + flags = 1 + data = length 3917, hash CFEBDF3E + sample 4: + time = 371519 + flags = 1 + data = length 3880, hash CCDB7EB5 + sample 5: + time = 464399 + flags = 1 + data = length 3830, hash 7FB90D6E + sample 6: + time = 557278 + flags = 1 + data = length 3845, hash 4481CE0F + sample 7: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 8: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 9: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 10: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 11: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.unknown_length.dump new file mode 100644 index 00000000000..372b96033b0 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.unknown_length.dump @@ -0,0 +1,74 @@ +seekMap: + isSeekable = true + duration = 1021678 + getPosition(0) = [[timeUs=0, position=4096]] + getPosition(1) = [[timeUs=1, position=4096]] + getPosition(510839) = [[timeUs=510839, position=21666]] + getPosition(1021678) = [[timeUs=1021678, position=44223]] +numberOfTracks = 1 +track 0: + total output bytes = 40135 + sample count = 12 + track duration = 1021678 + format 0: + averageBitrate = 288079 + id = 1 + containerMimeType = audio/mp4 + sampleMimeType = audio/alac + maxInputSize = 4105 + channelCount = 1 + sampleRate = 44100 + pcmEncoding = -2147483648 + encoderPadding = 4096 + metadata = entries=[Mp4Timestamp: creation time=3853596544, modification time=3853596544, timescale=44100] + initializationData: + data = length 24, hash 478A29BA + sample 0: + time = 0 + flags = 1 + data = length 1952, hash 298B8810 + sample 1: + time = 92879 + flags = 1 + data = length 3898, hash 7734D643 + sample 2: + time = 185759 + flags = 1 + data = length 3923, hash 8AAC13A1 + sample 3: + time = 278639 + flags = 1 + data = length 3917, hash CFEBDF3E + sample 4: + time = 371519 + flags = 1 + data = length 3880, hash CCDB7EB5 + sample 5: + time = 464399 + flags = 1 + data = length 3830, hash 7FB90D6E + sample 6: + time = 557278 + flags = 1 + data = length 3845, hash 4481CE0F + sample 7: + time = 650158 + flags = 1 + data = length 3850, hash 29F6A218 + sample 8: + time = 743038 + flags = 1 + data = length 3906, hash A1084987 + sample 9: + time = 835918 + flags = 1 + data = length 4075, hash 2D7C7AA4 + sample 10: + time = 928798 + flags = 1 + data = length 3051, hash 5D47B269 + sample 11: + time = 1021678 + flags = 536870913 + data = length 8, hash B2FBAA0E +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/media/mp4/sample_alac_20bit.mp4 b/libraries/test_data/src/test/assets/media/mp4/sample_alac_20bit.mp4 new file mode 100644 index 00000000000..1d1c0fa91fd Binary files /dev/null and b/libraries/test_data/src/test/assets/media/mp4/sample_alac_20bit.mp4 differ