use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.
the class Util method parseXsDateTime.
/**
* Parses an xs:dateTime attribute value, returning the parsed timestamp in milliseconds since
* the epoch.
*
* @param value The attribute value to decode.
* @return The parsed timestamp in milliseconds since the epoch.
* @throws ParserException if an error occurs parsing the dateTime attribute value.
*/
public static long parseXsDateTime(String value) throws ParserException {
Matcher matcher = XS_DATE_TIME_PATTERN.matcher(value);
if (!matcher.matches()) {
throw new ParserException("Invalid date/time format: " + value);
}
int timezoneShift;
if (matcher.group(9) == null) {
// No time zone specified.
timezoneShift = 0;
} else if (matcher.group(9).equalsIgnoreCase("Z")) {
timezoneShift = 0;
} else {
timezoneShift = ((Integer.parseInt(matcher.group(12)) * 60 + Integer.parseInt(matcher.group(13))));
if (matcher.group(11).equals("-")) {
timezoneShift *= -1;
}
}
Calendar dateTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
dateTime.clear();
// Note: The month value is 0-based, hence the -1 on group(2)
dateTime.set(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)) - 1, Integer.parseInt(matcher.group(3)), Integer.parseInt(matcher.group(4)), Integer.parseInt(matcher.group(5)), Integer.parseInt(matcher.group(6)));
if (!TextUtils.isEmpty(matcher.group(8))) {
final BigDecimal bd = new BigDecimal("0." + matcher.group(8));
// we care only for milliseconds, so movePointRight(3)
dateTime.set(Calendar.MILLISECOND, bd.movePointRight(3).intValue());
}
long time = dateTime.getTimeInMillis();
if (timezoneShift != 0) {
time -= timezoneShift * 60000;
}
return time;
}
use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.
the class AvcConfig method parse.
/**
* Parses AVC configuration data.
*
* @param data A {@link ParsableByteArray}, whose position is set to the start of the AVC
* configuration data to parse.
* @return A parsed representation of the HEVC configuration data.
* @throws ParserException If an error occurred parsing the data.
*/
public static AvcConfig parse(ParsableByteArray data) throws ParserException {
try {
// Skip to the AVCDecoderConfigurationRecord (defined in 14496-15)
data.skipBytes(4);
int nalUnitLengthFieldLength = (data.readUnsignedByte() & 0x3) + 1;
if (nalUnitLengthFieldLength == 3) {
throw new IllegalStateException();
}
List<byte[]> initializationData = new ArrayList<>();
int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
for (int j = 0; j < numSequenceParameterSets; j++) {
initializationData.add(buildNalUnitForChild(data));
}
int numPictureParameterSets = data.readUnsignedByte();
for (int j = 0; j < numPictureParameterSets; j++) {
initializationData.add(buildNalUnitForChild(data));
}
int width = Format.NO_VALUE;
int height = Format.NO_VALUE;
float pixelWidthAspectRatio = 1;
if (numSequenceParameterSets > 0) {
byte[] sps = initializationData.get(0);
SpsData spsData = NalUnitUtil.parseSpsNalUnit(initializationData.get(0), nalUnitLengthFieldLength, sps.length);
width = spsData.width;
height = spsData.height;
pixelWidthAspectRatio = spsData.pixelWidthAspectRatio;
}
return new AvcConfig(initializationData, nalUnitLengthFieldLength, width, height, pixelWidthAspectRatio);
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParserException("Error parsing AVC config", e);
}
}
use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.
the class HevcConfig method parse.
/**
* Parses HEVC configuration data.
*
* @param data A {@link ParsableByteArray}, whose position is set to the start of the HEVC
* configuration data to parse.
* @return A parsed representation of the HEVC configuration data.
* @throws ParserException If an error occurred parsing the data.
*/
public static HevcConfig parse(ParsableByteArray data) throws ParserException {
try {
// Skip to the NAL unit length size field.
data.skipBytes(21);
int lengthSizeMinusOne = data.readUnsignedByte() & 0x03;
// Calculate the combined size of all VPS/SPS/PPS bitstreams.
int numberOfArrays = data.readUnsignedByte();
int csdLength = 0;
int csdStartPosition = data.getPosition();
for (int i = 0; i < numberOfArrays; i++) {
// completeness (1), nal_unit_type (7)
data.skipBytes(1);
int numberOfNalUnits = data.readUnsignedShort();
for (int j = 0; j < numberOfNalUnits; j++) {
int nalUnitLength = data.readUnsignedShort();
// Start code and NAL unit.
csdLength += 4 + nalUnitLength;
data.skipBytes(nalUnitLength);
}
}
// Concatenate the codec-specific data into a single buffer.
data.setPosition(csdStartPosition);
byte[] buffer = new byte[csdLength];
int bufferPosition = 0;
for (int i = 0; i < numberOfArrays; i++) {
// completeness (1), nal_unit_type (7)
data.skipBytes(1);
int numberOfNalUnits = data.readUnsignedShort();
for (int j = 0; j < numberOfNalUnits; j++) {
int nalUnitLength = data.readUnsignedShort();
System.arraycopy(NalUnitUtil.NAL_START_CODE, 0, buffer, bufferPosition, NalUnitUtil.NAL_START_CODE.length);
bufferPosition += NalUnitUtil.NAL_START_CODE.length;
System.arraycopy(data.data, data.getPosition(), buffer, bufferPosition, nalUnitLength);
bufferPosition += nalUnitLength;
data.skipBytes(nalUnitLength);
}
}
List<byte[]> initializationData = csdLength == 0 ? null : Collections.singletonList(buffer);
return new HevcConfig(initializationData, lengthSizeMinusOne + 1);
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParserException("Error parsing HEVC config", e);
}
}
use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.
the class DashManifestParser method parseMediaPresentationDescription.
protected DashManifest parseMediaPresentationDescription(XmlPullParser xpp, String baseUrl) throws XmlPullParserException, IOException {
long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", C.TIME_UNSET);
long durationMs = parseDuration(xpp, "mediaPresentationDuration", C.TIME_UNSET);
long minBufferTimeMs = parseDuration(xpp, "minBufferTime", C.TIME_UNSET);
String typeString = xpp.getAttributeValue(null, "type");
boolean dynamic = typeString != null && typeString.equals("dynamic");
long minUpdateTimeMs = dynamic ? parseDuration(xpp, "minimumUpdatePeriod", C.TIME_UNSET) : C.TIME_UNSET;
long timeShiftBufferDepthMs = dynamic ? parseDuration(xpp, "timeShiftBufferDepth", C.TIME_UNSET) : C.TIME_UNSET;
long suggestedPresentationDelayMs = dynamic ? parseDuration(xpp, "suggestedPresentationDelay", C.TIME_UNSET) : C.TIME_UNSET;
UtcTimingElement utcTiming = null;
Uri location = null;
List<Period> periods = new ArrayList<>();
long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0;
boolean seenEarlyAccessPeriod = false;
boolean seenFirstBaseUrl = false;
do {
xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) {
if (!seenFirstBaseUrl) {
baseUrl = parseBaseUrl(xpp, baseUrl);
seenFirstBaseUrl = true;
}
} else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) {
utcTiming = parseUtcTiming(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Location")) {
location = Uri.parse(xpp.nextText());
} else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) {
Pair<Period, Long> periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs);
Period period = periodWithDurationMs.first;
if (period.startMs == C.TIME_UNSET) {
if (dynamic) {
// This is an early access period. Ignore it. All subsequent periods must also be
// early access.
seenEarlyAccessPeriod = true;
} else {
throw new ParserException("Unable to determine start of period " + periods.size());
}
} else {
long periodDurationMs = periodWithDurationMs.second;
nextPeriodStartMs = periodDurationMs == C.TIME_UNSET ? C.TIME_UNSET : (period.startMs + periodDurationMs);
periods.add(period);
}
}
} while (!XmlPullParserUtil.isEndTag(xpp, "MPD"));
if (durationMs == C.TIME_UNSET) {
if (nextPeriodStartMs != C.TIME_UNSET) {
// If we know the end time of the final period, we can use it as the duration.
durationMs = nextPeriodStartMs;
} else if (!dynamic) {
throw new ParserException("Unable to determine duration of static manifest.");
}
}
if (periods.isEmpty()) {
throw new ParserException("No periods found.");
}
return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, utcTiming, location, periods);
}
use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.
the class SsManifestParser method parse.
@Override
public SsManifest parse(Uri uri, InputStream inputStream) throws IOException {
try {
XmlPullParser xmlParser = xmlParserFactory.newPullParser();
xmlParser.setInput(inputStream, null);
SmoothStreamingMediaParser smoothStreamingMediaParser = new SmoothStreamingMediaParser(null, uri.toString());
return (SsManifest) smoothStreamingMediaParser.parse(xmlParser);
} catch (XmlPullParserException e) {
throw new ParserException(e);
}
}
Aggregations