Merge pull request #5908 from sr1990:dev-v2

PiperOrigin-RevId: 256147805
This commit is contained in:
Oliver Woodman 2019-07-02 17:49:45 +01:00
commit 16bf7f9106
2 changed files with 64 additions and 11 deletions

View File

@ -42,6 +42,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -242,7 +243,7 @@ public class DashManifestParser extends DefaultHandler
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
segmentBase = parseSegmentList(xpp, null); segmentBase = parseSegmentList(xpp, null);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, null); segmentBase = parseSegmentTemplate(xpp, null, Collections.emptyList());
} else { } else {
maybeSkipTag(xpp); maybeSkipTag(xpp);
} }
@ -323,6 +324,7 @@ public class DashManifestParser extends DefaultHandler
language, language,
roleDescriptors, roleDescriptors,
accessibilityDescriptors, accessibilityDescriptors,
supplementalProperties,
segmentBase); segmentBase);
contentType = checkContentTypeConsistency(contentType, contentType = checkContentTypeConsistency(contentType,
getContentType(representationInfo.format)); getContentType(representationInfo.format));
@ -332,7 +334,8 @@ public class DashManifestParser extends DefaultHandler
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase); segmentBase =
parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase, supplementalProperties);
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) { } else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream")); inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
} else if (XmlPullParserUtil.isStartTag(xpp)) { } else if (XmlPullParserUtil.isStartTag(xpp)) {
@ -485,6 +488,7 @@ public class DashManifestParser extends DefaultHandler
String adaptationSetLanguage, String adaptationSetLanguage,
List<Descriptor> adaptationSetRoleDescriptors, List<Descriptor> adaptationSetRoleDescriptors,
List<Descriptor> adaptationSetAccessibilityDescriptors, List<Descriptor> adaptationSetAccessibilityDescriptors,
List<Descriptor> adaptationSetSupplementalProperties,
SegmentBase segmentBase) SegmentBase segmentBase)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id"); String id = xpp.getAttributeValue(null, "id");
@ -517,7 +521,9 @@ public class DashManifestParser extends DefaultHandler
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase); segmentBase =
parseSegmentTemplate(
xpp, (SegmentTemplate) segmentBase, adaptationSetSupplementalProperties);
} else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) {
Pair<String, SchemeData> contentProtection = parseContentProtection(xpp); Pair<String, SchemeData> contentProtection = parseContentProtection(xpp);
if (contentProtection.first != null) { if (contentProtection.first != null) {
@ -756,13 +762,19 @@ public class DashManifestParser extends DefaultHandler
startNumber, duration, timeline, segments); startNumber, duration, timeline, segments);
} }
protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, SegmentTemplate parent) protected SegmentTemplate parseSegmentTemplate(
XmlPullParser xpp,
SegmentTemplate parent,
List<Descriptor> adaptationSetSupplementalProperties)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset",
parent != null ? parent.presentationTimeOffset : 0); parent != null ? parent.presentationTimeOffset : 0);
long duration = parseLong(xpp, "duration", parent != null ? parent.duration : C.TIME_UNSET); long duration = parseLong(xpp, "duration", parent != null ? parent.duration : C.TIME_UNSET);
long startNumber = parseLong(xpp, "startNumber", parent != null ? parent.startNumber : 1); long startNumber = parseLong(xpp, "startNumber", parent != null ? parent.startNumber : 1);
long endNumber =
parseLastSegmentNumberSupplementalProperty(adaptationSetSupplementalProperties);
UrlTemplate mediaTemplate = parseUrlTemplate(xpp, "media", UrlTemplate mediaTemplate = parseUrlTemplate(xpp, "media",
parent != null ? parent.mediaTemplate : null); parent != null ? parent.mediaTemplate : null);
UrlTemplate initializationTemplate = parseUrlTemplate(xpp, "initialization", UrlTemplate initializationTemplate = parseUrlTemplate(xpp, "initialization",
@ -787,8 +799,16 @@ public class DashManifestParser extends DefaultHandler
timeline = timeline != null ? timeline : parent.segmentTimeline; timeline = timeline != null ? timeline : parent.segmentTimeline;
} }
return buildSegmentTemplate(initialization, timescale, presentationTimeOffset, return buildSegmentTemplate(
startNumber, duration, timeline, initializationTemplate, mediaTemplate); initialization,
timescale,
presentationTimeOffset,
startNumber,
endNumber,
duration,
timeline,
initializationTemplate,
mediaTemplate);
} }
protected SegmentTemplate buildSegmentTemplate( protected SegmentTemplate buildSegmentTemplate(
@ -796,12 +816,21 @@ public class DashManifestParser extends DefaultHandler
long timescale, long timescale,
long presentationTimeOffset, long presentationTimeOffset,
long startNumber, long startNumber,
long endNumber,
long duration, long duration,
List<SegmentTimelineElement> timeline, List<SegmentTimelineElement> timeline,
UrlTemplate initializationTemplate, UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate) { UrlTemplate mediaTemplate) {
return new SegmentTemplate(initialization, timescale, presentationTimeOffset, return new SegmentTemplate(
startNumber, duration, timeline, initializationTemplate, mediaTemplate); initialization,
timescale,
presentationTimeOffset,
startNumber,
endNumber,
duration,
timeline,
initializationTemplate,
mediaTemplate);
} }
/** /**
@ -1438,6 +1467,18 @@ public class DashManifestParser extends DefaultHandler
} }
} }
protected static long parseLastSegmentNumberSupplementalProperty(
List<Descriptor> supplementalProperties) {
for (int i = 0; i < supplementalProperties.size(); i++) {
Descriptor descriptor = supplementalProperties.get(i);
if ("http://dashif.org/guidelines/last-segment-number"
.equalsIgnoreCase(descriptor.schemeIdUri)) {
return Long.parseLong(descriptor.value);
}
}
return C.INDEX_UNSET;
}
/** A parsed Representation element. */ /** A parsed Representation element. */
protected static final class RepresentationInfo { protected static final class RepresentationInfo {

View File

@ -277,6 +277,7 @@ public abstract class SegmentBase {
/* package */ final UrlTemplate initializationTemplate; /* package */ final UrlTemplate initializationTemplate;
/* package */ final UrlTemplate mediaTemplate; /* package */ final UrlTemplate mediaTemplate;
/* package */ final long endNumber;
/** /**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data * @param initialization A {@link RangedUri} corresponding to initialization data, if such data
@ -286,6 +287,9 @@ public abstract class SegmentBase {
* @param presentationTimeOffset The presentation time offset. The value in seconds is the * @param presentationTimeOffset The presentation time offset. The value in seconds is the
* division of this value and {@code timescale}. * division of this value and {@code timescale}.
* @param startNumber The sequence number of the first segment. * @param startNumber The sequence number of the first segment.
* @param endNumber The sequence number of the last segment as specified by the
* SupplementalProperty with schemeIdUri="http://dashif.org/guidelines/last-segment-number",
* or {@link C#INDEX_UNSET}.
* @param duration The duration of each segment in the case of fixed duration segments. The * @param duration The duration of each segment in the case of fixed duration segments. The
* value in seconds is the division of this value and {@code timescale}. If {@code * value in seconds is the division of this value and {@code timescale}. If {@code
* segmentTimeline} is non-null then this parameter is ignored. * segmentTimeline} is non-null then this parameter is ignored.
@ -302,14 +306,21 @@ public abstract class SegmentBase {
long timescale, long timescale,
long presentationTimeOffset, long presentationTimeOffset,
long startNumber, long startNumber,
long endNumber,
long duration, long duration,
List<SegmentTimelineElement> segmentTimeline, List<SegmentTimelineElement> segmentTimeline,
UrlTemplate initializationTemplate, UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate) { UrlTemplate mediaTemplate) {
super(initialization, timescale, presentationTimeOffset, startNumber, super(
duration, segmentTimeline); initialization,
timescale,
presentationTimeOffset,
startNumber,
duration,
segmentTimeline);
this.initializationTemplate = initializationTemplate; this.initializationTemplate = initializationTemplate;
this.mediaTemplate = mediaTemplate; this.mediaTemplate = mediaTemplate;
this.endNumber = endNumber;
} }
@Override @Override
@ -340,6 +351,8 @@ public abstract class SegmentBase {
public int getSegmentCount(long periodDurationUs) { public int getSegmentCount(long periodDurationUs) {
if (segmentTimeline != null) { if (segmentTimeline != null) {
return segmentTimeline.size(); return segmentTimeline.size();
} else if (endNumber != C.INDEX_UNSET) {
return (int) (endNumber - startNumber + 1);
} else if (periodDurationUs != C.TIME_UNSET) { } else if (periodDurationUs != C.TIME_UNSET) {
long durationUs = (duration * C.MICROS_PER_SECOND) / timescale; long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
return (int) Util.ceilDivide(periodDurationUs, durationUs); return (int) Util.ceilDivide(periodDurationUs, durationUs);
@ -347,7 +360,6 @@ public abstract class SegmentBase {
return DashSegmentIndex.INDEX_UNBOUNDED; return DashSegmentIndex.INDEX_UNBOUNDED;
} }
} }
} }
/** /**