Bug 1293613: Correct mediasource-duration.html r?gerald draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 10 Aug 2016 11:57:32 +1000
changeset 399465 92dd3d9c4b9ccdc8a47ac419bcd40fb74ab80aa6
parent 399464 cff35a95c21cf83e469fd6c35eb1dcd8ddc761c7
child 399466 4fb60cf715fc6dd81afdd972a97ef0b167e5ebb4
push id25845
push userbmo:jyavenard@mozilla.com
push dateThu, 11 Aug 2016 05:43:30 +0000
reviewersgerald
bugs1293613
milestone51.0a1
Bug 1293613: Correct mediasource-duration.html r?gerald - The WebM file manifest correctly indicates the duration as reported in the metadata. However, the last frame has an end time 0f 6.05s which would adjust the duration. As such it is incorrect to assume that after a full appendBuffer the duration will remain the same as set in the metadata. (source: https://w3c.github.io/media-source/index.html#sourcebuffer-coded-frame-processing "5. If the media segment contains data beyond the current duration, then run the duration change algorithm with new duration set to the maximum of the current duration and the group end timestamp") - When setting the duration, the actual final duration may be different to what was set as it will be aligned to the highest end time (source: https://w3c.github.io/media-source/index.html#duration-change-algorithm ("4.1 Update new duration to the highest end time reported by the buffered attribute across all SourceBuffer objects in sourceBuffers.") MozReview-Commit-ID: EpzSaSg8pWW
testing/web-platform/tests/media-source/mediasource-duration.html
--- a/testing/web-platform/tests/media-source/mediasource-duration.html
+++ b/testing/web-platform/tests/media-source/mediasource-duration.html
@@ -23,19 +23,16 @@
 
                   // Append all the segments
                   test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
                   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');
-
                       test.expectEvent(mediaElement, 'seeking', 'seeking to seekTo');
                       test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while seeking to seekTo');
                       test.expectEvent(mediaElement, 'seeked', 'seeked to seekTo');
                       mediaElement.currentTime = seekTo;
                       assert_true(mediaElement.seeking, 'mediaElement.seeking (to seekTo)');
                   });
 
                   test.waitForExpectedEvents(function()
@@ -50,19 +47,19 @@
                       assert_true(sourceBuffer.updating, 'sourceBuffer.updating');
                       test.expectEvent(sourceBuffer, 'updatestart', 'sourceBuffer');
                       test.expectEvent(sourceBuffer, 'update', 'sourceBuffer');
                       test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
                   });
 
                   test.waitForExpectedEvents(function()
                   {
+                      // remove will not remove partial frames. The truncated duration is as such the highest end time.
+                      truncatedDuration = sourceBuffer.buffered.end(sourceBuffer.buffered.length-1);
                       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');
                       test.expectEvent(mediaElement, 'seeking', 'Seeking to truncated duration');
 
                       assert_false(sourceBuffer.updating, 'sourceBuffer.updating');
 
                       mediaSource.duration = truncatedDuration;
 
                       assert_true(mediaElement.seeking, 'Seeking after setting truncatedDuration');
                   });
@@ -130,18 +127,20 @@
               test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while finishing seek to truncatedDuration');
               test.expectEvent(mediaElement, 'seeked', 'seeked to truncatedDuration');
 
               // Call endOfStream() to complete the pending seek.
               mediaSource.endOfStream();
 
               test.waitForExpectedEvents(function()
               {
-                  assert_equals(mediaElement.currentTime, truncatedDuration,
+                  assert_greater_than_equal(mediaElement.currentTime, truncatedDuration,
                                 'Playback time has reached truncatedDuration');
+                  // The mediaSource.readyState is "ended". Buffered ranges have been adjusted to the longest track.
+                  truncatedDuration = sourceBuffer.buffered.end(sourceBuffer.buffered.length-1);
                   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');
 
                   test.done();
               });
@@ -153,63 +152,54 @@
 
               var fullDuration = segmentInfo.duration;
               var newDuration = 0.5;
 
               var expectedDurationChangeEventCount = 1;
               var durationchangeEventCounter = 0;
               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, mediaSource.duration, 'mediaElement newDuration');
+                  // Final duration may be greater than originally set as per MSE's 2.4.6 Duration change
+                  // Adjust newDuration accordingly.
+                  assert_less_than_equal(newDuration, mediaSource.duration, 'mediaSource newDuration');
                   durationchangeEventCounter++;
               });
 
               mediaElement.play();
 
               // Append all the segments
               test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
               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_false(sourceBuffer.updating, "updating");
 
                   // Truncate duration. This should result in one 'durationchange' fired.
                   sourceBuffer.remove(newDuration, Infinity);
 
                   assert_true(sourceBuffer.updating, "updating");
                   test.expectEvent(sourceBuffer, 'updatestart', 'sourceBuffer');
                   test.expectEvent(sourceBuffer, 'update', 'sourceBuffer');
                   test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
               });
 
               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');
-
                   // Media load also fires 'durationchange' event, so only start counting them now.
                   mediaElement.addEventListener('durationchange', durationchangeEventHandler);
 
                   assert_false(sourceBuffer.updating, "updating");
 
                   // Truncate duration. This should result in one 'durationchange' fired.
                   mediaSource.duration = newDuration;
-              });
-
-              test.waitForExpectedEvents(function()
-              {
-                  assert_false(sourceBuffer.updating, "updating");
 
                   // Final duration may be greater than originally set as per MSE's 2.4.6 Duration change
                   // Adjust newDuration accordingly.
                   assert_true(newDuration <= mediaSource.duration, 'adjusted duration');
                   newDuration = mediaSource.duration;
 
                   // Set duration again to make sure it does not trigger another 'durationchange' event.
                   mediaSource.duration = newDuration;