From ec6604b4f716b01d4cd0d99019bf30ce2d029630 Mon Sep 17 00:00:00 2001 From: sr1990 Date: Wed, 26 Jun 2019 20:29:37 -0700 Subject: [PATCH] [Patch V4] Support signalling of last segment number via supplemental descriptor in mpd. --- .../dash/manifest/DashManifestParser.java | 62 ++++++++----------- .../source/dash/manifest/SegmentBase.java | 44 +++---------- 2 files changed, 32 insertions(+), 74 deletions(-) diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index 7e735e4844..912f7d1611 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -242,7 +242,7 @@ public class DashManifestParser extends DefaultHandler } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, null); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { - segmentBase = parseSegmentTemplate(xpp, null,null,null); + segmentBase = parseSegmentTemplate(xpp, null,null); } else { maybeSkipTag(xpp); } @@ -323,8 +323,8 @@ public class DashManifestParser extends DefaultHandler language, roleDescriptors, accessibilityDescriptors, - segmentBase, - supplementalProperties); + supplementalProperties, + segmentBase); contentType = checkContentTypeConsistency(contentType, getContentType(representationInfo.format)); representationInfos.add(representationInfo); @@ -334,7 +334,7 @@ public class DashManifestParser extends DefaultHandler segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase, - supplementalProperties,null); + supplementalProperties); } else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) { inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream")); } else if (XmlPullParserUtil.isStartTag(xpp)) { @@ -487,8 +487,8 @@ public class DashManifestParser extends DefaultHandler String adaptationSetLanguage, List adaptationSetRoleDescriptors, List adaptationSetAccessibilityDescriptors, - SegmentBase segmentBase, - ArrayList adaptationSetSupplementalProperties) + List adaptationSetSupplementalProperties, + SegmentBase segmentBase) throws XmlPullParserException, IOException { String id = xpp.getAttributeValue(null, "id"); int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE); @@ -521,7 +521,7 @@ public class DashManifestParser extends DefaultHandler segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase, - adaptationSetSupplementalProperties,supplementalProperties); + adaptationSetSupplementalProperties); } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { Pair contentProtection = parseContentProtection(xpp); if (contentProtection.first != null) { @@ -761,8 +761,7 @@ public class DashManifestParser extends DefaultHandler } protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, SegmentTemplate parent, - ArrayList adaptationSetSupplementalProperties, - ArrayList representationSupplementalProperties) + List adaptationSetSupplementalProperties) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", @@ -793,20 +792,27 @@ public class DashManifestParser extends DefaultHandler timeline = timeline != null ? timeline : parent.segmentTimeline; } + long endNumber = C.INDEX_UNSET; + + if (adaptationSetSupplementalProperties != null) { + endNumber = parseLastSegmentNumberSupplementalProperty + (adaptationSetSupplementalProperties); + } + return buildSegmentTemplate(initialization, timescale, presentationTimeOffset, startNumber, duration, timeline, initializationTemplate, mediaTemplate, - adaptationSetSupplementalProperties,representationSupplementalProperties); + endNumber); } - protected String parseLastSegmentNumberSupplementalProperty + protected long parseLastSegmentNumberSupplementalProperty (List supplementalProperties){ for (Descriptor descriptor : supplementalProperties) { - if (descriptor.schemeIdUri.equalsIgnoreCase - ("http://dashif.org/guidelines/last-segment-number")) { - return descriptor.value; + if ("http://dashif.org/guidelines/last-segment-number" + .equalsIgnoreCase(descriptor.schemeIdUri)) { + return Long.parseLong(descriptor.value); } } - return null; + return C.INDEX_UNSET; } protected SegmentTemplate buildSegmentTemplate( @@ -817,29 +823,11 @@ public class DashManifestParser extends DefaultHandler long duration, List timeline, UrlTemplate initializationTemplate, - UrlTemplate mediaTemplate,ArrayList adaptationSetSupplementalProperties, - ArrayList representationSupplementalProperties ) { + UrlTemplate mediaTemplate,long endNumber ) { - if (representationSupplementalProperties != null) { - if (parseLastSegmentNumberSupplementalProperty - (representationSupplementalProperties) != null) { - 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); - } + if (endNumber!=C.INDEX_UNSET) { + return new SegmentTemplate(initialization, timescale, presentationTimeOffset, + startNumber, endNumber,duration, timeline, initializationTemplate, mediaTemplate); } return new SegmentTemplate(initialization, timescale, presentationTimeOffset, diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java index 9eae69b345..7db44dd629 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java @@ -102,7 +102,6 @@ public abstract class SegmentBase { /* package */ final long startNumber; /* package */ final long duration; /* package */ final List segmentTimeline; - /* package */ final int endNumber; /** * @param initialization A {@link RangedUri} corresponding to initialization data, if such data @@ -129,38 +128,6 @@ public abstract class SegmentBase { this.startNumber = startNumber; this.duration = duration; 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 segmentTimeline) { - super(initialization, timescale, presentationTimeOffset); - this.startNumber = startNumber; - this.duration = duration; - this.segmentTimeline = segmentTimeline; - this.endNumber = endNumber; } /** @see DashSegmentIndex#getSegmentNum(long, long) */ @@ -310,6 +277,7 @@ public abstract class SegmentBase { /* package */ final UrlTemplate initializationTemplate; /* package */ final UrlTemplate mediaTemplate; + /* package */ final long endNumber; /** * @param initialization A {@link RangedUri} corresponding to initialization data, if such data @@ -343,6 +311,7 @@ public abstract class SegmentBase { duration, segmentTimeline); this.initializationTemplate = initializationTemplate; this.mediaTemplate = mediaTemplate; + this.endNumber = C.INDEX_UNSET; } /** @@ -371,15 +340,16 @@ public abstract class SegmentBase { long timescale, long presentationTimeOffset, long startNumber, - int endNumber, + long endNumber, long duration, List segmentTimeline, UrlTemplate initializationTemplate, UrlTemplate mediaTemplate) { - super(initialization, timescale, presentationTimeOffset, startNumber,endNumber, - duration, segmentTimeline); + super(initialization, timescale, presentationTimeOffset, startNumber, duration, + segmentTimeline); this.initializationTemplate = initializationTemplate; this.mediaTemplate = mediaTemplate; + this.endNumber = endNumber; } @Override @@ -411,7 +381,7 @@ public abstract class SegmentBase { if (segmentTimeline != null) { return segmentTimeline.size(); } else if (endNumber != C.INDEX_UNSET) { - return endNumber - (int) startNumber + 1; + return (int) (endNumber - startNumber + 1); } else if (periodDurationUs != C.TIME_UNSET) { long durationUs = (duration * C.MICROS_PER_SECOND) / timescale; return (int) Util.ceilDivide(periodDurationUs, durationUs);