blob: e1f0a5295d81cc0ac305b40e758360db1cde00b4 [file] [edit]
<!DOCTYPE html>
<html>
<head>
<title>WebCodecs VP9 HDR decoding with colorSpace overrides</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
const HDR_CODEC = "vp09.02.10.10.01.09.16.09.00";
let vp9Data;
promise_test(async () => {
// Profile 2, level 1.0, 10-bit, 4:2:0, BT.2020 video range.
const response = await fetch("vp9-hdr.bin");
const buffer = await response.arrayBuffer();
// Strip 32-byte IVF file header + 12-byte frame header.
vp9Data = new Uint8Array(buffer).slice(44);
}, "Setup");
async function decodeWithOverride(colorSpace, hardwareAcceleration) {
const frames = [];
const decoder = new VideoDecoder({
output: f => frames.push(f),
error: e => assert_unreached(`decode error: ${e.message}`),
});
const config = { codec: HDR_CODEC, codedWidth: 320, codedHeight: 240, hardwareAcceleration };
if (colorSpace)
config.colorSpace = colorSpace;
decoder.configure(config);
decoder.decode(new EncodedVideoChunk({ type: "key", timestamp: 0, data: vp9Data }));
await decoder.flush();
assert_equals(frames.length, 1, "one frame decoded");
return frames[0];
}
for (const hardwareAcceleration of ["prefer-hardware", "prefer-software"]) {
const tag = `[${hardwareAcceleration}]`;
promise_test(async () => {
assert_implements(window.VideoDecoder, "VideoDecoder is supported");
const config = { codec: HDR_CODEC, codedWidth: 320, codedHeight: 240, hardwareAcceleration };
const support = await VideoDecoder.isConfigSupported(config);
assert_true(support.supported, "VP9 profile 2 (10-bit) is supported");
}, `VP9 profile 2 isConfigSupported ${tag}`);
promise_test(async (t) => {
const f = await decodeWithOverride(undefined, hardwareAcceleration);
t.add_cleanup(() => f.close());
assert_equals(f.colorSpace.primaries, "bt2020", "primaries from bitstream");
assert_equals(f.colorSpace.matrix, "bt2020-ncl", "matrix from bitstream");
assert_false(f.colorSpace.fullRange, "video range from bitstream");
if (f.format !== "I420P10") {
assert_equals(f.format, null);
assert_true(!window.internals?.is10bitsVideoFrame || internals.is10bitsVideoFrame(f), "10 bits");
}
}, `VP9 (no override) ${tag}: bitstream colorSpace surfaces`);
promise_test(async (t) => {
const f = await decodeWithOverride({ primaries: "bt709", matrix: "bt2020-ncl", transfer: "bt709" }, hardwareAcceleration);
t.add_cleanup(() => f.close());
assert_equals(f.colorSpace.primaries, "bt709", "primaries overridden");
assert_equals(f.colorSpace.matrix, "bt2020-ncl", "matrix preserved from bitstream");
}, `VP9 colorSpace override ${tag}: primaries`);
promise_test(async (t) => {
const f = await decodeWithOverride({ matrix: "bt709" }, hardwareAcceleration);
t.add_cleanup(() => f.close());
assert_equals(f.colorSpace.primaries, "bt2020", "primaries preserved from bitstream");
assert_equals(f.colorSpace.matrix, "bt709", "matrix overridden");
}, `VP9 colorSpace override ${tag}: matrix`);
promise_test(async (t) => {
const f = await decodeWithOverride({ transfer: "pq" }, hardwareAcceleration);
t.add_cleanup(() => f.close());
assert_equals(f.colorSpace.primaries, "bt2020", "primaries preserved from bitstream");
assert_equals(f.colorSpace.matrix, "bt2020-ncl", "matrix preserved from bitstream");
assert_equals(f.colorSpace.transfer, "pq", "transfer overridden to PQ");
}, `VP9 colorSpace override ${tag}: transfer (pq)`);
promise_test(async (t) => {
const f = await decodeWithOverride({ fullRange: true }, hardwareAcceleration);
t.add_cleanup(() => f.close());
assert_equals(f.colorSpace.primaries, "bt2020", "primaries preserved from bitstream");
assert_equals(f.colorSpace.matrix, "bt2020-ncl", "matrix preserved from bitstream");
assert_true(f.colorSpace.fullRange, "range overridden to full");
}, `VP9 colorSpace override ${tag}: fullRange (true)`);
promise_test(async (t) => {
const f = await decodeWithOverride({ fullRange: false }, hardwareAcceleration);
t.add_cleanup(() => f.close());
assert_equals(f.colorSpace.primaries, "bt2020", "primaries preserved from bitstream");
assert_equals(f.colorSpace.matrix, "bt2020-ncl", "matrix preserved from bitstream");
assert_false(f.colorSpace.fullRange, "range overridden to video");
}, `VP9 colorSpace override ${tag}: fullRange (false)`);
}
</script>
</body>
</html>