blob: a016f194a2402677f7bf1d25850153ddcde90610 [file] [edit]
<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
const WIDTH = 320, HEIGHT = 240;
const MAX_ITERATIONS = 3000;
async function getVP8Keyframe(w, h) {
return new Promise((resolve, reject) => {
const chunks = [];
const enc = new VideoEncoder({
output: (chunk) => chunks.push(chunk),
error: reject
});
enc.configure({
codec: 'vp8',
width: w,
height: h,
bitrate: 500000,
framerate: 30
});
const canvas = new OffscreenCanvas(w, h);
const ctx = canvas.getContext('2d');
// Draw some content so it's a real frame
ctx.fillStyle = '#336699';
ctx.fillRect(0, 0, w, h);
ctx.fillStyle = '#FF0000';
ctx.fillRect(10, 10, 50, 50);
const bitmap = canvas.transferToImageBitmap();
const vf = new VideoFrame(bitmap, { timestamp: 0 });
enc.encode(vf, { keyFrame: true });
vf.close();
bitmap.close();
enc.flush().then(() => {
enc.close();
if (!chunks.length) { reject(new Error('No encoded chunks')); return; }
const buf = new ArrayBuffer(chunks[0].byteLength);
chunks[0].copyTo(buf);
resolve(buf);
}).catch(reject);
});
}
async function getVideoFrame(test)
{
const vp8Data = await getVP8Keyframe(WIDTH, HEIGHT);
let resolveCallback;
const promise = new Promise((resolve, reject) => {
resolveCallback = resolve;
test.step_timeout(() => reject("decoding timed out"), 5000);
});
const raceDecoder = new VideoDecoder({
output: frame => resolveCallback(frame),
error: (e) => {}
});
raceDecoder.configure({ codec: 'vp8' });
raceDecoder.decode(new EncodedVideoChunk({
type: 'key',
timestamp: 0,
data: vp8Data
}));
return promise;
}
promise_test(async t => {
let shouldDelay = false;
for (let i = 0; i < 10; ++i) {
const frame = await getVideoFrame(t);
t.add_cleanup(() => frame.close());
const raceEncoder = new VideoEncoder({
output: () => {},
error: (e) => {}
});
raceEncoder.configure({
codec: 'vp8',
width: WIDTH,
height: HEIGHT,
bitrate: 500000,
framerate: 30
});
const encodeCloneEncoder = new VideoEncoder({
output: () => {},
error: (e) => {}
});
encodeCloneEncoder.configure({
codec: 'vp8',
width: WIDTH,
height: HEIGHT,
bitrate: 500000,
framerate: 30
});
raceEncoder.encode(frame, { keyFrame: true });
if (shouldDelay)
await new Promise(resolve => t.step_timeout(resolve, 1));
shouldDelay = !shouldDelay;
const frameClone = new VideoFrame(frame, { timestamp: 1000 });
t.add_cleanup(() => frameClone.close());
encodeCloneEncoder.encode(frameClone, { keyFrame: true });
}
});
</script>
</body>
</html>