// META: global=window,dedicatedworker // META: script=/webcodecs/videoFrame-alpha-discard-utils.js const kSources = { 'OffscreenCanvas': () => makeTransparentCanvas(), 'ImageBitmap': () => makeTransparentCanvas().transferToImageBitmap(), 'VideoFrame': () => new VideoFrame( makeTransparentCanvas(), {alpha: 'keep', timestamp: 0}), }; for (const [name, makeSource] of Object.entries(kSources)) { function makeDiscardedFrame(t) { const source = makeSource(); const frame = new VideoFrame(source, {alpha: 'discard', timestamp: 0}); t.add_cleanup(() => frame.close()); if (source.close) source.close(); return frame; } promise_test(async t => { const frame = makeDiscardedFrame(t); assert_in_array(frame.format, ['RGBX', 'BGRX'], 'format'); verifyOpaquePicture(drawToNewCanvas(frame), 'new canvas'); }, `Drawing a VideoFrame made from an ${name} with alpha discard gives opaque pixels`); promise_test(async t => { const frame = makeDiscardedFrame(t); verifyOpaquePicture(drawToNewCanvas(frame, 'white'), 'white background'); }, `Drawing a VideoFrame made from an ${name} with alpha discard replaces the canvas background`); promise_test(async t => { const frame = makeDiscardedFrame(t); const clone = frame.clone(); t.add_cleanup(() => clone.close()); verifyOpaquePicture(drawToNewCanvas(clone), 'clone'); }, `Drawing a clone of a VideoFrame made from an ${name} with alpha discard gives opaque pixels`); promise_test(async t => { const frame = makeDiscardedFrame(t); const bitmap = await createImageBitmap(frame); t.add_cleanup(() => bitmap.close()); verifyOpaquePicture(drawToNewCanvas(bitmap), 'ImageBitmap'); }, `An ImageBitmap of a VideoFrame made from an ${name} with alpha discard is opaque`); } promise_test(async t => { const kept = new VideoFrame(makeTransparentCanvas(), {alpha: 'keep', timestamp: 0}); t.add_cleanup(() => kept.close()); const discarded = new VideoFrame(kept, {alpha: 'discard'}); t.add_cleanup(() => discarded.close()); assert_in_array(discarded.format, ['RGBX', 'BGRX'], 'format'); verifyOpaquePicture(drawToNewCanvas(discarded), 'discarded copy'); // The original frame is unchanged. assert_in_array(kept.format, ['RGBA', 'BGRA'], 'original format'); assert_array_equals(getPixel(drawToNewCanvas(kept), 24, 24), [0, 0, 0, 0], 'original keeps its transparency'); }, 'Discarding the alpha of a VideoFrame does not change the original frame'); // Control: with alpha keep, the transparent quadrant stays transparent. promise_test(async t => { const frame = new VideoFrame(makeTransparentCanvas(), {alpha: 'keep', timestamp: 0}); t.add_cleanup(() => frame.close()); const ctx = drawToNewCanvas(frame, 'white'); assert_array_equals(getPixel(ctx, 24, 24), [255, 255, 255, 255]); assert_array_equals(getPixel(drawToNewCanvas(frame), 24, 24), [0, 0, 0, 0]); }, 'Drawing a VideoFrame with alpha keep preserves its transparency');