tor-browser

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

test_peerConnection_simulcastOffer_lowResFirst.html (4385B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <script type="application/javascript" src="pc.js"></script>
      5  <script type="application/javascript" src="parser_rtp.js"></script>
      6  <script type="application/javascript" src="/tests/dom/canvas/test/captureStream_common.js"></script>
      7  <script type="application/javascript" src="helpers_from_wpt/sdp.js"></script>
      8  <script type="application/javascript" src="simulcast.js"></script>
      9  <script type="application/javascript" src="stats.js"></script>
     10 </head>
     11 <body>
     12 <pre id="test">
     13 <script type="application/javascript">
     14  createHTML({
     15    bug: "1231507",
     16    title: "Basic video-only peer connection with Simulcast offer, first rid has lowest resolution",
     17    visible: true
     18  });
     19 
     20  runNetworkTest(async () => {
     21    await pushPrefs(
     22        // 180Kbps was determined empirically, set well-higher than
     23        // the 80Kbps+overhead needed for the two simulcast streams.
     24        // 100Kbps was apparently too low.
     25        ['media.peerconnection.video.min_bitrate_estimate', 180*1000]);
     26 
     27    // [TODO] re-enable HW decoder after bug 1526207 is fixed.
     28    if (navigator.userAgent.includes("Android")) {
     29      await pushPrefs(["media.navigator.mediadatadecoder_vpx_enabled", false]);
     30    }
     31 
     32 
     33    const offerer = new RTCPeerConnection();
     34    const answerer = new RTCPeerConnection();
     35 
     36    const add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed);
     37    offerer.onicecandidate = e => add(answerer, e.candidate, generateErrorCallback());
     38    answerer.onicecandidate = e => add(offerer, e.candidate, generateErrorCallback());
     39 
     40    const metadataToBeLoaded = [];
     41    answerer.ontrack = (e) => {
     42      metadataToBeLoaded.push(getPlaybackWithLoadedMetadata(e.track));
     43    };
     44 
     45    // One send transceiver, that will be used to send both simulcast streams
     46    const emitter = new VideoFrameEmitter();
     47    const videoStream = emitter.stream();
     48    const sendEncodings = [
     49      { rid: '0', maxBitrate: 40000, scaleResolutionDownBy: 2 },
     50      { rid: '1', maxBitrate: 40000 }
     51    ];
     52    offerer.addTransceiver(videoStream.getVideoTracks()[0], {sendEncodings});
     53    emitter.start();
     54 
     55    const sender = offerer.getSenders()[0];
     56 
     57    const offer = await offerer.createOffer();
     58 
     59    const mungedOffer = ridToMid(offer);
     60    info(`Transformed send simulcast offer to multiple m-sections: ${offer.sdp} to ${mungedOffer}`);
     61 
     62    await answerer.setRemoteDescription({type: 'offer', sdp: mungedOffer});
     63    await offerer.setLocalDescription(offer);
     64 
     65    const rids = answerer.getTransceivers().map(t => t.mid);
     66    is(rids.length, 2, 'Should have 2 mids in offer');
     67    ok(rids[0] != '', 'First mid should be non-empty');
     68    ok(rids[1] != '', 'Second mid should be non-empty');
     69    info(`rids: ${JSON.stringify(rids)}`);
     70 
     71    const answer = await answerer.createAnswer();
     72 
     73    const mungedAnswer = midToRid(answer);
     74    info(`Transformed recv answer to simulcast: ${answer.sdp} to ${mungedAnswer}`);
     75    await offerer.setRemoteDescription({type: 'answer', sdp: mungedAnswer});
     76    await answerer.setLocalDescription(answer);
     77 
     78    is(metadataToBeLoaded.length, 2, 'Offerer should have gotten 2 ontrack events');
     79    info('Waiting for 2 loadedmetadata events');
     80    const videoElems = await Promise.all(metadataToBeLoaded);
     81 
     82    const statsReady =
     83      Promise.all([waitForSyncedRtcp(offerer), waitForSyncedRtcp(answerer)]);
     84 
     85    const helper = new VideoStreamHelper();
     86    info('Waiting for first video element to start playing');
     87    await helper.checkVideoPlaying(videoElems[0]);
     88    info('Waiting for second video element to start playing');
     89    await helper.checkVideoPlaying(videoElems[1]);
     90 
     91    is(videoElems[1].videoWidth, 64,
     92       "sink is same width as source, modulo our cropping algorithm");
     93    is(videoElems[1].videoHeight, 64,
     94       "sink is same height as source, modulo our cropping algorithm");
     95    is(videoElems[0].videoWidth, 32,
     96       "sink is 1/2 width of source, modulo our cropping algorithm");
     97    is(videoElems[0].videoHeight, 32,
     98       "sink is 1/2 height of source, modulo our cropping algorithm");
     99 
    100    await statsReady;
    101    const senderStats = await sender.getStats();
    102    checkSenderStats(senderStats, 2);
    103    checkExpectedFields(senderStats);
    104    pedanticChecks(senderStats);
    105 
    106    emitter.stop();
    107    videoStream.getVideoTracks()[0].stop();
    108    offerer.close();
    109    answerer.close();
    110  });
    111 </script>
    112 </pre>
    113 </body>
    114 </html>