forked from mirrors/gecko-dev
		
	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
		
			
				
	
	
		
			234 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			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>
 |