tor-browser

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

full-cycle-test.https.any.js (7246B)


      1 // META: timeout=long
      2 // META: global=window,dedicatedworker
      3 // META: script=/webcodecs/video-encoder-utils.js
      4 // META: variant=?av1
      5 // META: variant=?av1_444_high
      6 // META: variant=?vp8
      7 // META: variant=?vp9_p0
      8 // META: variant=?vp9_p2
      9 // META: variant=?vp9_444_p1
     10 // META: variant=?vp9_444_p3
     11 // META: variant=?h264_avc
     12 // META: variant=?h264_annexb
     13 // META: variant=?h265_hevc
     14 // META: variant=?h265_annexb
     15 
     16 var ENCODER_CONFIG = null;
     17 promise_setup(async () => {
     18  const config = {
     19    '?av1': {
     20      codec: 'av01.0.04M.08',
     21      hasEmbeddedColorSpace: true,
     22      hardwareAcceleration: 'prefer-software',
     23    },
     24    '?av1_444_high': {
     25      codec: 'av01.1.04M.08.0.000',
     26      hasEmbeddedColorSpace: true,
     27      hardwareAcceleration: 'prefer-software',
     28      outputPixelFormat: 'I444',
     29    },
     30    '?vp8': {
     31      codec: 'vp8',
     32      hasEmbeddedColorSpace: false,
     33      hardwareAcceleration: 'prefer-software',
     34    },
     35    '?vp9_p0': {
     36      codec: 'vp09.00.10.08',
     37      hasEmbeddedColorSpace: true,
     38      hardwareAcceleration: 'prefer-software',
     39    },
     40    '?vp9_p2': {
     41      codec: 'vp09.02.10.10',
     42      hasEmbeddedColorSpace: true,
     43      hardwareAcceleration: 'prefer-software',
     44      // TODO(https://github.com/w3c/webcodecs/issues/384):
     45      // outputPixelFormat should be 'I420P10'
     46    },
     47    '?vp9_444_p1': {
     48      codec: 'vp09.01.10.08.03',
     49      hasEmbeddedColorSpace: true,
     50      hardwareAcceleration: 'prefer-software',
     51      outputPixelFormat: 'I444',
     52    },
     53    '?vp9_444_p3': {
     54      codec: 'vp09.03.10.10.03',
     55      hasEmbeddedColorSpace: true,
     56      hardwareAcceleration: 'prefer-software',
     57      // TODO(https://github.com/w3c/webcodecs/issues/384):
     58      // outputPixelFormat should be 'I444P10'
     59    },
     60    '?h264_avc': {
     61      codec: 'avc1.42001E',
     62      avc: {format: 'avc'},
     63      hasEmbeddedColorSpace: true,
     64      hardwareAcceleration: 'prefer-software',
     65    },
     66    '?h264_annexb': {
     67      codec: 'avc1.42001E',
     68      avc: {format: 'annexb'},
     69      hasEmbeddedColorSpace: true,
     70      hardwareAcceleration: 'prefer-software',
     71    },
     72    '?h265_hevc': {
     73      codec: 'hvc1.1.6.L123.00',
     74      hevc: {format: 'hevc'},
     75      hasEmbeddedColorSpace: true,
     76      hardwareAcceleration: 'prefer-hardware',
     77    },
     78    '?h265_annexb': {
     79      codec: 'hvc1.1.6.L123.00',
     80      hevc: {format: 'annexb'},
     81      hasEmbeddedColorSpace: true,
     82      hardwareAcceleration: 'prefer-hardware',
     83    }
     84  }[location.search];
     85  config.width = 320;
     86  config.height = 200;
     87  config.bitrate = 1000000;
     88  config.bitrateMode = "constant";
     89  config.framerate = 30;
     90  ENCODER_CONFIG = config;
     91 });
     92 
     93 async function runFullCycleTest(t, options) {
     94  let encoder_config = { ...ENCODER_CONFIG };
     95  if (options.realTimeLatencyMode) {
     96    encoder_config.latencyMode = 'realtime';
     97  }
     98  let encoder_color_space = {};
     99  const w = encoder_config.width;
    100  const h = encoder_config.height;
    101  let next_ts = 0
    102  let frames_to_encode = 16;
    103  let frames_encoded = 0;
    104  let frames_decoded = 0;
    105 
    106  await checkEncoderSupport(t, encoder_config);
    107  let decoder = new VideoDecoder({
    108    output(frame) {
    109      t.add_cleanup(() => { frame.close() });
    110 
    111      assert_equals(frame.visibleRect.width, w, "visibleRect.width");
    112      assert_equals(frame.visibleRect.height, h, "visibleRect.height");
    113      if (!options.realTimeLatencyMode) {
    114        assert_equals(frame.timestamp, next_ts++, "decode timestamp");
    115      }
    116 
    117      if (ENCODER_CONFIG.outputPixelFormat) {
    118        assert_equals(
    119            frame.format, ENCODER_CONFIG.outputPixelFormat,
    120            "decoded pixel format");
    121      }
    122 
    123      // The encoder is allowed to change the color space to satisfy the
    124      // encoder when readback is needed to send the frame for encoding, but
    125      // the decoder shouldn't change it after the fact.
    126      assert_equals(
    127          frame.colorSpace.primaries, encoder_color_space.primaries,
    128          'colorSpace.primaries');
    129      assert_equals(
    130          frame.colorSpace.transfer, encoder_color_space.transfer,
    131          'colorSpace.transfer');
    132      assert_equals(
    133          frame.colorSpace.matrix, encoder_color_space.matrix,
    134          'colorSpace.matrix');
    135      assert_equals(
    136          frame.colorSpace.fullRange, encoder_color_space.fullRange,
    137          'colorSpace.fullRange');
    138 
    139      frames_decoded++;
    140      assert_true(validateBlackDots(frame, frame.timestamp),
    141        "frame doesn't match. ts: " + frame.timestamp);
    142    },
    143    error(e) {
    144      assert_unreached(e.message);
    145    }
    146  });
    147 
    148  let next_encode_ts = 0;
    149  const encoder_init = {
    150    output(chunk, metadata) {
    151      let config = metadata.decoderConfig;
    152      // Issue a configure if there's a new config, or on the
    153      // first chunk if testing rate control
    154      if (!options.rateControl && config ||
    155          options.rateControl && chunk.timestamp == 0) {
    156        config.hardwareAcceleration = encoder_config.hardwareAcceleration;
    157        encoder_color_space = config.colorSpace;
    158 
    159        // Removes the color space provided by the encoder so that color space
    160        // information in the underlying bitstream is exposed during decode.
    161        if (options.stripDecoderConfigColorSpace)
    162          config.colorSpace = {};
    163 
    164        decoder.configure(config);
    165      }
    166      decoder.decode(chunk);
    167      frames_encoded++;
    168      if (!options.realTimeLatencyMode) {
    169        assert_equals(chunk.timestamp, next_encode_ts++, "encode timestamp");
    170      }
    171    },
    172    error(e) {
    173      assert_unreached(e.message);
    174    }
    175  };
    176 
    177  let encoder = new VideoEncoder(encoder_init);
    178  encoder.configure(encoder_config);
    179 
    180  for (let i = 0; i < frames_to_encode; i++) {
    181    let frame = createDottedFrame(w, h, i);
    182 
    183    // Frames should have a valid color space when created from canvas.
    184    assert_not_equals(frame.colorSpace.primaries, null, 'colorSpace.primaries');
    185    assert_not_equals(frame.colorSpace.transfer, null, 'colorSpace.transfer');
    186    assert_not_equals(frame.colorSpace.matrix, null, 'colorSpace.matrix');
    187    assert_not_equals(frame.colorSpace.fullRange, null, 'colorSpace.fullRange');
    188 
    189    let keyframe = (i % 5 == 0);
    190    encoder.encode(frame, { keyFrame: keyframe });
    191    if (i % 3 == 0 && options.rateControl) {
    192      // reconfigure with a different rate
    193      encoder_config.bitrate = encoder_config.bitrate * 0.9;
    194      encoder.configure(encoder_config);
    195    }
    196    frame.close();
    197  }
    198  await encoder.flush();
    199  await decoder.flush();
    200  encoder.close();
    201  decoder.close();
    202  if (options.realTimeLatencyMode) {
    203    assert_greater_than(frames_encoded, 0, "frames_encoded");
    204  } else {
    205    assert_equals(frames_encoded, frames_to_encode, "frames_encoded");
    206  }
    207  assert_equals(frames_decoded, frames_encoded, "frames_decoded");
    208 }
    209 
    210 promise_test(async t => {
    211  return runFullCycleTest(t, {});
    212 }, 'Encoding and decoding cycle');
    213 
    214 promise_test(async t => {
    215  return runFullCycleTest(t, {realTimeLatencyMode: true});
    216 }, 'Encoding and decoding cycle with realtime latency mode');
    217 
    218 promise_test(async t => {
    219  if (ENCODER_CONFIG.hasEmbeddedColorSpace)
    220    return runFullCycleTest(t, {stripDecoderConfigColorSpace: true});
    221 }, 'Encoding and decoding cycle w/ stripped color space');
    222 
    223 promise_test(async t => {
    224  return runFullCycleTest(t, {rateControl: true});
    225 }, 'Encoding and decoding cycle w/ rate control');