Skip to content

Commit

Permalink
feat(DASH): Add signalling the last segment number in Period (#6416)
Browse files Browse the repository at this point in the history
  • Loading branch information
avelad committed Apr 9, 2024
1 parent bca6252 commit 07a3241
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
15 changes: 11 additions & 4 deletions lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1153,11 +1153,15 @@ shaka.dash.DashParser = class {
}
}

let lastSegmentNumber = null;

const supplementalProperties =
TXml.findChildren(elem, 'SupplementalProperty');
for (const prop of supplementalProperties) {
const schemeId = prop.attributes['schemeIdUri'];
if (schemeId == transferCharacteristicsScheme) {
if (schemeId == 'http://dashif.org/guidelines/last-segment-number') {
lastSegmentNumber = parseInt(prop.attributes['value'], 10) - 1;
} else if (schemeId == transferCharacteristicsScheme) {
videoRange = getVideoRangeFromTransferCharacteristicCICP(
parseInt(prop.attributes['value'], 10),
);
Expand Down Expand Up @@ -1303,7 +1307,8 @@ shaka.dash.DashParser = class {
const streams = representations.map((representation) => {
const parsedRepresentation = this.parseRepresentation_(context,
contentProtection, kind, language, label, main, roleValues,
closedCaptions, representation, accessibilityPurpose);
closedCaptions, representation, accessibilityPurpose,
lastSegmentNumber);
if (parsedRepresentation) {
parsedRepresentation.hdr = parsedRepresentation.hdr || videoRange;
parsedRepresentation.fastSwitching = isFastSwitching;
Expand Down Expand Up @@ -1388,13 +1393,15 @@ shaka.dash.DashParser = class {
* @param {!shaka.extern.xml.Node} node
* @param {?shaka.media.ManifestParser.AccessibilityPurpose}
* accessibilityPurpose
* @param {?number} lastSegmentNumber
*
* @return {?shaka.extern.Stream} The Stream, or null when there is a
* non-critical parsing error.
* @private
*/
parseRepresentation_(context, contentProtection, kind, language, label,
isPrimary, roles, closedCaptions, node, accessibilityPurpose) {
isPrimary, roles, closedCaptions, node, accessibilityPurpose,
lastSegmentNumber) {
const TXml = shaka.util.TXml;
const ContentType = shaka.util.ManifestParserUtils.ContentType;

Expand Down Expand Up @@ -1483,7 +1490,7 @@ shaka.dash.DashParser = class {
streamInfo = shaka.dash.SegmentTemplate.createStreamInfo(
context, requestSegment, this.streamMap_, hasManifest,
this.config_.dash.initialSegmentLimit, this.periodDurations_,
aesKey);
aesKey, lastSegmentNumber);
} else {
goog.asserts.assert(isText,
'Must have Segment* with non-text streams.');
Expand Down
10 changes: 6 additions & 4 deletions lib/dash/segment_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ shaka.dash.SegmentTemplate = class {
* a SegmentTemplate with fixed duration.
* @param {!Object.<string, number>} periodDurationMap
* @param {shaka.extern.aesKey|undefined} aesKey
* @param {?number} lastSegmentNumber
* @return {shaka.dash.DashParser.StreamInfo}
*/
static createStreamInfo(
context, requestSegment, streamMap, isUpdate, segmentLimit,
periodDurationMap, aesKey) {
periodDurationMap, aesKey, lastSegmentNumber) {
goog.asserts.assert(context.representation.segmentTemplate,
'Should only be called with SegmentTemplate');
const SegmentTemplate = shaka.dash.SegmentTemplate;
Expand Down Expand Up @@ -85,7 +86,7 @@ shaka.dash.SegmentTemplate = class {
generateSegmentIndex: () => {
return SegmentTemplate.generateSegmentIndexFromDuration_(
shallowCopyOfContext, info, segmentLimit, initSegmentReference,
periodDurationMap, aesKey);
periodDurationMap, aesKey, lastSegmentNumber);
},
};
} else {
Expand Down Expand Up @@ -307,12 +308,13 @@ shaka.dash.SegmentTemplate = class {
* @param {shaka.media.InitSegmentReference} initSegmentReference
* @param {!Object.<string, number>} periodDurationMap
* @param {shaka.extern.aesKey|undefined} aesKey
* @param {?number} lastSegmentNumber
* @return {!Promise.<shaka.media.SegmentIndex>}
* @private
*/
static generateSegmentIndexFromDuration_(
context, info, segmentLimit, initSegmentReference, periodDurationMap,
aesKey) {
aesKey, lastSegmentNumber) {
goog.asserts.assert(info.mediaTemplate,
'There should be a media template with duration');

Expand Down Expand Up @@ -408,7 +410,7 @@ shaka.dash.SegmentTemplate = class {
const minPosition = context.dynamic ?
Math.max(range[0], range[1] - segmentLimit + 1) :
range[0];
const maxPosition = range[1];
const maxPosition = lastSegmentNumber || range[1];

const references = [];
const createReference = (position) => {
Expand Down
29 changes: 29 additions & 0 deletions test/dash/dash_parser_manifest_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,35 @@ describe('DashParser Manifest', () => {
}
});

it('signaling last segment number via SupplementalProperty', async () => {
// (DASH-IF IOP v4.3 4.4.3.6.)
const scheme = 'http://dashif.org/guidelines/last-segment-number';
const value = 368;
const manifestText = [
'<MPD minBufferTime="PT75S" type="static">',
' <Period id="1" duration="PT0H12M14.167S">',
' <AdaptationSet id="2">',
` <SupplementalProperty schemeIdUri="${scheme}" value="${value}" />`,
' <Representation codecs="avc1.640028" mimeType="video/mp4">',
' <SegmentTemplate startNumber="1" media="m-$Number$.mp4"',
' initialization="i.mp4" timescale="12288" duration="24576"/>',
' </Representation>',
' </AdaptationSet>',
' </Period>',
'</MPD>',
].join('\n');

fakeNetEngine.setResponseText('dummy://foo', manifestText);

/** @type {shaka.extern.Manifest} */
const manifest = await parser.start('dummy://foo', playerInterface);
expect(manifest.variants.length).toBe(1);
const stream = manifest.variants[0].video;
await stream.createSegmentIndex();
goog.asserts.assert(stream.segmentIndex, 'Null segmentIndex!');
expect(Array.from(stream.segmentIndex).length).toBe(367);
});

it('Does not error when image adaptation sets are present', async () => {
const manifestText = [
'<MPD minBufferTime="PT75S">',
Expand Down

0 comments on commit 07a3241

Please sign in to comment.