Skip to content

Commit

Permalink
Skip text AdaptationSets with no segment info
Browse files Browse the repository at this point in the history
See also shaka-project/shaka-packager#422

Closes #1484

Change-Id: I293468a39918a4a8487d15ec70b365eec3dd1ebc
  • Loading branch information
joeyparrish committed Jul 3, 2018
1 parent 1885959 commit 64d72fe
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 43 deletions.
104 changes: 61 additions & 43 deletions lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,8 +957,9 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {

// Default kind for text streams is 'subtitle' if unspecified in the manifest.
let kind = undefined;
if (context.adaptationSet.contentType ==
ManifestParserUtils.ContentType.TEXT) {
const isText =
context.adaptationSet.contentType == ManifestParserUtils.ContentType.TEXT;
if (isText) {
kind = ManifestParserUtils.TextStreamKind.SUBTITLE;
}

Expand Down Expand Up @@ -1023,6 +1024,10 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {
.filter(function(s) { return !!s; });

if (streams.length == 0) {
// Ignore empty AdaptationSets if they are for text content.
if (isText) {
return null;
}
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
Expand Down Expand Up @@ -1111,47 +1116,60 @@ shaka.dash.DashParser.prototype.parseRepresentation_ = function(

/** @type {?shaka.dash.DashParser.StreamInfo} */
let streamInfo;
let requestInitSegment = this.requestInitSegment_.bind(this);
if (context.representation.segmentBase) {
streamInfo = shaka.dash.SegmentBase.createStream(
context, requestInitSegment);
} else if (context.representation.segmentList) {
streamInfo = shaka.dash.SegmentList.createStream(
context, this.segmentIndexMap_);
} else if (context.representation.segmentTemplate) {
streamInfo = shaka.dash.SegmentTemplate.createStream(
context, requestInitSegment, this.segmentIndexMap_, !!this.manifest_);
} else {
goog.asserts.assert(
context.representation.contentType == ContentType.TEXT ||
context.representation.contentType == ContentType.APPLICATION,
'Must have Segment* with non-text streams.');

let baseUris = context.representation.baseUris;
let duration = context.periodInfo.duration || 0;
streamInfo = {
createSegmentIndex: Promise.resolve.bind(Promise),
findSegmentPosition:
/** @return {?number} */ function(/** number */ time) {
if (time >= 0 && time < duration) {
return 1;
} else {
return null;
}
},
getSegmentReference:
/** @return {shaka.media.SegmentReference} */
function(/** number */ ref) {
if (ref != 1) {
return null;
}

return new shaka.media.SegmentReference(
1, 0, duration, function() { return baseUris; }, 0, null);
},
initSegmentReference: null,
scaledPresentationTimeOffset: 0
};

const contentType = context.representation.contentType;
const isText = contentType == ContentType.TEXT ||
contentType == ContentType.APPLICATION;

try {
const requestInitSegment = this.requestInitSegment_.bind(this);
if (context.representation.segmentBase) {
streamInfo = shaka.dash.SegmentBase.createStream(
context, requestInitSegment);
} else if (context.representation.segmentList) {
streamInfo = shaka.dash.SegmentList.createStream(
context, this.segmentIndexMap_);
} else if (context.representation.segmentTemplate) {
streamInfo = shaka.dash.SegmentTemplate.createStream(
context, requestInitSegment, this.segmentIndexMap_, !!this.manifest_);
} else {
goog.asserts.assert(isText,
'Must have Segment* with non-text streams.');

let baseUris = context.representation.baseUris;
let duration = context.periodInfo.duration || 0;
streamInfo = {
createSegmentIndex: Promise.resolve.bind(Promise),
findSegmentPosition:
/** @return {?number} */ function(/** number */ time) {
if (time >= 0 && time < duration) {
return 1;
} else {
return null;
}
},
getSegmentReference:
/** @return {shaka.media.SegmentReference} */
function(/** number */ ref) {
if (ref != 1) {
return null;
}

return new shaka.media.SegmentReference(
1, 0, duration, function() { return baseUris; }, 0, null);
},
initSegmentReference: null,
scaledPresentationTimeOffset: 0
};
}
} catch (error) {
if (isText && error.code == shaka.util.Error.Code.DASH_NO_SEGMENT_INFO) {
// We will ignore any DASH_NO_SEGMENT_INFO errors for text streams.
return null;
}

// For anything else, re-throw.
throw error;
}

let contentProtectionElems = XmlUtils.findChildren(node, 'ContentProtection');
Expand Down
22 changes: 22 additions & 0 deletions test/dash/dash_parser_manifest_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1027,4 +1027,26 @@ describe('DashParser Manifest', function() {
});
});
});

it('does not fail on AdaptationSets without segment info', async () => {
let manifestText = [
'<MPD minBufferTime="PT75S">',
' <Period id="1" duration="PT30S">',
' <AdaptationSet id="1" contentType="text">',
' <Representation mimeType="application/mp4" codecs="stpp">',
' <SegmentTemplate media="$Number$.mp4" />',
' </Representation>',
' </AdaptationSet>',
' <AdaptationSet id="2" mimeType="video/mp4">',
' <Representation bandwidth="1">',
' <SegmentTemplate media="2.mp4" duration="1" />',
' </Representation>',
' </AdaptationSet>',
' </Period>',
'</MPD>'
].join('\n');

fakeNetEngine.setResponseMapAsText({'dummy://foo': manifestText});
await parser.start('dummy://foo', playerInterface);
});
});

0 comments on commit 64d72fe

Please sign in to comment.