Index: third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-duration.html |
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-duration.html b/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-duration.html |
index f1a4cfdcc4b645154d17e74b3b7b61a612c8335b..a4a0b0530397c9f0f2dda13fe2a0cfd49feb477f 100644 |
--- a/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-duration.html |
+++ b/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-duration.html |
@@ -9,7 +9,7 @@ |
<body> |
<div id="log"></div> |
<script> |
- function mediasource_truncated_duration_seek_test(testFunction, description, options) |
+ function mediasource_duration_below_currentTime_seek_test(testFunction, description, options) |
{ |
return mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) |
{ |
@@ -17,19 +17,19 @@ |
var fullDuration = segmentInfo.duration; |
var seekTo = fullDuration / 2.0; |
- var truncatedDuration = seekTo / 2.0; |
+ var reducedDuration = seekTo / 2.0; |
mediaElement.play(); |
// Append all the segments |
- test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); |
+ test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer append completed'); |
test.expectEvent(mediaElement, 'playing', 'Playing triggered'); |
sourceBuffer.appendBuffer(mediaData); |
test.waitForExpectedEvents(function() |
{ |
- assert_equals(mediaElement.duration, fullDuration, 'mediaElement fullDuration'); |
- assert_equals(mediaSource.duration, fullDuration, 'mediaSource fullDuration'); |
+ assert_equals(mediaElement.duration, fullDuration, 'mediaElement duration matches fullDuration'); |
+ assert_equals(mediaSource.duration, fullDuration, 'mediaSource duration matches fullDuration'); |
test.expectEvent(mediaElement, 'seeking', 'seeking to seekTo'); |
test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while seeking to seekTo'); |
@@ -41,146 +41,155 @@ |
test.waitForExpectedEvents(function() |
{ |
assert_greater_than_equal(mediaElement.currentTime, seekTo, 'Playback time has reached seekTo'); |
- assert_equals(mediaElement.duration, fullDuration, 'mediaElement fullDuration after seekTo'); |
- assert_equals(mediaSource.duration, fullDuration, 'mediaSource fullDuration after seekTo'); |
+ assert_equals(mediaElement.duration, fullDuration, 'mediaElement duration matches fullDuration after seekTo'); |
+ assert_equals(mediaSource.duration, fullDuration, 'mediaSource duration matches fullDuration after seekTo'); |
assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to seekTo'); |
- test.expectEvent(mediaElement, 'seeking', 'Seeking to truncated duration'); |
- mediaSource.duration = truncatedDuration; |
- assert_true(mediaElement.seeking, 'Seeking after setting truncatedDuration'); |
+ // Explicitly remove buffered media beyond the new reduced duration prior to reducing duration. |
+ // Implicit removal of buffered media as part of duration reduction is disallowed as of |
+ // https://github.com/w3c/media-source/pull/65/ |
+ test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer range removal completed'); |
+ sourceBuffer.remove(reducedDuration, fullDuration); |
+ assert_true(sourceBuffer.updating, 'sourceBuffer.updating during range removal'); |
}); |
test.waitForExpectedEvents(function() |
{ |
- assert_equals(mediaElement.currentTime, truncatedDuration, |
- 'Playback time is truncatedDuration while seeking'); |
- assert_true(mediaElement.seeking, 'mediaElement.seeking while seeking to truncatedDuration'); |
- assert_equals(mediaElement.duration, truncatedDuration, |
- 'mediaElement truncatedDuration during seek to it'); |
- assert_equals(mediaSource.duration, truncatedDuration, |
- 'mediaSource truncatedDuration during seek to it'); |
+ assert_false(sourceBuffer.updating, 'sourceBuffer.updating after range removal'); |
+ assert_greater_than_equal(mediaElement.currentTime, seekTo, |
+ 'Playback time is still at least seekTo after range removal'); |
+ |
+ test.expectEvent(mediaElement, 'seeking', 'Seeking to reduced duration'); |
+ mediaSource.duration = reducedDuration; |
+ assert_true(mediaElement.seeking, 'Seeking after setting reducedDuration'); |
+ }); |
+ |
+ test.waitForExpectedEvents(function() |
+ { |
+ assert_equals(mediaElement.currentTime, reducedDuration, |
+ 'Playback time is reducedDuration while seeking'); |
+ assert_true(mediaElement.seeking, 'mediaElement.seeking while seeking to reducedDuration'); |
+ assert_equals(mediaElement.duration, reducedDuration, |
+ 'mediaElement duration matches reducedDuration during seek to it'); |
+ assert_equals(mediaSource.duration, reducedDuration, |
+ 'mediaSource duration matches reducedDuration during seek to it'); |
// FIXME: Confirm 'waiting' and then 'stalled' fire here. See http://crbug.com/266592. |
testFunction(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData, |
- truncatedDuration); |
+ reducedDuration); |
}); |
}, description, options); |
} |
- mediasource_truncated_duration_seek_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, |
- mediaData, truncatedDuration) |
+ mediasource_duration_below_currentTime_seek_test(function(test, mediaElement, mediaSource, segmentInfo, |
+ sourceBuffer, mediaData, reducedDuration) |
{ |
- // Tests that duration truncation below current playback position |
+ // Tests that duration reduction below current playback position |
// starts seek to new duration. |
test.done(); |
- }, 'Test seek starts on duration truncation below currentTime'); |
+ }, 'Test seek starts on duration reduction below currentTime'); |
- mediasource_truncated_duration_seek_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, |
- mediaData, truncatedDuration) |
+ mediasource_duration_below_currentTime_seek_test(function(test, mediaElement, mediaSource, segmentInfo, |
+ sourceBuffer, mediaData, reducedDuration) |
{ |
- // The duration has been truncated at this point, and there is an |
+ // The duration has been reduced at this point, and there is an |
// outstanding seek pending. |
test.expectEvent(sourceBuffer, 'updateend', 'updateend after appending more data'); |
// FIXME: Confirm 'playing' fires here. See http://crbug.com/266592. |
- test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while finishing seek to truncatedDuration'); |
- test.expectEvent(mediaElement, 'seeked', 'seeked to truncatedDuration'); |
+ test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while finishing seek to reducedDuration'); |
+ test.expectEvent(mediaElement, 'seeked', 'seeked to reducedDuration'); |
// Allow seek to complete by appending more data beginning at the |
- // truncated duration timestamp. |
- sourceBuffer.timestampOffset = truncatedDuration; |
+ // reduced duration timestamp. |
+ sourceBuffer.timestampOffset = reducedDuration; |
sourceBuffer.appendBuffer(mediaData); |
test.waitForExpectedEvents(function() |
{ |
- assert_greater_than_equal(mediaElement.currentTime, truncatedDuration, |
- 'Playback time has reached truncatedDuration'); |
- assert_approx_equals(mediaElement.duration, truncatedDuration + segmentInfo.duration, 0.05, |
+ assert_greater_than_equal(mediaElement.currentTime, reducedDuration, |
+ 'Playback time has reached reducedDuration'); |
+ assert_approx_equals(mediaElement.duration, reducedDuration + segmentInfo.duration, 0.05, |
'mediaElement duration increased by new append'); |
assert_equals(mediaSource.duration, mediaElement.duration, |
'mediaSource duration increased by new append'); |
- assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to truncatedDuration'); |
+ assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to reducedDuration'); |
test.done(); |
}); |
- }, 'Test appendBuffer completes previous seek to truncated duration'); |
+ }, 'Test appendBuffer completes previous seek to reduced duration'); |
- mediasource_truncated_duration_seek_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, |
- mediaData, truncatedDuration) |
+ mediasource_duration_below_currentTime_seek_test(function(test, mediaElement, mediaSource, segmentInfo, |
+ sourceBuffer, mediaData, reducedDuration) |
{ |
- // The duration has been truncated at this point, and there is an |
+ // The duration has been reduced at this point, and there is an |
// outstanding seek pending. |
test.expectEvent(mediaSource, 'sourceended', 'endOfStream acknowledged'); |
// FIXME: Investigate if 'playing' should fire here. See http://crbug.com/266592. |
- test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while finishing seek to truncatedDuration'); |
- test.expectEvent(mediaElement, 'seeked', 'seeked to truncatedDuration'); |
+ test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while finishing seek to reducedDuration'); |
+ test.expectEvent(mediaElement, 'seeked', 'seeked to reducedDuration'); |
// Call endOfStream() to complete the pending seek. |
mediaSource.endOfStream(); |
test.waitForExpectedEvents(function() |
{ |
- assert_equals(mediaElement.currentTime, truncatedDuration, |
- 'Playback time has reached truncatedDuration'); |
- assert_equals(mediaElement.duration, truncatedDuration, |
- 'mediaElement truncatedDuration after seek to it'); |
- assert_equals(mediaSource.duration, truncatedDuration, |
- 'mediaSource truncatedDuration after seek to it'); |
- assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to truncatedDuration'); |
+ assert_equals(mediaElement.currentTime, reducedDuration, |
+ 'Playback time has reached reducedDuration'); |
+ assert_equals(mediaElement.duration, reducedDuration, |
+ 'mediaElement duration matches reducedDuration after seek to it'); |
+ assert_equals(mediaSource.duration, reducedDuration, |
+ 'mediaSource duration matches reducedDuration after seek to it'); |
+ assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to reducedDuration'); |
test.done(); |
}); |
- }, 'Test endOfStream completes previous seek to truncated duration'); |
+ }, 'Test endOfStream completes previous seek to reduced duration'); |
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) |
{ |
assert_greater_than(segmentInfo.duration, 2, 'Sufficient test media duration'); |
var fullDuration = segmentInfo.duration; |
- var newDuration = 0.5; |
+ var newDuration = fullDuration * 2; |
var durationchangeEventCounter = 0; |
var expectedDurationChangeEventCount = 1; |
var durationchangeEventHandler = test.step_func(function(event) |
{ |
- assert_equals(mediaElement.duration, newDuration, 'mediaElement newDuration'); |
- assert_equals(mediaSource.duration, newDuration, 'mediaSource newDuration'); |
+ assert_equals(mediaElement.duration, newDuration, 'mediaElement duration matches newDuration'); |
+ assert_equals(mediaSource.duration, newDuration, 'mediaSource duration matches newDuration'); |
durationchangeEventCounter++; |
}); |
mediaElement.play(); |
// Append all the segments |
- test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); |
+ test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer append completed'); |
test.expectEvent(mediaElement, 'playing', 'Playing triggered'); |
sourceBuffer.appendBuffer(mediaData); |
test.waitForExpectedEvents(function() |
{ |
- assert_equals(mediaElement.duration, fullDuration, 'mediaElement fullDuration'); |
- assert_equals(mediaSource.duration, fullDuration, 'mediaSource fullDuration'); |
- assert_less_than(mediaElement.currentTime, newDuration / 2, 'mediaElement currentTime'); |
+ assert_equals(mediaElement.duration, fullDuration, 'mediaElement duration matches fullDuration'); |
+ assert_equals(mediaSource.duration, fullDuration, 'mediaSource duration matches fullDuration'); |
+ assert_less_than(mediaElement.currentTime, newDuration / 2, 'mediaElement currentTime check'); |
// Media load also fires 'durationchange' event, so only start counting them now. |
mediaElement.addEventListener('durationchange', durationchangeEventHandler); |
- // Truncate duration. This should result in one 'durationchange' fired. |
+ // Increase duration. This should result in one 'durationchange' fired. |
mediaSource.duration = newDuration; |
+ assert_false(sourceBuffer.updating, "sourceBuffer.updating after duration set to newDuration"); |
- assert_true(sourceBuffer.updating, "sourceBuffer.updating"); |
- test.expectEvent(sourceBuffer, "updateend"); |
- }); |
- |
- test.waitForExpectedEvents(function() |
- { |
// Set duration again to make sure it does not trigger another 'durationchange' event. |
mediaSource.duration = newDuration; |
- assert_false(sourceBuffer.updating, "sourceBuffer.updating"); |
+ assert_false(sourceBuffer.updating, "sourceBuffer.updating after duration set again to newDuration"); |
// Mark endOfStream so that playback can reach 'ended' at the new duration. |
test.expectEvent(mediaSource, 'sourceended', 'endOfStream acknowledged'); |
@@ -190,22 +199,64 @@ |
// Allow for one more 'durationchange' event only in this case. |
var currentDuration = mediaSource.duration; |
if (currentDuration != newDuration) { |
- assert_true(currentDuration > 0 && currentDuration < newDuration, 'adjusted duration'); |
+ assert_true(currentDuration > 0 && currentDuration < newDuration, 'adjusted duration check'); |
newDuration = currentDuration; |
++expectedDurationChangeEventCount; |
} |
+ }); |
- // Allow media to play to end while counting 'durationchange' events. |
- test.expectEvent(mediaElement, 'ended', 'Playback ended'); |
- test.waitForExpectedEvents(function() |
+ test.waitForExpectedEvents(function() |
+ { |
+ // Allow any remaining queued durationchange to fire, while counting 'durationchange' them. |
+ test.step_timeout(test.step_func(function() |
{ |
mediaElement.removeEventListener('durationchange', durationchangeEventHandler); |
- assert_equals(durationchangeEventCounter, expectedDurationChangeEventCount, 'durationchanges'); |
+ assert_equals(durationchangeEventCounter, expectedDurationChangeEventCount, 'durationchange count check'); |
test.done(); |
- }); |
+ }), 0); |
}); |
}, 'Test setting same duration multiple times does not fire duplicate durationchange', {timeout: 2500}); |
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) |
+ { |
+ assert_greater_than(segmentInfo.duration, 2, 'Sufficient test media duration'); |
+ |
+ var fullDuration = segmentInfo.duration; |
+ |
+ // Append all the segments |
+ test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); |
+ sourceBuffer.appendBuffer(mediaData); |
+ |
+ test.waitForExpectedEvents(function() |
+ { |
+ assert_equals(mediaElement.duration, fullDuration, 'mediaElement duration matches fullDuration'); |
+ assert_equals(mediaSource.duration, fullDuration, 'mediaSource duration matches fullDuration'); |
+ |
+ // TODO(wolenetz): Fine-tune this test to use the buffered attribute's highest end time |
+ // instead of fullDuration once Chrome correctly reports buffered PTS, not DTS. |
+ // See https://crbug.com/398130. |
+ |
+ // Setting duration to same as current, or increasing it, should not trigger exception. |
+ mediaSource.duration = fullDuration; |
+ mediaSource.duration = fullDuration + 1; |
+ |
+ // Reducing duration to below the highest buffered PTS should trigger exception. |
+ assert_throws('InvalidStateError', |
+ function() { mediaSource.duration = fullDuration - 0.05; }, |
+ 'Duration reduction that truncates at least one whole coded frame throws an exception.'); |
+ |
+ assert_equals(mediaSource.duration, fullDuration + 1, 'mediaSource duration matches fullDuration+1'); |
+ |
+ // Reducing duration without truncating any buffered media should not trigger exception. |
+ mediaSource.duration = fullDuration; |
+ |
+ // Reducing duration by less then the minimum of the last test audio and video frame |
+ // durations should not trigger exception. |
+ mediaSource.duration = fullDuration - 0.001; |
+ test.done(); |
+ }); |
+ }, 'Test duration reduction below highest buffered presentation time is disallowed'); |
+ |
</script> |
</body> |
</html> |