[Patch V4] Support signalling of last segment number via supplemental descriptor in mpd.

This commit is contained in:
sr1990 2019-06-26 20:29:37 -07:00 committed by sanil
parent 5f6a7fc7f1
commit ec6604b4f7
2 changed files with 32 additions and 74 deletions

View File

@ -242,7 +242,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,null,null); segmentBase = parseSegmentTemplate(xpp, null,null);
} else { } else {
maybeSkipTag(xpp); maybeSkipTag(xpp);
} }
@ -323,8 +323,8 @@ public class DashManifestParser extends DefaultHandler
language, language,
roleDescriptors, roleDescriptors,
accessibilityDescriptors, accessibilityDescriptors,
segmentBase, supplementalProperties,
supplementalProperties); segmentBase);
contentType = checkContentTypeConsistency(contentType, contentType = checkContentTypeConsistency(contentType,
getContentType(representationInfo.format)); getContentType(representationInfo.format));
representationInfos.add(representationInfo); representationInfos.add(representationInfo);
@ -334,7 +334,7 @@ public class DashManifestParser extends DefaultHandler
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,null); 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)) {
@ -487,8 +487,8 @@ public class DashManifestParser extends DefaultHandler
String adaptationSetLanguage, String adaptationSetLanguage,
List<Descriptor> adaptationSetRoleDescriptors, List<Descriptor> adaptationSetRoleDescriptors,
List<Descriptor> adaptationSetAccessibilityDescriptors, List<Descriptor> adaptationSetAccessibilityDescriptors,
SegmentBase segmentBase, List<Descriptor> adaptationSetSupplementalProperties,
ArrayList<Descriptor> adaptationSetSupplementalProperties) SegmentBase segmentBase)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id"); String id = xpp.getAttributeValue(null, "id");
int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE); int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
@ -521,7 +521,7 @@ public class DashManifestParser extends DefaultHandler
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,supplementalProperties); 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) {
@ -761,8 +761,7 @@ public class DashManifestParser extends DefaultHandler
} }
protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, SegmentTemplate parent, protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, SegmentTemplate parent,
ArrayList<Descriptor> adaptationSetSupplementalProperties, List<Descriptor> adaptationSetSupplementalProperties)
ArrayList<Descriptor> representationSupplementalProperties)
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",
@ -793,20 +792,27 @@ public class DashManifestParser extends DefaultHandler
timeline = timeline != null ? timeline : parent.segmentTimeline; timeline = timeline != null ? timeline : parent.segmentTimeline;
} }
long endNumber = C.INDEX_UNSET;
if (adaptationSetSupplementalProperties != null) {
endNumber = parseLastSegmentNumberSupplementalProperty
(adaptationSetSupplementalProperties);
}
return buildSegmentTemplate(initialization, timescale, presentationTimeOffset, return buildSegmentTemplate(initialization, timescale, presentationTimeOffset,
startNumber, duration, timeline, initializationTemplate, mediaTemplate, startNumber, duration, timeline, initializationTemplate, mediaTemplate,
adaptationSetSupplementalProperties,representationSupplementalProperties); endNumber);
} }
protected String parseLastSegmentNumberSupplementalProperty protected long parseLastSegmentNumberSupplementalProperty
(List<Descriptor> supplementalProperties){ (List<Descriptor> supplementalProperties){
for (Descriptor descriptor : supplementalProperties) { for (Descriptor descriptor : supplementalProperties) {
if (descriptor.schemeIdUri.equalsIgnoreCase if ("http://dashif.org/guidelines/last-segment-number"
("http://dashif.org/guidelines/last-segment-number")) { .equalsIgnoreCase(descriptor.schemeIdUri)) {
return descriptor.value; return Long.parseLong(descriptor.value);
} }
} }
return null; return C.INDEX_UNSET;
} }
protected SegmentTemplate buildSegmentTemplate( protected SegmentTemplate buildSegmentTemplate(
@ -817,29 +823,11 @@ public class DashManifestParser extends DefaultHandler
long duration, long duration,
List<SegmentTimelineElement> timeline, List<SegmentTimelineElement> timeline,
UrlTemplate initializationTemplate, UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate,ArrayList<Descriptor> adaptationSetSupplementalProperties, UrlTemplate mediaTemplate,long endNumber ) {
ArrayList<Descriptor> representationSupplementalProperties ) {
if (representationSupplementalProperties != null) { if (endNumber!=C.INDEX_UNSET) {
if (parseLastSegmentNumberSupplementalProperty return new SegmentTemplate(initialization, timescale, presentationTimeOffset,
(representationSupplementalProperties) != null) { startNumber, endNumber,duration, timeline, initializationTemplate, mediaTemplate);
String lastSegment = parseLastSegmentNumberSupplementalProperty
(representationSupplementalProperties);
return new SegmentTemplate(initialization, timescale, presentationTimeOffset,
startNumber, Integer.valueOf(lastSegment),duration, timeline,
initializationTemplate, mediaTemplate);
}
}
if (adaptationSetSupplementalProperties != null) {
if (parseLastSegmentNumberSupplementalProperty(adaptationSetSupplementalProperties) != null)
{
String lastSegment = parseLastSegmentNumberSupplementalProperty
(adaptationSetSupplementalProperties);
return new SegmentTemplate(initialization, timescale, presentationTimeOffset,
startNumber, Integer.valueOf(lastSegment),duration, timeline,
initializationTemplate, mediaTemplate);
}
} }
return new SegmentTemplate(initialization, timescale, presentationTimeOffset, return new SegmentTemplate(initialization, timescale, presentationTimeOffset,

View File

@ -102,7 +102,6 @@ public abstract class SegmentBase {
/* package */ final long startNumber; /* package */ final long startNumber;
/* package */ final long duration; /* package */ final long duration;
/* package */ final List<SegmentTimelineElement> segmentTimeline; /* package */ final List<SegmentTimelineElement> segmentTimeline;
/* package */ final int 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
@ -129,38 +128,6 @@ public abstract class SegmentBase {
this.startNumber = startNumber; this.startNumber = startNumber;
this.duration = duration; this.duration = duration;
this.segmentTimeline = segmentTimeline; this.segmentTimeline = segmentTimeline;
this.endNumber = C.INDEX_UNSET;
}
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
* exists.
* @param timescale The timescale in units per second.
* @param presentationTimeOffset The presentation time offset. The value in seconds is the
* division of this value and {@code timescale}.
* @param startNumber The sequence number of the first segment.
* @param endNumber The sequence number of the last segment specified by SupplementalProperty
* schemeIdUri="http://dashif.org/guidelines/last-segment-number"
* @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
* segmentTimeline} is non-null then this parameter is ignored.
* @param segmentTimeline A segment timeline corresponding to the segments. If null, then
* segments are assumed to be of fixed duration as specified by the {@code duration}
* parameter.
*/
public MultiSegmentBase(
RangedUri initialization,
long timescale,
long presentationTimeOffset,
long startNumber,
int endNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline) {
super(initialization, timescale, presentationTimeOffset);
this.startNumber = startNumber;
this.duration = duration;
this.segmentTimeline = segmentTimeline;
this.endNumber = endNumber;
} }
/** @see DashSegmentIndex#getSegmentNum(long, long) */ /** @see DashSegmentIndex#getSegmentNum(long, long) */
@ -310,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
@ -343,6 +311,7 @@ public abstract class SegmentBase {
duration, segmentTimeline); duration, segmentTimeline);
this.initializationTemplate = initializationTemplate; this.initializationTemplate = initializationTemplate;
this.mediaTemplate = mediaTemplate; this.mediaTemplate = mediaTemplate;
this.endNumber = C.INDEX_UNSET;
} }
/** /**
@ -371,15 +340,16 @@ public abstract class SegmentBase {
long timescale, long timescale,
long presentationTimeOffset, long presentationTimeOffset,
long startNumber, long startNumber,
int endNumber, 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,endNumber, super(initialization, timescale, presentationTimeOffset, startNumber, duration,
duration, segmentTimeline); segmentTimeline);
this.initializationTemplate = initializationTemplate; this.initializationTemplate = initializationTemplate;
this.mediaTemplate = mediaTemplate; this.mediaTemplate = mediaTemplate;
this.endNumber = endNumber;
} }
@Override @Override
@ -411,7 +381,7 @@ public abstract class SegmentBase {
if (segmentTimeline != null) { if (segmentTimeline != null) {
return segmentTimeline.size(); return segmentTimeline.size();
} else if (endNumber != C.INDEX_UNSET) { } else if (endNumber != C.INDEX_UNSET) {
return endNumber - (int) startNumber + 1; 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);