temporal-svc-encoding.https.any.js (3029B)
1 // META: timeout=long 2 // META: global=window,dedicatedworker 3 // META: script=/webcodecs/video-encoder-utils.js 4 // META: variant=?av1 5 // META: variant=?vp8 6 // META: variant=?vp9 7 // META: variant=?h264 8 9 var ENCODER_CONFIG = null; 10 promise_setup(async () => { 11 const config = { 12 '?av1': {codec: 'av01.0.04M.08'}, 13 '?vp8': {codec: 'vp8'}, 14 '?vp9': {codec: 'vp09.00.10.08'}, 15 '?h264': {codec: 'avc1.42001E', avc: {format: 'annexb'}} 16 }[location.search]; 17 config.hardwareAcceleration = 'prefer-software'; 18 config.width = 320; 19 config.height = 200; 20 config.bitrate = 1000000; 21 config.bitrateMode = "constant"; 22 config.framerate = 30; 23 ENCODER_CONFIG = config; 24 }); 25 26 async function svc_test(t, layers, base_layer_decimator) { 27 let encoder_config = { ...ENCODER_CONFIG }; 28 encoder_config.scalabilityMode = "L1T" + layers; 29 const w = encoder_config.width; 30 const h = encoder_config.height; 31 await checkEncoderSupport(t, encoder_config); 32 33 let frames_to_encode = 24; 34 let frames_decoded = 0; 35 let frames_encoded = 0; 36 let chunks = []; 37 let corrupted_frames = []; 38 39 const encoder_init = { 40 output(chunk, metadata) { 41 frames_encoded++; 42 43 // Filter out all frames, but base layer. 44 assert_own_property(metadata, "svc"); 45 assert_own_property(metadata.svc, "temporalLayerId"); 46 assert_less_than(metadata.svc.temporalLayerId, layers); 47 if (metadata.svc.temporalLayerId == 0) 48 chunks.push(chunk); 49 }, 50 error(e) { 51 assert_unreached(e.message); 52 } 53 }; 54 55 let encoder = new VideoEncoder(encoder_init); 56 encoder.configure(encoder_config); 57 58 for (let i = 0; i < frames_to_encode; i++) { 59 let frame = createDottedFrame(w, h, i); 60 encoder.encode(frame, { keyFrame: false }); 61 frame.close(); 62 } 63 await encoder.flush(); 64 65 let decoder = new VideoDecoder({ 66 output(frame) { 67 frames_decoded++; 68 // Check that we have intended number of dots and no more. 69 // Completely black frame shouldn't pass the test. 70 if(!validateBlackDots(frame, frame.timestamp) || 71 validateBlackDots(frame, frame.timestamp + 1)) { 72 corrupted_frames.push(frame.timestamp) 73 } 74 frame.close(); 75 }, 76 error(e) { 77 assert_unreached(e.message); 78 } 79 }); 80 81 let decoder_config = { 82 codec: encoder_config.codec, 83 hardwareAcceleration: encoder_config.hardwareAcceleration, 84 codedWidth: w, 85 codedHeight: h, 86 }; 87 decoder.configure(decoder_config); 88 89 for (let chunk of chunks) { 90 decoder.decode(chunk); 91 } 92 await decoder.flush(); 93 94 encoder.close(); 95 decoder.close(); 96 assert_equals(frames_encoded, frames_to_encode); 97 98 let base_layer_frames = frames_to_encode / base_layer_decimator; 99 assert_equals(chunks.length, base_layer_frames); 100 assert_equals(frames_decoded, base_layer_frames); 101 assert_equals(corrupted_frames.length, 0, 102 `corrupted_frames: ${corrupted_frames}`); 103 } 104 105 promise_test(async t => { return svc_test(t, 2, 2) }, "SVC L1T2"); 106 promise_test(async t => { return svc_test(t, 3, 4) }, "SVC L1T3");