summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/copyToTexture/video.spec.ts
diff options
context:
space:
mode:
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/copyToTexture/video.spec.ts')
-rw-r--r--dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/copyToTexture/video.spec.ts119
1 files changed, 119 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/copyToTexture/video.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/copyToTexture/video.spec.ts
new file mode 100644
index 0000000000..1888eb7e58
--- /dev/null
+++ b/dom/webgpu/tests/cts/checkout/src/webgpu/web_platform/copyToTexture/video.spec.ts
@@ -0,0 +1,119 @@
+export const description = `
+copyToTexture with HTMLVideoElement and VideoFrame.
+
+- videos with various encodings/formats (webm vp8, webm vp9, ogg theora, mp4), color spaces
+ (bt.601, bt.709, bt.2020)
+`;
+
+import { makeTestGroup } from '../../../common/framework/test_group.js';
+import { GPUTest, TextureTestMixin } from '../../gpu_test.js';
+import {
+ startPlayingAndWaitForVideo,
+ getVideoElement,
+ getVideoFrameFromVideoElement,
+ kVideoExpectations,
+} from '../../web_platform/util.js';
+
+const kFormat = 'rgba8unorm';
+
+export const g = makeTestGroup(TextureTestMixin(GPUTest));
+
+g.test('copy_from_video')
+ .desc(
+ `
+Test HTMLVideoElement and VideoFrame can be copied to WebGPU texture correctly.
+
+It creates HTMLVideoElement with videos under Resource folder.
+
+ Then call copyExternalImageToTexture() to do a full copy to the 0 mipLevel
+ of dst texture, and read the contents out to compare with the ImageBitmap contents.
+
+ If 'flipY' in 'GPUImageCopyExternalImage' is set to 'true', copy will ensure the result
+ is flipped.
+
+ The tests covers:
+ - Video comes from different color spaces.
+ - Valid 'flipY' config in 'GPUImageCopyExternalImage' (named 'srcDoFlipYDuringCopy' in cases)
+ - TODO: partial copy tests should be added
+ - TODO: all valid dstColorFormat tests should be added.
+ - TODO: dst color space tests need to be added
+`
+ )
+ .params(u =>
+ u //
+ .combineWithParams(kVideoExpectations)
+ .combine('sourceType', ['VideoElement', 'VideoFrame'] as const)
+ .combine('srcDoFlipYDuringCopy', [true, false])
+ )
+ .fn(async t => {
+ const { videoName, sourceType, srcDoFlipYDuringCopy } = t.params;
+
+ if (sourceType === 'VideoFrame' && typeof VideoFrame === 'undefined') {
+ t.skip('WebCodec is not supported');
+ }
+
+ const videoElement = getVideoElement(t, videoName);
+
+ await startPlayingAndWaitForVideo(videoElement, async () => {
+ let source, width, height;
+ if (sourceType === 'VideoFrame') {
+ source = await getVideoFrameFromVideoElement(t, videoElement);
+ width = source.codedWidth;
+ height = source.codedHeight;
+ } else {
+ source = videoElement;
+ width = source.videoWidth;
+ height = source.videoHeight;
+ }
+
+ const dstTexture = t.device.createTexture({
+ format: kFormat,
+ size: { width, height, depthOrArrayLayers: 1 },
+ usage:
+ GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
+ });
+
+ t.queue.copyExternalImageToTexture(
+ {
+ source,
+ origin: { x: 0, y: 0 },
+ flipY: srcDoFlipYDuringCopy,
+ },
+ {
+ texture: dstTexture,
+ origin: { x: 0, y: 0 },
+ colorSpace: 'srgb',
+ premultipliedAlpha: true,
+ },
+ { width, height, depthOrArrayLayers: 1 }
+ );
+
+ if (srcDoFlipYDuringCopy) {
+ t.expectSinglePixelComparisonsAreOkInTexture({ texture: dstTexture }, [
+ // Top-left should be blue.
+ { coord: { x: width * 0.25, y: height * 0.25 }, exp: t.params._blueExpectation },
+ // Top-right should be green.
+ { coord: { x: width * 0.75, y: height * 0.25 }, exp: t.params._greenExpectation },
+ // Bottom-left should be yellow.
+ { coord: { x: width * 0.25, y: height * 0.75 }, exp: t.params._yellowExpectation },
+ // Bottom-right should be red.
+ { coord: { x: width * 0.75, y: height * 0.75 }, exp: t.params._redExpectation },
+ ]);
+ } else {
+ t.expectSinglePixelComparisonsAreOkInTexture({ texture: dstTexture }, [
+ // Top-left should be yellow.
+ { coord: { x: width * 0.25, y: height * 0.25 }, exp: t.params._yellowExpectation },
+ // Top-right should be red.
+ { coord: { x: width * 0.75, y: height * 0.25 }, exp: t.params._redExpectation },
+ // Bottom-left should be blue.
+ { coord: { x: width * 0.25, y: height * 0.75 }, exp: t.params._blueExpectation },
+ // Bottom-right should be green.
+ { coord: { x: width * 0.75, y: height * 0.75 }, exp: t.params._greenExpectation },
+ ]);
+ }
+
+ if (source instanceof VideoFrame) {
+ source.close();
+ }
+ });
+ });