2 Copyright (c) 2021 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
11 <meta charset=
"UTF-8">
12 <link rel=
"stylesheet" href=
"../../resources/js-test-style.css" />
13 <script src=
"../../js/js-test-pre.js"></script>
14 <script src=
"../../js/webgl-test-utils.js"></script>
15 <script src=
"../../js/tests/out-of-bounds-test.js"></script>
16 <script src=
"../../../../extensions/proposals/WEBGL_webcodecs_video_frame/webgl_webcodecs_video_frame.js"></script>
24 background-color: #
555555;
37 <canvas id=
"src" width=
"640" height=
"480"></canvas>
38 <canvas id=
"dst" width=
"640" height=
"480"></canvas>
40 <div id=
"description"></div>
41 <div id=
"console"></div>
44 description("Test of importing Videoframe from Webcodecs to Webgl");
46 const kIsRunningTest
= true;
48 const kTestPixel
= [255, 128, 0, 255];
49 // Sum of pixel difference of R/G/B channel. Use to decide whether a
50 // pixel is matched with another.
51 const codec_string
= "vp09.00.51.08.00";
53 let wtu
= WebGLTestUtils
;
54 let cnv
= document
.getElementById("src");
55 let src_width
= cnv
.width
;
56 let src_height
= cnv
.height
;
57 let src_color
= "rgba(" + kTestPixel
[0].toString() + "," + kTestPixel
[1].toString() + ","
58 + kTestPixel
[2].toString() + "," + kTestPixel
[3].toString() + ")";
59 let frame_counter
= 0;
60 let pixelCompareTolerance
= 5;
62 function getQueryVariable(variable
) {
63 var query
= window
.location
.search
.substring(1);
64 var vars
= query
.split("&");
65 for (var i
= 0; i
< vars
.length
; i
++) {
66 var pair
= vars
[i
].split("=");
67 if (pair
[0] == variable
) { return pair
[1]; }
72 let th
= parseInt(getQueryVariable('threshold'));
74 pixelCompareTolerance
= th
;
76 async
function startDrawing() {
77 let cnv
= document
.getElementById("src");
78 var ctx
= cnv
.getContext('2d', { alpha
: false });
80 ctx
.fillStyle
= src_color
;
81 let drawOneFrame = function (time
) {
82 ctx
.fillStyle
= src_color
;
83 ctx
.fillRect(0, 0, src_width
, src_height
);
84 window
.requestAnimationFrame(drawOneFrame
);
86 window
.requestAnimationFrame(drawOneFrame
);
89 function captureAndEncode(processChunk
) {
90 let cnv
= document
.getElementById("src");
92 let pending_outputs
= 0;
93 let stream
= cnv
.captureStream(fps
);
94 let processor
= new MediaStreamTrackProcessor(stream
.getVideoTracks()[0]);
98 testPassed("Encode frame successfully.");
103 testFailed("Failed to encode frame.");
117 let encoder
= new VideoEncoder(init
);
118 encoder
.configure(config
);
120 const frame_reader
= processor
.readable
.getReader();
121 frame_reader
.read().then(function processFrame({done
, value
}) {
125 if (pending_outputs
> 30) {
126 console
.log("drop this frame");
127 // Too many frames in flight, encoder is overwhelmed
128 // let's drop this frame.
130 frame_reader
.read().then(processFrame
);
134 if(frame_counter
== kMaxFrame
) {
135 frame_reader
.releaseLock();
136 processor
.readable
.cancel();
143 const insert_keyframe
= (frame_counter
% 150) == 0;
144 encoder
.encode(value
, { keyFrame
: insert_keyframe
});
146 frame_reader
.read().then(processFrame
);
150 function startDecodingAndRendering(cnv
, handleFrame
) {
154 testFailed("Failed to decode frame.");
161 codedWidth
: cnv
.width
,
162 codedHeight
: cnv
.height
,
163 acceleration
: "deny",
167 let decoder
= new VideoDecoder(init
);
168 decoder
.configure(config
);
172 function isFramePixelMatched(gl
, th_per_pixel
= pixelCompareTolerance
) {
173 WebGLTestUtils
.checkCanvasRect(gl
, 0, 0, src_width
, src_width
, kTestPixel
, "should be orange", pixelCompareTolerance
)
177 if (!("VideoEncoder" in window
)) {
178 testPassed("WebCodecs API is not supported.");
182 let cnv
= document
.getElementById("dst");
184 let webgl_webcodecs_test_context
= {
185 maxFrameTested
: kMaxFrame
,
187 isFramePixelMatched
: isFramePixelMatched
,
188 testFailed
: testFailed
,
189 testPassed
: testPassed
,
190 finishTest
: finishTest
192 setTestMode(webgl_webcodecs_test_context
);
193 let handleFrame
= requestWebGLVideoFrameHandler(cnv
);
194 if (handleFrame
=== null) {
200 let decoder
= startDecodingAndRendering(cnv
, handleFrame
);
201 captureAndEncode((chunk
) => {
202 decoder
.decode(chunk
);
206 document
.body
.onload
= main
;