diff options
Diffstat (limited to 'testing/web-platform/tests/webcodecs/full-cycle-test.https.any.js')
-rw-r--r-- | testing/web-platform/tests/webcodecs/full-cycle-test.https.any.js | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webcodecs/full-cycle-test.https.any.js b/testing/web-platform/tests/webcodecs/full-cycle-test.https.any.js new file mode 100644 index 0000000000..7428f60748 --- /dev/null +++ b/testing/web-platform/tests/webcodecs/full-cycle-test.https.any.js @@ -0,0 +1,136 @@ +// META: global=window,dedicatedworker +// META: script=/webcodecs/video-encoder-utils.js +// META: variant=?av1 +// META: variant=?vp8 +// META: variant=?vp9_p0 +// META: variant=?vp9_p2 +// META: variant=?h264_avc +// META: variant=?h264_annexb + +var ENCODER_CONFIG = null; +promise_setup(async () => { + const config = { + // FIXME: H.264 has embedded color space information too. + '?av1': {codec: 'av01.0.04M.08', hasEmbeddedColorSpace: true}, + '?vp8': {codec: 'vp8', hasEmbeddedColorSpace: false}, + '?vp9_p0': {codec: 'vp09.00.10.08', hasEmbeddedColorSpace: true}, + '?vp9_p2': {codec: 'vp09.02.10.10', hasEmbeddedColorSpace: true}, + '?h264_avc': { + codec: 'avc1.42001E', + avc: {format: 'avc'}, + hasEmbeddedColorSpace: true + }, + '?h264_annexb': { + codec: 'avc1.42001E', + avc: {format: 'annexb'}, + hasEmbeddedColorSpace: true + } + }[location.search]; + config.hardwareAcceleration = 'prefer-software'; + config.width = 320; + config.height = 200; + config.bitrate = 1000000; + config.bitrateMode = "constant"; + config.framerate = 30; + ENCODER_CONFIG = config; +}); + +async function runFullCycleTest(t, options) { + let encoder_config = { ...ENCODER_CONFIG }; + let encoder_color_space = {}; + const w = encoder_config.width; + const h = encoder_config.height; + let next_ts = 0 + let frames_to_encode = 16; + let frames_encoded = 0; + let frames_decoded = 0; + + await checkEncoderSupport(t, encoder_config); + let decoder = new VideoDecoder({ + output(frame) { + assert_equals(frame.visibleRect.width, w, "visibleRect.width"); + assert_equals(frame.visibleRect.height, h, "visibleRect.height"); + assert_equals(frame.timestamp, next_ts++, "decode timestamp"); + + // The encoder is allowed to change the color space to satisfy the + // encoder when readback is needed to send the frame for encoding, but + // the decoder shouldn't change it after the fact. + assert_equals( + frame.colorSpace.primaries, encoder_color_space.primaries, + 'colorSpace.primaries'); + assert_equals( + frame.colorSpace.transfer, encoder_color_space.transfer, + 'colorSpace.transfer'); + assert_equals( + frame.colorSpace.matrix, encoder_color_space.matrix, + 'colorSpace.matrix'); + assert_equals( + frame.colorSpace.fullRange, encoder_color_space.fullRange, + 'colorSpace.fullRange'); + + frames_decoded++; + assert_true(validateBlackDots(frame, frame.timestamp), + "frame doesn't match. ts: " + frame.timestamp); + frame.close(); + }, + error(e) { + assert_unreached(e.message); + } + }); + + let next_encode_ts = 0; + const encoder_init = { + output(chunk, metadata) { + let config = metadata.decoderConfig; + if (config) { + config.hardwareAcceleration = encoder_config.hardwareAcceleration; + encoder_color_space = config.colorSpace; + + // Removes the color space provided by the encoder so that color space + // information in the underlying bitstream is exposed during decode. + if (options.stripDecoderConfigColorSpace) + config.colorSpace = {}; + + decoder.configure(config); + } + decoder.decode(chunk); + frames_encoded++; + assert_equals(chunk.timestamp, next_encode_ts++, "encode timestamp"); + }, + error(e) { + assert_unreached(e.message); + } + }; + + let encoder = new VideoEncoder(encoder_init); + encoder.configure(encoder_config); + + for (let i = 0; i < frames_to_encode; i++) { + let frame = createDottedFrame(w, h, i); + + // Frames should have a valid color space when created from canvas. + assert_not_equals(frame.colorSpace.primaries, null, 'colorSpace.primaries'); + assert_not_equals(frame.colorSpace.transfer, null, 'colorSpace.transfer'); + assert_not_equals(frame.colorSpace.matrix, null, 'colorSpace.matrix'); + assert_not_equals(frame.colorSpace.fullRange, null, 'colorSpace.fullRange'); + + let keyframe = (i % 5 == 0); + encoder.encode(frame, { keyFrame: keyframe }); + frame.close(); + } + await encoder.flush(); + await decoder.flush(); + encoder.close(); + decoder.close(); + assert_equals(frames_encoded, frames_to_encode, "frames_encoded"); + assert_equals(frames_decoded, frames_to_encode, "frames_decoded"); +} + +promise_test(async t => { + return runFullCycleTest(t, {}); +}, 'Encoding and decoding cycle'); + +promise_test(async t => { + if (ENCODER_CONFIG.hasEmbeddedColorSpace) + return runFullCycleTest(t, {stripDecoderConfigColorSpace: true}); +}, 'Encoding and decoding cycle w/ stripped color space'); |