tor-browser

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

RTCRtpSender-setParameters-keyFrame.html (3999B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <meta name="timeout" content="long">
      4 <title>RTCRtpSender.prototype.setParameters for generating keyFrames</title>
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="RTCPeerConnection-helper.js"></script>
      8 <script src="third_party/sdp/sdp.js"></script>
      9 <script src="simulcast/simulcast.js"></script>
     10 <script>
     11 'use strict';
     12 
     13 // https://w3c.github.io/webrtc-extensions/#rtcrtpsender-setparameters-keyframe
     14 
     15 async function waitForKeyFrameCount(t, pc, spatialLayer, minimumKeyFrames) {
     16  // return after 5 seconds.
     17  const startTime = performance.now();
     18  while (true) {
     19    const report = await pc.getStats();
     20    const stats = [...report.values()].find(({type, rid}) => type === 'outbound-rtp' && rid === spatialLayer);
     21    if (stats && stats.keyFramesEncoded >= minimumKeyFrames) {
     22      return stats;
     23    }
     24    await new Promise(r => t.step_timeout(r, 100));
     25    if (performance.now() > startTime + 5000) {
     26      break;
     27    }
     28  }
     29 }
     30 
     31 promise_test(async t => {
     32  const pc1 = new RTCPeerConnection();
     33  t.add_cleanup(() => pc1.close());
     34  const pc2 = new RTCPeerConnection();
     35  t.add_cleanup(() => pc2.close());
     36  // Video must be small enough to reach a key frame of the right size immediately.
     37  const stream = await getNoiseStream({video: {width: 320, height: 160}});
     38  t.add_cleanup(() => stream.getTracks().forEach(t => t.stop()));
     39 
     40  const sender = pc1.addTrack(stream.getTracks()[0], stream);
     41  exchangeIceCandidates(pc1, pc2);
     42  await exchangeOfferAnswer(pc1, pc2);
     43 
     44  const rid = undefined;
     45  const first_stats = await waitForKeyFrameCount(t, pc1, rid, 1);
     46  assert_true(!!first_stats);
     47  sender.setParameters(sender.getParameters(), {
     48    encodingOptions: [{keyFrame: true}],
     49  });
     50  const second_stats = await waitForKeyFrameCount(t, pc1, rid, first_stats.keyFramesEncoded + 1);
     51  assert_true(!!second_stats);
     52  assert_greater_than(second_stats.keyFramesEncoded, first_stats.keyFramesEncoded);
     53 }, `setParameters() second argument can be used to trigger keyFrame generation`);
     54 
     55 promise_test(async t => {
     56  const pc1 = new RTCPeerConnection();
     57  t.add_cleanup(() => pc1.close());
     58  const pc2 = new RTCPeerConnection();
     59  t.add_cleanup(() => pc2.close());
     60  // Video must be small enough to reach a key frame of the right size immediately.
     61  const stream = await getNoiseStream({video: {width: 640, height: 360}});
     62  t.add_cleanup(() => stream.getTracks().forEach(t => t.stop()));
     63 
     64  const rids = ['0', '1'];
     65  const {sender} = pc1.addTransceiver(stream.getTracks()[0], {
     66    streams: [stream],
     67    sendEncodings: [{rid: 0}, {rid: 1}],
     68  });
     69  exchangeIceCandidates(pc1, pc2);
     70  await pc1.setLocalDescription();
     71  await pc2.setRemoteDescription({type: 'offer', sdp: ridToMid(pc1.localDescription, rids)});
     72  await pc2.setLocalDescription();
     73  await pc1.setRemoteDescription({type: 'answer', sdp: midToRid(
     74    pc2.localDescription,
     75    pc1.localDescription,
     76    rids
     77  )});
     78 
     79  const first_stats_l0 = await waitForKeyFrameCount(t, pc1, '0', 1);
     80  assert_true(!!first_stats_l0);
     81  const first_stats_l1 = await waitForKeyFrameCount(t, pc1, '1', 1);
     82  assert_true(!!first_stats_l1);
     83 
     84  // Generate a keyframe on the second layer. This may, depending on the encoder, force
     85  // a key frame on the first layer as well.
     86  sender.setParameters(sender.getParameters(), {
     87    encodingOptions: [{keyFrame: false}, {keyFrame: true}],
     88  });
     89  const second_stats_l1 = await waitForKeyFrameCount(t, pc1, '1', first_stats_l1.keyFramesEncoded + 1);
     90  assert_true(!!second_stats_l1);
     91  assert_greater_than(second_stats_l1.keyFramesEncoded, first_stats_l1.keyFramesEncoded);
     92 
     93  const second_stats_l0 = await waitForKeyFrameCount(t, pc1, '0', first_stats_l0.keyFramesEncoded);
     94  assert_true(!!second_stats_l0);
     95  assert_greater_than_equal(second_stats_l0.keyFramesEncoded, first_stats_l0.keyFramesEncoded);
     96 }, `setParameters() second argument can be used to trigger keyFrame generation (simulcast)`);
     97 </script>