Bug 1360452 - use SeekToNextFrame() to guarantee the last frame is shown on the reference video; r?jwwang draft
authorKaku Kuo <kaku@mozilla.com>
Tue, 16 May 2017 12:09:10 +0800
changeset 596434 92a11eb0515855014ff95af22c311239bc2cbe1e
parent 596264 f1be9384d272a0ab8084feedf7c157e76e78e888
child 633956 ca4f704bb00739682b979f518849b26155cf0870
push id64634
push userbmo:kaku@mozilla.com
push dateMon, 19 Jun 2017 08:30:39 +0000
reviewersjwwang
bugs1360452
milestone56.0a1
Bug 1360452 - use SeekToNextFrame() to guarantee the last frame is shown on the reference video; r?jwwang MozReview-Commit-ID: IyhVYq4atML
dom/media/test/mochitest.ini
dom/media/test/test_background_video_resume_after_end_show_last_frame.html
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -1154,17 +1154,17 @@ skip-if = toolkit == 'android' # android
 tags = suspend
 [test_background_video_no_suspend_short_vid.html]
 skip-if = toolkit == 'android' # android(bug 1304480)
 tags = suspend
 [test_background_video_no_suspend_not_in_tree.html]
 skip-if = toolkit == 'android' # bug 1346705
 tags = suspend
 [test_background_video_resume_after_end_show_last_frame.html]
-skip-if = toolkit == 'android' || (os == "win" && debug) # bug 1346705, win bug 1360452
+skip-if = toolkit == 'android' # bug 1346705
 tags = suspend
 [test_background_video_suspend.html]
 skip-if = toolkit == 'android' # android(bug 1304480)
 tags = suspend
 [test_background_video_suspend_ends.html]
 skip-if = toolkit == 'android' # bug 1295884, android(bug 1304480, bug 1232305)
 tags = suspend
 [test_background_video_tainted_by_capturestream.html]
--- a/dom/media/test/test_background_video_resume_after_end_show_last_frame.html
+++ b/dom/media/test/test_background_video_resume_after_end_show_last_frame.html
@@ -54,38 +54,92 @@ function testSameContent(video1, video2)
       ok(false, `${video1.token} video1 and video2 have different content.`);
       return;
     }
   }
 
   ok(true, `${video1.token} video1 and video2 have identical content.`);
 }
 
+function waitUntilSeekToLastFrame(video) {
+  Log(video.token, "Waiting for seeking to the last frame");
+  function callSeekToNextFrame() {
+    video.seekToNextFrame().then(
+      () => {
+        if (!video.seenEnded) {
+          callSeekToNextFrame();
+        }
+      },
+      () => {
+        // When seek reaches the end, the promise is resolved before 'ended'
+        // is fired. The resolver calls callSeekToNextFrame() to schedule
+        // another seek and then the 'ended' handler calls finish() to shut
+        // down the MediaDecoder which will reject the seek promise. So we don't
+        // raise an error in this case.
+        ok(video.seenEnded, "seekToNextFrame() failed.");
+      }
+    );
+  }
+
+  return new Promise(function(resolve, reject) {
+    video.seenEnded = false;
+    video.addEventListener("ended", () => {
+      video.seenEnded = true;
+      resolve();
+    }, true);
+    callSeekToNextFrame(video);
+  });
+}
+
+function appendVideoToDocWithoutLoad(token, width, height) {
+  // Default size of (160, 120) is used by other media tests.
+  if (width === undefined) { width = 160; }
+  if (height === undefined) { height = 3*width/4; }
+
+  let v = document.createElement('video');
+  v.token = token;
+  document.body.appendChild(v);
+  v.width = width;
+  v.height = height;
+  return v;
+}
+
+function loadAndWaitUntilLoadedmetadata(video, url, preloadType = "metadata") {
+  return new Promise((resolve, reject) => {
+    video.preload = preloadType;
+    video.addEventListener("loadedmetadata", () => { resolve(); }, true);
+    video.src = url;
+  });
+}
+
 startTest({
   desc: "Test resume an ended video shows the last frame.",
   prefs: [
     [ "media.test.video-suspend", true ],
     [ "media.suspend-bkgnd-video.enabled", true ],
-    [ "media.suspend-bkgnd-video.delay-ms", 100 ]
+    [ "media.suspend-bkgnd-video.delay-ms", 100 ],
+    [ "media.dormant-on-pause-timeout-ms", -1],
+    [ "media.decoder.skip-to-next-key-frame.enabled", false]
   ],
   tests: gDecodeSuspendTests,
+
   runTest: (test, token) => {
     let v = appendVideoToDoc(test.name, token);
-    let vReference = appendVideoToDoc(test.name, token);
+    let vReference = appendVideoToDocWithoutLoad(token+"-ref");
     manager.started(token);
 
     /*
      * This test checks that, after a video element had finished its playback,
      * resuming video decoder should seek to the last frame.
      * This issue was found in bug 1358057.
      */
-    Promise.all([waitUntilPlaying(v), waitUntilPlaying(vReference)])
+    Promise.all([waitUntilPlaying(v), loadAndWaitUntilLoadedmetadata(vReference, test.name, "auto")])
       .then(() => testVideoSuspendsWhenHidden(v))
       .then(() => {
-        return Promise.all([waitUntilEnded(v), waitUntilEnded(vReference)]);
+        return Promise.all([waitUntilEnded(v), waitUntilSeekToLastFrame(vReference)]);
       })
       .then(() => testVideoOnlySeekCompletedWhenShown(v))
       .then(() => {
         testSameContent(v, vReference);
         removeNodeAndSource(v);
         removeNodeAndSource(vReference);
         manager.finished(token);
       });