From c5085b4c2e8b1d193f8f8214a0c9503ed149838b Mon Sep 17 00:00:00 2001 From: nift4 Date: Tue, 10 Feb 2026 20:43:57 +0100 Subject: [PATCH] Fixed issue with ALAC 20-bit files not having PCM format detected - after https://github.com/androidx/media/pull/2738 common alac files had bit depth populated correctly, but I recently learnt that there is also 20-bit alac files (you can create them with afconvert). it doesn't make any sense and it's very complex to handle 20-bit PCM in the media3 pipelines because one byte may belong to multiple samples, but we also don't need to. create an encoding used to flag that this file is 20-bit PCM in the ALAC Format object, but expect decoders to output 24-bit or 16-bit PCM instead (playback will otherwise fail). (test file created from other test files in this repo included.) --- .../main/java/androidx/media3/common/C.java | 30 ++++++- .../media3/common/util/MediaFormatUtil.java | 2 + .../androidx/media3/common/util/Util.java | 57 ++++++++++++-- .../exoplayer/audio/DefaultAudioSink.java | 2 + .../media3/exoplayer/util/EventLogger.java | 4 + .../media3/extractor/ExtractorUtil.java | 2 + .../androidx/media3/extractor/WavUtil.java | 2 + .../media3/extractor/mp4/BoxParser.java | 8 +- .../mp4/Mp4ExtractorParameterizedTest.java | 5 ++ .../mp4/sample_alac_20bit.mp4.0.dump | 74 ++++++++++++++++++ .../mp4/sample_alac_20bit.mp4.1.dump | 62 +++++++++++++++ .../mp4/sample_alac_20bit.mp4.2.dump | 46 +++++++++++ .../mp4/sample_alac_20bit.mp4.3.dump | 30 +++++++ ...ding_within_gop_sample_dependencies.0.dump | 74 ++++++++++++++++++ ...ding_within_gop_sample_dependencies.1.dump | 62 +++++++++++++++ ...ding_within_gop_sample_dependencies.2.dump | 46 +++++++++++ ...ding_within_gop_sample_dependencies.3.dump | 30 +++++++ ...op_sample_dependencies.unknown_length.dump | 74 ++++++++++++++++++ .../sample_alac_20bit.mp4.unknown_length.dump | 74 ++++++++++++++++++ .../assets/media/mp4/sample_alac_20bit.mp4 | Bin 0 -> 44231 bytes 20 files changed, 673 insertions(+), 11 deletions(-) create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.0.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.1.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.2.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.3.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.0.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.1.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.2.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.3.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.reading_within_gop_sample_dependencies.unknown_length.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/mp4/sample_alac_20bit.mp4.unknown_length.dump create mode 100644 libraries/test_data/src/test/assets/media/mp4/sample_alac_20bit.mp4 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 0000000000000000000000000000000000000000..1d1c0fa91fd83c2fbb79a0c280b35e4a5533f3a4 GIT binary patch literal 44231 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 F0l=-D|7`#O literal 0 HcmV?d00001