| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
| <html> |
| <head> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script src ="routines.js"></script> |
| <style type="text/css"> |
| video { width: 40px; } |
| canvas { width: 40px; } |
| </style> |
| </head> |
| <body> |
| <div id="debuge"></div> |
| <script> |
| "use strict"; |
| |
| function with2DContext(subcase, canvas, patternNumber) |
| { |
| drawCanvasTestPattern2D(canvas, patternNumber); |
| } |
| |
| function withWebGL(subcase, canvas, patternNumber) |
| { |
| drawCanvasTestPatternWebGL(canvas, patternNumber); |
| } |
| |
| async function createLocalPeerConnectionStream(stream) |
| { |
| return new Promise((resolve, reject) => { |
| createConnections((firstConnection) => { |
| firstConnection.addTrack(stream.getVideoTracks()[0], stream); |
| }, (secondConnection) => { |
| secondConnection.ontrack = (trackEvent) => { |
| resolve(trackEvent.streams[0]); |
| }; |
| }); |
| }); |
| } |
| |
| function waitForVideoFrame(video) |
| { |
| return new Promise((resolve) => { |
| video.requestVideoFrameCallback((now, metadata) => { |
| resolve(now, metadata); |
| }); |
| }); |
| } |
| |
| const width = 500; |
| const height = 500; |
| |
| async function waitForVideoFrameSize(video, width, height, counter) |
| { |
| if (!counter) |
| counter = 0; |
| else if (counter > 100) |
| return Promise.reject("waitForVideoFrameSize timed out"); |
| |
| const result = await new Promise((resolve, reject) => { |
| video.requestVideoFrameCallback((now, metadata) => { |
| resolve(metadata.width === width && metadata.height === height); |
| }); |
| setTimeout(() => reject("video.requestVideoFrameCallback timed out"), 5000); |
| }); |
| if (result) |
| return; |
| |
| return waitForVideoFrameSize(video, width, height, ++counter); |
| } |
| |
| async function drawAndValidate(subcase, canvas, video, counter, stepName) |
| { |
| // First change canvas width and wait for width change to clear previous frames. |
| canvas.width = canvas.width + 500; |
| canvas.height = canvas.height + 500; |
| |
| let counter1 = counter; |
| let id = setInterval(() => { subcase.draw(subcase, canvas, counter1++)}, 100); |
| await waitForVideoFrameSize(video, canvas.width, canvas.height); |
| clearInterval(id); |
| |
| // Get back canvas size to normal and wait for width change to get test frames. |
| canvas.width = canvas.width - 500; |
| canvas.height = canvas.height - 500; |
| id = setInterval(() => { subcase.draw(subcase, canvas, counter)}, 100); |
| subcase.draw(subcase, canvas, counter); |
| await waitForVideoFrameSize(video, canvas.width, canvas.height); |
| clearInterval(id); |
| |
| assertImageSourceContainsCanvasTestPattern(video, counter, stepName); |
| } |
| |
| async function testCanvasToPeerConnection(t, subcase) |
| { |
| const canvas = document.createElement("canvas"); |
| canvas.width = width; |
| canvas.height = height; |
| debuge.appendChild(canvas); |
| t.add_cleanup(async () => debuge.removeChild(canvas)); |
| const localStream = canvas.captureStream(); |
| const remoteStream = await createLocalPeerConnectionStream(localStream); |
| t.add_cleanup(async () => closeConnections()); |
| |
| const video = document.createElement("video"); |
| video.autoplay = true; |
| video.controls = false; |
| debuge.appendChild(video); |
| t.add_cleanup(async () => debuge.removeChild(video)); |
| video.srcObject = remoteStream; |
| |
| for (let i = 0; i < 5; ++i) |
| await drawAndValidate(subcase, canvas, video, 1, `base case: ${i}`); |
| |
| for (let i = 0; i < 5; ++i) |
| await drawAndValidate(subcase, canvas, video, i, `iteration: ${i}`); |
| } |
| |
| const subcases = []; |
| // FIXME: This should be filled when 2D context supports HTMLCanvasElement.captureStream(). |
| // subcases.push({draw: with2DContext}); |
| subcases.push({draw: withWebGL}); |
| |
| function testDescription(subcase) { |
| return Object.keys(subcase).map((k) => `${k}: ${typeof subcase[k] === "function" ? subcase[k].name : subcase[k]}`).join(","); |
| } |
| |
| function createCanvasToPeerConnectionTests(slice, slices) { |
| const sliceSize = Math.floor(subcases.length / slices); |
| const first = sliceSize * slice; |
| for (const subcase of subcases.slice(first, first + sliceSize)) |
| promise_test(async t => { await testCanvasToPeerConnection(t, subcase); }, testDescription(subcase)); |
| } |
| createCanvasToPeerConnectionTests(0, 1); |
| </script> |
| </body> |
| </html> |