diff --git a/library/src/main/java/com/google/android/exoplayer/hls/parser/MpaReader.java b/library/src/main/java/com/google/android/exoplayer/hls/parser/MpaReader.java index b18266faf4..1ea3489ced 100644 --- a/library/src/main/java/com/google/android/exoplayer/hls/parser/MpaReader.java +++ b/library/src/main/java/com/google/android/exoplayer/hls/parser/MpaReader.java @@ -38,7 +38,6 @@ import java.util.Collections; private static final int STATE_READING_SAMPLE = 2; private static final int HEADER_SIZE = 4; - private static final int SYNCWORD_SIZE = 2; private static final int CRC_SIZE = 2; private final ParsableBitArray mpaScratch; @@ -172,13 +171,8 @@ import java.util.Collections; case STATE_READING_HEADER: int targetLength = hasCrc ? HEADER_SIZE + CRC_SIZE : HEADER_SIZE; if (continueRead(data, mpaScratch.getData(), targetLength)) { - parseHeader(); startSample(timeUs); - /** - * Reset buffer after Header data extraction in order to pass full - * mpeg audio frame to the mpeg decoder - */ - data.setPosition(data.getPosition() - targetLength); + parseHeader(); bytesRead = 0; state = STATE_READING_SAMPLE; } @@ -260,6 +254,7 @@ import java.util.Collections; * Parses the sample header. */ private void parseHeader() { + int headerLength = hasCrc ? HEADER_SIZE + CRC_SIZE : HEADER_SIZE; mpaScratch.setPosition(0); if (!hasMediaFormat()) { @@ -270,12 +265,7 @@ import java.util.Collections; int audioObjectType = 32 + layer; int bitRate = MPA_BITRATES[isLSF][layer][mpaScratch.readBits(4)]; int sampleRate = MPA_SAMPLING_RATES[3 - isLSF][mpaScratch.readBits(2)]; - int sampleRateIndex = 0; - for (; sampleRateIndex < (CodecSpecificDataUtil.AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE).length; sampleRateIndex++) { - if ((CodecSpecificDataUtil.AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE)[sampleRateIndex] == sampleRate) { - break; - } - } + int sampleRateIndex = CodecSpecificDataUtil.getSampleRateIndex(sampleRate); int paddingBit = (mpaScratch.readBit()) ? 1 : 0; mpaScratch.skipBits(1); int channelConfig = mpaScratch.readBits(2) == 3 ? 1 : 2; @@ -291,7 +281,12 @@ import java.util.Collections; Collections.singletonList(audioSpecificConfig)); frameDurationUs = (C.MICROS_PER_SECOND * MPA_SAMPLES_PER_FRAME[isLSF][layer]) / mediaFormat.sampleRate; setMediaFormat(mediaFormat); - sampleSize = CalcMpaFrameSize(layer, isLSF, bitRate * 1000, sampleRate, paddingBit); + sampleSize = CalcMpaFrameSize(layer, isLSF, bitRate * 1000, sampleRate, paddingBit) - headerLength; } + + mpaScratch.setPosition(0); + + ParsableByteArray header = new ParsableByteArray(mpaScratch.getData(),headerLength); + appendData(header, headerLength); } } diff --git a/library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java b/library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java index bb1d937c08..771a9957ee 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java +++ b/library/src/main/java/com/google/android/exoplayer/util/CodecSpecificDataUtil.java @@ -29,11 +29,11 @@ public final class CodecSpecificDataUtil { private static final byte[] NAL_START_CODE = new byte[] {0, 0, 0, 1}; - public static final int[] AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE = new int[] { + private static final int[] AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE = new int[] { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 }; - public static final int[] AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE = new int[] { + private static final int[] AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE = new int[] { 0, 1, 2, 3, 4, 5, 6, 8 }; @@ -41,6 +41,22 @@ public final class CodecSpecificDataUtil { private CodecSpecificDataUtil() {} + /** + * Gets the sample rate index. + * + * @param sampleRate The sample rate in Hz. + * @return The sample rate index. + */ + public static int getSampleRateIndex(int sampleRate) { + int sampleRateIndex = 0; + for (; sampleRateIndex < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; sampleRateIndex++) { + if (AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[sampleRateIndex] == sampleRate) { + return sampleRateIndex; + } + } + return -1; + } + /** * Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 * @@ -49,7 +65,7 @@ public final class CodecSpecificDataUtil { */ public static Pair parseAudioSpecificConfig(byte[] audioSpecificConfig) { int audioObjectType = (audioSpecificConfig[0] >> 3) & 0x1F; - if (audioObjectType != 31) { + if (audioObjectType < 31) { int byteOffset = audioObjectType == 5 || audioObjectType == 29 ? 1 : 0; int frequencyIndex = (audioSpecificConfig[byteOffset] & 0x7) << 1 | ((audioSpecificConfig[byteOffset + 1] >> 7) & 0x1);