videoFrame-canvasImageSource.html (5908B)
1 <title>Test VideoFrame creation from CanvasImageSource.</title> 2 <style> 3 button { 4 display: inline-block; 5 min-height: 100px; min-width: 100px; 6 background: no-repeat 5% center url(four-colors.png); 7 } 8 </style> 9 <video preload="auto"></video> 10 <img src="four-colors.png"/> 11 <canvas id=""></canvas> 12 <svg width="320" height="240" xmlns="http://www.w3.org/2000/svg"> 13 <image href="four-colors.png" height="320" width="240"/> 14 </svg> 15 <button></button> 16 <script src="/resources/testharness.js"></script> 17 <script src="/resources/testharnessreport.js"></script> 18 <script src="/webcodecs/image-decoder-utils.js"></script> 19 <script> 20 async_test(t => { 21 let video = document.querySelector('video'); 22 video.onerror = t.unreached_func(); 23 video.requestVideoFrameCallback(t.step_func(_ => { 24 let frame = new VideoFrame(video); 25 assert_true(!!frame); 26 assert_equals(frame.displayWidth, video.videoWidth); 27 assert_equals(frame.displayHeight, video.videoHeight); 28 29 let canvas = new OffscreenCanvas(frame.displayWidth, frame.displayHeight); 30 let ctx = canvas.getContext('2d'); 31 ctx.drawImage(video, 0, 0); 32 verifyFourColorsImage(video.videoWidth, video.videoHeight, ctx); 33 ctx.clearRect(0, 0, canvas.width, canvas.height); 34 ctx.drawImage(frame, 0, 0); 35 verifyFourColorsImage(frame.displayWidth, frame.displayHeight, ctx); 36 37 let frame_copy = new VideoFrame(frame, {duration: 1234}); 38 assert_equals(frame.timestamp, frame_copy.timestamp); 39 assert_equals(frame_copy.duration, 1234); 40 ctx.clearRect(0, 0, canvas.width, canvas.height); 41 ctx.drawImage(frame_copy, 0, 0); 42 verifyFourColorsImage(frame_copy.displayWidth, frame_copy.displayHeight, 43 ctx); 44 frame_copy.close(); 45 46 frame_copy = new VideoFrame(frame, {timestamp: 1234, duration: 456}); 47 assert_equals(frame_copy.timestamp, 1234); 48 assert_equals(frame_copy.duration, 456); 49 frame_copy.close(); 50 51 frame_copy = new VideoFrame(frame); 52 assert_equals(frame.format, frame_copy.format); 53 assert_equals(frame.timestamp, frame_copy.timestamp); 54 assert_equals(frame.codedWidth, frame_copy.codedWidth); 55 assert_equals(frame.codedHeight, frame_copy.codedHeight); 56 assert_equals(frame.displayWidth, frame_copy.displayWidth); 57 assert_equals(frame.displayHeight, frame_copy.displayHeight); 58 assert_equals(frame.duration, frame_copy.duration); 59 frame_copy.close(); 60 61 frame.close(); 62 t.done(); 63 })); 64 65 const mediaConfig = { 66 type: 'file', 67 video: { 68 contentType: 'video/mp4; codecs="av01.0.04M.08"', 69 width: 320, 70 height: 240, 71 bitrate: 1000000, 72 framerate: '30' 73 } 74 }; 75 navigator.mediaCapabilities.decodingInfo(mediaConfig).then(t.step_func(result => { 76 assert_implements_optional(result.supported, "AV.1 file streaming unsupported"); 77 video.src = 'four-colors.mp4'; 78 })); 79 }, '<video> and VideoFrame constructed VideoFrame'); 80 81 test(t => { 82 let button = document.querySelector('button'); 83 let bgImage = button.computedStyleMap().get('background-image'); 84 assert_throws_dom('SecurityError', _ => { new VideoFrame(bgImage, {timestamp: 0}); }, 85 'CSSImageValues are currently always tainted'); 86 }, 'CSSImageValue constructed VideoFrame'); 87 88 promise_test(() => { 89 return new Promise(resolve => onload = resolve); 90 }, "Wait for onload event to get access to image data"); 91 92 promise_test(async t => { 93 let frame = new VideoFrame(document.querySelector('img'), {timestamp: 0}); 94 let canvas = new OffscreenCanvas(frame.displayWidth, frame.displayHeight); 95 let ctx = canvas.getContext('2d'); 96 ctx.drawImage(frame, 0, 0); 97 verifyFourColorsImage(frame.displayWidth, frame.displayHeight, ctx); 98 frame.close(); 99 }, 'Image element constructed VideoFrame'); 100 101 promise_test(async t => { 102 let frame = new VideoFrame(document.querySelector('image'), {timestamp: 0}); 103 let canvas = new OffscreenCanvas(frame.displayWidth, frame.displayHeight); 104 let ctx = canvas.getContext('2d'); 105 ctx.drawImage(frame, 0, 0); 106 verifyFourColorsImage(frame.displayWidth, frame.displayHeight, ctx); 107 frame.close(); 108 }, 'SVGImageElement constructed VideoFrame'); 109 110 function drawFourColors(canvas) { 111 let ctx = canvas.getContext('2d'); 112 ctx.fillStyle = '#FFFF00'; // yellow 113 ctx.fillRect(0, 0, canvas.width / 2, canvas.height / 2); 114 ctx.fillStyle = '#FF0000'; // red 115 ctx.fillRect(canvas.width / 2, 0, canvas.width / 2, canvas.height / 2); 116 ctx.fillStyle = '#0000FF'; // blue 117 ctx.fillRect(0, canvas.height / 2, canvas.width / 2, canvas.height / 2); 118 ctx.fillStyle = '#00FF00'; // green 119 ctx.fillRect(canvas.width / 2, canvas.height / 2, canvas.width / 2, 120 canvas.height / 2); 121 } 122 123 test(t => { 124 let canvas = document.querySelector('canvas'); 125 canvas.width = 320; 126 canvas.height = 240; 127 128 // Draw and verify four colors image. 129 drawFourColors(canvas); 130 let ctx = canvas.getContext('2d'); 131 verifyFourColorsImage(canvas.width, canvas.height, ctx); 132 133 let frame = new VideoFrame(canvas, {timestamp: 0}); 134 ctx.clearRect(0, 0, canvas.width, canvas.height); 135 ctx.drawImage(frame, 0, 0); 136 verifyFourColorsImage(canvas.width, canvas.height, ctx); 137 frame.close(); 138 }, 'Canvas element constructed VideoFrame'); 139 140 test(t => { 141 let canvas = document.querySelector('canvas'); 142 canvas.width = 320; 143 canvas.height = 240; 144 145 // Draw and verify four colors image. 146 drawFourColors(canvas); 147 let ctx = canvas.getContext('2d'); 148 verifyFourColorsImage(canvas.width, canvas.height, ctx); 149 150 // Set a different timestamp to try and ensure the same frame isn't reused. 151 let frame = new VideoFrame(canvas, {timestamp: 0}); 152 let frame_copy = new VideoFrame(frame, {timestamp: 1}); 153 frame.close(); 154 155 ctx.clearRect(0, 0, canvas.width, canvas.height); 156 ctx.drawImage(frame_copy, 0, 0); 157 verifyFourColorsImage(canvas.width, canvas.height, ctx); 158 frame_copy.close(); 159 }, 'Copy of canvas element constructed VideoFrame'); 160 </script>