diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 435658a954..47180ebfc8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -35,6 +35,8 @@ * IMA: Allow setting the ad media load timeout ([#3691](https://github.com/google/ExoPlayer/issues/3691)). * Audio: + * Support extracting data from AMR container formats, including both narrow + and wide band ([#2527](https://github.com/google/ExoPlayer/issues/2527)). * FLAC: * Sniff FLAC files correctly if they have ID3 headers ([#4055](https://github.com/google/ExoPlayer/issues/4055)). diff --git a/extensions/flac/build.gradle b/extensions/flac/build.gradle index 9bf8d39435..609953130b 100644 --- a/extensions/flac/build.gradle +++ b/extensions/flac/build.gradle @@ -34,6 +34,7 @@ dependencies { implementation 'com.android.support:support-annotations:' + supportLibraryVersion implementation project(modulePrefix + 'library-core') androidTestImplementation project(modulePrefix + 'testutils') + testImplementation project(modulePrefix + 'testutils-robolectric') } ext { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactory.java index b85ecba3a4..425f2b77cd 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactory.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.extractor; +import com.google.android.exoplayer2.extractor.amr.AmrExtractor; import com.google.android.exoplayer2.extractor.flv.FlvExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor; @@ -35,18 +36,19 @@ import java.lang.reflect.Constructor; * An {@link ExtractorsFactory} that provides an array of extractors for the following formats: * *
This extractor only supports single-channel AMR container formats.
+ */
+public final class AmrExtractor implements Extractor {
+
+ /** Factory for {@link AmrExtractor} instances. */
+ public static final ExtractorsFactory FACTORY =
+ new ExtractorsFactory() {
+
+ @Override
+ public Extractor[] createExtractors() {
+ return new Extractor[] {new AmrExtractor()};
+ }
+ };
+
+ /**
+ * The frame size in bytes, including header (1 byte), for each of the 16 frame types for AMR
+ * narrow band.
+ */
+ private static final int[] frameSizeBytesByTypeNb = {
+ 13,
+ 14,
+ 16,
+ 18,
+ 20,
+ 21,
+ 27,
+ 32,
+ 6, // AMR SID
+ 7, // GSM-EFR SID
+ 6, // TDMA-EFR SID
+ 6, // PDC-EFR SID
+ 1, // Future use
+ 1, // Future use
+ 1, // Future use
+ 1 // No data
+ };
+
+ /**
+ * The frame size in bytes, including header (1 byte), for each of the 16 frame types for AMR wide
+ * band.
+ */
+ private static final int[] frameSizeBytesByTypeWb = {
+ 18,
+ 24,
+ 33,
+ 37,
+ 41,
+ 47,
+ 51,
+ 59,
+ 61,
+ 6, // AMR-WB SID
+ 1, // Future use
+ 1, // Future use
+ 1, // Future use
+ 1, // Future use
+ 1, // speech lost
+ 1 // No data
+ };
+
+ private static final byte[] amrSignatureNb = Util.getUtf8Bytes("#!AMR\n");
+ private static final byte[] amrSignatureWb = Util.getUtf8Bytes("#!AMR-WB\n");
+
+ /** Theoretical maximum frame size for a AMR frame. */
+ private static final int MAX_FRAME_SIZE_BYTES = frameSizeBytesByTypeWb[8];
+
+ private static final int SAMPLE_RATE_WB = 16_000;
+ private static final int SAMPLE_RATE_NB = 8_000;
+ private static final int SAMPLE_TIME_PER_FRAME_US = 20_000;
+
+ private final byte[] scratch;
+
+ private boolean isWideBand;
+ private long currentSampleTimeUs;
+ private int currentSampleTotalBytes;
+ private int currentSampleBytesRemaining;
+
+ private TrackOutput trackOutput;
+ private boolean hasOutputFormat;
+
+ public AmrExtractor() {
+ scratch = new byte[1];
+ }
+
+ // Extractor implementation.
+
+ @Override
+ public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
+ return readAmrHeader(input);
+ }
+
+ @Override
+ public void init(ExtractorOutput output) {
+ output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
+ trackOutput = output.track(/* id= */ 0, C.TRACK_TYPE_AUDIO);
+ output.endTracks();
+ }
+
+ @Override
+ public int read(ExtractorInput input, PositionHolder seekPosition)
+ throws IOException, InterruptedException {
+ if (input.getPosition() == 0) {
+ if (!readAmrHeader(input)) {
+ throw new ParserException("Could not find AMR header.");
+ }
+ }
+ maybeOutputFormat();
+ return readSample(input);
+ }
+
+ @Override
+ public void seek(long position, long timeUs) {
+ currentSampleTimeUs = 0;
+ currentSampleTotalBytes = 0;
+ currentSampleBytesRemaining = 0;
+ }
+
+ @Override
+ public void release() {
+ // Do nothing
+ }
+
+ /* package */ static int frameSizeBytesByTypeNb(int frameType) {
+ return frameSizeBytesByTypeNb[frameType];
+ }
+
+ /* package */ static int frameSizeBytesByTypeWb(int frameType) {
+ return frameSizeBytesByTypeWb[frameType];
+ }
+
+ /* package */ static byte[] amrSignatureNb() {
+ return Arrays.copyOf(amrSignatureNb, amrSignatureNb.length);
+ }
+
+ /* package */ static byte[] amrSignatureWb() {
+ return Arrays.copyOf(amrSignatureWb, amrSignatureWb.length);
+ }
+
+ // Internal methods.
+
+ /**
+ * Peeks the AMR header from the beginning of the input, and consumes it if it exists.
+ *
+ * @param input The {@link ExtractorInput} from which data should be peeked/read.
+ * @return Whether the AMR header has been read.
+ */
+ private boolean readAmrHeader(ExtractorInput input) throws IOException, InterruptedException {
+ if (peekAmrSignature(input, amrSignatureNb)) {
+ isWideBand = false;
+ input.skipFully(amrSignatureNb.length);
+ return true;
+ } else if (peekAmrSignature(input, amrSignatureWb)) {
+ isWideBand = true;
+ input.skipFully(amrSignatureWb.length);
+ return true;
+ }
+ return false;
+ }
+
+ /** Peeks from the beginning of the input to see if the given AMR signature exists. */
+ private boolean peekAmrSignature(ExtractorInput input, byte[] amrSignature)
+ throws IOException, InterruptedException {
+ input.resetPeekPosition();
+ byte[] header = new byte[amrSignature.length];
+ input.peekFully(header, 0, amrSignature.length);
+ return Arrays.equals(header, amrSignature);
+ }
+
+ private void maybeOutputFormat() {
+ if (!hasOutputFormat) {
+ hasOutputFormat = true;
+ String mimeType = isWideBand ? MimeTypes.AUDIO_AMR_WB : MimeTypes.AUDIO_AMR_NB;
+ int sampleRate = isWideBand ? SAMPLE_RATE_WB : SAMPLE_RATE_NB;
+ trackOutput.format(
+ Format.createAudioSampleFormat(
+ /* id= */ null,
+ mimeType,
+ /* codecs= */ null,
+ /* bitrate= */ Format.NO_VALUE,
+ MAX_FRAME_SIZE_BYTES,
+ /* channelCount= */ 1,
+ sampleRate,
+ /* pcmEncoding= */ Format.NO_VALUE,
+ /* initializationData= */ null,
+ /* drmInitData= */ null,
+ /* selectionFlags= */ 0,
+ /* language= */ null));
+ }
+ }
+
+ private int readSample(ExtractorInput extractorInput) throws IOException, InterruptedException {
+ if (currentSampleBytesRemaining == 0) {
+ try {
+ currentSampleTotalBytes = readNextSampleSize(extractorInput);
+ } catch (EOFException e) {
+ return RESULT_END_OF_INPUT;
+ }
+ currentSampleBytesRemaining = currentSampleTotalBytes;
+ }
+
+ int bytesAppended =
+ trackOutput.sampleData(
+ extractorInput, currentSampleBytesRemaining, /* allowEndOfInput= */ true);
+ if (bytesAppended == C.RESULT_END_OF_INPUT) {
+ return RESULT_END_OF_INPUT;
+ }
+ currentSampleBytesRemaining -= bytesAppended;
+ if (currentSampleBytesRemaining > 0) {
+ return RESULT_CONTINUE;
+ }
+
+ trackOutput.sampleMetadata(
+ currentSampleTimeUs,
+ C.BUFFER_FLAG_KEY_FRAME,
+ currentSampleTotalBytes,
+ /* offset= */ 0,
+ /* encryptionData= */ null);
+ currentSampleTimeUs += SAMPLE_TIME_PER_FRAME_US;
+ return RESULT_CONTINUE;
+ }
+
+ private int readNextSampleSize(ExtractorInput extractorInput)
+ throws IOException, InterruptedException {
+ extractorInput.resetPeekPosition();
+ extractorInput.peekFully(scratch, /* offset= */ 0, /* length= */ 1);
+
+ byte frameHeader = scratch[0];
+ if ((frameHeader & 0x83) > 0) {
+ // The padding bits are at bit-1 positions in the following pattern: 1000 0011
+ // Padding bits must be 0.
+ throw new ParserException("Invalid padding bits for frame header " + frameHeader);
+ }
+
+ int frameType = (frameHeader >> 3) & 0x0f;
+ return getFrameSizeInBytes(frameType);
+ }
+
+ private int getFrameSizeInBytes(int frameType) throws ParserException {
+ if (!isValidFrameType(frameType)) {
+ throw new ParserException(
+ "Illegal AMR " + (isWideBand ? "WB" : "NB") + " frame type " + frameType);
+ }
+
+ return isWideBand ? frameSizeBytesByTypeWb[frameType] : frameSizeBytesByTypeNb[frameType];
+ }
+
+ private boolean isValidFrameType(int frameType) {
+ return frameType >= 0
+ && frameType <= 15
+ && (isWideBandValidFrameType(frameType) || isNarrowBandValidFrameType(frameType));
+ }
+
+ private boolean isWideBandValidFrameType(int frameType) {
+ // For wide band, type 10-13 are for future use.
+ return isWideBand && (frameType < 10 || frameType > 13);
+ }
+
+ private boolean isNarrowBandValidFrameType(int frameType) {
+ // For narrow band, type 12-14 are for future use.
+ return !isWideBand && (frameType < 12 || frameType > 14);
+ }
+}
diff --git a/library/core/src/test/assets/amr/sample_nb.amr b/library/core/src/test/assets/amr/sample_nb.amr
new file mode 100644
index 0000000000..2e21cc843c
Binary files /dev/null and b/library/core/src/test/assets/amr/sample_nb.amr differ
diff --git a/library/core/src/test/assets/amr/sample_nb.amr.0.dump b/library/core/src/test/assets/amr/sample_nb.amr.0.dump
new file mode 100644
index 0000000000..e0dec9c62c
--- /dev/null
+++ b/library/core/src/test/assets/amr/sample_nb.amr.0.dump
@@ -0,0 +1,902 @@
+seekMap:
+ isSeekable = false
+ duration = UNSET TIME
+ getPosition(0) = [[timeUs=0, position=0]]
+numberOfTracks = 1
+track 0:
+ format:
+ bitrate = -1
+ id = null
+ containerMimeType = null
+ sampleMimeType = audio/3gpp
+ maxInputSize = 61
+ width = -1
+ height = -1
+ frameRate = -1.0
+ rotationDegrees = 0
+ pixelWidthHeightRatio = 1.0
+ channelCount = 1
+ sampleRate = 8000
+ pcmEncoding = -1
+ encoderDelay = 0
+ encoderPadding = 0
+ subsampleOffsetUs = 9223372036854775807
+ selectionFlags = 0
+ language = null
+ drmInitData = -
+ initializationData:
+ total output bytes = 2834
+ sample count = 218
+ sample 0:
+ time = 0
+ flags = 1
+ data = length 13, hash 371B046C
+ sample 1:
+ time = 20000
+ flags = 1
+ data = length 13, hash CE30BF5B
+ sample 2:
+ time = 40000
+ flags = 1
+ data = length 13, hash 19A59975
+ sample 3:
+ time = 60000
+ flags = 1
+ data = length 13, hash 4879773C
+ sample 4:
+ time = 80000
+ flags = 1
+ data = length 13, hash E8F83019
+ sample 5:
+ time = 100000
+ flags = 1
+ data = length 13, hash D265CDC9
+ sample 6:
+ time = 120000
+ flags = 1
+ data = length 13, hash 91653DAA
+ sample 7:
+ time = 140000
+ flags = 1
+ data = length 13, hash C79456F6
+ sample 8:
+ time = 160000
+ flags = 1
+ data = length 13, hash CDDC4422
+ sample 9:
+ time = 180000
+ flags = 1
+ data = length 13, hash D9ED3AF1
+ sample 10:
+ time = 200000
+ flags = 1
+ data = length 13, hash BAB75A33
+ sample 11:
+ time = 220000
+ flags = 1
+ data = length 13, hash 2221B4FF
+ sample 12:
+ time = 240000
+ flags = 1
+ data = length 13, hash 96400A0B
+ sample 13:
+ time = 260000
+ flags = 1
+ data = length 13, hash 582E6FB
+ sample 14:
+ time = 280000
+ flags = 1
+ data = length 13, hash C4E878E5
+ sample 15:
+ time = 300000
+ flags = 1
+ data = length 13, hash C849A1BD
+ sample 16:
+ time = 320000
+ flags = 1
+ data = length 13, hash CFA8A9ED
+ sample 17:
+ time = 340000
+ flags = 1
+ data = length 13, hash 70CA4907
+ sample 18:
+ time = 360000
+ flags = 1
+ data = length 13, hash B47D4454
+ sample 19:
+ time = 380000
+ flags = 1
+ data = length 13, hash 282998C1
+ sample 20:
+ time = 400000
+ flags = 1
+ data = length 13, hash 3F3F7A65
+ sample 21:
+ time = 420000
+ flags = 1
+ data = length 13, hash CC2EAB58
+ sample 22:
+ time = 440000
+ flags = 1
+ data = length 13, hash 279EF712
+ sample 23:
+ time = 460000
+ flags = 1
+ data = length 13, hash AA2F4B29
+ sample 24:
+ time = 480000
+ flags = 1
+ data = length 13, hash F6F658C4
+ sample 25:
+ time = 500000
+ flags = 1
+ data = length 13, hash D7DEBD17
+ sample 26:
+ time = 520000
+ flags = 1
+ data = length 13, hash 6DAB9A17
+ sample 27:
+ time = 540000
+ flags = 1
+ data = length 13, hash 6ECE1571
+ sample 28:
+ time = 560000
+ flags = 1
+ data = length 13, hash B3D0507F
+ sample 29:
+ time = 580000
+ flags = 1
+ data = length 13, hash 21E356B9
+ sample 30:
+ time = 600000
+ flags = 1
+ data = length 13, hash 410EA12
+ sample 31:
+ time = 620000
+ flags = 1
+ data = length 13, hash 533895A8
+ sample 32:
+ time = 640000
+ flags = 1
+ data = length 13, hash C61B3E5A
+ sample 33:
+ time = 660000
+ flags = 1
+ data = length 13, hash 982170E6
+ sample 34:
+ time = 680000
+ flags = 1
+ data = length 13, hash 7A0468C5
+ sample 35:
+ time = 700000
+ flags = 1
+ data = length 13, hash 9C85EAA7
+ sample 36:
+ time = 720000
+ flags = 1
+ data = length 13, hash B6B341B6
+ sample 37:
+ time = 740000
+ flags = 1
+ data = length 13, hash 6937532E
+ sample 38:
+ time = 760000
+ flags = 1
+ data = length 13, hash 8CF2A3A0
+ sample 39:
+ time = 780000
+ flags = 1
+ data = length 13, hash D2682AC6
+ sample 40:
+ time = 800000
+ flags = 1
+ data = length 13, hash BBC5710F
+ sample 41:
+ time = 820000
+ flags = 1
+ data = length 13, hash 59080B6C
+ sample 42:
+ time = 840000
+ flags = 1
+ data = length 13, hash E4118291
+ sample 43:
+ time = 860000
+ flags = 1
+ data = length 13, hash A1E5B296
+ sample 44:
+ time = 880000
+ flags = 1
+ data = length 13, hash D7B8F95B
+ sample 45:
+ time = 900000
+ flags = 1
+ data = length 13, hash CC839BE1
+ sample 46:
+ time = 920000
+ flags = 1
+ data = length 13, hash D459DFCE
+ sample 47:
+ time = 940000
+ flags = 1
+ data = length 13, hash D6AD19EC
+ sample 48:
+ time = 960000
+ flags = 1
+ data = length 13, hash D05E373D
+ sample 49:
+ time = 980000
+ flags = 1
+ data = length 13, hash 6A4460C7
+ sample 50:
+ time = 1000000
+ flags = 1
+ data = length 13, hash C9A0D93F
+ sample 51:
+ time = 1020000
+ flags = 1
+ data = length 13, hash 3FA819E7
+ sample 52:
+ time = 1040000
+ flags = 1
+ data = length 13, hash 1D3CBDFC
+ sample 53:
+ time = 1060000
+ flags = 1
+ data = length 13, hash 8BBBB403
+ sample 54:
+ time = 1080000
+ flags = 1
+ data = length 13, hash 21B4A0F9
+ sample 55:
+ time = 1100000
+ flags = 1
+ data = length 13, hash C0F921D1
+ sample 56:
+ time = 1120000
+ flags = 1
+ data = length 13, hash 5D812AAB
+ sample 57:
+ time = 1140000
+ flags = 1
+ data = length 13, hash 50C9F3F8
+ sample 58:
+ time = 1160000
+ flags = 1
+ data = length 13, hash 5C2BB5D1
+ sample 59:
+ time = 1180000
+ flags = 1
+ data = length 13, hash 6BF9BEA5
+ sample 60:
+ time = 1200000
+ flags = 1
+ data = length 13, hash 2738C1E6
+ sample 61:
+ time = 1220000
+ flags = 1
+ data = length 13, hash 5FC288A6
+ sample 62:
+ time = 1240000
+ flags = 1
+ data = length 13, hash 7E8E442A
+ sample 63:
+ time = 1260000
+ flags = 1
+ data = length 13, hash AEAA2BBA
+ sample 64:
+ time = 1280000
+ flags = 1
+ data = length 13, hash 4E2ACD2F
+ sample 65:
+ time = 1300000
+ flags = 1
+ data = length 13, hash D6C90ACF
+ sample 66:
+ time = 1320000
+ flags = 1
+ data = length 13, hash 6FD8A944
+ sample 67:
+ time = 1340000
+ flags = 1
+ data = length 13, hash A835BBF9
+ sample 68:
+ time = 1360000
+ flags = 1
+ data = length 13, hash F7713830
+ sample 69:
+ time = 1380000
+ flags = 1
+ data = length 13, hash 3AA966E5
+ sample 70:
+ time = 1400000
+ flags = 1
+ data = length 13, hash F939E829
+ sample 71:
+ time = 1420000
+ flags = 1
+ data = length 13, hash 7676DE49
+ sample 72:
+ time = 1440000
+ flags = 1
+ data = length 13, hash 93BB890A
+ sample 73:
+ time = 1460000
+ flags = 1
+ data = length 13, hash B57DBEC8
+ sample 74:
+ time = 1480000
+ flags = 1
+ data = length 13, hash 66B0A5B6
+ sample 75:
+ time = 1500000
+ flags = 1
+ data = length 13, hash D733E0D
+ sample 76:
+ time = 1520000
+ flags = 1
+ data = length 13, hash 80941726
+ sample 77:
+ time = 1540000
+ flags = 1
+ data = length 13, hash 556ED633
+ sample 78:
+ time = 1560000
+ flags = 1
+ data = length 13, hash C5EDF4E1
+ sample 79:
+ time = 1580000
+ flags = 1
+ data = length 13, hash 6B287445
+ sample 80:
+ time = 1600000
+ flags = 1
+ data = length 13, hash DC97C4A7
+ sample 81:
+ time = 1620000
+ flags = 1
+ data = length 13, hash DA8CBDF4
+ sample 82:
+ time = 1640000
+ flags = 1
+ data = length 13, hash 6F60FF77
+ sample 83:
+ time = 1660000
+ flags = 1
+ data = length 13, hash 3EB22B96
+ sample 84:
+ time = 1680000
+ flags = 1
+ data = length 13, hash B3C31AF5
+ sample 85:
+ time = 1700000
+ flags = 1
+ data = length 13, hash 1854AA92
+ sample 86:
+ time = 1720000
+ flags = 1
+ data = length 13, hash 6488264B
+ sample 87:
+ time = 1740000
+ flags = 1
+ data = length 13, hash 4CC8C5C1
+ sample 88:
+ time = 1760000
+ flags = 1
+ data = length 13, hash 19CC7523
+ sample 89:
+ time = 1780000
+ flags = 1
+ data = length 13, hash 9BE7B928
+ sample 90:
+ time = 1800000
+ flags = 1
+ data = length 13, hash 47EC7CFD
+ sample 91:
+ time = 1820000
+ flags = 1
+ data = length 13, hash EC940120
+ sample 92:
+ time = 1840000
+ flags = 1
+ data = length 13, hash 73BDA6D0
+ sample 93:
+ time = 1860000
+ flags = 1
+ data = length 13, hash FACB3314
+ sample 94:
+ time = 1880000
+ flags = 1
+ data = length 13, hash EC61D13B
+ sample 95:
+ time = 1900000
+ flags = 1
+ data = length 13, hash B28C7B6C
+ sample 96:
+ time = 1920000
+ flags = 1
+ data = length 13, hash B1A4CECD
+ sample 97:
+ time = 1940000
+ flags = 1
+ data = length 13, hash 56D41BA6
+ sample 98:
+ time = 1960000
+ flags = 1
+ data = length 13, hash 90499F4
+ sample 99:
+ time = 1980000
+ flags = 1
+ data = length 13, hash 65D9A9D3
+ sample 100:
+ time = 2000000
+ flags = 1
+ data = length 13, hash D9004CC
+ sample 101:
+ time = 2020000
+ flags = 1
+ data = length 13, hash 4139C6ED
+ sample 102:
+ time = 2040000
+ flags = 1
+ data = length 13, hash C4F8097C
+ sample 103:
+ time = 2060000
+ flags = 1
+ data = length 13, hash 94D424FA
+ sample 104:
+ time = 2080000
+ flags = 1
+ data = length 13, hash C2C6F5FD
+ sample 105:
+ time = 2100000
+ flags = 1
+ data = length 13, hash 15719008
+ sample 106:
+ time = 2120000
+ flags = 1
+ data = length 13, hash 4F64F524
+ sample 107:
+ time = 2140000
+ flags = 1
+ data = length 13, hash F9E01C1E
+ sample 108:
+ time = 2160000
+ flags = 1
+ data = length 13, hash 74C4EE74
+ sample 109:
+ time = 2180000
+ flags = 1
+ data = length 13, hash 7EE7553D
+ sample 110:
+ time = 2200000
+ flags = 1
+ data = length 13, hash 62DE6539
+ sample 111:
+ time = 2220000
+ flags = 1
+ data = length 13, hash 7F5EC222
+ sample 112:
+ time = 2240000
+ flags = 1
+ data = length 13, hash 644067F
+ sample 113:
+ time = 2260000
+ flags = 1
+ data = length 13, hash CDF6C9DC
+ sample 114:
+ time = 2280000
+ flags = 1
+ data = length 13, hash 8B5DBC80
+ sample 115:
+ time = 2300000
+ flags = 1
+ data = length 13, hash AD4BBA03
+ sample 116:
+ time = 2320000
+ flags = 1
+ data = length 13, hash 7A76340
+ sample 117:
+ time = 2340000
+ flags = 1
+ data = length 13, hash 3610F5B0
+ sample 118:
+ time = 2360000
+ flags = 1
+ data = length 13, hash 430BC60B
+ sample 119:
+ time = 2380000
+ flags = 1
+ data = length 13, hash 99CF1CA6
+ sample 120:
+ time = 2400000
+ flags = 1
+ data = length 13, hash 1331C70B
+ sample 121:
+ time = 2420000
+ flags = 1
+ data = length 13, hash BD76E69D
+ sample 122:
+ time = 2440000
+ flags = 1
+ data = length 13, hash 5DA652AC
+ sample 123:
+ time = 2460000
+ flags = 1
+ data = length 13, hash 3B7BF6CE
+ sample 124:
+ time = 2480000
+ flags = 1
+ data = length 13, hash ABBFD143
+ sample 125:
+ time = 2500000
+ flags = 1
+ data = length 13, hash E9447166
+ sample 126:
+ time = 2520000
+ flags = 1
+ data = length 13, hash EC40068C
+ sample 127:
+ time = 2540000
+ flags = 1
+ data = length 13, hash A2869400
+ sample 128:
+ time = 2560000
+ flags = 1
+ data = length 13, hash C7E0746B
+ sample 129:
+ time = 2580000
+ flags = 1
+ data = length 13, hash 60601BB1
+ sample 130:
+ time = 2600000
+ flags = 1
+ data = length 13, hash 975AAE9B
+ sample 131:
+ time = 2620000
+ flags = 1
+ data = length 13, hash 8BBC0EB2
+ sample 132:
+ time = 2640000
+ flags = 1
+ data = length 13, hash 57FB39E5
+ sample 133:
+ time = 2660000
+ flags = 1
+ data = length 13, hash 4CDCEEDB
+ sample 134:
+ time = 2680000
+ flags = 1
+ data = length 13, hash EA16E256
+ sample 135:
+ time = 2700000
+ flags = 1
+ data = length 13, hash 287E7D9E
+ sample 136:
+ time = 2720000
+ flags = 1
+ data = length 13, hash 55AB8FB9
+ sample 137:
+ time = 2740000
+ flags = 1
+ data = length 13, hash 129890EF
+ sample 138:
+ time = 2760000
+ flags = 1
+ data = length 13, hash 90834F57
+ sample 139:
+ time = 2780000
+ flags = 1
+ data = length 13, hash 5B3228E0
+ sample 140:
+ time = 2800000
+ flags = 1
+ data = length 13, hash DD19E175
+ sample 141:
+ time = 2820000
+ flags = 1
+ data = length 13, hash EE7EA342
+ sample 142:
+ time = 2840000
+ flags = 1
+ data = length 13, hash DB3AF473
+ sample 143:
+ time = 2860000
+ flags = 1
+ data = length 13, hash 25AEC43F
+ sample 144:
+ time = 2880000
+ flags = 1
+ data = length 13, hash EE9BF97F
+ sample 145:
+ time = 2900000
+ flags = 1
+ data = length 13, hash FFFBE047
+ sample 146:
+ time = 2920000
+ flags = 1
+ data = length 13, hash BEACFCB0
+ sample 147:
+ time = 2940000
+ flags = 1
+ data = length 13, hash AEB5096C
+ sample 148:
+ time = 2960000
+ flags = 1
+ data = length 13, hash B0D381B
+ sample 149:
+ time = 2980000
+ flags = 1
+ data = length 13, hash 3D9D5122
+ sample 150:
+ time = 3000000
+ flags = 1
+ data = length 13, hash 6C1DDB95
+ sample 151:
+ time = 3020000
+ flags = 1
+ data = length 13, hash ADACADCF
+ sample 152:
+ time = 3040000
+ flags = 1
+ data = length 13, hash 159E321E
+ sample 153:
+ time = 3060000
+ flags = 1
+ data = length 13, hash B1466264
+ sample 154:
+ time = 3080000
+ flags = 1
+ data = length 13, hash 4DDF7223
+ sample 155:
+ time = 3100000
+ flags = 1
+ data = length 13, hash C9BDB82A
+ sample 156:
+ time = 3120000
+ flags = 1
+ data = length 13, hash A49B2D9D
+ sample 157:
+ time = 3140000
+ flags = 1
+ data = length 13, hash D645E7E5
+ sample 158:
+ time = 3160000
+ flags = 1
+ data = length 13, hash 1C4232DC
+ sample 159:
+ time = 3180000
+ flags = 1
+ data = length 13, hash 83078219
+ sample 160:
+ time = 3200000
+ flags = 1
+ data = length 13, hash D6D8B072
+ sample 161:
+ time = 3220000
+ flags = 1
+ data = length 13, hash 975DB40
+ sample 162:
+ time = 3240000
+ flags = 1
+ data = length 13, hash A15FDD05
+ sample 163:
+ time = 3260000
+ flags = 1
+ data = length 13, hash 4B839E41
+ sample 164:
+ time = 3280000
+ flags = 1
+ data = length 13, hash 7418F499
+ sample 165:
+ time = 3300000
+ flags = 1
+ data = length 13, hash 7A4945E4
+ sample 166:
+ time = 3320000
+ flags = 1
+ data = length 13, hash 6249558C
+ sample 167:
+ time = 3340000
+ flags = 1
+ data = length 13, hash BD4C5BE3
+ sample 168:
+ time = 3360000
+ flags = 1
+ data = length 13, hash BAB30F1D
+ sample 169:
+ time = 3380000
+ flags = 1
+ data = length 13, hash 1E1C7012
+ sample 170:
+ time = 3400000
+ flags = 1
+ data = length 13, hash 9A3F8A89
+ sample 171:
+ time = 3420000
+ flags = 1
+ data = length 13, hash 20BE6D7B
+ sample 172:
+ time = 3440000
+ flags = 1
+ data = length 13, hash CAA0591D
+ sample 173:
+ time = 3460000
+ flags = 1
+ data = length 13, hash 6D554D17
+ sample 174:
+ time = 3480000
+ flags = 1
+ data = length 13, hash D97C3B31
+ sample 175:
+ time = 3500000
+ flags = 1
+ data = length 13, hash 75BC5C3
+ sample 176:
+ time = 3520000
+ flags = 1
+ data = length 13, hash 7BA1784B
+ sample 177:
+ time = 3540000
+ flags = 1
+ data = length 13, hash 1D175D92
+ sample 178:
+ time = 3560000
+ flags = 1
+ data = length 13, hash ADCA60FD
+ sample 179:
+ time = 3580000
+ flags = 1
+ data = length 13, hash 37018693
+ sample 180:
+ time = 3600000
+ flags = 1
+ data = length 13, hash 4553606F
+ sample 181:
+ time = 3620000
+ flags = 1
+ data = length 13, hash CF434565
+ sample 182:
+ time = 3640000
+ flags = 1
+ data = length 13, hash D264D757
+ sample 183:
+ time = 3660000
+ flags = 1
+ data = length 13, hash 4FB493EF
+ sample 184:
+ time = 3680000
+ flags = 1
+ data = length 13, hash 919F53A
+ sample 185:
+ time = 3700000
+ flags = 1
+ data = length 13, hash C22B009B
+ sample 186:
+ time = 3720000
+ flags = 1
+ data = length 13, hash 5981470
+ sample 187:
+ time = 3740000
+ flags = 1
+ data = length 13, hash A5D3937C
+ sample 188:
+ time = 3760000
+ flags = 1
+ data = length 13, hash A2504429
+ sample 189:
+ time = 3780000
+ flags = 1
+ data = length 13, hash AD1B70BE
+ sample 190:
+ time = 3800000
+ flags = 1
+ data = length 13, hash 2E39ED5E
+ sample 191:
+ time = 3820000
+ flags = 1
+ data = length 13, hash 13A8BE8E
+ sample 192:
+ time = 3840000
+ flags = 1
+ data = length 13, hash 1ACD740B
+ sample 193:
+ time = 3860000
+ flags = 1
+ data = length 13, hash 80F38B3
+ sample 194:
+ time = 3880000
+ flags = 1
+ data = length 13, hash DA9DA79F
+ sample 195:
+ time = 3900000
+ flags = 1
+ data = length 13, hash 21B95B7E
+ sample 196:
+ time = 3920000
+ flags = 1
+ data = length 13, hash CD22497B
+ sample 197:
+ time = 3940000
+ flags = 1
+ data = length 13, hash 718BB35D
+ sample 198:
+ time = 3960000
+ flags = 1
+ data = length 13, hash 69ABA6AD
+ sample 199:
+ time = 3980000
+ flags = 1
+ data = length 13, hash BAE19549
+ sample 200:
+ time = 4000000
+ flags = 1
+ data = length 13, hash 2A792FB3
+ sample 201:
+ time = 4020000
+ flags = 1
+ data = length 13, hash 71FCD8
+ sample 202:
+ time = 4040000
+ flags = 1
+ data = length 13, hash 44D2B5B3
+ sample 203:
+ time = 4060000
+ flags = 1
+ data = length 13, hash 1E87B11B
+ sample 204:
+ time = 4080000
+ flags = 1
+ data = length 13, hash 78CD2C11
+ sample 205:
+ time = 4100000
+ flags = 1
+ data = length 13, hash 9F198DF0
+ sample 206:
+ time = 4120000
+ flags = 1
+ data = length 13, hash B291F16A
+ sample 207:
+ time = 4140000
+ flags = 1
+ data = length 13, hash CF820EE0
+ sample 208:
+ time = 4160000
+ flags = 1
+ data = length 13, hash 4E24F683
+ sample 209:
+ time = 4180000
+ flags = 1
+ data = length 13, hash 52BCD68F
+ sample 210:
+ time = 4200000
+ flags = 1
+ data = length 13, hash 42588CB0
+ sample 211:
+ time = 4220000
+ flags = 1
+ data = length 13, hash EBBFECA2
+ sample 212:
+ time = 4240000
+ flags = 1
+ data = length 13, hash C11050CF
+ sample 213:
+ time = 4260000
+ flags = 1
+ data = length 13, hash 6F738603
+ sample 214:
+ time = 4280000
+ flags = 1
+ data = length 13, hash DAD06E5
+ sample 215:
+ time = 4300000
+ flags = 1
+ data = length 13, hash 5B036C64
+ sample 216:
+ time = 4320000
+ flags = 1
+ data = length 13, hash A58DC12E
+ sample 217:
+ time = 4340000
+ flags = 1
+ data = length 13, hash AC59BA7C
+tracksEnded = true
diff --git a/library/core/src/test/assets/amr/sample_wb.amr b/library/core/src/test/assets/amr/sample_wb.amr
new file mode 100644
index 0000000000..14b85b553c
Binary files /dev/null and b/library/core/src/test/assets/amr/sample_wb.amr differ
diff --git a/library/core/src/test/assets/amr/sample_wb.amr.0.dump b/library/core/src/test/assets/amr/sample_wb.amr.0.dump
new file mode 100644
index 0000000000..1b3b8bd0dd
--- /dev/null
+++ b/library/core/src/test/assets/amr/sample_wb.amr.0.dump
@@ -0,0 +1,706 @@
+seekMap:
+ isSeekable = false
+ duration = UNSET TIME
+ getPosition(0) = [[timeUs=0, position=0]]
+numberOfTracks = 1
+track 0:
+ format:
+ bitrate = -1
+ id = null
+ containerMimeType = null
+ sampleMimeType = audio/amr-wb
+ maxInputSize = 61
+ width = -1
+ height = -1
+ frameRate = -1.0
+ rotationDegrees = 0
+ pixelWidthHeightRatio = 1.0
+ channelCount = 1
+ sampleRate = 16000
+ pcmEncoding = -1
+ encoderDelay = 0
+ encoderPadding = 0
+ subsampleOffsetUs = 9223372036854775807
+ selectionFlags = 0
+ language = null
+ drmInitData = -
+ initializationData:
+ total output bytes = 4056
+ sample count = 169
+ sample 0:
+ time = 0
+ flags = 1
+ data = length 24, hash C3025798
+ sample 1:
+ time = 20000
+ flags = 1
+ data = length 24, hash 39CABAE9
+ sample 2:
+ time = 40000
+ flags = 1
+ data = length 24, hash 2752F470
+ sample 3:
+ time = 60000
+ flags = 1
+ data = length 24, hash 394F76F6
+ sample 4:
+ time = 80000
+ flags = 1
+ data = length 24, hash FF9EEF
+ sample 5:
+ time = 100000
+ flags = 1
+ data = length 24, hash 54ECB1B4
+ sample 6:
+ time = 120000
+ flags = 1
+ data = length 24, hash 6D7A3A5F
+ sample 7:
+ time = 140000
+ flags = 1
+ data = length 24, hash 684CD144
+ sample 8:
+ time = 160000
+ flags = 1
+ data = length 24, hash 87B7D176
+ sample 9:
+ time = 180000
+ flags = 1
+ data = length 24, hash 4C02F9A5
+ sample 10:
+ time = 200000
+ flags = 1
+ data = length 24, hash B4154108
+ sample 11:
+ time = 220000
+ flags = 1
+ data = length 24, hash 4448F477
+ sample 12:
+ time = 240000
+ flags = 1
+ data = length 24, hash 755A4939
+ sample 13:
+ time = 260000
+ flags = 1
+ data = length 24, hash 8C8BC6C3
+ sample 14:
+ time = 280000
+ flags = 1
+ data = length 24, hash BC37F63F
+ sample 15:
+ time = 300000
+ flags = 1
+ data = length 24, hash 3352C43C
+ sample 16:
+ time = 320000
+ flags = 1
+ data = length 24, hash 7998E1F2
+ sample 17:
+ time = 340000
+ flags = 1
+ data = length 24, hash A8ECBEFC
+ sample 18:
+ time = 360000
+ flags = 1
+ data = length 24, hash 944AC118
+ sample 19:
+ time = 380000
+ flags = 1
+ data = length 24, hash FD2C8E1F
+ sample 20:
+ time = 400000
+ flags = 1
+ data = length 24, hash B3D867AF
+ sample 21:
+ time = 420000
+ flags = 1
+ data = length 24, hash 3DC6E592
+ sample 22:
+ time = 440000
+ flags = 1
+ data = length 24, hash 32B276CD
+ sample 23:
+ time = 460000
+ flags = 1
+ data = length 24, hash 5488AEF3
+ sample 24:
+ time = 480000
+ flags = 1
+ data = length 24, hash 7A4D516
+ sample 25:
+ time = 500000
+ flags = 1
+ data = length 24, hash 570AE83F
+ sample 26:
+ time = 520000
+ flags = 1
+ data = length 24, hash E5CB3477
+ sample 27:
+ time = 540000
+ flags = 1
+ data = length 24, hash E04C00E4
+ sample 28:
+ time = 560000
+ flags = 1
+ data = length 24, hash 21B7C97
+ sample 29:
+ time = 580000
+ flags = 1
+ data = length 24, hash 1633F470
+ sample 30:
+ time = 600000
+ flags = 1
+ data = length 24, hash 28D65CA6
+ sample 31:
+ time = 620000
+ flags = 1
+ data = length 24, hash CC6A675C
+ sample 32:
+ time = 640000
+ flags = 1
+ data = length 24, hash 4C91080A
+ sample 33:
+ time = 660000
+ flags = 1
+ data = length 24, hash F6482FB5
+ sample 34:
+ time = 680000
+ flags = 1
+ data = length 24, hash 2C76F48C
+ sample 35:
+ time = 700000
+ flags = 1
+ data = length 24, hash 6E3B0D72
+ sample 36:
+ time = 720000
+ flags = 1
+ data = length 24, hash 799AA003
+ sample 37:
+ time = 740000
+ flags = 1
+ data = length 24, hash DFC0BA81
+ sample 38:
+ time = 760000
+ flags = 1
+ data = length 24, hash CBDF3826
+ sample 39:
+ time = 780000
+ flags = 1
+ data = length 24, hash 16862B75
+ sample 40:
+ time = 800000
+ flags = 1
+ data = length 24, hash 865A828E
+ sample 41:
+ time = 820000
+ flags = 1
+ data = length 24, hash 336BBDC9
+ sample 42:
+ time = 840000
+ flags = 1
+ data = length 24, hash 6CFC6C34
+ sample 43:
+ time = 860000
+ flags = 1
+ data = length 24, hash 32C8CD46
+ sample 44:
+ time = 880000
+ flags = 1
+ data = length 24, hash 9FE11C4C
+ sample 45:
+ time = 900000
+ flags = 1
+ data = length 24, hash AA5A12B7
+ sample 46:
+ time = 920000
+ flags = 1
+ data = length 24, hash AA0F4A4D
+ sample 47:
+ time = 940000
+ flags = 1
+ data = length 24, hash 34415484
+ sample 48:
+ time = 960000
+ flags = 1
+ data = length 24, hash 5018928E
+ sample 49:
+ time = 980000
+ flags = 1
+ data = length 24, hash 4A04D162
+ sample 50:
+ time = 1000000
+ flags = 1
+ data = length 24, hash 4C70F9F0
+ sample 51:
+ time = 1020000
+ flags = 1
+ data = length 24, hash 99EF3168
+ sample 52:
+ time = 1040000
+ flags = 1
+ data = length 24, hash C600DAF
+ sample 53:
+ time = 1060000
+ flags = 1
+ data = length 24, hash FDBB192E
+ sample 54:
+ time = 1080000
+ flags = 1
+ data = length 24, hash 99096A48
+ sample 55:
+ time = 1100000
+ flags = 1
+ data = length 24, hash D793F88B
+ sample 56:
+ time = 1120000
+ flags = 1
+ data = length 24, hash EEB921BD
+ sample 57:
+ time = 1140000
+ flags = 1
+ data = length 24, hash 8B941A4C
+ sample 58:
+ time = 1160000
+ flags = 1
+ data = length 24, hash ED5F5FEE
+ sample 59:
+ time = 1180000
+ flags = 1
+ data = length 24, hash A588E0BB
+ sample 60:
+ time = 1200000
+ flags = 1
+ data = length 24, hash 588CBC01
+ sample 61:
+ time = 1220000
+ flags = 1
+ data = length 24, hash DE22266C
+ sample 62:
+ time = 1240000
+ flags = 1
+ data = length 24, hash 921B6E5C
+ sample 63:
+ time = 1260000
+ flags = 1
+ data = length 24, hash EC11F041
+ sample 64:
+ time = 1280000
+ flags = 1
+ data = length 24, hash 5BA9E0A3
+ sample 65:
+ time = 1300000
+ flags = 1
+ data = length 24, hash DB6D52F3
+ sample 66:
+ time = 1320000
+ flags = 1
+ data = length 24, hash 8EEBE525
+ sample 67:
+ time = 1340000
+ flags = 1
+ data = length 24, hash 47A742AE
+ sample 68:
+ time = 1360000
+ flags = 1
+ data = length 24, hash E93F1E03
+ sample 69:
+ time = 1380000
+ flags = 1
+ data = length 24, hash 3251F57C
+ sample 70:
+ time = 1400000
+ flags = 1
+ data = length 24, hash 3EDBBBDD
+ sample 71:
+ time = 1420000
+ flags = 1
+ data = length 24, hash 2E98465A
+ sample 72:
+ time = 1440000
+ flags = 1
+ data = length 24, hash A09EA52E
+ sample 73:
+ time = 1460000
+ flags = 1
+ data = length 24, hash A2A86FA6
+ sample 74:
+ time = 1480000
+ flags = 1
+ data = length 24, hash 71DCD51C
+ sample 75:
+ time = 1500000
+ flags = 1
+ data = length 24, hash 2B02DEE1
+ sample 76:
+ time = 1520000
+ flags = 1
+ data = length 24, hash 7A725192
+ sample 77:
+ time = 1540000
+ flags = 1
+ data = length 24, hash 929AD483
+ sample 78:
+ time = 1560000
+ flags = 1
+ data = length 24, hash 68440BF5
+ sample 79:
+ time = 1580000
+ flags = 1
+ data = length 24, hash 5BD41AD6
+ sample 80:
+ time = 1600000
+ flags = 1
+ data = length 24, hash 91A381
+ sample 81:
+ time = 1620000
+ flags = 1
+ data = length 24, hash 8010C408
+ sample 82:
+ time = 1640000
+ flags = 1
+ data = length 24, hash 482274BE
+ sample 83:
+ time = 1660000
+ flags = 1
+ data = length 24, hash D7DB8BCC
+ sample 84:
+ time = 1680000
+ flags = 1
+ data = length 24, hash 680BD9DD
+ sample 85:
+ time = 1700000
+ flags = 1
+ data = length 24, hash E313577C
+ sample 86:
+ time = 1720000
+ flags = 1
+ data = length 24, hash 9C10B0CD
+ sample 87:
+ time = 1740000
+ flags = 1
+ data = length 24, hash 2D90AC02
+ sample 88:
+ time = 1760000
+ flags = 1
+ data = length 24, hash 64E8C245
+ sample 89:
+ time = 1780000
+ flags = 1
+ data = length 24, hash 3954AC1B
+ sample 90:
+ time = 1800000
+ flags = 1
+ data = length 24, hash ACB8999F
+ sample 91:
+ time = 1820000
+ flags = 1
+ data = length 24, hash 43AE3957
+ sample 92:
+ time = 1840000
+ flags = 1
+ data = length 24, hash 3C664DB7
+ sample 93:
+ time = 1860000
+ flags = 1
+ data = length 24, hash 9354B576
+ sample 94:
+ time = 1880000
+ flags = 1
+ data = length 24, hash B5B9C14E
+ sample 95:
+ time = 1900000
+ flags = 1
+ data = length 24, hash 7DA9C98F
+ sample 96:
+ time = 1920000
+ flags = 1
+ data = length 24, hash EFEE54C6
+ sample 97:
+ time = 1940000
+ flags = 1
+ data = length 24, hash 79DC8CBD
+ sample 98:
+ time = 1960000
+ flags = 1
+ data = length 24, hash A71A475C
+ sample 99:
+ time = 1980000
+ flags = 1
+ data = length 24, hash CA1CBB94
+ sample 100:
+ time = 2000000
+ flags = 1
+ data = length 24, hash 91922226
+ sample 101:
+ time = 2020000
+ flags = 1
+ data = length 24, hash C90278BC
+ sample 102:
+ time = 2040000
+ flags = 1
+ data = length 24, hash BD51986F
+ sample 103:
+ time = 2060000
+ flags = 1
+ data = length 24, hash 90AEF368
+ sample 104:
+ time = 2080000
+ flags = 1
+ data = length 24, hash 1D83C955
+ sample 105:
+ time = 2100000
+ flags = 1
+ data = length 24, hash 8FA9A915
+ sample 106:
+ time = 2120000
+ flags = 1
+ data = length 24, hash C6C753E0
+ sample 107:
+ time = 2140000
+ flags = 1
+ data = length 24, hash 85FA27A7
+ sample 108:
+ time = 2160000
+ flags = 1
+ data = length 24, hash A0277324
+ sample 109:
+ time = 2180000
+ flags = 1
+ data = length 24, hash B7696535
+ sample 110:
+ time = 2200000
+ flags = 1
+ data = length 24, hash D69D668C
+ sample 111:
+ time = 2220000
+ flags = 1
+ data = length 24, hash 34C057CD
+ sample 112:
+ time = 2240000
+ flags = 1
+ data = length 24, hash 4EC5E974
+ sample 113:
+ time = 2260000
+ flags = 1
+ data = length 24, hash 1C1CD40D
+ sample 114:
+ time = 2280000
+ flags = 1
+ data = length 24, hash 76CC54BC
+ sample 115:
+ time = 2300000
+ flags = 1
+ data = length 24, hash D497ACF5
+ sample 116:
+ time = 2320000
+ flags = 1
+ data = length 24, hash A1386080
+ sample 117:
+ time = 2340000
+ flags = 1
+ data = length 24, hash 7ED36954
+ sample 118:
+ time = 2360000
+ flags = 1
+ data = length 24, hash C11A3BF9
+ sample 119:
+ time = 2380000
+ flags = 1
+ data = length 24, hash 8FB69488
+ sample 120:
+ time = 2400000
+ flags = 1
+ data = length 24, hash C6225F59
+ sample 121:
+ time = 2420000
+ flags = 1
+ data = length 24, hash 122AB6D2
+ sample 122:
+ time = 2440000
+ flags = 1
+ data = length 24, hash 1E195E7D
+ sample 123:
+ time = 2460000
+ flags = 1
+ data = length 24, hash BD3DF418
+ sample 124:
+ time = 2480000
+ flags = 1
+ data = length 24, hash D8AE4A5
+ sample 125:
+ time = 2500000
+ flags = 1
+ data = length 24, hash 977BD182
+ sample 126:
+ time = 2520000
+ flags = 1
+ data = length 24, hash F361F060
+ sample 127:
+ time = 2540000
+ flags = 1
+ data = length 24, hash 11EC8CD0
+ sample 128:
+ time = 2560000
+ flags = 1
+ data = length 24, hash 3798F3D2
+ sample 129:
+ time = 2580000
+ flags = 1
+ data = length 24, hash B2C2517C
+ sample 130:
+ time = 2600000
+ flags = 1
+ data = length 24, hash FBE0D0D8
+ sample 131:
+ time = 2620000
+ flags = 1
+ data = length 24, hash 7033172F
+ sample 132:
+ time = 2640000
+ flags = 1
+ data = length 24, hash BE760029
+ sample 133:
+ time = 2660000
+ flags = 1
+ data = length 24, hash 590AF28C
+ sample 134:
+ time = 2680000
+ flags = 1
+ data = length 24, hash AD28C48F
+ sample 135:
+ time = 2700000
+ flags = 1
+ data = length 24, hash 640AA61B
+ sample 136:
+ time = 2720000
+ flags = 1
+ data = length 24, hash ABE659B
+ sample 137:
+ time = 2740000
+ flags = 1
+ data = length 24, hash ED2691D2
+ sample 138:
+ time = 2760000
+ flags = 1
+ data = length 24, hash D998C80E
+ sample 139:
+ time = 2780000
+ flags = 1
+ data = length 24, hash 8DC0DF5C
+ sample 140:
+ time = 2800000
+ flags = 1
+ data = length 24, hash 7692247B
+ sample 141:
+ time = 2820000
+ flags = 1
+ data = length 24, hash C1D1CCB9
+ sample 142:
+ time = 2840000
+ flags = 1
+ data = length 24, hash 362CE78E
+ sample 143:
+ time = 2860000
+ flags = 1
+ data = length 24, hash 54FA84A
+ sample 144:
+ time = 2880000
+ flags = 1
+ data = length 24, hash 29E88C84
+ sample 145:
+ time = 2900000
+ flags = 1
+ data = length 24, hash 1CD848AC
+ sample 146:
+ time = 2920000
+ flags = 1
+ data = length 24, hash 5C3D4A79
+ sample 147:
+ time = 2940000
+ flags = 1
+ data = length 24, hash 1AA8E604
+ sample 148:
+ time = 2960000
+ flags = 1
+ data = length 24, hash 186A4316
+ sample 149:
+ time = 2980000
+ flags = 1
+ data = length 24, hash 61ACE481
+ sample 150:
+ time = 3000000
+ flags = 1
+ data = length 24, hash D0C42780
+ sample 151:
+ time = 3020000
+ flags = 1
+ data = length 24, hash FAD51BA1
+ sample 152:
+ time = 3040000
+ flags = 1
+ data = length 24, hash F1A9AC71
+ sample 153:
+ time = 3060000
+ flags = 1
+ data = length 24, hash 24425449
+ sample 154:
+ time = 3080000
+ flags = 1
+ data = length 24, hash 37AAC3E6
+ sample 155:
+ time = 3100000
+ flags = 1
+ data = length 24, hash 91F68CB4
+ sample 156:
+ time = 3120000
+ flags = 1
+ data = length 24, hash F8C92820
+ sample 157:
+ time = 3140000
+ flags = 1
+ data = length 24, hash ECD39C3E
+ sample 158:
+ time = 3160000
+ flags = 1
+ data = length 24, hash B27D8F78
+ sample 159:
+ time = 3180000
+ flags = 1
+ data = length 24, hash C9EB3DFB
+ sample 160:
+ time = 3200000
+ flags = 1
+ data = length 24, hash 88DC54A2
+ sample 161:
+ time = 3220000
+ flags = 1
+ data = length 24, hash 7FC4C5BE
+ sample 162:
+ time = 3240000
+ flags = 1
+ data = length 24, hash E4F684EF
+ sample 163:
+ time = 3260000
+ flags = 1
+ data = length 24, hash 55C08B56
+ sample 164:
+ time = 3280000
+ flags = 1
+ data = length 24, hash E5A0F006
+ sample 165:
+ time = 3300000
+ flags = 1
+ data = length 24, hash DE3F3AA7
+ sample 166:
+ time = 3320000
+ flags = 1
+ data = length 24, hash 3F28AE7F
+ sample 167:
+ time = 3340000
+ flags = 1
+ data = length 24, hash 3949CAFF
+ sample 168:
+ time = 3360000
+ flags = 1
+ data = length 24, hash 772665A0
+tracksEnded = true
diff --git a/library/core/src/test/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactoryTest.java b/library/core/src/test/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactoryTest.java
new file mode 100644
index 0000000000..148e04ca77
--- /dev/null
+++ b/library/core/src/test/java/com/google/android/exoplayer2/extractor/DefaultExtractorsFactoryTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.exoplayer2.extractor;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.android.exoplayer2.extractor.amr.AmrExtractor;
+import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
+import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
+import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
+import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
+import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
+import com.google.android.exoplayer2.extractor.ogg.OggExtractor;
+import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
+import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
+import com.google.android.exoplayer2.extractor.ts.PsExtractor;
+import com.google.android.exoplayer2.extractor.ts.TsExtractor;
+import com.google.android.exoplayer2.extractor.wav.WavExtractor;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Unit test for {@link DefaultExtractorsFactory}. */
+@RunWith(RobolectricTestRunner.class)
+public final class DefaultExtractorsFactoryTest {
+
+ @Test
+ public void testCreateExtractors_returnExpectedClasses() {
+ DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
+
+ Extractor[] extractors = defaultExtractorsFactory.createExtractors();
+ List