summaryrefslogtreecommitdiffstats
path: root/dom/media/test/test_mediarecorder_record_changing_video_resolution.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/test/test_mediarecorder_record_changing_video_resolution.html')
-rw-r--r--dom/media/test/test_mediarecorder_record_changing_video_resolution.html174
1 files changed, 174 insertions, 0 deletions
diff --git a/dom/media/test/test_mediarecorder_record_changing_video_resolution.html b/dom/media/test/test_mediarecorder_record_changing_video_resolution.html
new file mode 100644
index 0000000000..d6354ee5a1
--- /dev/null
+++ b/dom/media/test/test_mediarecorder_record_changing_video_resolution.html
@@ -0,0 +1,174 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test MediaRecorder Recording canvas stream that dynamically changes resolution</title>
+ <script src="/tests/SimpleTest/SimpleTest.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() {
+ let canvas = document.createElement("canvas");
+ 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;
+
+ let ctx = canvas.getContext("2d");
+ ctx.fillStyle = resolution_change[0].color;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+ // The recorded stream coming from canvas.
+ let stream = canvas.captureStream();
+
+ // Check values for events
+ let numDataAvailabledRaised = 0;
+ let numResizeRaised = 0;
+ // Recorded data that will be playback.
+ let blob;
+
+ // Media recorder for VP8 and canvas stream.
+ let mediaRecorder = new MediaRecorder(stream);
+ is(mediaRecorder.stream, stream,
+ "Media recorder stream = canvas stream at the start 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, "Should only get one dataavailable event");
+ // Save recorded data for playback
+ blob = ev.data;
+ };
+
+ mediaRecorder.onstart = () => {
+ info('onstart fired successfully');
+ };
+
+ mediaRecorder.onstop = () => {
+ info("Got 'stop' event");
+ is(numDataAvailabledRaised, 1, "Should have gotten 1 dataavailable event");
+ // Playback stream and verify resolution changes.
+ ok(blob, "Should have gotten a data blob");
+
+ let video = document.createElement("video");
+ video.id = "recorded-video";
+ video.src = URL.createObjectURL(blob);
+ video.preload = "metadata";
+
+ video.onerror = err => {
+ ok(false, "Should be able to play the recording. Got error. code=" + video.error.code);
+ SimpleTest.finish();
+ };
+
+ // Check that the encoded frames have the correct sizes.
+ 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.onloadedmetadata = function() {
+ info("loadedmetadata");
+ seekThroughFrames();
+ };
+
+ video.onended = function() {
+ is(numResizeRaised, resolution_change.length, "Expected number of resize events");
+ SimpleTest.finish();
+ // This shouldn't be needed, however video.ended may not be set after
+ // seeking to the final frame. This can result in seekToNextFrame being
+ // called again by seekThroughFrames and onended being invoked again,
+ // resulting in multiple finish() calls.
+ // FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1386489
+ video.onended = null;
+ };
+
+ document.getElementById("content").appendChild(video);
+
+ function seekThroughFrames() {
+ info("Seeking to next frame");
+ video.seekToNextFrame()
+ .then(() => {
+ info("Seeking to next frame finished. width=" + video.videoWidth
+ + ", height=" + video.videoHeight);
+
+ if (video.ended) {
+ return;
+ }
+
+ // After seeking finished we queue the next seek task on the event
+ // loop so it gets in the same queue as the "resize" events.
+ setTimeout(seekThroughFrames, 0);
+ })
+ .catch(error => {
+ ok(false, "seekToNextFrame rejected: " + error);
+ });
+ }
+ };
+
+ // Start here by stream recorder.
+ mediaRecorder.start();
+ is(mediaRecorder.state, "recording", "Media recorder should be recording");
+ requestAnimationFrame(draw);
+
+ // Change resolution in every frame
+ // Stop recorder on last frame
+ let countFrames = 0;
+ let previous_time = performance.now();
+ function draw(timestamp) {
+ if (timestamp - previous_time < 100) {
+ requestAnimationFrame(draw);
+ return;
+ }
+ previous_time = timestamp;
+
+ if (countFrames == resolution_change.length) {
+ mediaRecorder.stop();
+ return;
+ }
+
+ 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++;
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv(
+ {
+ "set": [
+ ["media.seekToNextFrame.enabled", true ],
+ ["media.video-queue.send-to-compositor-size", 1]
+ ]
+ }, startTest);
+
+</script>
+</pre>
+</body>
+</html>