Bug 1232043 - Update/create mochitests for recorder resolution change. r?pehrsons draft
authorAlex Chronopoulos <achronop@gmail.com>
Tue, 04 Apr 2017 17:57:27 +0300
changeset 555631 3550866b428bcc8b1904606a768016e4d5a89801
parent 555630 288d18e765abbc11c0e93b59610af01070991a1b
child 622656 b9ea444822a78263be07e8cff5df121472b25350
push id52291
push userachronop@gmail.com
push dateTue, 04 Apr 2017 16:02:17 +0000
reviewerspehrsons
bugs1232043
milestone55.0a1
Bug 1232043 - Update/create mochitests for recorder resolution change. r?pehrsons * * * [mq]: mochitest-errors MozReview-Commit-ID: 7hI91WYWPkT * * * [mq]: second-patch MozReview-Commit-ID: Wd9z0milhj * * * [mq]: tmp MozReview-Commit-ID: 89fVn5vg7My
dom/media/test/mochitest.ini
dom/media/test/test_mediarecorder_record_changing_video_resolution.html
dom/media/test/test_mediarecorder_record_downsize_resolution.html
dom/media/test/test_mediarecorder_record_upsize_resolution.html
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -816,16 +816,22 @@ tags=msg
 skip-if = android_version == '17' # android(bug 1232305)
 tags=msg
 [test_mediarecorder_record_canvas_captureStream.html]
 skip-if = toolkit == 'android' # android(bug 1232305)
 tags=msg
 [test_mediarecorder_record_changing_video_resolution.html]
 skip-if = android_version == '17' # android(bug 1232305)
 tags=msg
+[test_mediarecorder_record_upsize_resolution.html]
+skip-if = android_version == '17' # android(bug 1232305)
+tags=msg
+[test_mediarecorder_record_downsize_resolution.html]
+skip-if = android_version == '17' # android(bug 1232305)
+tags=msg
 [test_mediarecorder_record_gum_video_timeslice.html]
 skip-if = android_version == '17' # bug 1297298, android(bug 1232305)
 tags=msg
 [test_mediarecorder_record_immediate_stop.html]
 skip-if = android_version == '17' # android(bug 1232305)
 tags=msg capturestream
 [test_mediarecorder_record_no_timeslice.html]
 skip-if = android_version == '17' # bug 1306513, android(bug 1232305)
--- a/dom/media/test/test_mediarecorder_record_changing_video_resolution.html
+++ b/dom/media/test/test_mediarecorder_record_changing_video_resolution.html
@@ -10,60 +10,152 @@
 <div id="content">
 </div>
 <script class="testbody" type="text/javascript">
 
 function startTest() {
   var content = document.getElementById("content");
 
   var canvas = document.createElement("canvas");
-  canvas.width = canvas.height = 100;
+  const resolution_change = [
+    {width: 100, height: 100, color: "red"},
+    {width: 150, height: 150, color: "blue"},
+    {width: 100, height: 100, color: "red"},
+  ];
+  canvas.width = resolution_change[0].width;
+  canvas.height = resolution_change[0].height;
 
   var ctx = canvas.getContext("2d");
-  ctx.fillStyle = "red";
+  ctx.fillStyle = resolution_change[0].color;
   ctx.fillRect(0, 0, canvas.width, canvas.height);
 
-  var stream = canvas.captureStream(0);
+  // The recorded stream coming from canvas.
+  var stream = canvas.captureStream();
 
-  var numErrorRaised = 0;
+  // Check values for events
   var numDataAvailabledRaised = 0;
+  var numResizeRaised = 0;
+  var seekFrames = 0;
+  // Recorded data that will be playback.
+  var blob;
 
-  mediaRecorder = new MediaRecorder(stream);
+  // Media recorder for VP8 and canvas stream.
+  var mediaRecorder = new MediaRecorder(stream);
   is(mediaRecorder.stream, stream,
      "Media recorder stream = canvas stream at the start of recording");
 
-  mediaRecorder.onwarning = () => ok(false, "onwarning unexpectedly fired");
-
+  // Not expected events.
+  mediaRecorder.onwarning = () => ok(false, "MediaRecorder: onwarning unexpectedly fired");
   mediaRecorder.onerror = err => {
-    info("Got 'error' event, " + err.name + " (" + err.message + ")");
-    ++numErrorRaised;
+    ok(false, "MediaRecorder: onerror unexpectedly fired. Code " + err.name);
+    SimpleTest.finish();
   };
 
+  // When recorder is stopped get recorded data.
   mediaRecorder.ondataavailable = ev => {
     info("Got 'dataavailable' event");
     ++numDataAvailabledRaised;
+    is(blob, undefined, "Should only get one dataavailable event");
+    // Save recorded data for playback
+    blob = ev.data;
   };
 
   mediaRecorder.onstart = () => {
-    canvas.width = canvas.height = canvas.width * 1.1;
-    ctx.fillStyle = "blue";
-    ctx.fillRect(0, 0, canvas.width, canvas.height);
-    stream.requestFrame();
+    info('onstart fired successfully');
   };
 
   mediaRecorder.onstop = () => {
     info("Got 'stop' event");
-    is(numErrorRaised, 1, "Should have gotten 1 error event");
     is(numDataAvailabledRaised, 1, "Should have gotten 1 dataavailable event");
-    SimpleTest.finish();
+    // Playback stream and verify resolution changes.
+    ok(blob, "Should have gotten a data blob");
+
+    var video = document.createElement("video");
+    video.id = "recorded-video";
+    video.src = URL.createObjectURL(blob);
+    video.preload = "auto";
+
+    video.onerror = err => {
+      ok(false, "Should be able to play the recording. Got error. code=" + video.error.code);
+      SimpleTest.finish();
+    };
+
+    // Check that resize is correct for playback stream.
+    video.onresize = function() {
+      if (numResizeRaised < resolution_change.length) {
+        is(video.videoWidth, resolution_change[numResizeRaised].width, "onresize width should be as expected");
+        is(video.videoHeight, resolution_change[numResizeRaised].height, "onresize height should be as expected");
+      } else {
+        ok(false, "Got more resize events than expected");
+      }
+      ++numResizeRaised;
+    };
+
+    video.onended = () => {
+      video.finished = true;
+      is(numResizeRaised, resolution_change.length, "Expected number of resize events");
+      is(seekFrames, resolution_change.length, "Expected number of frames");
+      SimpleTest.finish();
+    };
+
+    document.getElementById("content").appendChild(video);
+
+    video.onloadedmetadata = () => {
+      callSeekToNextFrame();
+    };
+
+    function callSeekToNextFrame() {
+      video.seekToNextFrame().then(
+        () => {
+          if (seekFrames < resolution_change.length) {
+            ++seekFrames;
+            callSeekToNextFrame();
+          }
+        },
+        () => {
+          ok(video.finished, "seekToNextFrame() failed.");
+        });
+    }
   };
 
+  // Start here by stream recorder.
   mediaRecorder.start();
   is(mediaRecorder.state, "recording", "Media recorder should be recording");
+  requestAnimationFrame(draw);
+
+  // Change resolution in every frames
+  // Stop recoredr on last frame
+  var countFrames=0;
+  var previous_time = performance.now();
+  function draw(timestamp) {
+    if (timestamp - previous_time < 100) {
+      requestAnimationFrame(draw);
+      return;
+    }
+    previous_time = timestamp;
+
+    if (countFrames < resolution_change.length) {
+      canvas.width = resolution_change[countFrames].width;
+      canvas.height = resolution_change[countFrames].height;
+      ctx.fillStyle = resolution_change[countFrames].color;
+      // Resize and draw canvas
+      ctx.fillRect(0, 0, canvas.width, canvas.height);
+      // Register draw to be called on next rendering
+      requestAnimationFrame(draw);
+      countFrames++;
+    } else {
+      mediaRecorder.stop();
+    }
+  }
 }
 
 SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv(
+  {
+    "set": [["media.seekToNextFrame.enabled", true ]],
+    "set": [["media.video-queue.send-to-compositor-size", 1]]
+  });
 startTest();
 
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_mediarecorder_record_downsize_resolution.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test MediaRecorder Recording canvas dynamically changes to greater resolution</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="/tests/dom/canvas/test/captureStream_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<div id="content">
+</div>
+<script class="testbody" type="text/javascript">
+
+function startTest() {
+  var canvas = document.createElement("canvas");
+  var canvas_size = 100;
+  var new_canvas_size = 50;
+  canvas.width = canvas.height = canvas_size;
+
+  var helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size);
+  helper.drawColor(canvas, helper.red);
+
+  // The recorded stream coming from canvas.
+  var stream = canvas.captureStream();
+
+  // Check values for events
+  var numDataAvailabledRaised = 0;
+  var numResizeRaised = 0;
+  // Recorded data that will be playback.
+  var blob;
+
+  // Media recorder for VP8 and canvas stream.
+  var mediaRecorder = new MediaRecorder(stream);
+  is(mediaRecorder.stream, stream,
+     "Media recorder stream = canvas stream at the beginning of recording");
+
+  // Not expected events.
+  mediaRecorder.onwarning = () => ok(false, "MediaRecorder: onwarning unexpectedly fired");
+  mediaRecorder.onerror = err => {
+    ok(false, "MediaRecorder: onerror unexpectedly fired. Code " + err.name);
+    SimpleTest.finish();
+  }
+
+  // When recorder is stopped get recorded data.
+  mediaRecorder.ondataavailable = ev => {
+    info("Got 'dataavailable' event");
+    ++numDataAvailabledRaised;
+    is(blob, undefined, "On dataavailable event blob is undefined");
+    // Save recorded data for playback
+    blob = ev.data;
+  };
+
+  mediaRecorder.onstart = () => {
+    info('onstart fired successfully');
+  };
+
+  mediaRecorder.onstop = () => {
+    info("Got 'stop' event");
+    is(numDataAvailabledRaised, 1, "Expected 1 dataavailable event");
+
+    // Playback stream and verify resolution changes.
+    ok(blob, "Should have gotten a data blob");
+    var video = document.createElement("video");
+    video.id = "recorded-video";
+    video.src = URL.createObjectURL(blob);
+    video.onerror = err => {
+      ok(false, "Should be able to play the recording. Got error. code=" + video.error.code);
+      SimpleTest.finish();
+    };
+
+    // Check here that resize is correct in the playback stream.
+    video.onresize = function() {
+      ++numResizeRaised;
+      if (numResizeRaised == 1) {
+        is(this.videoWidth, canvas_size, "1st resize event original width");
+        is(this.videoHeight, canvas_size, "1st resize event original height ");
+      } else if (numResizeRaised == 2) {
+        is(this.videoWidth, new_canvas_size, "2nd resize event new width");
+        is(this.videoHeight, new_canvas_size, "2nd resize event new height");
+      } else {
+        ok(false, "Only 2 numResizeRaised events are expected");
+      }
+    };
+
+    video.onended = () => {
+      is(numResizeRaised, 2, "Expected 2 resize event");
+    };
+    document.getElementById("content").appendChild(video);
+    video.play();
+
+    // Check last color
+    helper.waitForPixelColor(video, helper.red, 128, "Should become red")
+      .then(() => {
+        video.onresize = {};
+        video.onended = {};
+        SimpleTest.finish();
+      });
+  };
+
+  // Start here by stream recorder.
+  mediaRecorder.start();
+  is(mediaRecorder.state, "recording", "Media recorder started");
+  requestAnimationFrame(draw);
+
+  // Change resolution every 100ms
+  var countFrames=0;
+  var previous_time = performance.now();
+  function draw(timestamp) {
+    if (timestamp - previous_time < 100) {
+      requestAnimationFrame(draw);
+      return;
+    }
+    previous_time = timestamp;
+
+    var size = 0;
+    var color = "";
+    if (countFrames < 1) {
+      // Initial size
+      size = canvas_size;
+      color = helper.blue;
+    } else if (countFrames < 2) {
+      // upsize
+      size = new_canvas_size;
+      color = helper.red;
+    } else {
+      // Stop recoredr on last frame
+      mediaRecorder.stop();
+      return;
+    }
+    // Resize and draw canvas
+    canvas.width = canvas.height = size;
+    helper.drawColor(canvas, color);
+    // Register next draw on every call
+    requestAnimationFrame(draw);
+    countFrames++;
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+startTest();
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_mediarecorder_record_upsize_resolution.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test MediaRecorder Recording canvas dynamically changes to greater resolution</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="/tests/dom/canvas/test/captureStream_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<div id="content">
+</div>
+<script class="testbody" type="text/javascript">
+
+function startTest() {
+  var canvas = document.createElement("canvas");
+  var canvas_size = 100;
+  var new_canvas_size = 150;
+  canvas.width = canvas.height = canvas_size;
+
+  var helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size);
+  helper.drawColor(canvas, helper.red);
+
+  // The recorded stream coming from canvas.
+  var stream = canvas.captureStream();
+
+  // Check values for events
+  var numDataAvailabledRaised = 0;
+  var numResizeRaised = 0;
+  // Recorded data that will be playback.
+  var blob;
+
+  // Media recorder for VP8 and canvas stream.
+  var mediaRecorder = new MediaRecorder(stream);
+  is(mediaRecorder.stream, stream,
+     "Media recorder stream = canvas stream at the beginning of recording");
+
+  // Not expected events.
+  mediaRecorder.onwarning = () => ok(false, "MediaRecorder: onwarning unexpectedly fired");
+  mediaRecorder.onerror = err => {
+    ok(false, "MediaRecorder: onerror unexpectedly fired. Code " + err.name);
+    SimpleTest.finish();
+  }
+
+  // When recorder is stopped get recorded data.
+  mediaRecorder.ondataavailable = ev => {
+    info("Got 'dataavailable' event");
+    ++numDataAvailabledRaised;
+    is(blob, undefined, "On dataavailable event blob is undefined");
+    // Save recorded data for playback
+    blob = ev.data;
+  };
+
+  mediaRecorder.onstart = () => {
+    info('onstart fired successfully');
+  };
+
+  mediaRecorder.onstop = () => {
+    info("Got 'stop' event");
+    is(numDataAvailabledRaised, 1, "Expected 1 dataavailable event");
+
+    // Playback stream and verify resolution changes.
+    ok(blob, "Should have gotten a data blob");
+    var video = document.createElement("video");
+    video.id = "recorded-video";
+    video.src = URL.createObjectURL(blob);
+    video.onerror = err => {
+      ok(false, "Should be able to play the recording. Got error. code=" + video.error.code);
+      SimpleTest.finish();
+    };
+
+    // Check here that resize is correct in the playback stream.
+    video.onresize = function() {
+      ++numResizeRaised;
+      if (numResizeRaised == 1) {
+        is(this.videoWidth, canvas_size, "1st resize event original width");
+        is(this.videoHeight, canvas_size, "1st resize event original height ");
+      } else if (numResizeRaised == 2) {
+        is(this.videoWidth, new_canvas_size, "2nd resize event new width");
+        is(this.videoHeight, new_canvas_size, "2nd resize event new height");
+      } else {
+        ok(false, "Only 2 numResizeRaised events are expected");
+      }
+    };
+
+    video.onended = () => {
+      is(numResizeRaised, 2, "Expected 2 resize event");
+    };
+    document.getElementById("content").appendChild(video);
+    video.play();
+
+    // Check last color
+    helper.waitForPixelColor(video, helper.red, 128, "Should become red")
+      .then(() => {
+        video.onresize = {};
+        video.onended = {};
+        SimpleTest.finish();
+      });
+  };
+
+  // Start here by stream recorder.
+  mediaRecorder.start();
+  is(mediaRecorder.state, "recording", "Media recorder started");
+  requestAnimationFrame(draw);
+
+  // Change resolution every 100 ms
+  var countFrames=0;
+  var previous_time = performance.now();
+  function draw(timestamp) {
+    if (timestamp - previous_time < 100) {
+      requestAnimationFrame(draw);
+      return;
+    }
+    previous_time = timestamp;
+
+    var size = 0;
+    var color = "";
+    if (countFrames < 1) {
+      // Initial size
+      size = canvas_size;
+      color = helper.blue;
+    } else if (countFrames < 2) {
+      // upsize
+      size = new_canvas_size;
+      color = helper.red;
+    }else {
+      // Stop recoredr on last frame
+      mediaRecorder.stop();
+      return;
+    }
+    // Resize and draw canvas
+    canvas.width = canvas.height = size;
+    helper.drawColor(canvas, color);
+    // Register next draw on every call
+    requestAnimationFrame(draw);
+    countFrames++;
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+startTest();
+
+</script>
+</pre>
+</body>
+</html>