tor-browser

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

test_rvfc_timestamp_alignment.html (4745B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4  <script src="pc.js" type="application/javascript"></script>
      5  <script src="/tests/dom/canvas/test/captureStream_common.js" type="application/javascript"></script>
      6  <script src="stats.js" type="application/javascript"></script>
      7 </head>
      8 <body>
      9 <pre id="test">
     10 <script type="application/javascript">
     11  createHTML({
     12    bug: "1937776",
     13    title: "Verify VideoFrameCallback receiveTime/captureTime alignment",
     14  });
     15 
     16  const {AppConstants} = SpecialPowers.ChromeUtils.importESModule(
     17    "resource://gre/modules/AppConstants.sys.mjs"
     18  );
     19 
     20  runNetworkTest(async function(options) {
     21    async function WAIT_FOR_SYNCED_RTCP(test, count) {
     22      for (let i = 0; i < count; i++) {
     23        await waitForSyncedRtcp(test.pcLocal._pc);
     24        await waitForSyncedRtcp(test.pcRemote._pc);
     25      }
     26    }
     27 
     28    async function CHECK_TIMESTAMP_ALIGNMENT(test, ok_or_todo, header_text) {
     29      const video = test.pcRemote.remoteMediaElements[0];
     30      const maxFrames = 60;
     31      const maxRecvDelta = 250;
     32      const maxCaptDelta = 250;
     33      const minCaptCount = 5;
     34      let frameCount = 0;
     35      let captCount = 0;
     36 
     37      // macOS fixes for high jitter on try
     38      const recvOffset = AppConstants.platform == "macosx" ? -200 : 0;
     39      const captOffset = AppConstants.platform == "macosx" ? -200 : 0;
     40 
     41      // captureTime may not be present for several frames
     42      let missedCaptCount = 0;
     43 
     44      info(`***** RUNNING ${header_text} ALIGNMENT TEST`);
     45      info(`***** USING ASSERT ${ok_or_todo == ok ? "ok" : "todo"}() FOR captureTime`);
     46      info(`***** APPLYING ${recvOffset} ms OFFSET TO receiveTime ASSERTS`);
     47 
     48      while (++frameCount <= maxFrames) {
     49        info(`Checking frame #${frameCount} of ${maxFrames}`);
     50        const {now, metadata} =
     51          await new Promise(r => video.requestVideoFrameCallback(
     52              (now, metadata) => r({now, metadata})));
     53        const {presentationTime, receiveTime, captureTime} = metadata;
     54 
     55        ok(receiveTime, "receiveTime is present");
     56        if (receiveTime) {
     57          const dt = presentationTime - receiveTime;
     58          ok(dt > recvOffset, `receiveTime (${receiveTime.toFixed(2)} ms) < `
     59             + `presentationTime (${presentationTime.toFixed(2)} ms)`);
     60          if (dt > recvOffset) {
     61            ok(dt <= maxRecvDelta, `receiveTime delta (${dt.toFixed(2)} ms) <= ${maxRecvDelta} ms`);
     62          }
     63        }
     64 
     65        if (captureTime) {
     66          ok_or_todo(captureTime, `captureTime is present`);
     67          const dt = presentationTime - captureTime;
     68          ok(dt > captOffset, `captureTime (${captureTime.toFixed(2)} ms) < `
     69             + `presentationTime (${presentationTime.toFixed(2)} ms)`);
     70          if (dt > captOffset) {
     71            ok(dt <= maxCaptDelta, `captureTime delta (${dt.toFixed(2)} ms) <= ${maxCaptDelta} ms`);
     72          }
     73          if (++captCount >= minCaptCount) {
     74            info(`Received ${minCaptCount} captureTime, exiting test`);
     75            break;
     76          }
     77        } else {
     78          ok(++missedCaptCount == frameCount,
     79             "missing captureTime occurred sequentially from test start.");
     80        }
     81      }
     82      ok_or_todo(captCount >= minCaptCount,
     83                 `Captured at least ${captCount} captureTime`)
     84    }
     85 
     86    function arg_wrapper(fn, argsArr) {
     87      return async function wrap() {
     88        return fn(...argsArr);
     89      };
     90    }
     91 
     92    SimpleTest.requestCompleteLog();
     93    await pushPrefs(
     94      ["media.video_loopback_dev", ""],
     95      ["media.navigator.streams.fake", true]
     96    );
     97 
     98    // Note we use two RTCP syncs in these tests as we currently need two
     99    // RTCP measurements in order to estimate a NTP timestamp.
    100    // See: Use of rtp_to_ntp_.Estimate(rtp_timestamp) in
    101    //      RemoteNtpTimeEstimator::EstimateNtp() and
    102    //      the two measurement requirement in
    103    //      RtpToNtpEstimator::UpdateParameters()
    104    //      (as of 618678dd32e52dbaa8a56d72c6655032f48068b3)
    105 
    106    // Unidirectional captureTime is currently BROKEN.
    107    // See: bug 1971078 , bug 1971117
    108    const test_uni = new PeerConnectionTest(options);
    109    test_uni.setMediaConstraints([{ video: true }], []);
    110    test_uni.chain.append([
    111      arg_wrapper(WAIT_FOR_SYNCED_RTCP, [test_uni, 2]),
    112      arg_wrapper(CHECK_TIMESTAMP_ALIGNMENT, [test_uni, todo, "UNIDIRECTIONAL"]),
    113    ]);
    114    await test_uni.run();
    115 
    116    // Bidirectional test should pass.
    117    const test_bi = new PeerConnectionTest(options);
    118    test_bi.setMediaConstraints([{ video: true }], [{ video: true }]);
    119    test_bi.chain.append([
    120      arg_wrapper(WAIT_FOR_SYNCED_RTCP, [test_bi, 2]),
    121      arg_wrapper(CHECK_TIMESTAMP_ALIGNMENT, [test_bi, ok, "BIDIRECTIONAL"]),
    122    ]);
    123    await test_bi.run();
    124  });
    125 </script>
    126 </pre>
    127 </body>
    128 </html>