Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't ignore InbandEventStreams at the Representation level #687

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,7 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {

// InbandEventStream indicates that a segment contains inband
// information.
var eventStream = XmlUtils.findChild(elem, 'InbandEventStream');
var containsInband = eventStream != null;
var containsInband = this.inBandEventStreamIsPresent_(elem);

var essentialProperties = XmlUtils.findChildren(elem, 'EssentialProperty');
// ID of real AdaptationSet if this is a trick mode set:
Expand Down Expand Up @@ -991,6 +990,38 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {
};


/**
* Indicates whether an InbandEventStream element is present at the Adaption
* Set or Representation level.
*
* @param {!Element} elem The AdaptationSet element.
* @return {boolean} Whether the InbandEventStream element is present.
* @private
*/
shaka.dash.DashParser.prototype.inBandEventStreamIsPresent_ = function(elem) {
var XmlUtils = shaka.util.XmlUtils;

var adaptationEventStream = XmlUtils.findChild(elem, 'InbandEventStream');
if (adaptationEventStream != null) {
return true;
}

var representations = XmlUtils.findChildren(elem, 'Representation');
var representationEventStream = null;
if (representations.length > 0) {
for (var i = 0; i < representations.length; i++) {
representationEventStream =
XmlUtils.findChild(representations[i], 'InbandEventStream');

if (representationEventStream)
return true;
}
}

return false;
};


/**
* Parses a Representation XML element.
*
Expand Down
91 changes: 62 additions & 29 deletions test/dash/dash_parser_manifest_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,35 +751,46 @@ describe('DashParser Manifest', function() {
.then(done);
});

it('updates manifest when emsg box is present', function(done) {
var manifestText = [
'<MPD minBufferTime="PT75S">',
' <Period id="1" duration="PT30S">',
' <AdaptationSet mimeType="video/mp4">',
' <InbandEventStream scheme_id_uri="urn:mpeg:dash:event:2012" />',
' <Representation bandwidth="1">',
' <SegmentTemplate media="1.mp4" duration="1" />',
' </Representation>',
' </AdaptationSet>',
' </Period>',
'</MPD>'
].join('\n');

fakeNetEngine.setResponseMapAsText({'dummy://foo': manifestText});
parser.start('dummy://foo', playerInterface)
.then(function() {
expect(fakeNetEngine.registerResponseFilter).toHaveBeenCalled();
var filter =
fakeNetEngine.registerResponseFilter.calls.mostRecent().args[0];
var type = shaka.net.NetworkingEngine.RequestType.SEGMENT;
var response = {data: emsgUpdate.buffer};
fakeNetEngine.request.calls.reset();
filter(type, response);
expect(fakeNetEngine.request).toHaveBeenCalled();
})
.catch(fail)
.then(done);
});
it('updates manifest when emsg box is present on AdaptationSet',
function(done) {
var manifestText = [
'<MPD minBufferTime="PT75S">',
' <Period id="1" duration="PT30S">',
' <AdaptationSet mimeType="video/mp4">',
' <InbandEventStream',
' scheme_id_uri="urn:mpeg:dash:event:2012" />',
' <Representation bandwidth="1">',
' <SegmentTemplate media="1.mp4" duration="1" />',
' </Representation>',
' </AdaptationSet>',
' </Period>',
'</MPD>'
].join('\n');

emsgBoxPresenceHelper(manifestText, emsgUpdate, done);
});

it('updates manifest when emsg box is present on Representation',
function(done) {
var manifestText = [
'<MPD minBufferTime="PT75S">',
' <Period id="1" duration="PT30S">',
' <AdaptationSet mimeType="video/mp4">',
' <Representation bandwidth="1">',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a test case with multiple Representations, please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rolled this into a single test because I thought it would be sufficient but I can separate the single Representation case from the multiple Representation case if you'd prefer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single test is fine. Thanks!

' <InbandEventStream',
' scheme_id_uri="urn:mpeg:dash:event:2012" />',
' <SegmentTemplate media="1.mp4" duration="1" />',
' </Representation>',
' <Representation bandwidth="1">',
' <SegmentTemplate media="1.mp4" duration="1" />',
' </Representation>',
' </AdaptationSet>',
' </Period>',
'</MPD>'
].join('\n');

emsgBoxPresenceHelper(manifestText, emsgUpdate, done);
});

it('dispatches an event on non-typical emsg content', function(done) {
var manifestText = [
Expand Down Expand Up @@ -969,4 +980,26 @@ describe('DashParser Manifest', function() {
.catch(fail)
.then(done);
});

/**
* @param {string} manifestText
* @param {Uint8Array} emsgUpdate
* @param {Function} done
*/
function emsgBoxPresenceHelper(manifestText, emsgUpdate, done) {
fakeNetEngine.setResponseMapAsText({'dummy://foo': manifestText});
parser.start('dummy://foo', playerInterface)
.then(function() {
expect(fakeNetEngine.registerResponseFilter).toHaveBeenCalled();
var filter =
fakeNetEngine.registerResponseFilter.calls.mostRecent().args[0];
var type = shaka.net.NetworkingEngine.RequestType.SEGMENT;
var response = {data: emsgUpdate.buffer};
fakeNetEngine.request.calls.reset();
filter(type, response);
expect(fakeNetEngine.request).toHaveBeenCalled();
})
.catch(fail)
.then(done);
}
});