fune/testing/web-platform/tests/media-source/mediasource-errors.html
Jean-Yves Avenard 9f6cc56c92 Bug 1314533: Do not expect init segment to be parsed when appending corrupted data. r=gerald
From the Segment Parser Loop definition:
https://w3c.github.io/media-source/index.html#sourcebuffer-segment-parser-loop
"2. If the input buffer contains bytes that violate the SourceBuffer byte stream format specification, then run the append error algorithm and abort this algorithm."

The test appends data with a valid init segment followed by corrupted content.
The corrupted content satisfies the condition that the input buffer contains bytes that violate byte stream format specification.
As such, the append error algorithm is to be run prior parsing the init segment.

Add a new test verifying the defined behavior.

--HG--
extra : rebase_source : b20c653129c9f38bb5930c309f919131cd2fcc51
2016-11-06 21:57:06 +11:00

234 lines
11 KiB
HTML

<!DOCTYPE html>
<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="mediasource-util.js"></script>
<script>
function ErrorTest(testFunction, description)
{
mediasource_test(function(test, mediaElement, mediaSource)
{
var segmentInfo = MediaSourceUtil.SEGMENT_INFO;
if (!segmentInfo) {
assert_unreached("No segment info compatible with this MediaSource implementation.");
return;
}
var sourceBuffer = mediaSource.addSourceBuffer(segmentInfo.type);
MediaSourceUtil.loadBinaryData(test, segmentInfo.url, function(mediaData)
{
testFunction(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData);
});
}, description);
}
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
test.expectEvent(sourceBuffer, "error", "sourceBuffer error.");
test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
test.expectEvent(mediaSource, "sourceclose", "mediaSource closed.");
sourceBuffer.appendBuffer(mediaSegment);
test.waitForExpectedEvents(function()
{
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
assert_equals(mediaSource.sourceBuffers.length, 0);
assert_equals(mediaSource.readyState, "closed");
test.done();
});
}, "Appending media segment before the first initialization segment.");
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
// Fail if the append error algorithm occurs, since the decode
// error will be provided by us directly via endOfStream().
sourceBuffer.addEventListener("error", test.unreached_func("'error' should not be fired on sourceBuffer"));
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
test.expectEvent(mediaSource, "sourceclose", "mediaSource closed.");
mediaSource.endOfStream("decode");
test.waitForExpectedEvents(function()
{
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
assert_equals(mediaSource.sourceBuffers.length, 0);
assert_equals(mediaSource.readyState, "closed");
// Give a short time for a broken implementation to errantly fire
// "error" on sourceBuffer.
test.step_timeout(test.step_func_done(), 0);
});
}, "Signaling 'decode' error via endOfStream() before initialization segment has been appended.");
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
// Fail if the append error algorithm occurs, since the network
// error will be provided by us directly via endOfStream().
sourceBuffer.addEventListener("error", test.unreached_func("'error' should not be fired on sourceBuffer"));
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
test.expectEvent(mediaSource, "sourceclose", "mediaSource closed.");
mediaSource.endOfStream("network");
test.waitForExpectedEvents(function()
{
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
assert_equals(mediaSource.sourceBuffers.length, 0);
assert_equals(mediaSource.readyState, "closed");
// Give a short time for a broken implementation to errantly fire
// "error" on sourceBuffer.
test.step_timeout(test.step_func_done(), 0);
});
}, "Signaling 'network' error via endOfStream() before initialization segment has been appended.");
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
// Fail if the append error algorithm occurs, since the decode
// error will be provided by us directly via endOfStream().
sourceBuffer.addEventListener("error", test.unreached_func("'error' should not be fired on sourceBuffer"));
test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
test.expectEvent(mediaElement, "loadedmetadata", "mediaElement metadata.");
sourceBuffer.appendBuffer(initSegment);
test.waitForExpectedEvents(function()
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_METADATA);
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
mediaSource.endOfStream("decode");
});
test.waitForExpectedEvents(function()
{
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_DECODE);
assert_equals(mediaSource.readyState, "ended");
// Give a short time for a broken implementation to errantly fire
// "error" on sourceBuffer.
test.step_timeout(test.step_func_done(), 0);
});
}, "Signaling 'decode' error via endOfStream() after initialization segment has been appended and the HTMLMediaElement has reached HAVE_METADATA.");
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
// Fail if the append error algorithm occurs, since the network
// error will be provided by us directly via endOfStream().
sourceBuffer.addEventListener("error", test.unreached_func("'error' should not be fired on sourceBuffer"));
test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
test.expectEvent(mediaElement, "loadedmetadata", "mediaElement metadata.");
sourceBuffer.appendBuffer(initSegment);
test.waitForExpectedEvents(function()
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_METADATA);
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
mediaSource.endOfStream("network");
});
test.waitForExpectedEvents(function()
{
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_NETWORK);
assert_equals(mediaSource.readyState, "ended");
// Give a short time for a broken implementation to errantly fire
// "error" on sourceBuffer.
test.step_timeout(test.step_func_done(), 0);
});
}, "Signaling 'network' error via endOfStream() after initialization segment has been appended and the HTMLMediaElement has reached HAVE_METADATA.");
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
test.expectEvent(mediaElement, "loadedmetadata", "mediaElement metadata.");
sourceBuffer.appendBuffer(initSegment);
test.waitForExpectedEvents(function()
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_METADATA);
var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
var index = segmentInfo.init.size + (mediaSegment.length - 1) / 2;
// Corrupt the media data from index of mediaData, so it can signal 'decode' error.
// Here use mediaSegment to replace the original mediaData[index, index + mediaSegment.length]
mediaData.set(mediaSegment, index);
test.expectEvent(sourceBuffer, "error", "sourceBuffer error.");
test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
sourceBuffer.appendBuffer(mediaData);
});
test.waitForExpectedEvents(function()
{
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_DECODE);
test.done();
});
}, "Signaling 'decode' error via segment parser loop algorithm after initialization segment has been appended.");
ErrorTest(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
// Fail if the append error algorithm occurs, since the network
// error will be provided by us directly via endOfStream().
mediaElement.addEventListener("loadedmetadata", test.unreached_func("'loadedmetadata' should not be fired on mediaElement"));
var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
var index = segmentInfo.init.size + (mediaSegment.length - 1) / 2;
// Corrupt the media data from index of mediaData, so it can signal 'decode' error.
// Here use mediaSegment to replace the original mediaData[index, index + mediaSegment.length]
mediaData.set(mediaSegment, index);
test.expectEvent(sourceBuffer, "error", "sourceBuffer error.");
test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
test.expectEvent(mediaElement, "error", "mediaElement error.");
test.expectEvent(mediaSource, "sourceended", "mediaSource ended.");
sourceBuffer.appendBuffer(mediaData);
test.waitForExpectedEvents(function()
{
assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_NOTHING);
assert_true(mediaElement.error != null);
assert_equals(mediaElement.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
test.done();
});
}, "Signaling 'decode' error via segment parser loop algorithm.");
</script>