tor-browser

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

last-frame-dimensions.html (3789B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <title>Test dimensions of last frame with short frame durations</title>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="mediasource-util.js"></script>
      8 </head>
      9 <body>
     10 </body>
     11 <script>
     12 const frames_per_keyframe = 10;
     13 const default_sample_duration = 512;
     14 // The frame rate is very high to test that frame dropping logic does not drop
     15 // the final frame, but small enough that "plus 1 microsecond" on "remove
     16 // window timestamp" does not cause the first frame to be removed.
     17 const fps = 0.5e6;
     18 const timescale = default_sample_duration * fps;
     19 const earliest_presentation_time = 1024;
     20 const frame0_offset = earliest_presentation_time / default_sample_duration;
     21 const media_timescale_start = 0x182;
     22 const segment_index_timescale_start = 0x353;
     23 
     24 let media_320, media_640;
     25 promise_test(async t => {
     26  media_320 = await new Promise(
     27    r => MediaSourceUtil.fetchManifestAndData(
     28      t,
     29      `mp4/test-v-128k-320x240-30fps-${frames_per_keyframe}kfr-manifest.json`,
     30      (type, data) => r({type, data})));
     31  // Overwrite timescale to shorten frame durations.
     32  MediaSourceUtil.WriteBigEndianInteger32ToUint8Array(
     33    timescale, media_320.data.subarray(media_timescale_start));
     34  MediaSourceUtil.WriteBigEndianInteger32ToUint8Array(
     35    timescale, media_320.data.subarray(segment_index_timescale_start));
     36 
     37  media_640 = await new Promise(
     38    r => MediaSourceUtil.fetchManifestAndData(
     39      t,
     40      `mp4/test-v-128k-640x480-30fps-${frames_per_keyframe}kfr-manifest.json`,
     41      (type, data) => r({type, data})));
     42  // Overwrite timescale to shorten frame durations.
     43  MediaSourceUtil.WriteBigEndianInteger32ToUint8Array(
     44    timescale, media_640.data.subarray(media_timescale_start));
     45  MediaSourceUtil.WriteBigEndianInteger32ToUint8Array(
     46    timescale, media_640.data.subarray(segment_index_timescale_start));
     47 }, 'setup');
     48 
     49 promise_test(async t => {
     50  assert_implements_optional(MediaSource.isTypeSupported(media_320.type),
     51                             'type supported');
     52 
     53  const v = document.createElement('video');
     54  const v_watcher = new EventWatcher(t, v, ['error', 'ended']);
     55  document.body.appendChild(v);
     56  const media_source = new MediaSource();
     57  const media_source_watcher =
     58        new EventWatcher(t, media_source, ['sourceopen']);
     59  v.src = URL.createObjectURL(media_source);
     60  await media_source_watcher.wait_for('sourceopen');
     61 
     62  const source_buffer = media_source.addSourceBuffer(media_320.type);
     63  assert_equals(source_buffer.mode, 'segments', 'source_buffer.mode');
     64  const source_buffer_watcher =
     65        new EventWatcher(t, source_buffer, ['updateend']);
     66 
     67  // Append the first 320x240 frame.
     68  source_buffer.appendWindowEnd = (frame0_offset + 1) / fps;
     69  source_buffer.appendBuffer(media_320.data);
     70  await source_buffer_watcher.wait_for('updateend');
     71  assert_true(true, 'updateend');
     72 
     73  // Append the first 640x480 frame.
     74  source_buffer.timestampOffset = 1 / fps;
     75  source_buffer.appendWindowEnd = (1 + frame0_offset + 1) / fps;
     76  source_buffer.appendBuffer(media_640.data);
     77  // Not using v_watcher to work around an extra canplaythrough from Chrome.
     78  const canplaythrough_promise = new Promise(r => v.oncanplaythrough = r);
     79  await source_buffer_watcher.wait_for('updateend');
     80 
     81  media_source.endOfStream();
     82  await canplaythrough_promise;
     83  assert_equals(v.videoWidth, 320, 'videoWidth 320');
     84  assert_approx_equals(v.duration,
     85                       source_buffer.appendWindowEnd,
     86                       1e-6,
     87                       'duration');
     88 
     89  v.play();
     90  await v_watcher.wait_for('ended');
     91  assert_equals(v.currentTime, v.duration, 'v.currentTime');
     92  assert_equals(v.videoWidth, 640, 'videoWidth 640');
     93 }, 'last frame dimensions');
     94 </script>
     95 </html>