| <!DOCTYPE html> | |
| <!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). --> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>SourceBuffer.remove() test cases.</title> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="mediasource-util.js"></script> | |
| </head> | |
| <body> | |
| <div id="log"></div> | |
| <script> | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(-1, 2); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove with an negative start."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| [ undefined, NaN, Infinity, -Infinity ].forEach(function(item) | |
| { | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(item, 2); | |
| }, "remove"); | |
| }); | |
| test.done(); | |
| }, "Test remove with non-finite start."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(11, 12); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove with a start beyond the duration."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(2, 1); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove with a start larger than the end."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(0, Number.NEGATIVE_INFINITY); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove with a NEGATIVE_INFINITY end."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(0, Number.NaN); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove with a NaN end."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| mediaSource.removeSourceBuffer(sourceBuffer); | |
| assert_throws_dom("InvalidStateError", function() | |
| { | |
| sourceBuffer.remove(1, 2); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove after SourceBuffer removed from mediaSource."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| assert_false(sourceBuffer.updating, "updating is false"); | |
| assert_equals(mediaSource.duration, NaN, "duration isn't set"); | |
| assert_throws_js(TypeError, function() | |
| { | |
| sourceBuffer.remove(0, 0); | |
| }, "remove"); | |
| test.done(); | |
| }, "Test remove with a NaN duration."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| sourceBuffer.remove(1, 2); | |
| assert_true(sourceBuffer.updating, "updating"); | |
| assert_throws_dom("InvalidStateError", function() | |
| { | |
| sourceBuffer.remove(3, 4); | |
| }, "remove"); | |
| test.waitForExpectedEvents(function() | |
| { | |
| test.done(); | |
| }); | |
| }, "Test remove while update pending."); | |
| mediasource_test(function(test, mediaElement, mediaSource) | |
| { | |
| var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE); | |
| mediaSource.duration = 10; | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| sourceBuffer.remove(1, 2); | |
| assert_true(sourceBuffer.updating, "updating"); | |
| assert_throws_dom("InvalidStateError", function() | |
| { | |
| sourceBuffer.abort(); | |
| }, "abort"); | |
| assert_true(sourceBuffer.updating, "updating"); | |
| test.waitForExpectedEvents(function() | |
| { | |
| test.done(); | |
| }); | |
| }, "Test aborting a remove operation."); | |
| mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) | |
| { | |
| sourceBuffer.appendBuffer(mediaData); | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| test.waitForExpectedEvents(function() | |
| { | |
| assert_less_than(mediaSource.duration, 10) | |
| mediaSource.duration = 10; | |
| sourceBuffer.remove(mediaSource.duration, mediaSource.duration + 2); | |
| assert_true(sourceBuffer.updating, "updating"); | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| }); | |
| test.waitForExpectedEvents(function() | |
| { | |
| test.done(); | |
| }); | |
| }, "Test remove with a start at the duration."); | |
| mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) | |
| { | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| sourceBuffer.appendBuffer(mediaData); | |
| test.waitForExpectedEvents(function() | |
| { | |
| mediaSource.endOfStream(); | |
| assert_equals(mediaSource.readyState, "ended"); | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| test.expectEvent(mediaSource, "sourceopen"); | |
| sourceBuffer.remove(1, 2); | |
| assert_true(sourceBuffer.updating, "updating"); | |
| assert_equals(mediaSource.readyState, "open"); | |
| }); | |
| test.waitForExpectedEvents(function() | |
| { | |
| assert_false(sourceBuffer.updating, "updating"); | |
| test.done(); | |
| }); | |
| }, "Test remove transitioning readyState from 'ended' to 'open'."); | |
| function removeAppendedDataTests(callback, description) | |
| { | |
| mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) | |
| { | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| sourceBuffer.appendBuffer(mediaData); | |
| test.waitForExpectedEvents(function() | |
| { | |
| mediaSource.endOfStream(); | |
| assert_false(sourceBuffer.updating, "updating"); | |
| var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3); | |
| var duration = mediaElement.duration.toFixed(3); | |
| var subType = MediaSourceUtil.getSubType(segmentInfo.type); | |
| assertBufferedEquals(sourceBuffer, "{ [" + start + ", " + duration + ") }", "Initial buffered range."); | |
| callback(test, mediaSource, sourceBuffer, duration, subType, segmentInfo); | |
| }); | |
| }, description); | |
| }; | |
| function removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, start, end, expected) | |
| { | |
| test.expectEvent(sourceBuffer, "updatestart"); | |
| test.expectEvent(sourceBuffer, "update"); | |
| test.expectEvent(sourceBuffer, "updateend"); | |
| sourceBuffer.remove(start, end); | |
| test.waitForExpectedEvents(function() | |
| { | |
| mediaSource.endOfStream(); | |
| assert_false(sourceBuffer.updating, "updating"); | |
| assertBufferedEquals(sourceBuffer, expected, "Buffered ranges after remove()."); | |
| test.done(); | |
| }); | |
| } | |
| removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo) | |
| { | |
| removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 0, Number.POSITIVE_INFINITY, "{ }"); | |
| }, "Test removing all appended data."); | |
| removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo) | |
| { | |
| var expectations = { | |
| webm: ("{ [3.315, " + duration + ") }"), | |
| mp4: ("{ [3.298, " + duration + ") }"), | |
| }; | |
| // Note: Range doesn't start exactly at the end of the remove range because there isn't | |
| // a keyframe there. The resulting range starts at the first keyframe >= the end time. | |
| removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 0, 3, expectations[subType]); | |
| }, "Test removing beginning of appended data."); | |
| removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo) | |
| { | |
| var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3); | |
| var expectations = { | |
| webm: ("{ [" + start + ", 1.005) [3.315, " + duration + ") }"), | |
| mp4: ("{ [" + start + ", 0.997) [3.298, " + duration + ") }"), | |
| }; | |
| // Note: The first resulting range ends slightly after start because the removal algorithm only removes | |
| // frames with a timestamp >= the start time. If a frame starts before and ends after the remove() start | |
| // timestamp, then it stays in the buffer. | |
| removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 1, 3, expectations[subType]); | |
| }, "Test removing the middle of appended data."); | |
| removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo) | |
| { | |
| var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3); | |
| var expectations = { | |
| webm: "{ [" + start + ", 1.013) }", | |
| mp4: "{ [" + start + ", 1.022) }", | |
| }; | |
| removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 1, Number.POSITIVE_INFINITY, expectations[subType]); | |
| }, "Test removing the end of appended data."); | |
| </script> | |
| </body> | |
| </html> |