blob: 20ce8c89d3d1bd0d4e7e2848f13f2a4bbd362e11 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="/w3c/resources/testharness.js"></script>
<script src="/w3c/resources/testharnessreport.js"></script>
<script src="mediasource-util.js"></script>
<link rel="stylesheet" href="/w3c/resources/testharness.css">
</head>
<body>
<div id="log"></div>
<script>
var subType = MediaSourceUtil.getSubType(MediaSourceUtil.AUDIO_ONLY_TYPE);
var manifestFilenameA = subType + '/test-a-128k-44100Hz-1ch-manifest.json';
var manifestFilenameB = subType + '/test-v-128k-320x240-30fps-10kfr-manifest.json';
var expectationsA = {
webm: '{ [0.000, 2.022) }',
mp4: '{ [0.000, 2.043) }',
};
var expectationsB = {
webm: '{ [0.000, 2.000) }',
mp4: '{ [0.000, 2.000) }',
};
function mediaSourceDemuxedTest(callback, description)
{
mediasource_test(function(test, mediaElement, mediaSource)
{
mediaElement.pause();
test.failOnEvent(mediaElement, 'error');
test.endOnEvent(mediaElement, 'ended');
MediaSourceUtil.fetchManifestAndData(test, manifestFilenameA, function(typeA, dataA)
{
MediaSourceUtil.fetchManifestAndData(test, manifestFilenameB, function(typeB, dataB)
{
mediaSource.addSourceBuffer(typeA);
mediaSource.addSourceBuffer(typeB);
assert_equals(mediaSource.sourceBuffers.length, 2);
callback(test, mediaElement, mediaSource, dataA, dataB);
});
});
}, description);
};
function appendDataAndVerifyAddedToActiveSourceBuffers(test, mediaSource, dataA, dataB, swapAppendBufferOrder, forceParsingOrder, callback)
{
// Verification here assumes no prior initialization segment received for any of mediaSource's sourceBuffers.
assert_equals(mediaSource.sourceBuffers.length, 2, 'mediaSource sourceBuffers length before appends');
assert_equals(mediaSource.activeSourceBuffers.length, 0, 'mediaSource activeSourceBuffers length before appends');
var sourceBufferA = mediaSource.sourceBuffers[0];
var sourceBufferB = mediaSource.sourceBuffers[1];
var firstBuffer = swapAppendBufferOrder ? sourceBufferB : sourceBufferA;
var firstData = swapAppendBufferOrder ? dataB : dataA;
var secondBuffer = swapAppendBufferOrder ? sourceBufferA : sourceBufferB;
var secondData = swapAppendBufferOrder ? dataA : dataB;
test.expectEvent(firstBuffer, 'update');
test.expectEvent(firstBuffer, 'updateend');
firstBuffer.appendBuffer(firstData);
var doSecondAppend = function()
{
test.expectEvent(secondBuffer, 'update');
test.expectEvent(secondBuffer, 'updateend');
secondBuffer.appendBuffer(secondData);
};
if (forceParsingOrder) {
test.waitForExpectedEvents(function()
{
assert_equals(mediaSource.sourceBuffers.length, 2, 'mediaSource sourceBuffers length between completed appends');
assert_equals(mediaSource.activeSourceBuffers.length, 1, 'mediaSource activeSourceBuffers length between completed appends');
assert_equals(mediaSource.activeSourceBuffers[0], firstBuffer);
doSecondAppend();
});
} else {
doSecondAppend();
}
test.waitForExpectedEvents(function()
{
assert_equals(mediaSource.sourceBuffers.length, 2, 'mediaSource sourceBuffers length after appends completed');
assert_equals(mediaSource.activeSourceBuffers.length, 2, 'mediaSource activeSourceBuffers length after appends completed');
assert_equals(mediaSource.activeSourceBuffers[0], sourceBufferA);
assert_equals(mediaSource.activeSourceBuffers[1], sourceBufferB);
callback();
});
}
mediaSourceDemuxedTest(function(test, mediaElement, mediaSource, dataA, dataB) {
appendDataAndVerifyAddedToActiveSourceBuffers(test, mediaSource, dataA, dataB, false, false, function()
{
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[1], expectationsB[subType], 'mediaSource.activeSourceBuffers[1]');
assertBufferedEquals(mediaElement, expectationsB[subType], 'mediaElement.buffered');
mediaSource.endOfStream();
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[1], expectationsB[subType], 'mediaSource.activeSourceBuffers[1]');
assertBufferedEquals(mediaElement, expectationsA[subType], 'mediaElement.buffered');
test.done();
});
}, 'Demuxed content with different lengths');
mediaSourceDemuxedTest(function(test, mediaElement, mediaSource, dataA, dataB) {
appendDataAndVerifyAddedToActiveSourceBuffers(test, mediaSource, dataA, dataB, false, true, function()
{
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[1], expectationsB[subType], 'mediaSource.activeSourceBuffers[1]');
assertBufferedEquals(mediaElement, expectationsB[subType], 'mediaElement.buffered');
test.done();
});
}, 'Process first init segment for sourceBuffer[0] first');
mediaSourceDemuxedTest(function(test, mediaElement, mediaSource, dataA, dataB) {
appendDataAndVerifyAddedToActiveSourceBuffers(test, mediaSource, dataA, dataB, true, true, function()
{
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[1], expectationsB[subType], 'mediaSource.activeSourceBuffers[1]');
assertBufferedEquals(mediaElement, expectationsB[subType], 'mediaElement.buffered');
test.done();
});
}, 'Process first init segment for sourceBuffer[1] first');
mediasource_test(function(test, mediaElement, mediaSource)
{
mediaElement.pause();
test.failOnEvent(mediaElement, 'error');
test.endOnEvent(mediaElement, 'ended');
MediaSourceUtil.fetchManifestAndData(test, subType + '/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr-manifest.json', function(type, data)
{
var sourceBuffer = mediaSource.addSourceBuffer(type);
test.expectEvent(sourceBuffer, 'update');
test.expectEvent(sourceBuffer, 'updateend');
sourceBuffer.appendBuffer(data);
test.waitForExpectedEvents(function()
{
var expectationsAV = {
webm: ['{ [0.000, 2.003) }', '{ [0.000, 2.022) }'],
mp4: ['{ [0.000, 2.000) }', '{ [0.000, 2.043) }'],
};
var expectedBeforeEndOfStream = expectationsAV[subType][0];
var expectedAfterEndOfStream = expectationsAV[subType][1];
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectedBeforeEndOfStream, 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaElement, expectedBeforeEndOfStream, 'mediaElement.buffered');
mediaSource.endOfStream();
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectedAfterEndOfStream, 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaElement, expectedAfterEndOfStream, 'mediaElement.buffered');
test.done();
});
});
}, 'Muxed tracks with different lengths');
mediaSourceDemuxedTest(function(test, mediaElement, mediaSource, dataA, dataB) {
appendDataAndVerifyAddedToActiveSourceBuffers(test, mediaSource, dataA, dataB.subarray(0, 318), false, false, function()
{
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[1], '{ }', 'mediaSource.activeSourceBuffers[1]');
assertBufferedEquals(mediaElement, '{ }', 'mediaElement.buffered');
mediaSource.endOfStream();
assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[1], '{ }', 'mediaSource.activeSourceBuffers[1]');
assertBufferedEquals(mediaElement, '{ }', 'mediaElement.buffered');
test.done();
});
}, 'Demuxed content with an empty buffered range on one SourceBuffer');
mediasource_test(function(test, mediaElement, mediaSource)
{
mediaElement.pause();
test.failOnEvent(mediaElement, 'error');
test.endOnEvent(mediaElement, 'ended');
MediaSourceUtil.fetchManifestAndData(test, subType + '/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr-manifest.json', function(type, data)
{
var sourceBuffer = mediaSource.addSourceBuffer(type);
test.expectEvent(sourceBuffer, 'update');
test.expectEvent(sourceBuffer, 'updateend');
sourceBuffer.appendBuffer(data.subarray(0, 4052));
test.waitForExpectedEvents(function()
{
assertBufferedEquals(mediaSource.activeSourceBuffers[0], '{ }', 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaElement, '{ }', 'mediaElement.buffered');
mediaSource.endOfStream();
assertBufferedEquals(mediaSource.activeSourceBuffers[0], '{ }', 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaElement, '{ }', 'mediaElement.buffered');
test.done();
});
});
}, 'Muxed content empty buffered ranges.');
mediasource_test(function(test, mediaElement, mediaSource)
{
mediaElement.pause();
test.failOnEvent(mediaElement, 'error');
test.endOnEvent(mediaElement, 'ended');
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_ONLY_TYPE);
assertBufferedEquals(mediaSource.sourceBuffers[0], '{ }', 'mediaSource.sourceBuffers[0]');
assertBufferedEquals(mediaElement, '{ }', 'mediaElement.buffered');
test.done();
}, 'Get buffered range when sourcebuffer is empty.');
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
test.expectEvent(sourceBuffer, 'updateend', 'initSegment append ended.');
sourceBuffer.appendBuffer(initSegment);
test.waitForExpectedEvents(function()
{
assertBufferedEquals(mediaSource.sourceBuffers[0], '{ }', 'mediaSource.sourceBuffers[0]');
assertBufferedEquals(mediaSource.activeSourceBuffers[0], '{ }', 'mediaSource.activeSourceBuffers[0]');
assertBufferedEquals(mediaElement, '{ }', 'mediaElement.buffered');
test.done();
});
}, 'Get buffered range when only initsegment is appended.');
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
test.expectEvent(mediaSource.sourceBuffers, 'removesourcebuffer', 'SourceBuffer removed.');
mediaSource.removeSourceBuffer(sourceBuffer);
test.waitForExpectedEvents(function()
{
assert_throws('InvalidStateError',
function() { sourceBuffer.buffered; },
'get sourceBuffer.buffered throws an exception for InvalidStateError.');
test.done();
});
}, 'Get buffered range after removing sourcebuffer.');
</script>
</body>
</html>