Throw ParserException if parsing unsupported media

This is for consistency with what we do elsewhere;
specifically in FragmentedMp4Extractor.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=163974960
This commit is contained in:
olly 2017-08-02 07:07:38 -07:00 committed by Oliver Woodman
parent 22ea9ed687
commit 49b83c01ca
10 changed files with 44 additions and 27 deletions

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.extractor.ts;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator;
import com.google.android.exoplayer2.testutil.FakeExtractorOutput;
import com.google.android.exoplayer2.testutil.FakeTrackOutput;
@ -154,20 +155,20 @@ public class AdtsReaderTest extends TestCase {
}
}
public void testAdtsDataOnly() throws Exception {
public void testAdtsDataOnly() throws ParserException {
data.setPosition(ID3_DATA_1.length + ID3_DATA_2.length);
feed();
assertSampleCounts(0, 1);
adtsOutput.assertSample(0, ADTS_CONTENT, 0, C.BUFFER_FLAG_KEY_FRAME, null);
}
private void feedLimited(int limit) {
private void feedLimited(int limit) throws ParserException {
maybeStartPacket();
data.setLimit(limit);
feed();
}
private void feed() {
private void feed() throws ParserException {
maybeStartPacket();
adtsReader.consume(data);
}

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.extractor.flv;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.util.CodecSpecificDataUtil;
import com.google.android.exoplayer2.util.MimeTypes;
@ -85,7 +86,7 @@ import java.util.Collections;
}
@Override
protected void parsePayload(ParsableByteArray data, long timeUs) {
protected void parsePayload(ParsableByteArray data, long timeUs) throws ParserException {
if (audioFormat == AUDIO_FORMAT_MP3) {
int sampleSize = data.bytesLeft();
output.sampleData(data, sampleSize);

View File

@ -816,7 +816,7 @@ import java.util.List;
private static void parseAudioSampleEntry(ParsableByteArray parent, int atomType, int position,
int size, int trackId, String language, boolean isQuickTime, DrmInitData drmInitData,
StsdData out, int entryIndex) {
StsdData out, int entryIndex) throws ParserException {
parent.setPosition(position + Atom.HEADER_SIZE + StsdData.STSD_HEADER_SIZE);
int quickTimeSoundDescriptionVersion = 0;

View File

@ -19,6 +19,7 @@ import android.util.Log;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.DummyTrackOutput;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
@ -128,7 +129,7 @@ public final class AdtsReader implements ElementaryStreamReader {
}
@Override
public void consume(ParsableByteArray data) {
public void consume(ParsableByteArray data) throws ParserException {
while (data.bytesLeft() > 0) {
switch (state) {
case STATE_FINDING_SAMPLE:
@ -276,7 +277,7 @@ public final class AdtsReader implements ElementaryStreamReader {
/**
* Parses the sample header.
*/
private void parseAdtsHeader() {
private void parseAdtsHeader() throws ParserException {
adtsScratch.setPosition(0);
if (!hasOutputFormat) {

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.util.ParsableByteArray;
@ -50,8 +51,9 @@ public interface ElementaryStreamReader {
* Consumes (possibly partial) data from the current packet.
*
* @param data The data to consume.
* @throws ParserException If the data could not be parsed.
*/
void consume(ParsableByteArray data);
void consume(ParsableByteArray data) throws ParserException;
/**
* Called when a packet ends.

View File

@ -19,6 +19,7 @@ import android.support.annotation.Nullable;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator;
@ -98,7 +99,7 @@ public final class LatmReader implements ElementaryStreamReader {
}
@Override
public void consume(ParsableByteArray data) {
public void consume(ParsableByteArray data) throws ParserException {
int bytesToRead;
while (data.bytesLeft() > 0) {
switch (state) {
@ -148,7 +149,7 @@ public final class LatmReader implements ElementaryStreamReader {
*
* @param data A {@link ParsableBitArray} containing the AudioMuxElement's bytes.
*/
private void parseAudioMuxElement(ParsableBitArray data) {
private void parseAudioMuxElement(ParsableBitArray data) throws ParserException {
boolean useSameStreamMux = data.readBit();
if (!useSameStreamMux) {
streamMuxRead = true;
@ -159,7 +160,7 @@ public final class LatmReader implements ElementaryStreamReader {
if (audioMuxVersionA == 0) {
if (numSubframes != 0) {
throw new UnsupportedOperationException();
throw new ParserException();
}
int muxSlotLengthBytes = parsePayloadLengthInfo(data);
parsePayloadMux(data, muxSlotLengthBytes);
@ -167,14 +168,14 @@ public final class LatmReader implements ElementaryStreamReader {
data.skipBits((int) otherDataLenBits);
}
} else {
throw new UnsupportedOperationException(); // Not defined by ISO/IEC 14496-3:2009.
throw new ParserException(); // Not defined by ISO/IEC 14496-3:2009.
}
}
/**
* Parses a StreamMuxConfig as defined in ISO/IEC 14496-3:2009 Section 1.7.3.1, Table 1.42.
*/
private void parseStreamMuxConfig(ParsableBitArray data) {
private void parseStreamMuxConfig(ParsableBitArray data) throws ParserException {
audioMuxVersion = data.readBits(1);
audioMuxVersionA = audioMuxVersion == 1 ? data.readBits(1) : 0;
if (audioMuxVersionA == 0) {
@ -182,13 +183,13 @@ public final class LatmReader implements ElementaryStreamReader {
latmGetValue(data); // Skip taraBufferFullness.
}
if (!data.readBit()) {
throw new UnsupportedOperationException();
throw new ParserException();
}
numSubframes = data.readBits(6);
int numProgram = data.readBits(4);
int numLayer = data.readBits(3);
if (numProgram != 0 || numLayer != 0) {
throw new UnsupportedOperationException();
throw new ParserException();
}
if (audioMuxVersion == 0) {
int startPosition = data.getPosition();
@ -228,7 +229,7 @@ public final class LatmReader implements ElementaryStreamReader {
data.skipBits(8); // crcCheckSum.
}
} else {
throw new UnsupportedOperationException(); // This is not defined by ISO/IEC 14496-3:2009.
throw new ParserException(); // This is not defined by ISO/IEC 14496-3:2009.
}
}
@ -253,7 +254,7 @@ public final class LatmReader implements ElementaryStreamReader {
}
}
private int parseAudioSpecificConfig(ParsableBitArray data) {
private int parseAudioSpecificConfig(ParsableBitArray data) throws ParserException {
int bitsLeft = data.bitsLeft();
Pair<Integer, Integer> config = CodecSpecificDataUtil.parseAacAudioSpecificConfig(data);
sampleRateHz = config.first;
@ -261,7 +262,7 @@ public final class LatmReader implements ElementaryStreamReader {
return bitsLeft - data.bitsLeft();
}
private int parsePayloadLengthInfo(ParsableBitArray data) {
private int parsePayloadLengthInfo(ParsableBitArray data) throws ParserException {
int muxSlotLengthBytes = 0;
// Assuming single program and single layer.
if (frameLengthType == 0) {
@ -272,7 +273,7 @@ public final class LatmReader implements ElementaryStreamReader {
} while (tmp == 255);
return muxSlotLengthBytes;
} else {
throw new UnsupportedOperationException();
throw new ParserException();
}
}

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.extractor.ts;
import android.util.Log;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.util.ParsableBitArray;
import com.google.android.exoplayer2.util.ParsableByteArray;
@ -77,7 +78,8 @@ public final class PesReader implements TsPayloadReader {
}
@Override
public final void consume(ParsableByteArray data, boolean payloadUnitStartIndicator) {
public final void consume(ParsableByteArray data, boolean payloadUnitStartIndicator)
throws ParserException {
if (payloadUnitStartIndicator) {
switch (state) {
case STATE_FINDING_HEADER:

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.extractor.ts;
import android.util.SparseArray;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
@ -30,7 +31,7 @@ import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.io.IOException;
/**
* Facilitates the extraction of data from the MPEG-2 TS container format.
* Facilitates the extraction of data from the MPEG-2 PS container format.
*/
public final class PsExtractor implements Extractor {
@ -275,8 +276,9 @@ public final class PsExtractor implements Extractor {
* Consumes the payload of a PS packet.
*
* @param data The PES packet. The position will be set to the start of the payload.
* @throws ParserException If the payload could not be parsed.
*/
public void consume(ParsableByteArray data) {
public void consume(ParsableByteArray data) throws ParserException {
data.readBytes(pesScratch.data, 0, 3);
pesScratch.setPosition(0);
parseHeader();

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.extractor.ts;
import android.util.SparseArray;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.util.ParsableByteArray;
@ -196,7 +197,8 @@ public interface TsPayloadReader {
*
* @param data The TS packet. The position will be set to the start of the payload.
* @param payloadUnitStartIndicator Whether payloadUnitStartIndicator was set on the TS packet.
* @throws ParserException If the payload could not be parsed.
*/
void consume(ParsableByteArray data, boolean payloadUnitStartIndicator);
void consume(ParsableByteArray data, boolean payloadUnitStartIndicator) throws ParserException;
}

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.util;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import java.util.ArrayList;
import java.util.List;
@ -85,8 +86,10 @@ public final class CodecSpecificDataUtil {
*
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
* @return A pair consisting of the sample rate in Hz and the channel count.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(byte[] audioSpecificConfig) {
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(byte[] audioSpecificConfig)
throws ParserException {
return parseAacAudioSpecificConfig(new ParsableBitArray(audioSpecificConfig));
}
@ -96,8 +99,10 @@ public final class CodecSpecificDataUtil {
* @param bitArray A {@link ParsableBitArray} containing the AudioSpecificConfig to parse. The
* position is advanced to the end of the AudioSpecificConfig.
* @return A pair consisting of the sample rate in Hz and the channel count.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(ParsableBitArray bitArray) {
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(ParsableBitArray bitArray)
throws ParserException {
int audioObjectType = getAacAudioObjectType(bitArray);
int sampleRate = getAacSamplingFrequency(bitArray);
int channelConfiguration = bitArray.readBits(4);
@ -131,7 +136,7 @@ public final class CodecSpecificDataUtil {
parseGaSpecificConfig(bitArray, audioObjectType, channelConfiguration);
break;
default:
throw new UnsupportedOperationException();
throw new ParserException("Unsupported audio object type: " + audioObjectType);
}
switch (audioObjectType) {
case 17:
@ -142,7 +147,7 @@ public final class CodecSpecificDataUtil {
case 23:
int epConfig = bitArray.readBits(2);
if (epConfig == 2 || epConfig == 3) {
throw new UnsupportedOperationException();
throw new ParserException("Unsupported epConfig: " + epConfig);
}
break;
}