Skip to content

Commit

Permalink
Add tests for oversize canvas capture
Browse files Browse the repository at this point in the history
Bug: 1178292
Change-Id: I1ed80b0d260466472dd62608975c1d8ecccc8fa0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2748240
Auto-Submit: Ben Wagner aka dogben <benjaminwagner@google.com>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#908915}
  • Loading branch information
dogben authored and Chromium LUCI CQ committed Aug 5, 2021
1 parent 5f56891 commit 7511de9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
2 changes: 2 additions & 0 deletions third_party/blink/web_tests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,8 @@ crbug.com/1170052 external/wpt/mediacapture-streams/MediaStreamTrack-MediaElemen
crbug.com/1174937 virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-clone.https.html [ Crash ]
crbug.com/1174937 external/wpt/mediacapture-streams/MediaStream-clone.https.html [ Crash ]

crbug.com/1178292 fast/mediacapturefromelement/CanvasCaptureMediaStream-canvas-initially-too-large.html [ Crash ]

crbug.com/766135 fast/dom/Window/redirect-with-timer.html [ Pass Timeout ]

# Ref tests that needs investigation.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This is a testharness.js-based test.
FAIL captureStream() throws Exception with invalid frame size assert_throws_dom: video frame width too large function "function() { canvas.captureStream() }" did not throw
Harness: the test ran to completion.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<title>captureStream() throws Exception with invalid frame size</title>
<link rel="help" href="https://crbug.com/1178292">
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script>
'use strict';

test(function() {
var canvas = document.createElement('canvas');
canvas.width = 32768;
canvas.height = 1;
assert_throws_dom("NotSupportedError", function() { canvas.captureStream() },
"video frame width too large");
canvas.width = 1;
canvas.height = 32768;
assert_throws_dom("NotSupportedError", function() { canvas.captureStream() },
"video frame height too large");
canvas.width = 16385;
canvas.height = 16384;
assert_throws_dom("NotSupportedError", function() { canvas.captureStream() },
"video frame area too large");
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!DOCTYPE html>
<title>setting too-large width after captureStream() does not produce invalid frames</title>
<link rel="help" href="https://crbug.com/1178292">
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script>
'use strict';

const maxSize = 32767;

// Setting the canvas width or height too large when there is a canvas capture
// stream does not cause the stream to have frames exceeding Chrome's internal
// limits.
promise_test(async t => {
const canvas = document.createElement('canvas');
canvas.width = 160;
canvas.height = 160;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
const stream = canvas.captureStream(0);
const track = stream.getVideoTracks()[0];

const intervalId = setInterval(() => {
ctx.fillRect(0, 0, canvas.width, canvas.height);
track.requestFrame();
}, 50);
t.add_cleanup(() => { clearInterval(intervalId); });

const video = document.createElement('video');
video.srcObject = stream;
t.add_cleanup(() => { video.src = ''; });
let frameCount = 0;
let callbackId;
const newFrame = (ts, metadata) => {
assert_less_than_equal(metadata.width, maxSize);
assert_less_than_equal(metadata.height, maxSize);
frameCount++;
callbackId = video.requestVideoFrameCallback(newFrame);
};
callbackId = video.requestVideoFrameCallback(newFrame);
t.add_cleanup(() => { video.cancelVideoFrameCallback(callbackId); });
await video.play();

await t.step_wait(() => {
return frameCount > 0;
}, 'await first frame');

// Now generate frames that are too large.
canvas.width = maxSize + 1;
// The video element should stop getting frames, but there may still be frames in the pipeline.
// Wait for them to flush out.
await t.step_wait(() => {
const flushed = frameCount === 0;
frameCount = 0;
return flushed;
}, 'await old frames to be flushed out', 1000, 200);

// Should not see any new frames when canvas is too large.
// Since we're asserting that something *doesn't* happen, we need to use step_timeout.
await new Promise(resolve => t.step_timeout(resolve, 5000));
assert_equals(frameCount, 0, 'frames seen when canvas is too large');

// Should resume frames after canvas size becomes valid again.
frameCount = 0;
canvas.width = 160;
await t.step_wait(() => frameCount > 0, 'await resume of frames');
});
</script>

0 comments on commit 7511de9

Please sign in to comment.