tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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");