Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 6 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /webcodecs/videoFrame-texImage.any.html - WPT Dashboard Interop Dashboard
- /webcodecs/videoFrame-texImage.any.worker.html - WPT Dashboard Interop Dashboard
// META: global=window,dedicatedworker
// META: script=/webcodecs/utils.js
// META: script=/webcodecs/webgl-test-utils.js
function testGLCanvas(gl, width, height, expectedPixel, assertCompares) {
var colorData =
new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
gl.readPixels(
0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA,
gl.UNSIGNED_BYTE, colorData);
assertCompares(gl.getError(), gl.NO_ERROR);
const kMaxPixelToCheck = 128 * 96;
let step = width * height / kMaxPixelToCheck;
step = Math.round(step);
step = (step < 1) ? 1 : step;
for (let i = 0; i < 4 * width * height; i += (4 * step)) {
assertCompares(colorData[i], expectedPixel[0]);
assertCompares(colorData[i + 1], expectedPixel[1]);
assertCompares(colorData[i + 2], expectedPixel[2]);
assertCompares(colorData[i + 3], expectedPixel[3]);
}
}
function testTexImage2DFromVideoFrame(
width, height, useTexSubImage2D, expectedPixel) {
let vfInit =
{format: 'RGBA', timestamp: 0, codedWidth: width, codedHeight: height};
let argbData = new Uint32Array(vfInit.codedWidth * vfInit.codedHeight);
argbData.fill(0xFF966432); // 'rgb(50, 100, 150)';
let frame = new VideoFrame(argbData, vfInit);
let canvas;
if (self.HTMLCanvasElement) {
canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
} else
canvas = new OffscreenCanvas(width, height);
let gl = canvas.getContext('webgl');
let program = WebGLTestUtils.setupTexturedQuad(gl);
gl.clearColor(0, 0, 0, 1);
gl.clearDepth(1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.colorMask(1, 1, 1, 0); // Disable any writes to the alpha channel.
let textureLoc = gl.getUniformLocation(program, 'tex');
let texture = gl.createTexture();
// Bind the texture to texture unit 0.
gl.bindTexture(gl.TEXTURE_2D, texture);
// Set up texture parameters.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Set up pixel store parameters.
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
// Upload the videoElement into the texture
if (useTexSubImage2D) {
// Initialize the texture to black first
gl.texImage2D(
gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
null);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, frame);
} else {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, frame);
}
frame.close();
assert_equals(gl.getError(), gl.NO_ERROR);
// Point the uniform sampler to texture unit 0
gl.uniform1i(textureLoc, 0);
// Draw the triangles
WebGLTestUtils.drawQuad(gl, [0, 0, 0, 255]);
// Wait for drawing to complete.
gl.finish();
testGLCanvas(gl, width, height, expectedPixel, assert_equals);
}
function testTexImageWithClosedVideoFrame(useTexSubImage2D) {
let width = 128;
let height = 128;
let vfInit =
{format: 'RGBA', timestamp: 0, codedWidth: width, codedHeight: height};
let argbData = new Uint32Array(vfInit.codedWidth * vfInit.codedHeight);
argbData.fill(0xFF966432); // 'rgb(50, 100, 150)';
let frame = new VideoFrame(argbData, vfInit);
let canvas;
if (self.HTMLCanvasElement) {
canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
} else
canvas = new OffscreenCanvas(width, height);
let gl = canvas.getContext('webgl');
frame.close();
if (useTexSubImage2D) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, frame);
} else {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, frame);
}
assert_equals(gl.getError(), gl.INVALID_OPERATION);
}
test(_ => {
testTexImage2DFromVideoFrame(48, 36, false, kSRGBPixel);
}, 'texImage2D with 48x36 srgb VideoFrame.');
test(_ => {
testTexImage2DFromVideoFrame(48, 36, true, kSRGBPixel);
}, 'texSubImage2D with 48x36 srgb VideoFrame.');
test(_ => {
testTexImage2DFromVideoFrame(480, 360, false, kSRGBPixel);
}, 'texImage2D with 480x360 srgb VideoFrame.');
test(_ => {
testTexImage2DFromVideoFrame(480, 360, true, kSRGBPixel);
}, 'texSubImage2D with 480x360 srgb VideoFrame.');
test(_ => {
testTexImageWithClosedVideoFrame(false);
}, 'texImage2D with a closed VideoFrame.');
test(_ => {
testTexImageWithClosedVideoFrame(true);
}, 'texSubImage2D with a closed VideoFrame.');