mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Throw ParserException from parsers when a parse exception occurs.
This commit is contained in:
parent
13aaa5a5db
commit
c59fc47565
@ -22,6 +22,10 @@ import java.io.IOException;
|
||||
*/
|
||||
public class ParserException extends IOException {
|
||||
|
||||
public ParserException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ParserException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer.extractor.mp4;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.drm.DrmInitData;
|
||||
import com.google.android.exoplayer.extractor.ChunkIndex;
|
||||
import com.google.android.exoplayer.extractor.Extractor;
|
||||
@ -26,7 +27,6 @@ import com.google.android.exoplayer.extractor.SeekMap;
|
||||
import com.google.android.exoplayer.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer.extractor.mp4.Atom.ContainerAtom;
|
||||
import com.google.android.exoplayer.extractor.mp4.Atom.LeafAtom;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
import com.google.android.exoplayer.util.NalUnitUtil;
|
||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
@ -234,15 +234,15 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
} else {
|
||||
// We don't support parsing of leaf atoms that define extended atom sizes, or that have
|
||||
// lengths greater than Integer.MAX_VALUE.
|
||||
Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
|
||||
Assertions.checkState(atomSize <= Integer.MAX_VALUE);
|
||||
checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
|
||||
checkState(atomSize <= Integer.MAX_VALUE);
|
||||
atomData = new ParsableByteArray((int) atomSize);
|
||||
System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
|
||||
parserState = STATE_READING_ATOM_PAYLOAD;
|
||||
}
|
||||
} else {
|
||||
// We don't support skipping of atoms that have lengths greater than Integer.MAX_VALUE.
|
||||
Assertions.checkState(atomSize <= Integer.MAX_VALUE);
|
||||
checkState(atomSize <= Integer.MAX_VALUE);
|
||||
atomData = null;
|
||||
parserState = STATE_READING_ATOM_PAYLOAD;
|
||||
}
|
||||
@ -265,7 +265,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
enterReadingAtomHeaderState();
|
||||
}
|
||||
|
||||
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) {
|
||||
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) throws ParserException {
|
||||
if (!containerAtoms.isEmpty()) {
|
||||
containerAtoms.peek().add(leaf);
|
||||
} else if (leaf.type == Atom.TYPE_sidx) {
|
||||
@ -275,7 +275,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
}
|
||||
|
||||
private void onContainerAtomRead(ContainerAtom container) {
|
||||
private void onContainerAtomRead(ContainerAtom container) throws ParserException {
|
||||
if (container.type == Atom.TYPE_moov) {
|
||||
onMoovContainerAtomRead(container);
|
||||
} else if (container.type == Atom.TYPE_moof) {
|
||||
@ -285,7 +285,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
}
|
||||
|
||||
private void onMoovContainerAtomRead(ContainerAtom moov) {
|
||||
private void onMoovContainerAtomRead(ContainerAtom moov) throws ParserException {
|
||||
List<Atom.LeafAtom> moovChildren = moov.leafChildren;
|
||||
int moovChildrenSize = moovChildren.size();
|
||||
|
||||
@ -308,16 +308,28 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
extendsDefaults = parseTrex(mvex.getLeafAtomOfType(Atom.TYPE_trex).data);
|
||||
track = AtomParsers.parseTrak(moov.getContainerAtomOfType(Atom.TYPE_trak),
|
||||
moov.getLeafAtomOfType(Atom.TYPE_mvhd));
|
||||
Assertions.checkState(track != null);
|
||||
checkState(track != null);
|
||||
trackOutput.format(track.mediaFormat);
|
||||
}
|
||||
|
||||
private void onMoofContainerAtomRead(ContainerAtom moof) {
|
||||
private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
|
||||
fragmentRun.reset();
|
||||
parseMoof(track, extendsDefaults, moof, fragmentRun, workaroundFlags, extendedTypeScratch);
|
||||
sampleIndex = 0;
|
||||
}
|
||||
|
||||
private static void checkState(boolean expression) throws ParserException {
|
||||
if (!expression) {
|
||||
throw new ParserException();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkState(boolean expression, String errorMessage) throws ParserException {
|
||||
if (!expression) {
|
||||
throw new ParserException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a trex atom (defined in 14496-12).
|
||||
*/
|
||||
@ -332,9 +344,10 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
|
||||
private static void parseMoof(Track track, DefaultSampleValues extendsDefaults,
|
||||
ContainerAtom moof, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch) {
|
||||
ContainerAtom moof, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch)
|
||||
throws ParserException {
|
||||
// This extractor only supports one traf per moof.
|
||||
Assertions.checkArgument(1 == moof.getChildAtomOfTypeCount(Atom.TYPE_traf));
|
||||
checkState(1 == moof.getChildAtomOfTypeCount(Atom.TYPE_traf));
|
||||
parseTraf(track, extendsDefaults, moof.getContainerAtomOfType(Atom.TYPE_traf),
|
||||
out, workaroundFlags, extendedTypeScratch);
|
||||
}
|
||||
@ -343,9 +356,10 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
* Parses a traf atom (defined in 14496-12).
|
||||
*/
|
||||
private static void parseTraf(Track track, DefaultSampleValues extendsDefaults,
|
||||
ContainerAtom traf, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch) {
|
||||
ContainerAtom traf, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch)
|
||||
throws ParserException {
|
||||
// This extractor only supports one trun per traf.
|
||||
Assertions.checkArgument(1 == traf.getChildAtomOfTypeCount(Atom.TYPE_trun));
|
||||
checkState(1 == traf.getChildAtomOfTypeCount(Atom.TYPE_trun));
|
||||
LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
|
||||
long decodeTime;
|
||||
if (tfdtAtom == null || (workaroundFlags & WORKAROUND_IGNORE_TFDT_BOX) != 0) {
|
||||
@ -387,7 +401,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
|
||||
private static void parseSaiz(TrackEncryptionBox encryptionBox, ParsableByteArray saiz,
|
||||
TrackFragment out) {
|
||||
TrackFragment out) throws ParserException {
|
||||
int vectorSize = encryptionBox.initializationVectorSize;
|
||||
saiz.setPosition(Atom.HEADER_SIZE);
|
||||
int fullAtom = saiz.readInt();
|
||||
@ -399,7 +413,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
|
||||
int sampleCount = saiz.readUnsignedIntToInt();
|
||||
if (sampleCount != out.length) {
|
||||
throw new IllegalStateException("Length mismatch: " + sampleCount + ", " + out.length);
|
||||
throw new ParserException("Length mismatch: " + sampleCount + ", " + out.length);
|
||||
}
|
||||
|
||||
int totalSize = 0;
|
||||
@ -424,7 +438,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
* @param saio The saio atom to parse.
|
||||
* @param out The track fragment to populate with data from the saio atom.
|
||||
*/
|
||||
private static void parseSaio(ParsableByteArray saio, TrackFragment out) {
|
||||
private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException {
|
||||
saio.setPosition(Atom.HEADER_SIZE);
|
||||
int fullAtom = saio.readInt();
|
||||
int flags = Atom.parseFullAtomFlags(fullAtom);
|
||||
@ -435,7 +449,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
int entryCount = saio.readUnsignedIntToInt();
|
||||
if (entryCount != 1) {
|
||||
// We only support one trun element currently, so always expect one entry.
|
||||
throw new IllegalStateException("Unexpected saio entry count: " + entryCount);
|
||||
throw new ParserException("Unexpected saio entry count: " + entryCount);
|
||||
}
|
||||
|
||||
int version = Atom.parseFullAtomVersion(fullAtom);
|
||||
@ -558,7 +572,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
|
||||
private static void parseUuid(ParsableByteArray uuid, TrackFragment out,
|
||||
byte[] extendedTypeScratch) {
|
||||
byte[] extendedTypeScratch) throws ParserException {
|
||||
uuid.setPosition(Atom.HEADER_SIZE);
|
||||
uuid.readBytes(extendedTypeScratch, 0, 16);
|
||||
|
||||
@ -573,24 +587,25 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
parseSenc(uuid, 16, out);
|
||||
}
|
||||
|
||||
private static void parseSenc(ParsableByteArray senc, TrackFragment out) {
|
||||
private static void parseSenc(ParsableByteArray senc, TrackFragment out) throws ParserException {
|
||||
parseSenc(senc, 0, out);
|
||||
}
|
||||
|
||||
private static void parseSenc(ParsableByteArray senc, int offset, TrackFragment out) {
|
||||
private static void parseSenc(ParsableByteArray senc, int offset, TrackFragment out)
|
||||
throws ParserException {
|
||||
senc.setPosition(Atom.HEADER_SIZE + offset);
|
||||
int fullAtom = senc.readInt();
|
||||
int flags = Atom.parseFullAtomFlags(fullAtom);
|
||||
|
||||
if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) {
|
||||
// TODO: Implement this.
|
||||
throw new IllegalStateException("Overriding TrackEncryptionBox parameters is unsupported");
|
||||
throw new ParserException("Overriding TrackEncryptionBox parameters is unsupported.");
|
||||
}
|
||||
|
||||
boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0;
|
||||
int sampleCount = senc.readUnsignedIntToInt();
|
||||
if (sampleCount != out.length) {
|
||||
throw new IllegalStateException("Length mismatch: " + sampleCount + ", " + out.length);
|
||||
throw new ParserException("Length mismatch: " + sampleCount + ", " + out.length);
|
||||
}
|
||||
|
||||
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption);
|
||||
@ -601,7 +616,8 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
/**
|
||||
* Parses a sidx atom (defined in 14496-12).
|
||||
*/
|
||||
private static ChunkIndex parseSidx(ParsableByteArray atom, long inputPosition) {
|
||||
private static ChunkIndex parseSidx(ParsableByteArray atom, long inputPosition)
|
||||
throws ParserException {
|
||||
atom.setPosition(Atom.HEADER_SIZE);
|
||||
int fullAtom = atom.readInt();
|
||||
int version = Atom.parseFullAtomVersion(fullAtom);
|
||||
@ -633,7 +649,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
|
||||
int type = 0x80000000 & firstInt;
|
||||
if (type != 0) {
|
||||
throw new IllegalStateException("Unhandled indirect reference");
|
||||
throw new ParserException("Unhandled indirect reference");
|
||||
}
|
||||
long referenceDuration = atom.readUnsignedInt();
|
||||
|
||||
@ -656,7 +672,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
|
||||
private void readEncryptionData(ExtractorInput input) throws IOException, InterruptedException {
|
||||
int bytesToSkip = (int) (fragmentRun.auxiliaryDataPosition - input.getPosition());
|
||||
Assertions.checkState(bytesToSkip >= 0, "Offset to encryption data was negative.");
|
||||
checkState(bytesToSkip >= 0, "Offset to encryption data was negative.");
|
||||
input.skipFully(bytesToSkip);
|
||||
fragmentRun.fillEncryptionData(input);
|
||||
parserState = STATE_READING_SAMPLE_START;
|
||||
@ -679,13 +695,13 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
private boolean readSample(ExtractorInput input) throws IOException, InterruptedException {
|
||||
if (sampleIndex == 0) {
|
||||
int bytesToSkip = (int) (fragmentRun.dataPosition - input.getPosition());
|
||||
Assertions.checkState(bytesToSkip >= 0, "Offset to sample data was negative.");
|
||||
checkState(bytesToSkip >= 0, "Offset to sample data was negative.");
|
||||
input.skipFully(bytesToSkip);
|
||||
}
|
||||
|
||||
if (sampleIndex >= fragmentRun.length) {
|
||||
int bytesToSkip = (int) (endOfMdatPosition - input.getPosition());
|
||||
Assertions.checkState(bytesToSkip >= 0, "Offset to end of mdat was negative.");
|
||||
checkState(bytesToSkip >= 0, "Offset to end of mdat was negative.");
|
||||
input.skipFully(bytesToSkip);
|
||||
// We've run out of samples in the current mdat atom.
|
||||
enterReadingAtomHeaderState();
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer.extractor.webm;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
|
||||
@ -100,7 +101,7 @@ import java.util.Stack;
|
||||
return true;
|
||||
case TYPE_UNSIGNED_INT:
|
||||
if (elementContentSize > MAX_INTEGER_ELEMENT_SIZE_BYTES) {
|
||||
throw new IllegalStateException("Invalid integer size: " + elementContentSize);
|
||||
throw new ParserException("Invalid integer size: " + elementContentSize);
|
||||
}
|
||||
output.integerElement(elementId, readInteger(input, (int) elementContentSize));
|
||||
elementState = ELEMENT_STATE_READ_ID;
|
||||
@ -108,14 +109,14 @@ import java.util.Stack;
|
||||
case TYPE_FLOAT:
|
||||
if (elementContentSize != VALID_FLOAT32_ELEMENT_SIZE_BYTES
|
||||
&& elementContentSize != VALID_FLOAT64_ELEMENT_SIZE_BYTES) {
|
||||
throw new IllegalStateException("Invalid float size: " + elementContentSize);
|
||||
throw new ParserException("Invalid float size: " + elementContentSize);
|
||||
}
|
||||
output.floatElement(elementId, readFloat(input, (int) elementContentSize));
|
||||
elementState = ELEMENT_STATE_READ_ID;
|
||||
return true;
|
||||
case TYPE_STRING:
|
||||
if (elementContentSize > Integer.MAX_VALUE) {
|
||||
throw new IllegalStateException("String element size: " + elementContentSize);
|
||||
throw new ParserException("String element size: " + elementContentSize);
|
||||
}
|
||||
output.stringElement(elementId, readString(input, (int) elementContentSize));
|
||||
elementState = ELEMENT_STATE_READ_ID;
|
||||
@ -129,7 +130,7 @@ import java.util.Stack;
|
||||
elementState = ELEMENT_STATE_READ_ID;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid element type " + type);
|
||||
throw new ParserException("Invalid element type " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import com.google.android.exoplayer.extractor.ExtractorOutput;
|
||||
import com.google.android.exoplayer.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer.extractor.SeekMap;
|
||||
import com.google.android.exoplayer.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.LongArray;
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
import com.google.android.exoplayer.util.NalUnitUtil;
|
||||
@ -738,7 +737,7 @@ public final class WebmExtractor implements Extractor {
|
||||
contentSize - blockTrackNumberLength - headerSize - totalSamplesSize;
|
||||
} else {
|
||||
// Lacing is always in the range 0--3.
|
||||
throw new IllegalStateException("Unexpected lacing value: " + lacing);
|
||||
throw new ParserException("Unexpected lacing value: " + lacing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,7 +1256,9 @@ public final class WebmExtractor implements Extractor {
|
||||
// TODO: Deduplicate with AtomParsers.parseAvcCFromParent.
|
||||
buffer.setPosition(4);
|
||||
int nalUnitLengthFieldLength = (buffer.readUnsignedByte() & 0x03) + 1;
|
||||
Assertions.checkState(nalUnitLengthFieldLength != 3);
|
||||
if (nalUnitLengthFieldLength == 3) {
|
||||
throw new ParserException();
|
||||
}
|
||||
List<byte[]> initializationData = new ArrayList<>();
|
||||
int numSequenceParameterSets = buffer.readUnsignedByte() & 0x1F;
|
||||
for (int i = 0; i < numSequenceParameterSets; i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user