Remove the last deprecated ParserException constructor
PiperOrigin-RevId: 381221669
This commit is contained in:
parent
1cb4fb290f
commit
fc26d4eeb1
@ -327,7 +327,8 @@ public class SampleChooserActivity extends AppCompatActivity
|
|||||||
reader.nextString(); // Ignore.
|
reader.nextString(); // Ignore.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Unsupported name: " + name);
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Unsupported name: " + name, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.endObject();
|
reader.endObject();
|
||||||
@ -415,7 +416,8 @@ public class SampleChooserActivity extends AppCompatActivity
|
|||||||
reader.endArray();
|
reader.endArray();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Unsupported attribute name: " + name);
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Unsupported attribute name: " + name, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.endObject();
|
reader.endObject();
|
||||||
|
@ -148,7 +148,8 @@ import java.nio.ByteBuffer;
|
|||||||
public FlacStreamMetadata decodeStreamMetadata() throws IOException {
|
public FlacStreamMetadata decodeStreamMetadata() throws IOException {
|
||||||
FlacStreamMetadata streamMetadata = flacDecodeMetadata(nativeDecoderContext);
|
FlacStreamMetadata streamMetadata = flacDecodeMetadata(nativeDecoderContext);
|
||||||
if (streamMetadata == null) {
|
if (streamMetadata == null) {
|
||||||
throw new ParserException("Failed to decode stream metadata");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Failed to decode stream metadata", /* cause= */ null);
|
||||||
}
|
}
|
||||||
return streamMetadata;
|
return streamMetadata;
|
||||||
}
|
}
|
||||||
|
@ -96,18 +96,6 @@ public class ParserException extends IOException {
|
|||||||
/** The {@link DataType data type} of the parsed bitstream. */
|
/** The {@link DataType data type} of the parsed bitstream. */
|
||||||
public final int dataType;
|
public final int dataType;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance.
|
|
||||||
*
|
|
||||||
* @param message The detail message for the exception.
|
|
||||||
* @deprecated Use a factory method which initializes {@link #contentIsMalformed}, and {@link
|
|
||||||
* #dataType} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public ParserException(String message) {
|
|
||||||
this(message, /* cause= */ null, /* contentIsMalformed= */ true, C.DATA_TYPE_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ParserException(
|
protected ParserException(
|
||||||
@Nullable String message,
|
@Nullable String message,
|
||||||
@Nullable Throwable cause,
|
@Nullable Throwable cause,
|
||||||
|
@ -229,7 +229,8 @@ public final class AacUtil {
|
|||||||
parseGaSpecificConfig(bitArray, audioObjectType, channelConfiguration);
|
parseGaSpecificConfig(bitArray, audioObjectType, channelConfiguration);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Unsupported audio object type: " + audioObjectType);
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Unsupported audio object type: " + audioObjectType);
|
||||||
}
|
}
|
||||||
switch (audioObjectType) {
|
switch (audioObjectType) {
|
||||||
case 17:
|
case 17:
|
||||||
@ -240,7 +241,8 @@ public final class AacUtil {
|
|||||||
case 23:
|
case 23:
|
||||||
int epConfig = bitArray.readBits(2);
|
int epConfig = bitArray.readBits(2);
|
||||||
if (epConfig == 2 || epConfig == 3) {
|
if (epConfig == 2 || epConfig == 3) {
|
||||||
throw new ParserException("Unsupported epConfig: " + epConfig);
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Unsupported epConfig: " + epConfig);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1216,7 +1216,8 @@ public final class Util {
|
|||||||
public static long parseXsDateTime(String value) throws ParserException {
|
public static long parseXsDateTime(String value) throws ParserException {
|
||||||
Matcher matcher = XS_DATE_TIME_PATTERN.matcher(value);
|
Matcher matcher = XS_DATE_TIME_PATTERN.matcher(value);
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
throw new ParserException("Invalid date/time format: " + value);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid date/time format: " + value, /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int timezoneShift;
|
int timezoneShift;
|
||||||
|
@ -237,7 +237,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
public void maybeThrowPrepareError() throws IOException {
|
public void maybeThrowPrepareError() throws IOException {
|
||||||
maybeThrowError();
|
maybeThrowError();
|
||||||
if (loadingFinished && !prepared) {
|
if (loadingFinished && !prepared) {
|
||||||
throw new ParserException("Loading finished before preparation is complete.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Loading finished before preparation is complete.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ public final class WebvttParserUtil {
|
|||||||
int startPosition = input.getPosition();
|
int startPosition = input.getPosition();
|
||||||
if (!isWebvttHeaderLine(input)) {
|
if (!isWebvttHeaderLine(input)) {
|
||||||
input.setPosition(startPosition);
|
input.setPosition(startPosition);
|
||||||
throw new ParserException("Expected WEBVTT. Got " + input.readLine());
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Expected WEBVTT. Got " + input.readLine(), /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import android.util.Base64;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -48,12 +49,11 @@ public final class DataSchemeDataSource extends BaseDataSource {
|
|||||||
this.dataSpec = dataSpec;
|
this.dataSpec = dataSpec;
|
||||||
Uri uri = dataSpec.uri;
|
Uri uri = dataSpec.uri;
|
||||||
String scheme = uri.getScheme();
|
String scheme = uri.getScheme();
|
||||||
if (!SCHEME_DATA.equals(scheme)) {
|
Assertions.checkArgument(SCHEME_DATA.equals(scheme), "Unsupported scheme: " + scheme);
|
||||||
throw new ParserException("Unsupported scheme: " + scheme);
|
|
||||||
}
|
|
||||||
String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
|
String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
|
||||||
if (uriParts.length != 2) {
|
if (uriParts.length != 2) {
|
||||||
throw new ParserException("Unexpected URI format: " + uri);
|
throw ParserException.createForMalformedDataOfUnknownType(
|
||||||
|
"Unexpected URI format: " + uri, /* cause= */ null);
|
||||||
}
|
}
|
||||||
String dataString = uriParts[1];
|
String dataString = uriParts[1];
|
||||||
if (uriParts[0].contains(";base64")) {
|
if (uriParts[0].contains(";base64")) {
|
||||||
|
@ -108,11 +108,11 @@ public final class DataSchemeDataSourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void incorrectScheme() {
|
public void incorrectScheme() throws IOException {
|
||||||
try {
|
try {
|
||||||
schemeDataDataSource.open(buildDataSpec("http://www.google.com"));
|
schemeDataDataSource.open(buildDataSpec("http://www.google.com"));
|
||||||
fail();
|
fail();
|
||||||
} catch (IOException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Expected.
|
// Expected.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1443,7 +1443,8 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||||||
try {
|
try {
|
||||||
Matcher matcher = TIMESTAMP_WITH_TIMEZONE_PATTERN.matcher(firstLine);
|
Matcher matcher = TIMESTAMP_WITH_TIMEZONE_PATTERN.matcher(firstLine);
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
throw new ParserException("Couldn't parse timestamp: " + firstLine);
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Couldn't parse timestamp: " + firstLine, /* cause= */ null);
|
||||||
}
|
}
|
||||||
// Parse the timestamp.
|
// Parse the timestamp.
|
||||||
String timestampWithoutTimezone = matcher.group(1);
|
String timestampWithoutTimezone = matcher.group(1);
|
||||||
|
@ -169,7 +169,8 @@ public class DashManifestParser extends DefaultHandler
|
|||||||
// early access.
|
// early access.
|
||||||
seenEarlyAccessPeriod = true;
|
seenEarlyAccessPeriod = true;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("Unable to determine start of period " + periods.size());
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Unable to determine start of period " + periods.size(), /* cause= */ null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
long periodDurationMs = periodWithDurationMs.second;
|
long periodDurationMs = periodWithDurationMs.second;
|
||||||
@ -187,12 +188,13 @@ public class DashManifestParser extends DefaultHandler
|
|||||||
// If we know the end time of the final period, we can use it as the duration.
|
// If we know the end time of the final period, we can use it as the duration.
|
||||||
durationMs = nextPeriodStartMs;
|
durationMs = nextPeriodStartMs;
|
||||||
} else if (!dynamic) {
|
} else if (!dynamic) {
|
||||||
throw new ParserException("Unable to determine duration of static manifest.");
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Unable to determine duration of static manifest.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (periods.isEmpty()) {
|
if (periods.isEmpty()) {
|
||||||
throw new ParserException("No periods found.");
|
throw ParserException.createForMalformedManifest("No periods found.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildMediaPresentationDescription(
|
return buildMediaPresentationDescription(
|
||||||
|
@ -120,7 +120,8 @@ public final class FlacMetadataReader {
|
|||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
|
||||||
input.readFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
|
input.readFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
|
||||||
if (scratch.readUnsignedInt() != STREAM_MARKER) {
|
if (scratch.readUnsignedInt() != STREAM_MARKER) {
|
||||||
throw new ParserException("Failed to read FLAC stream marker.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Failed to read FLAC stream marker.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +235,8 @@ public final class FlacMetadataReader {
|
|||||||
int syncCode = frameStartMarker >> 2;
|
int syncCode = frameStartMarker >> 2;
|
||||||
if (syncCode != SYNC_CODE) {
|
if (syncCode != SYNC_CODE) {
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
throw new ParserException("First frame does not start with sync code.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"First frame does not start with sync code.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
|
@ -241,7 +241,8 @@ public final class VorbisUtil {
|
|||||||
length += comments[i].length();
|
length += comments[i].length();
|
||||||
}
|
}
|
||||||
if (hasFramingBit && (headerData.readUnsignedByte() & 0x01) == 0) {
|
if (hasFramingBit && (headerData.readUnsignedByte() & 0x01) == 0) {
|
||||||
throw new ParserException("framing bit expected to be set");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"framing bit expected to be set", /* cause= */ null);
|
||||||
}
|
}
|
||||||
length += 1;
|
length += 1;
|
||||||
return new CommentHeader(vendor, comments, length);
|
return new CommentHeader(vendor, comments, length);
|
||||||
@ -263,7 +264,8 @@ public final class VorbisUtil {
|
|||||||
if (quiet) {
|
if (quiet) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("too short header: " + header.bytesLeft());
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"too short header: " + header.bytesLeft(), /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +273,8 @@ public final class VorbisUtil {
|
|||||||
if (quiet) {
|
if (quiet) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("expected header type " + Integer.toHexString(headerType));
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"expected header type " + Integer.toHexString(headerType), /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +287,8 @@ public final class VorbisUtil {
|
|||||||
if (quiet) {
|
if (quiet) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("expected characters 'vorbis'");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"expected characters 'vorbis'", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -319,7 +323,8 @@ public final class VorbisUtil {
|
|||||||
int timeCount = bitArray.readBits(6) + 1;
|
int timeCount = bitArray.readBits(6) + 1;
|
||||||
for (int i = 0; i < timeCount; i++) {
|
for (int i = 0; i < timeCount; i++) {
|
||||||
if (bitArray.readBits(16) != 0x00) {
|
if (bitArray.readBits(16) != 0x00) {
|
||||||
throw new ParserException("placeholder of time domain transforms not zeroed out");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"placeholder of time domain transforms not zeroed out", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
readFloors(bitArray);
|
readFloors(bitArray);
|
||||||
@ -328,7 +333,8 @@ public final class VorbisUtil {
|
|||||||
|
|
||||||
Mode[] modes = readModes(bitArray);
|
Mode[] modes = readModes(bitArray);
|
||||||
if (!bitArray.readBit()) {
|
if (!bitArray.readBit()) {
|
||||||
throw new ParserException("framing bit after modes not set as expected");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"framing bit after modes not set as expected", /* cause= */ null);
|
||||||
}
|
}
|
||||||
return modes;
|
return modes;
|
||||||
}
|
}
|
||||||
@ -371,7 +377,8 @@ public final class VorbisUtil {
|
|||||||
couplingSteps = 0;
|
couplingSteps = 0;
|
||||||
}*/
|
}*/
|
||||||
if (bitArray.readBits(2) != 0x00) {
|
if (bitArray.readBits(2) != 0x00) {
|
||||||
throw new ParserException("to reserved bits must be zero after mapping coupling steps");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"to reserved bits must be zero after mapping coupling steps", /* cause= */ null);
|
||||||
}
|
}
|
||||||
if (submaps > 1) {
|
if (submaps > 1) {
|
||||||
for (int j = 0; j < channels; j++) {
|
for (int j = 0; j < channels; j++) {
|
||||||
@ -391,7 +398,8 @@ public final class VorbisUtil {
|
|||||||
for (int i = 0; i < residueCount; i++) {
|
for (int i = 0; i < residueCount; i++) {
|
||||||
int residueType = bitArray.readBits(16);
|
int residueType = bitArray.readBits(16);
|
||||||
if (residueType > 2) {
|
if (residueType > 2) {
|
||||||
throw new ParserException("residueType greater than 2 is not decodable");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"residueType greater than 2 is not decodable", /* cause= */ null);
|
||||||
} else {
|
} else {
|
||||||
bitArray.skipBits(24); // begin
|
bitArray.skipBits(24); // begin
|
||||||
bitArray.skipBits(24); // end
|
bitArray.skipBits(24); // end
|
||||||
@ -467,15 +475,17 @@ public final class VorbisUtil {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("floor type greater than 1 not decodable: " + floorType);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"floor type greater than 1 not decodable: " + floorType, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CodeBook readBook(VorbisBitArray bitArray) throws ParserException {
|
private static CodeBook readBook(VorbisBitArray bitArray) throws ParserException {
|
||||||
if (bitArray.readBits(24) != 0x564342) {
|
if (bitArray.readBits(24) != 0x564342) {
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedContainer(
|
||||||
"expected code book to start with [0x56, 0x43, 0x42] at " + bitArray.getPosition());
|
"expected code book to start with [0x56, 0x43, 0x42] at " + bitArray.getPosition(),
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
int dimensions = bitArray.readBits(16);
|
int dimensions = bitArray.readBits(16);
|
||||||
int entries = bitArray.readBits(24);
|
int entries = bitArray.readBits(24);
|
||||||
@ -508,7 +518,8 @@ public final class VorbisUtil {
|
|||||||
|
|
||||||
int lookupType = bitArray.readBits(4);
|
int lookupType = bitArray.readBits(4);
|
||||||
if (lookupType > 2) {
|
if (lookupType > 2) {
|
||||||
throw new ParserException("lookup type greater than 2 not decodable: " + lookupType);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"lookup type greater than 2 not decodable: " + lookupType, /* cause= */ null);
|
||||||
} else if (lookupType == 1 || lookupType == 2) {
|
} else if (lookupType == 1 || lookupType == 2) {
|
||||||
bitArray.skipBits(32); // minimumValue
|
bitArray.skipBits(32); // minimumValue
|
||||||
bitArray.skipBits(32); // deltaValue
|
bitArray.skipBits(32); // deltaValue
|
||||||
|
@ -176,7 +176,8 @@ public final class AmrExtractor implements Extractor {
|
|||||||
assertInitialized();
|
assertInitialized();
|
||||||
if (input.getPosition() == 0) {
|
if (input.getPosition() == 0) {
|
||||||
if (!readAmrHeader(input)) {
|
if (!readAmrHeader(input)) {
|
||||||
throw new ParserException("Could not find AMR header.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Could not find AMR header.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maybeOutputFormat();
|
maybeOutputFormat();
|
||||||
@ -311,7 +312,8 @@ public final class AmrExtractor implements Extractor {
|
|||||||
if ((frameHeader & 0x83) > 0) {
|
if ((frameHeader & 0x83) > 0) {
|
||||||
// The padding bits are at bit-1 positions in the following pattern: 1000 0011
|
// The padding bits are at bit-1 positions in the following pattern: 1000 0011
|
||||||
// Padding bits must be 0.
|
// Padding bits must be 0.
|
||||||
throw new ParserException("Invalid padding bits for frame header " + frameHeader);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid padding bits for frame header " + frameHeader, /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int frameType = (frameHeader >> 3) & 0x0f;
|
int frameType = (frameHeader >> 3) & 0x0f;
|
||||||
@ -320,8 +322,9 @@ public final class AmrExtractor implements Extractor {
|
|||||||
|
|
||||||
private int getFrameSizeInBytes(int frameType) throws ParserException {
|
private int getFrameSizeInBytes(int frameType) throws ParserException {
|
||||||
if (!isValidFrameType(frameType)) {
|
if (!isValidFrameType(frameType)) {
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Illegal AMR " + (isWideBand ? "WB" : "NB") + " frame type " + frameType);
|
"Illegal AMR " + (isWideBand ? "WB" : "NB") + " frame type " + frameType,
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isWideBand ? frameSizeBytesByTypeWb[frameType] : frameSizeBytesByTypeNb[frameType];
|
return isWideBand ? frameSizeBytesByTypeWb[frameType] : frameSizeBytesByTypeNb[frameType];
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.extractor.flv;
|
package com.google.android.exoplayer2.extractor.flv;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
@ -26,7 +27,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
|||||||
public static final class UnsupportedFormatException extends ParserException {
|
public static final class UnsupportedFormatException extends ParserException {
|
||||||
|
|
||||||
public UnsupportedFormatException(String msg) {
|
public UnsupportedFormatException(String msg) {
|
||||||
super(msg);
|
super(msg, /* cause= */ null, /* contentIsMalformed= */ false, C.DATA_TYPE_MEDIA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,8 @@ import org.xmlpull.v1.XmlPullParserFactory;
|
|||||||
xpp.setInput(new StringReader(xmpString));
|
xpp.setInput(new StringReader(xmpString));
|
||||||
xpp.next();
|
xpp.next();
|
||||||
if (!XmlPullParserUtil.isStartTag(xpp, "x:xmpmeta")) {
|
if (!XmlPullParserUtil.isStartTag(xpp, "x:xmpmeta")) {
|
||||||
throw new ParserException("Couldn't find xmp metadata");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Couldn't find xmp metadata", /* cause= */ null);
|
||||||
}
|
}
|
||||||
long motionPhotoPresentationTimestampUs = C.TIME_UNSET;
|
long motionPhotoPresentationTimestampUs = C.TIME_UNSET;
|
||||||
List<MotionPhotoDescription.ContainerItem> containerItems = ImmutableList.of();
|
List<MotionPhotoDescription.ContainerItem> containerItems = ImmutableList.of();
|
||||||
|
@ -114,7 +114,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
return true;
|
return true;
|
||||||
case EbmlProcessor.ELEMENT_TYPE_UNSIGNED_INT:
|
case EbmlProcessor.ELEMENT_TYPE_UNSIGNED_INT:
|
||||||
if (elementContentSize > MAX_INTEGER_ELEMENT_SIZE_BYTES) {
|
if (elementContentSize > MAX_INTEGER_ELEMENT_SIZE_BYTES) {
|
||||||
throw new ParserException("Invalid integer size: " + elementContentSize);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid integer size: " + elementContentSize, /* cause= */ null);
|
||||||
}
|
}
|
||||||
processor.integerElement(elementId, readInteger(input, (int) elementContentSize));
|
processor.integerElement(elementId, readInteger(input, (int) elementContentSize));
|
||||||
elementState = ELEMENT_STATE_READ_ID;
|
elementState = ELEMENT_STATE_READ_ID;
|
||||||
@ -122,14 +123,16 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
case EbmlProcessor.ELEMENT_TYPE_FLOAT:
|
case EbmlProcessor.ELEMENT_TYPE_FLOAT:
|
||||||
if (elementContentSize != VALID_FLOAT32_ELEMENT_SIZE_BYTES
|
if (elementContentSize != VALID_FLOAT32_ELEMENT_SIZE_BYTES
|
||||||
&& elementContentSize != VALID_FLOAT64_ELEMENT_SIZE_BYTES) {
|
&& elementContentSize != VALID_FLOAT64_ELEMENT_SIZE_BYTES) {
|
||||||
throw new ParserException("Invalid float size: " + elementContentSize);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid float size: " + elementContentSize, /* cause= */ null);
|
||||||
}
|
}
|
||||||
processor.floatElement(elementId, readFloat(input, (int) elementContentSize));
|
processor.floatElement(elementId, readFloat(input, (int) elementContentSize));
|
||||||
elementState = ELEMENT_STATE_READ_ID;
|
elementState = ELEMENT_STATE_READ_ID;
|
||||||
return true;
|
return true;
|
||||||
case EbmlProcessor.ELEMENT_TYPE_STRING:
|
case EbmlProcessor.ELEMENT_TYPE_STRING:
|
||||||
if (elementContentSize > Integer.MAX_VALUE) {
|
if (elementContentSize > Integer.MAX_VALUE) {
|
||||||
throw new ParserException("String element size: " + elementContentSize);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"String element size: " + elementContentSize, /* cause= */ null);
|
||||||
}
|
}
|
||||||
processor.stringElement(elementId, readString(input, (int) elementContentSize));
|
processor.stringElement(elementId, readString(input, (int) elementContentSize));
|
||||||
elementState = ELEMENT_STATE_READ_ID;
|
elementState = ELEMENT_STATE_READ_ID;
|
||||||
@ -143,7 +146,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
elementState = ELEMENT_STATE_READ_ID;
|
elementState = ELEMENT_STATE_READ_ID;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Invalid element type " + type);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid element type " + type, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,7 +626,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
case ID_SEGMENT:
|
case ID_SEGMENT:
|
||||||
if (segmentContentPosition != C.POSITION_UNSET
|
if (segmentContentPosition != C.POSITION_UNSET
|
||||||
&& segmentContentPosition != contentPosition) {
|
&& segmentContentPosition != contentPosition) {
|
||||||
throw new ParserException("Multiple Segment elements not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Multiple Segment elements not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
segmentContentPosition = contentPosition;
|
segmentContentPosition = contentPosition;
|
||||||
segmentContentSize = contentSize;
|
segmentContentSize = contentSize;
|
||||||
@ -696,7 +697,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
break;
|
break;
|
||||||
case ID_SEEK:
|
case ID_SEEK:
|
||||||
if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.POSITION_UNSET) {
|
if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.POSITION_UNSET) {
|
||||||
throw new ParserException("Mandatory element SeekID or SeekPosition not found");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Mandatory element SeekID or SeekPosition not found", /* cause= */ null);
|
||||||
}
|
}
|
||||||
if (seekEntryId == ID_CUES) {
|
if (seekEntryId == ID_CUES) {
|
||||||
cuesContentPosition = seekEntryPosition;
|
cuesContentPosition = seekEntryPosition;
|
||||||
@ -742,7 +744,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
assertInTrackEntry(id);
|
assertInTrackEntry(id);
|
||||||
if (currentTrack.hasContentEncryption) {
|
if (currentTrack.hasContentEncryption) {
|
||||||
if (currentTrack.cryptoData == null) {
|
if (currentTrack.cryptoData == null) {
|
||||||
throw new ParserException("Encrypted Track found but ContentEncKeyID was not found");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Encrypted Track found but ContentEncKeyID was not found", /* cause= */ null);
|
||||||
}
|
}
|
||||||
currentTrack.drmInitData =
|
currentTrack.drmInitData =
|
||||||
new DrmInitData(
|
new DrmInitData(
|
||||||
@ -753,13 +756,15 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
case ID_CONTENT_ENCODINGS:
|
case ID_CONTENT_ENCODINGS:
|
||||||
assertInTrackEntry(id);
|
assertInTrackEntry(id);
|
||||||
if (currentTrack.hasContentEncryption && currentTrack.sampleStrippedBytes != null) {
|
if (currentTrack.hasContentEncryption && currentTrack.sampleStrippedBytes != null) {
|
||||||
throw new ParserException("Combining encryption and compression is not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Combining encryption and compression is not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_TRACK_ENTRY:
|
case ID_TRACK_ENTRY:
|
||||||
Track currentTrack = checkStateNotNull(this.currentTrack);
|
Track currentTrack = checkStateNotNull(this.currentTrack);
|
||||||
if (currentTrack.codecId == null) {
|
if (currentTrack.codecId == null) {
|
||||||
throw new ParserException("CodecId is missing in TrackEntry element");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"CodecId is missing in TrackEntry element", /* cause= */ null);
|
||||||
} else {
|
} else {
|
||||||
if (isCodecSupported(currentTrack.codecId)) {
|
if (isCodecSupported(currentTrack.codecId)) {
|
||||||
currentTrack.initializeOutput(extractorOutput, currentTrack.number);
|
currentTrack.initializeOutput(extractorOutput, currentTrack.number);
|
||||||
@ -770,7 +775,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
break;
|
break;
|
||||||
case ID_TRACKS:
|
case ID_TRACKS:
|
||||||
if (tracks.size() == 0) {
|
if (tracks.size() == 0) {
|
||||||
throw new ParserException("No valid tracks were found");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"No valid tracks were found", /* cause= */ null);
|
||||||
}
|
}
|
||||||
extractorOutput.endTracks();
|
extractorOutput.endTracks();
|
||||||
break;
|
break;
|
||||||
@ -790,13 +796,15 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
case ID_EBML_READ_VERSION:
|
case ID_EBML_READ_VERSION:
|
||||||
// Validate that EBMLReadVersion is supported. This extractor only supports v1.
|
// Validate that EBMLReadVersion is supported. This extractor only supports v1.
|
||||||
if (value != 1) {
|
if (value != 1) {
|
||||||
throw new ParserException("EBMLReadVersion " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"EBMLReadVersion " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_DOC_TYPE_READ_VERSION:
|
case ID_DOC_TYPE_READ_VERSION:
|
||||||
// Validate that DocTypeReadVersion is supported. This extractor only supports up to v2.
|
// Validate that DocTypeReadVersion is supported. This extractor only supports up to v2.
|
||||||
if (value < 1 || value > 2) {
|
if (value < 1 || value > 2) {
|
||||||
throw new ParserException("DocTypeReadVersion " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"DocTypeReadVersion " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_SEEK_POSITION:
|
case ID_SEEK_POSITION:
|
||||||
@ -861,31 +869,36 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
case ID_CONTENT_ENCODING_ORDER:
|
case ID_CONTENT_ENCODING_ORDER:
|
||||||
// This extractor only supports one ContentEncoding element and hence the order has to be 0.
|
// This extractor only supports one ContentEncoding element and hence the order has to be 0.
|
||||||
if (value != 0) {
|
if (value != 0) {
|
||||||
throw new ParserException("ContentEncodingOrder " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"ContentEncodingOrder " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_CONTENT_ENCODING_SCOPE:
|
case ID_CONTENT_ENCODING_SCOPE:
|
||||||
// This extractor only supports the scope of all frames.
|
// This extractor only supports the scope of all frames.
|
||||||
if (value != 1) {
|
if (value != 1) {
|
||||||
throw new ParserException("ContentEncodingScope " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"ContentEncodingScope " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_CONTENT_COMPRESSION_ALGORITHM:
|
case ID_CONTENT_COMPRESSION_ALGORITHM:
|
||||||
// This extractor only supports header stripping.
|
// This extractor only supports header stripping.
|
||||||
if (value != 3) {
|
if (value != 3) {
|
||||||
throw new ParserException("ContentCompAlgo " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"ContentCompAlgo " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_CONTENT_ENCRYPTION_ALGORITHM:
|
case ID_CONTENT_ENCRYPTION_ALGORITHM:
|
||||||
// Only the value 5 (AES) is allowed according to the WebM specification.
|
// Only the value 5 (AES) is allowed according to the WebM specification.
|
||||||
if (value != 5) {
|
if (value != 5) {
|
||||||
throw new ParserException("ContentEncAlgo " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"ContentEncAlgo " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_CONTENT_ENCRYPTION_AES_SETTINGS_CIPHER_MODE:
|
case ID_CONTENT_ENCRYPTION_AES_SETTINGS_CIPHER_MODE:
|
||||||
// Only the value 1 is allowed according to the WebM specification.
|
// Only the value 1 is allowed according to the WebM specification.
|
||||||
if (value != 1) {
|
if (value != 1) {
|
||||||
throw new ParserException("AESSettingsCipherMode " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"AESSettingsCipherMode " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_CUE_TIME:
|
case ID_CUE_TIME:
|
||||||
@ -1058,7 +1071,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
case ID_DOC_TYPE:
|
case ID_DOC_TYPE:
|
||||||
// Validate that DocType is supported.
|
// Validate that DocType is supported.
|
||||||
if (!DOC_TYPE_WEBM.equals(value) && !DOC_TYPE_MATROSKA.equals(value)) {
|
if (!DOC_TYPE_WEBM.equals(value) && !DOC_TYPE_MATROSKA.equals(value)) {
|
||||||
throw new ParserException("DocType " + value + " not supported");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"DocType " + value + " not supported", /* cause= */ null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_NAME:
|
case ID_NAME:
|
||||||
@ -1180,7 +1194,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
blockSampleSizes[sampleIndex] = 0;
|
blockSampleSizes[sampleIndex] = 0;
|
||||||
readScratch(input, ++headerSize);
|
readScratch(input, ++headerSize);
|
||||||
if (scratch.getData()[headerSize - 1] == 0) {
|
if (scratch.getData()[headerSize - 1] == 0) {
|
||||||
throw new ParserException("No valid varint length mask found");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"No valid varint length mask found", /* cause= */ null);
|
||||||
}
|
}
|
||||||
long readValue = 0;
|
long readValue = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@ -1202,7 +1217,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (readValue < Integer.MIN_VALUE || readValue > Integer.MAX_VALUE) {
|
if (readValue < Integer.MIN_VALUE || readValue > Integer.MAX_VALUE) {
|
||||||
throw new ParserException("EBML lacing sample size out of range.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"EBML lacing sample size out of range.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
int intReadValue = (int) readValue;
|
int intReadValue = (int) readValue;
|
||||||
blockSampleSizes[sampleIndex] =
|
blockSampleSizes[sampleIndex] =
|
||||||
@ -1215,7 +1231,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
contentSize - blockTrackNumberLength - headerSize - totalSamplesSize;
|
contentSize - blockTrackNumberLength - headerSize - totalSamplesSize;
|
||||||
} else {
|
} else {
|
||||||
// Lacing is always in the range 0--3.
|
// Lacing is always in the range 0--3.
|
||||||
throw new ParserException("Unexpected lacing value: " + lacing);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unexpected lacing value: " + lacing, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1262,7 +1279,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
tracks.get(blockTrackNumber), blockAdditionalId, input, contentSize);
|
tracks.get(blockTrackNumber), blockAdditionalId, input, contentSize);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Unexpected id: " + id);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unexpected id: " + id, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,14 +1312,16 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
@EnsuresNonNull("currentTrack")
|
@EnsuresNonNull("currentTrack")
|
||||||
private void assertInTrackEntry(int id) throws ParserException {
|
private void assertInTrackEntry(int id) throws ParserException {
|
||||||
if (currentTrack == null) {
|
if (currentTrack == null) {
|
||||||
throw new ParserException("Element " + id + " must be in a TrackEntry");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Element " + id + " must be in a TrackEntry", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnsuresNonNull({"cueTimesUs", "cueClusterPositions"})
|
@EnsuresNonNull({"cueTimesUs", "cueClusterPositions"})
|
||||||
private void assertInCues(int id) throws ParserException {
|
private void assertInCues(int id) throws ParserException {
|
||||||
if (cueTimesUs == null || cueClusterPositions == null) {
|
if (cueTimesUs == null || cueClusterPositions == null) {
|
||||||
throw new ParserException("Element " + id + " must be in a Cues");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Element " + id + " must be in a Cues", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1401,7 +1421,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
input.readFully(scratch.getData(), 0, 1);
|
input.readFully(scratch.getData(), 0, 1);
|
||||||
sampleBytesRead++;
|
sampleBytesRead++;
|
||||||
if ((scratch.getData()[0] & 0x80) == 0x80) {
|
if ((scratch.getData()[0] & 0x80) == 0x80) {
|
||||||
throw new ParserException("Extension bit is set in signal byte");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Extension bit is set in signal byte", /* cause= */ null);
|
||||||
}
|
}
|
||||||
sampleSignalByte = scratch.getData()[0];
|
sampleSignalByte = scratch.getData()[0];
|
||||||
sampleSignalByteRead = true;
|
sampleSignalByteRead = true;
|
||||||
@ -1766,7 +1787,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
|
|
||||||
private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException {
|
private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException {
|
||||||
if (timecodeScale == C.TIME_UNSET) {
|
if (timecodeScale == C.TIME_UNSET) {
|
||||||
throw new ParserException("Can't scale timecode prior to timecodeScale being set.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Can't scale timecode prior to timecodeScale being set.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000);
|
return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000);
|
||||||
}
|
}
|
||||||
@ -2207,7 +2229,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
initializationData = ImmutableList.of(initializationDataBytes);
|
initializationData = ImmutableList.of(initializationDataBytes);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Unrecognized codec identifier.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unrecognized codec identifier.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dolbyVisionConfigBytes != null) {
|
if (dolbyVisionConfigBytes != null) {
|
||||||
@ -2284,7 +2307,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)) {
|
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)) {
|
||||||
type = C.TRACK_TYPE_TEXT;
|
type = C.TRACK_TYPE_TEXT;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("Unexpected MIME type.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unexpected MIME type.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name != null && !TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) {
|
if (name != null && !TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) {
|
||||||
@ -2389,10 +2413,12 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
return new Pair<>(MimeTypes.VIDEO_VC1, Collections.singletonList(initializationData));
|
return new Pair<>(MimeTypes.VIDEO_VC1, Collections.singletonList(initializationData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ParserException("Failed to find FourCC VC1 initialization data");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Failed to find FourCC VC1 initialization data", /* cause= */ null);
|
||||||
}
|
}
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
throw new ParserException("Error parsing FourCC private data");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing FourCC private data", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.w(TAG, "Unknown FourCC. Setting mimeType to " + MimeTypes.VIDEO_UNKNOWN);
|
Log.w(TAG, "Unknown FourCC. Setting mimeType to " + MimeTypes.VIDEO_UNKNOWN);
|
||||||
@ -2409,7 +2435,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
throws ParserException {
|
throws ParserException {
|
||||||
try {
|
try {
|
||||||
if (codecPrivate[0] != 0x02) {
|
if (codecPrivate[0] != 0x02) {
|
||||||
throw new ParserException("Error parsing vorbis codec private");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing vorbis codec private", /* cause= */ null);
|
||||||
}
|
}
|
||||||
int offset = 1;
|
int offset = 1;
|
||||||
int vorbisInfoLength = 0;
|
int vorbisInfoLength = 0;
|
||||||
@ -2427,17 +2454,20 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
vorbisSkipLength += codecPrivate[offset++] & 0xFF;
|
vorbisSkipLength += codecPrivate[offset++] & 0xFF;
|
||||||
|
|
||||||
if (codecPrivate[offset] != 0x01) {
|
if (codecPrivate[offset] != 0x01) {
|
||||||
throw new ParserException("Error parsing vorbis codec private");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing vorbis codec private", /* cause= */ null);
|
||||||
}
|
}
|
||||||
byte[] vorbisInfo = new byte[vorbisInfoLength];
|
byte[] vorbisInfo = new byte[vorbisInfoLength];
|
||||||
System.arraycopy(codecPrivate, offset, vorbisInfo, 0, vorbisInfoLength);
|
System.arraycopy(codecPrivate, offset, vorbisInfo, 0, vorbisInfoLength);
|
||||||
offset += vorbisInfoLength;
|
offset += vorbisInfoLength;
|
||||||
if (codecPrivate[offset] != 0x03) {
|
if (codecPrivate[offset] != 0x03) {
|
||||||
throw new ParserException("Error parsing vorbis codec private");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing vorbis codec private", /* cause= */ null);
|
||||||
}
|
}
|
||||||
offset += vorbisSkipLength;
|
offset += vorbisSkipLength;
|
||||||
if (codecPrivate[offset] != 0x05) {
|
if (codecPrivate[offset] != 0x05) {
|
||||||
throw new ParserException("Error parsing vorbis codec private");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing vorbis codec private", /* cause= */ null);
|
||||||
}
|
}
|
||||||
byte[] vorbisBooks = new byte[codecPrivate.length - offset];
|
byte[] vorbisBooks = new byte[codecPrivate.length - offset];
|
||||||
System.arraycopy(codecPrivate, offset, vorbisBooks, 0, codecPrivate.length - offset);
|
System.arraycopy(codecPrivate, offset, vorbisBooks, 0, codecPrivate.length - offset);
|
||||||
@ -2446,7 +2476,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
initializationData.add(vorbisBooks);
|
initializationData.add(vorbisBooks);
|
||||||
return initializationData;
|
return initializationData;
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
throw new ParserException("Error parsing vorbis codec private");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing vorbis codec private", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2469,7 +2500,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
throw new ParserException("Error parsing MS/ACM codec private");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Error parsing MS/ACM codec private", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2488,7 +2520,8 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
@EnsuresNonNull("codecPrivate")
|
@EnsuresNonNull("codecPrivate")
|
||||||
private byte[] getCodecPrivate(String codecId) throws ParserException {
|
private byte[] getCodecPrivate(String codecId) throws ParserException {
|
||||||
if (codecPrivate == null) {
|
if (codecPrivate == null) {
|
||||||
throw new ParserException("Missing CodecPrivate for codec " + codecId);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Missing CodecPrivate for codec " + codecId, /* cause= */ null);
|
||||||
}
|
}
|
||||||
return codecPrivate;
|
return codecPrivate;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,8 @@ public final class Mp3Extractor implements Extractor {
|
|||||||
// The header doesn't match the candidate header or is invalid. Try the next byte offset.
|
// The header doesn't match the candidate header or is invalid. Try the next byte offset.
|
||||||
if (searchedBytes++ == searchLimitBytes) {
|
if (searchedBytes++ == searchLimitBytes) {
|
||||||
if (!sniffing) {
|
if (!sniffing) {
|
||||||
throw new ParserException("Searched too many bytes.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Searched too many bytes.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (atomSize < atomHeaderBytesRead) {
|
if (atomSize < atomHeaderBytesRead) {
|
||||||
throw new ParserException("Atom size less than header length (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Atom size less than header length (unsupported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
long atomPosition = input.getPosition() - atomHeaderBytesRead;
|
long atomPosition = input.getPosition() - atomHeaderBytesRead;
|
||||||
@ -420,10 +421,12 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
}
|
}
|
||||||
} else if (shouldParseLeafAtom(atomType)) {
|
} else if (shouldParseLeafAtom(atomType)) {
|
||||||
if (atomHeaderBytesRead != Atom.HEADER_SIZE) {
|
if (atomHeaderBytesRead != Atom.HEADER_SIZE) {
|
||||||
throw new ParserException("Leaf atom defines extended atom size (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Leaf atom defines extended atom size (unsupported).");
|
||||||
}
|
}
|
||||||
if (atomSize > Integer.MAX_VALUE) {
|
if (atomSize > Integer.MAX_VALUE) {
|
||||||
throw new ParserException("Leaf atom with length > 2147483647 (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Leaf atom with length > 2147483647 (unsupported).");
|
||||||
}
|
}
|
||||||
ParsableByteArray atomData = new ParsableByteArray((int) atomSize);
|
ParsableByteArray atomData = new ParsableByteArray((int) atomSize);
|
||||||
System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE);
|
System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE);
|
||||||
@ -431,7 +434,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
parserState = STATE_READING_ATOM_PAYLOAD;
|
parserState = STATE_READING_ATOM_PAYLOAD;
|
||||||
} else {
|
} else {
|
||||||
if (atomSize > Integer.MAX_VALUE) {
|
if (atomSize > Integer.MAX_VALUE) {
|
||||||
throw new ParserException("Skipping atom with length > 2147483647 (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Skipping atom with length > 2147483647 (unsupported).");
|
||||||
}
|
}
|
||||||
atomData = null;
|
atomData = null;
|
||||||
parserState = STATE_READING_ATOM_PAYLOAD;
|
parserState = STATE_READING_ATOM_PAYLOAD;
|
||||||
@ -827,11 +831,12 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
|
|
||||||
int sampleCount = saiz.readUnsignedIntToInt();
|
int sampleCount = saiz.readUnsignedIntToInt();
|
||||||
if (sampleCount > out.sampleCount) {
|
if (sampleCount > out.sampleCount) {
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Saiz sample count "
|
"Saiz sample count "
|
||||||
+ sampleCount
|
+ sampleCount
|
||||||
+ " is greater than fragment sample count"
|
+ " is greater than fragment sample count"
|
||||||
+ out.sampleCount);
|
+ out.sampleCount,
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalSize = 0;
|
int totalSize = 0;
|
||||||
@ -870,7 +875,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
int entryCount = saio.readUnsignedIntToInt();
|
int entryCount = saio.readUnsignedIntToInt();
|
||||||
if (entryCount != 1) {
|
if (entryCount != 1) {
|
||||||
// We only support one trun element currently, so always expect one entry.
|
// We only support one trun element currently, so always expect one entry.
|
||||||
throw new ParserException("Unexpected saio entry count: " + entryCount);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unexpected saio entry count: " + entryCount, /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int version = Atom.parseFullAtomVersion(fullAtom);
|
int version = Atom.parseFullAtomVersion(fullAtom);
|
||||||
@ -1055,7 +1061,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
|
|
||||||
private static int checkNonNegative(int value) throws ParserException {
|
private static int checkNonNegative(int value) throws ParserException {
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
throw new ParserException("Unexpected negative value: " + value);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unexpected negative value: " + value, /* cause= */ null);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -1089,7 +1096,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
|
|
||||||
if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) {
|
if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) {
|
||||||
// TODO: Implement this.
|
// TODO: Implement this.
|
||||||
throw new ParserException("Overriding TrackEncryptionBox parameters is unsupported.");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Overriding TrackEncryptionBox parameters is unsupported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0;
|
boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0;
|
||||||
@ -1099,11 +1107,12 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, out.sampleCount, false);
|
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, out.sampleCount, false);
|
||||||
return;
|
return;
|
||||||
} else if (sampleCount != out.sampleCount) {
|
} else if (sampleCount != out.sampleCount) {
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Senc sample count "
|
"Senc sample count "
|
||||||
+ sampleCount
|
+ sampleCount
|
||||||
+ " is different from fragment sample count"
|
+ " is different from fragment sample count"
|
||||||
+ out.sampleCount);
|
+ out.sampleCount,
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption);
|
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption);
|
||||||
@ -1142,7 +1151,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
sbgp.skipBytes(4); // grouping_type_parameter.
|
sbgp.skipBytes(4); // grouping_type_parameter.
|
||||||
}
|
}
|
||||||
if (sbgp.readInt() != 1) { // entry_count.
|
if (sbgp.readInt() != 1) { // entry_count.
|
||||||
throw new ParserException("Entry count in sbgp != 1 (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Entry count in sbgp != 1 (unsupported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
sgpd.setPosition(Atom.HEADER_SIZE);
|
sgpd.setPosition(Atom.HEADER_SIZE);
|
||||||
@ -1150,13 +1160,15 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
sgpd.skipBytes(4); // grouping_type == seig.
|
sgpd.skipBytes(4); // grouping_type == seig.
|
||||||
if (sgpdVersion == 1) {
|
if (sgpdVersion == 1) {
|
||||||
if (sgpd.readUnsignedInt() == 0) {
|
if (sgpd.readUnsignedInt() == 0) {
|
||||||
throw new ParserException("Variable length description in sgpd found (unsupported)");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Variable length description in sgpd found (unsupported)");
|
||||||
}
|
}
|
||||||
} else if (sgpdVersion >= 2) {
|
} else if (sgpdVersion >= 2) {
|
||||||
sgpd.skipBytes(4); // default_sample_description_index.
|
sgpd.skipBytes(4); // default_sample_description_index.
|
||||||
}
|
}
|
||||||
if (sgpd.readUnsignedInt() != 1) { // entry_count.
|
if (sgpd.readUnsignedInt() != 1) { // entry_count.
|
||||||
throw new ParserException("Entry count in sgpd != 1 (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Entry count in sgpd != 1 (unsupported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
// CencSampleEncryptionInformationGroupEntry
|
// CencSampleEncryptionInformationGroupEntry
|
||||||
@ -1232,7 +1244,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
|
|
||||||
int type = 0x80000000 & firstInt;
|
int type = 0x80000000 & firstInt;
|
||||||
if (type != 0) {
|
if (type != 0) {
|
||||||
throw new ParserException("Unhandled indirect reference");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unhandled indirect reference", /* cause= */ null);
|
||||||
}
|
}
|
||||||
long referenceDuration = atom.readUnsignedInt();
|
long referenceDuration = atom.readUnsignedInt();
|
||||||
|
|
||||||
@ -1272,7 +1285,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
}
|
}
|
||||||
int bytesToSkip = (int) (nextDataOffset - input.getPosition());
|
int bytesToSkip = (int) (nextDataOffset - input.getPosition());
|
||||||
if (bytesToSkip < 0) {
|
if (bytesToSkip < 0) {
|
||||||
throw new ParserException("Offset to encryption data was negative.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Offset to encryption data was negative.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
input.skipFully(bytesToSkip);
|
input.skipFully(bytesToSkip);
|
||||||
nextTrackBundle.fragment.fillEncryptionData(input);
|
nextTrackBundle.fragment.fillEncryptionData(input);
|
||||||
@ -1302,7 +1316,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
// read the header of the next atom.
|
// read the header of the next atom.
|
||||||
int bytesToSkip = (int) (endOfMdatPosition - input.getPosition());
|
int bytesToSkip = (int) (endOfMdatPosition - input.getPosition());
|
||||||
if (bytesToSkip < 0) {
|
if (bytesToSkip < 0) {
|
||||||
throw new ParserException("Offset to end of mdat was negative.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Offset to end of mdat was negative.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
input.skipFully(bytesToSkip);
|
input.skipFully(bytesToSkip);
|
||||||
enterReadingAtomHeaderState();
|
enterReadingAtomHeaderState();
|
||||||
@ -1380,7 +1395,8 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
nalPrefix.setPosition(0);
|
nalPrefix.setPosition(0);
|
||||||
int nalLengthInt = nalPrefix.readInt();
|
int nalLengthInt = nalPrefix.readInt();
|
||||||
if (nalLengthInt < 1) {
|
if (nalLengthInt < 1) {
|
||||||
throw new ParserException("Invalid NAL length");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid NAL length", /* cause= */ null);
|
||||||
}
|
}
|
||||||
sampleCurrentNalBytesRemaining = nalLengthInt - 1;
|
sampleCurrentNalBytesRemaining = nalLengthInt - 1;
|
||||||
// Write a start code for the current NAL unit.
|
// Write a start code for the current NAL unit.
|
||||||
|
@ -360,7 +360,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (atomSize < atomHeaderBytesRead) {
|
if (atomSize < atomHeaderBytesRead) {
|
||||||
throw new ParserException("Atom size less than header length (unsupported).");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Atom size less than header length (unsupported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldParseContainerAtom(atomType)) {
|
if (shouldParseContainerAtom(atomType)) {
|
||||||
@ -598,7 +599,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
|||||||
nalLength.setPosition(0);
|
nalLength.setPosition(0);
|
||||||
int nalLengthInt = nalLength.readInt();
|
int nalLengthInt = nalLength.readInt();
|
||||||
if (nalLengthInt < 0) {
|
if (nalLengthInt < 0) {
|
||||||
throw new ParserException("Invalid NAL length");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Invalid NAL length", /* cause= */ null);
|
||||||
}
|
}
|
||||||
sampleCurrentNalBytesRemaining = nalLengthInt;
|
sampleCurrentNalBytesRemaining = nalLengthInt;
|
||||||
// Write a start code for the current NAL unit.
|
// Write a start code for the current NAL unit.
|
||||||
|
@ -260,7 +260,7 @@ import java.util.List;
|
|||||||
case "Super_SlowMotion_Deflickering_On":
|
case "Super_SlowMotion_Deflickering_On":
|
||||||
return TYPE_SUPER_SLOW_DEFLICKERING_ON;
|
return TYPE_SUPER_SLOW_DEFLICKERING_ON;
|
||||||
default:
|
default:
|
||||||
throw new ParserException("Invalid SEF name");
|
throw ParserException.createForMalformedContainer("Invalid SEF name", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,8 @@ public class OggExtractor implements Extractor {
|
|||||||
checkStateNotNull(output); // Check that init has been called.
|
checkStateNotNull(output); // Check that init has been called.
|
||||||
if (streamReader == null) {
|
if (streamReader == null) {
|
||||||
if (!sniffInternal(input)) {
|
if (!sniffInternal(input)) {
|
||||||
throw new ParserException("Failed to determine bitstream type");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Failed to determine bitstream type", /* cause= */ null);
|
||||||
}
|
}
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,8 @@ import java.io.IOException;
|
|||||||
if (quiet) {
|
if (quiet) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("unsupported bit stream revision");
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"unsupported bit stream revision");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type = scratch.readUnsignedByte();
|
type = scratch.readUnsignedByte();
|
||||||
|
@ -144,7 +144,8 @@ public final class RawCcExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
timestampUs = dataScratch.readLong();
|
timestampUs = dataScratch.readLong();
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("Unsupported version number: " + version);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unsupported version number: " + version, /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingSampleCount = dataScratch.readUnsignedByte();
|
remainingSampleCount = dataScratch.readUnsignedByte();
|
||||||
|
@ -287,7 +287,8 @@ public final class AdtsExtractor implements Extractor {
|
|||||||
// Either the stream is malformed OR we're not parsing an ADTS stream.
|
// Either the stream is malformed OR we're not parsing an ADTS stream.
|
||||||
if (currentFrameSize <= 6) {
|
if (currentFrameSize <= 6) {
|
||||||
hasCalculatedAverageFrameSize = true;
|
hasCalculatedAverageFrameSize = true;
|
||||||
throw new ParserException("Malformed ADTS stream");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Malformed ADTS stream", /* cause= */ null);
|
||||||
}
|
}
|
||||||
totalValidFramesSize += currentFrameSize;
|
totalValidFramesSize += currentFrameSize;
|
||||||
if (++numValidFrames == NUM_FRAMES_FOR_AVERAGE_FRAME_SIZE) {
|
if (++numValidFrames == NUM_FRAMES_FOR_AVERAGE_FRAME_SIZE) {
|
||||||
|
@ -443,7 +443,8 @@ public final class TsExtractor implements Extractor {
|
|||||||
if (endOfPacket > limit) {
|
if (endOfPacket > limit) {
|
||||||
bytesSinceLastSync += syncBytePosition - searchStart;
|
bytesSinceLastSync += syncBytePosition - searchStart;
|
||||||
if (mode == MODE_HLS && bytesSinceLastSync > TS_PACKET_SIZE * 2) {
|
if (mode == MODE_HLS && bytesSinceLastSync > TS_PACKET_SIZE * 2) {
|
||||||
throw new ParserException("Cannot find sync byte. Most likely not a Transport Stream.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Cannot find sync byte. Most likely not a Transport Stream.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We have found a packet within the buffer.
|
// We have found a packet within the buffer.
|
||||||
|
@ -92,7 +92,8 @@ public final class WavExtractor implements Extractor {
|
|||||||
WavHeader header = WavHeaderReader.peek(input);
|
WavHeader header = WavHeaderReader.peek(input);
|
||||||
if (header == null) {
|
if (header == null) {
|
||||||
// Should only happen if the media wasn't sniffed.
|
// Should only happen if the media wasn't sniffed.
|
||||||
throw new ParserException("Unsupported or unrecognized wav header.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unsupported or unrecognized wav header.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
||||||
@ -117,7 +118,8 @@ public final class WavExtractor implements Extractor {
|
|||||||
@C.PcmEncoding
|
@C.PcmEncoding
|
||||||
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
||||||
if (pcmEncoding == C.ENCODING_INVALID) {
|
if (pcmEncoding == C.ENCODING_INVALID) {
|
||||||
throw new ParserException("Unsupported WAV format type: " + header.formatType);
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Unsupported WAV format type: " + header.formatType);
|
||||||
}
|
}
|
||||||
outputWriter =
|
outputWriter =
|
||||||
new PassthroughOutputWriter(
|
new PassthroughOutputWriter(
|
||||||
@ -217,8 +219,9 @@ public final class WavExtractor implements Extractor {
|
|||||||
int bytesPerFrame = header.numChannels * header.bitsPerSample / 8;
|
int bytesPerFrame = header.numChannels * header.bitsPerSample / 8;
|
||||||
// Validate the header. Blocks are expected to correspond to single frames.
|
// Validate the header. Blocks are expected to correspond to single frames.
|
||||||
if (header.blockSize != bytesPerFrame) {
|
if (header.blockSize != bytesPerFrame) {
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Expected block size: " + bytesPerFrame + "; got: " + header.blockSize);
|
"Expected block size: " + bytesPerFrame + "; got: " + header.blockSize,
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int constantBitrate = header.frameRateHz * bytesPerFrame * 8;
|
int constantBitrate = header.frameRateHz * bytesPerFrame * 8;
|
||||||
@ -351,8 +354,9 @@ public final class WavExtractor implements Extractor {
|
|||||||
int expectedFramesPerBlock =
|
int expectedFramesPerBlock =
|
||||||
(((header.blockSize - (4 * numChannels)) * 8) / (header.bitsPerSample * numChannels)) + 1;
|
(((header.blockSize - (4 * numChannels)) * 8) / (header.bitsPerSample * numChannels)) + 1;
|
||||||
if (framesPerBlock != expectedFramesPerBlock) {
|
if (framesPerBlock != expectedFramesPerBlock) {
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Expected frames per block: " + expectedFramesPerBlock + "; got: " + framesPerBlock);
|
"Expected frames per block: " + expectedFramesPerBlock + "; got: " + framesPerBlock,
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the number of blocks we'll need to decode to obtain an output sample of the
|
// Calculate the number of blocks we'll need to decode to obtain an output sample of the
|
||||||
|
@ -127,7 +127,8 @@ import java.io.IOException;
|
|||||||
bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
|
bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
|
||||||
}
|
}
|
||||||
if (bytesToSkip > Integer.MAX_VALUE) {
|
if (bytesToSkip > Integer.MAX_VALUE) {
|
||||||
throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
|
||||||
}
|
}
|
||||||
input.skipFully((int) bytesToSkip);
|
input.skipFully((int) bytesToSkip);
|
||||||
chunkHeader = ChunkHeader.peek(input, scratch);
|
chunkHeader = ChunkHeader.peek(input, scratch);
|
||||||
|
@ -278,7 +278,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
public void maybeThrowPrepareError() throws IOException {
|
public void maybeThrowPrepareError() throws IOException {
|
||||||
maybeThrowError();
|
maybeThrowError();
|
||||||
if (loadingFinished && !prepared) {
|
if (loadingFinished && !prepared) {
|
||||||
throw new ParserException("Loading finished before preparation is complete.");
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Loading finished before preparation is complete.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +153,13 @@ public final class WebvttExtractor implements Extractor {
|
|||||||
if (line.startsWith("X-TIMESTAMP-MAP")) {
|
if (line.startsWith("X-TIMESTAMP-MAP")) {
|
||||||
Matcher localTimestampMatcher = LOCAL_TIMESTAMP.matcher(line);
|
Matcher localTimestampMatcher = LOCAL_TIMESTAMP.matcher(line);
|
||||||
if (!localTimestampMatcher.find()) {
|
if (!localTimestampMatcher.find()) {
|
||||||
throw new ParserException("X-TIMESTAMP-MAP doesn't contain local timestamp: " + line);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"X-TIMESTAMP-MAP doesn't contain local timestamp: " + line, /* cause= */ null);
|
||||||
}
|
}
|
||||||
Matcher mediaTimestampMatcher = MEDIA_TIMESTAMP.matcher(line);
|
Matcher mediaTimestampMatcher = MEDIA_TIMESTAMP.matcher(line);
|
||||||
if (!mediaTimestampMatcher.find()) {
|
if (!mediaTimestampMatcher.find()) {
|
||||||
throw new ParserException("X-TIMESTAMP-MAP doesn't contain media timestamp: " + line);
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"X-TIMESTAMP-MAP doesn't contain media timestamp: " + line, /* cause= */ null);
|
||||||
}
|
}
|
||||||
vttTimestampUs =
|
vttTimestampUs =
|
||||||
WebvttParserUtil.parseTimestampUs(
|
WebvttParserUtil.parseTimestampUs(
|
||||||
|
@ -567,7 +567,9 @@ public final class DefaultHlsPlaylistTracker
|
|||||||
processLoadedPlaylist((HlsMediaPlaylist) result, loadEventInfo);
|
processLoadedPlaylist((HlsMediaPlaylist) result, loadEventInfo);
|
||||||
eventDispatcher.loadCompleted(loadEventInfo, C.DATA_TYPE_MANIFEST);
|
eventDispatcher.loadCompleted(loadEventInfo, C.DATA_TYPE_MANIFEST);
|
||||||
} else {
|
} else {
|
||||||
playlistError = new ParserException("Loaded playlist has unexpected type.");
|
playlistError =
|
||||||
|
ParserException.createForMalformedManifest(
|
||||||
|
"Loaded playlist has unexpected type.", /* cause= */ null);
|
||||||
eventDispatcher.loadError(
|
eventDispatcher.loadError(
|
||||||
loadEventInfo, C.DATA_TYPE_MANIFEST, playlistError, /* wasCanceled= */ true);
|
loadEventInfo, C.DATA_TYPE_MANIFEST, playlistError, /* wasCanceled= */ true);
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
} finally {
|
} finally {
|
||||||
Util.closeQuietly(reader);
|
Util.closeQuietly(reader);
|
||||||
}
|
}
|
||||||
throw new ParserException("Failed to parse the playlist, could not identify any tags.");
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Failed to parse the playlist, could not identify any tags.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkPlaylistHeader(BufferedReader reader) throws IOException {
|
private static boolean checkPlaylistHeader(BufferedReader reader) throws IOException {
|
||||||
@ -404,7 +405,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
uri =
|
uri =
|
||||||
UriUtil.resolveToUri(baseUri, parseStringAttr(line, REGEX_URI, variableDefinitions));
|
UriUtil.resolveToUri(baseUri, parseStringAttr(line, REGEX_URI, variableDefinitions));
|
||||||
} else if (!iterator.hasNext()) {
|
} else if (!iterator.hasNext()) {
|
||||||
throw new ParserException("#EXT-X-STREAM-INF must be followed by another line");
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"#EXT-X-STREAM-INF must be followed by another line", /* cause= */ null);
|
||||||
} else {
|
} else {
|
||||||
// The following line contains #EXT-X-STREAM-INF's URI.
|
// The following line contains #EXT-X-STREAM-INF's URI.
|
||||||
line = replaceVariableReferences(iterator.next(), variableDefinitions);
|
line = replaceVariableReferences(iterator.next(), variableDefinitions);
|
||||||
@ -720,9 +722,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
}
|
}
|
||||||
if (fullSegmentEncryptionKeyUri != null && fullSegmentEncryptionIV == null) {
|
if (fullSegmentEncryptionKeyUri != null && fullSegmentEncryptionIV == null) {
|
||||||
// See RFC 8216, Section 4.3.2.5.
|
// See RFC 8216, Section 4.3.2.5.
|
||||||
throw new ParserException(
|
throw ParserException.createForMalformedManifest(
|
||||||
"The encryption IV attribute must be present when an initialization segment is "
|
"The encryption IV attribute must be present when an initialization segment is"
|
||||||
+ "encrypted with METHOD=AES-128.");
|
+ " encrypted with METHOD=AES-128.",
|
||||||
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
initializationSegment =
|
initializationSegment =
|
||||||
new Segment(
|
new Segment(
|
||||||
@ -1199,7 +1202,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
if (value != null) {
|
if (value != null) {
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("Couldn't match " + pattern.pattern() + " in " + line);
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Couldn't match " + pattern.pattern() + " in " + line, /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,11 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
|||||||
public static class MissingFieldException extends ParserException {
|
public static class MissingFieldException extends ParserException {
|
||||||
|
|
||||||
public MissingFieldException(String fieldName) {
|
public MissingFieldException(String fieldName) {
|
||||||
super("Missing required field: " + fieldName);
|
super(
|
||||||
|
"Missing required field: " + fieldName,
|
||||||
|
/* cause= */ null,
|
||||||
|
/* contentIsMalformed= */ true,
|
||||||
|
C.DATA_TYPE_MANIFEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +566,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
|||||||
startTime = startTimes.get(chunkIndex - 1) + lastChunkDuration;
|
startTime = startTimes.get(chunkIndex - 1) + lastChunkDuration;
|
||||||
} else {
|
} else {
|
||||||
// We don't have the start time, and we're unable to infer it.
|
// We don't have the start time, and we're unable to infer it.
|
||||||
throw new ParserException("Unable to infer start time");
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Unable to infer start time", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chunkIndex++;
|
chunkIndex++;
|
||||||
@ -571,7 +576,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
|||||||
// Handle repeated chunks.
|
// Handle repeated chunks.
|
||||||
long repeatCount = parseLong(parser, KEY_FRAGMENT_REPEAT_COUNT, 1L);
|
long repeatCount = parseLong(parser, KEY_FRAGMENT_REPEAT_COUNT, 1L);
|
||||||
if (repeatCount > 1 && lastChunkDuration == C.TIME_UNSET) {
|
if (repeatCount > 1 && lastChunkDuration == C.TIME_UNSET) {
|
||||||
throw new ParserException("Repeated chunk with unspecified duration");
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Repeated chunk with unspecified duration", /* cause= */ null);
|
||||||
}
|
}
|
||||||
for (int i = 1; i < repeatCount; i++) {
|
for (int i = 1; i < repeatCount; i++) {
|
||||||
chunkIndex++;
|
chunkIndex++;
|
||||||
@ -613,7 +619,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
|||||||
} else if (KEY_TYPE_TEXT.equalsIgnoreCase(value)) {
|
} else if (KEY_TYPE_TEXT.equalsIgnoreCase(value)) {
|
||||||
return C.TRACK_TYPE_TEXT;
|
return C.TRACK_TYPE_TEXT;
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException("Invalid key value[" + value + "]");
|
throw ParserException.createForMalformedManifest(
|
||||||
|
"Invalid key value[" + value + "]", /* cause= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new MissingFieldException(KEY_TYPE);
|
throw new MissingFieldException(KEY_TYPE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user