summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/media-source/mediasource-append-buffer.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/web-platform/tests/media-source/mediasource-append-buffer.html623
1 files changed, 623 insertions, 0 deletions
diff --git a/testing/web-platform/tests/media-source/mediasource-append-buffer.html b/testing/web-platform/tests/media-source/mediasource-append-buffer.html
new file mode 100644
index 0000000000..750ccaf456
--- /dev/null
+++ b/testing/web-platform/tests/media-source/mediasource-append-buffer.html
@@ -0,0 +1,623 @@
+<!DOCTYPE html>
+<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<html>
+ <head>
+ <title>SourceBuffer.appendBuffer() test cases</title>
+ <meta name="timeout" content="long">
+ <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_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test SourceBuffer.appendBuffer() event dispatching.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ assert_throws_dom("InvalidStateError",
+ function() { sourceBuffer.appendBuffer(mediaData); },
+ "appendBuffer() throws an exception there is a pending append.");
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test SourceBuffer.appendBuffer() call during a pending appendBuffer().");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "abort", "Append aborted.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ sourceBuffer.abort();
+
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test SourceBuffer.abort() call during a pending appendBuffer().");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+
+ test.expectEvent(mediaSource, "sourceended", "MediaSource sourceended event");
+ mediaSource.endOfStream();
+ assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
+
+ test.expectEvent(mediaSource, "sourceopen", "MediaSource sourceopen event");
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test SourceBuffer.appendBuffer() triggering an 'ended' to 'open' transition.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+
+ test.expectEvent(mediaSource, "sourceended", "MediaSource sourceended event");
+ mediaSource.endOfStream();
+ assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "ended", "MediaSource readyState is 'ended'");
+
+ test.expectEvent(mediaSource, "sourceopen", "MediaSource sourceopen event");
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(new Uint8Array(0));
+
+ assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "open", "MediaSource readyState is 'open'");
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test zero byte SourceBuffer.appendBuffer() call triggering an 'ended' to 'open' transition.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "abort", "Append aborted.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+ assert_equals(mediaSource.activeSourceBuffers.length, 0, "activeSourceBuffers.length");
+
+ test.expectEvent(mediaSource.sourceBuffers, "removesourcebuffer", "sourceBuffers");
+ mediaSource.removeSourceBuffer(sourceBuffer);
+
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+
+ assert_throws_dom("InvalidStateError",
+ function() { sourceBuffer.appendBuffer(mediaData); },
+ "appendBuffer() throws an exception because it isn't attached to the mediaSource anymore.");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test MediaSource.removeSourceBuffer() call during a pending appendBuffer().");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ assert_throws_dom("InvalidStateError",
+ function() { mediaSource.duration = 1.0; },
+ "set duration throws an exception when updating attribute is true.");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test set MediaSource.duration during a pending appendBuffer() for one of its SourceBuffers.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
+ mediaSource.addEventListener("sourceended", test.unreached_func("Unexpected event 'sourceended'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ assert_throws_dom("InvalidStateError",
+ function() { mediaSource.endOfStream(); },
+ "endOfStream() throws an exception when updating attribute is true.");
+
+ assert_equals(mediaSource.readyState, "open");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ assert_equals(mediaSource.readyState, "open");
+ test.done();
+ });
+ }, "Test MediaSource.endOfStream() during a pending appendBuffer() for one of its SourceBuffers.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(mediaData);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ assert_throws_dom("InvalidStateError",
+ function() { sourceBuffer.timestampOffset = 10.0; },
+ "set timestampOffset throws an exception when updating attribute is true.");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test set SourceBuffer.timestampOffset during a pending appendBuffer().");
+
+ mediasource_test(function(test, mediaElement, mediaSource)
+ {
+ var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(new Uint8Array(0));
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test appending an empty ArrayBufferView.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+
+ var arrayBufferView = new Uint8Array(mediaData);
+
+ assert_equals(arrayBufferView.length, mediaData.length, "arrayBufferView.length before transfer.");
+
+ // Send the buffer as in a message so it gets neutered.
+ window.postMessage( "test", "*", [arrayBufferView.buffer]);
+
+ assert_equals(arrayBufferView.length, 0, "arrayBufferView.length after transfer.");
+
+ sourceBuffer.appendBuffer(arrayBufferView);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test appending a neutered ArrayBufferView.");
+
+ mediasource_test(function(test, mediaElement, mediaSource)
+ {
+ var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendBuffer(new ArrayBuffer(0));
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test appending an empty ArrayBuffer.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+
+ var arrayBuffer = mediaData.buffer.slice(0);
+
+ assert_equals(arrayBuffer.byteLength, mediaData.buffer.byteLength, "arrayBuffer.byteLength before transfer.");
+
+ // Send the buffer as in a message so it gets neutered.
+ window.postMessage( "test", "*", [arrayBuffer]);
+
+ assert_equals(arrayBuffer.byteLength, 0, "arrayBuffer.byteLength after transfer.");
+
+ sourceBuffer.appendBuffer(arrayBuffer);
+
+ assert_true(sourceBuffer.updating, "updating attribute is true");
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ test.done();
+ });
+ }, "Test appending a neutered ArrayBuffer.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+ var halfIndex = (initSegment.length + 1) / 2;
+ var partialInitSegment = initSegment.subarray(0, halfIndex);
+ var remainingInitSegment = initSegment.subarray(halfIndex);
+ var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
+
+ test.expectEvent(sourceBuffer, "updateend", "partialInitSegment append ended.");
+ sourceBuffer.appendBuffer(partialInitSegment);
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaElement.readyState, mediaElement.HAVE_NOTHING);
+ assert_equals(mediaSource.duration, Number.NaN);
+ test.expectEvent(sourceBuffer, "updateend", "remainingInitSegment append ended.");
+ test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata event received.");
+ sourceBuffer.appendBuffer(remainingInitSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
+ assert_equals(mediaSource.duration, segmentInfo.duration);
+ test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
+ test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
+ sourceBuffer.appendBuffer(mediaSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
+ assert_equals(sourceBuffer.updating, false);
+ assert_equals(mediaSource.readyState, "open");
+ test.done();
+ });
+ }, "Test appendBuffer with partial init segments.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+ var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
+ var halfIndex = (mediaSegment.length + 1) / 2;
+ var partialMediaSegment = mediaSegment.subarray(0, halfIndex);
+ var remainingMediaSegment = mediaSegment.subarray(halfIndex);
+
+ test.expectEvent(sourceBuffer, "updateend", "InitSegment append ended.");
+ test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata done.");
+ sourceBuffer.appendBuffer(initSegment);
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
+ assert_equals(mediaSource.duration, segmentInfo.duration);
+ test.expectEvent(sourceBuffer, "updateend", "partial media segment append ended.");
+ sourceBuffer.appendBuffer(partialMediaSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
+ test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
+ sourceBuffer.appendBuffer(remainingMediaSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
+ assert_equals(mediaSource.readyState, "open");
+ assert_equals(sourceBuffer.updating, false);
+ test.done();
+ });
+ }, "Test appendBuffer with partial media segments.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+ var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
+
+ assert_equals(mediaElement.readyState, mediaElement.HAVE_NOTHING);
+ assert_equals(mediaSource.duration, Number.NaN);
+
+ // readyState is changing as per the Initialization Segment Received algorithm.
+ var loadedmetadataCalled = false;
+ mediaElement.addEventListener("loadedmetadata", function metadata(e) {
+ loadedmetadataCalled = true;
+ e.target.removeEventListener(e.type, metadata);
+ });
+ sourceBuffer.addEventListener("updateend", test.step_func(function updateend(e) {
+ assert_true(loadedmetadataCalled);
+ assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
+ e.target.removeEventListener(e.type, updateend);
+ }));
+ test.expectEvent(sourceBuffer, "updateend", "remainingInitSegment append ended.");
+ test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata event received.");
+ sourceBuffer.appendBuffer(initSegment);
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA);
+ assert_equals(mediaSource.duration, segmentInfo.duration);
+ // readyState is changing as per the Coded Frame Processing algorithm.
+ var loadeddataCalled = false;
+ mediaElement.addEventListener("loadeddata", function loadeddata(e) {
+ loadeddataCalled = true;
+ e.target.removeEventListener(e.type, loadeddata);
+ });
+ sourceBuffer.addEventListener("updateend", test.step_func(function updateend(e) {
+ assert_true(loadeddataCalled);
+ assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
+ e.target.removeEventListener(e.type, updateend);
+ }));
+ test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
+ test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
+ sourceBuffer.appendBuffer(mediaSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA);
+ assert_equals(sourceBuffer.updating, false);
+ assert_equals(mediaSource.readyState, "open");
+ test.done();
+ });
+ }, "Test appendBuffer events order.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+ var partialInitSegment = initSegment.subarray(0, initSegment.length / 2);
+ var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
+
+ test.expectEvent(sourceBuffer, "updateend", "partialInitSegment append ended.");
+ sourceBuffer.appendBuffer(partialInitSegment);
+
+ test.waitForExpectedEvents(function()
+ {
+ // Call abort to reset the parser.
+ sourceBuffer.abort();
+
+ // Append the full intiialization segment.
+ test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
+ sourceBuffer.appendBuffer(initSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
+ test.expectEvent(mediaElement, "loadeddata", "loadeddata fired.");
+ sourceBuffer.appendBuffer(mediaSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ test.done();
+ });
+ }, "Test abort in the middle of an initialization segment.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ test.expectEvent(mediaSource.sourceBuffers, "removesourcebuffer", "SourceBuffer removed.");
+ mediaSource.removeSourceBuffer(sourceBuffer);
+ test.waitForExpectedEvents(function()
+ {
+ assert_throws_dom("InvalidStateError",
+ function() { sourceBuffer.abort(); },
+ "sourceBuffer.abort() throws an exception for InvalidStateError.");
+
+ test.done();
+ });
+ }, "Test abort after removing sourcebuffer.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+ var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
+
+ test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
+ sourceBuffer.appendBuffer(initSegment);
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "open", "readyState is open after init segment appended.");
+ test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
+ sourceBuffer.appendBuffer(mediaSegment);
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(sourceBuffer.buffered.length, 1, "sourceBuffer has a buffered range");
+ assert_equals(mediaSource.readyState, "open", "readyState is open after media segment appended.");
+ test.expectEvent(mediaSource, "sourceended", "source ended");
+ mediaSource.endOfStream();
+ });
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "ended", "readyState is ended.");
+ assert_throws_dom("InvalidStateError",
+ function() { sourceBuffer.abort(); },
+ "sourceBuffer.abort() throws an exception for InvalidStateError.");
+ test.done();
+ });
+
+ }, "Test abort after readyState is ended following init segment and media segment.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+ sourceBuffer.appendWindowStart = 1;
+ sourceBuffer.appendWindowEnd = 100;
+ sourceBuffer.appendBuffer(mediaData);
+
+ test.waitForExpectedEvents(function()
+ {
+ assert_false(sourceBuffer.updating, "updating attribute is false");
+ sourceBuffer.abort();
+ assert_equals(sourceBuffer.appendWindowStart, 0, "appendWindowStart is reset to 0");
+ assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_INFINITY,
+ "appendWindowEnd is reset to +INFINITY");
+ test.done();
+ });
+ }, "Test abort after appendBuffer update ends.");
+
+ mediasource_test(function(test, mediaElement, mediaSource)
+ {
+ var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
+
+ test.expectEvent(sourceBuffer, "updatestart", "Append started.");
+ test.expectEvent(sourceBuffer, "update", "Append success.");
+ test.expectEvent(sourceBuffer, "updateend", "Append ended.");
+
+ assert_throws_js( TypeError,
+ function() { sourceBuffer.appendBuffer(null); },
+ "appendBuffer(null) throws an exception.");
+ test.done();
+ }, "Test appending null.");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ mediaSource.removeSourceBuffer(sourceBuffer);
+
+ assert_throws_dom( "InvalidStateError",
+ function() { sourceBuffer.appendBuffer(mediaData); },
+ "appendBuffer() throws an exception when called after removeSourceBuffer().");
+ test.done();
+ }, "Test appending after removeSourceBuffer().");
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ // Media elements using MSE should not fire the stalled event. See discussion at
+ // https://github.com/w3c/media-source/issues/88#issuecomment-374406928
+ mediaElement.addEventListener("stalled", test.unreached_func("Unexpected 'stalled' event."));
+
+ // Prime the media element with initial appends.
+ var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+ var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[0]);
+ test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
+ sourceBuffer.appendBuffer(initSegment);
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(mediaSource.readyState, "open", "readyState is open after init segment appended.");
+ test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended.");
+ sourceBuffer.appendBuffer(mediaSegment);
+ });
+
+ // Verify state and wait for the 'stalled' event.
+ test.waitForExpectedEvents(function()
+ {
+ assert_equals(sourceBuffer.buffered.length, 1, "sourceBuffer has a buffered range");
+ assert_equals(mediaSource.readyState, "open", "readyState is open after media segment appended.");
+
+ // Set timeout to 4 seconds. This creates an opportunity for UAs to _improperly_ fire the stalled event.
+ // For media elements doing progressive download (not MSE), stalled is thrown after ~3 seconds of the
+ // download failing to progress.
+ test.step_timeout(function() { test.done(); }, 4000);
+ });
+ }, "Test slow appending does not trigger stalled events.");
+
+ </script>
+ </body>
+</html>