From 49b83c01ca2d005f54530adef360b5e9ae9bd235 Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 2 Aug 2017 07:07:38 -0700 Subject: [PATCH] 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 --- .../extractor/ts/AdtsReaderTest.java | 7 +++--- .../extractor/flv/AudioTagPayloadReader.java | 3 ++- .../exoplayer2/extractor/mp4/AtomParsers.java | 2 +- .../exoplayer2/extractor/ts/AdtsReader.java | 5 ++-- .../extractor/ts/ElementaryStreamReader.java | 4 +++- .../exoplayer2/extractor/ts/LatmReader.java | 23 ++++++++++--------- .../exoplayer2/extractor/ts/PesReader.java | 4 +++- .../exoplayer2/extractor/ts/PsExtractor.java | 6 +++-- .../extractor/ts/TsPayloadReader.java | 4 +++- .../util/CodecSpecificDataUtil.java | 13 +++++++---- 10 files changed, 44 insertions(+), 27 deletions(-) diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java index bcfa90a565..6a31250e15 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java @@ -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); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java index 2f21898007..ec5ad88aeb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java @@ -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); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java index f7e3e846e9..0a5e0e8a6d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java @@ -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; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java index 7277df5bb8..96b964a4c4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java @@ -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) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/ElementaryStreamReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/ElementaryStreamReader.java index 57bcf31fc5..fa7f78c8c0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/ElementaryStreamReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/ElementaryStreamReader.java @@ -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. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/LatmReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/LatmReader.java index 425dc43ea7..d21943eae8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/LatmReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/LatmReader.java @@ -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 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(); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PesReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PesReader.java index 59696b9dea..4863df42eb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PesReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PesReader.java @@ -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: diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PsExtractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PsExtractor.java index 883fb8f880..69c5745eaa 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PsExtractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/PsExtractor.java @@ -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(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsPayloadReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsPayloadReader.java index e7996c66c3..efa764b572 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsPayloadReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsPayloadReader.java @@ -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; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java index 468e8dd666..c9884abe78 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java @@ -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 parseAacAudioSpecificConfig(byte[] audioSpecificConfig) { + public static Pair 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 parseAacAudioSpecificConfig(ParsableBitArray bitArray) { + public static Pair 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; }