DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
<!DOCTYPE HTML>
<html>
<head>
  <script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
  createHTML({
    bug: "1363667",
    title: "Test audio receiver getContributingSources"
  });

  var SpWrap = (pc) => SpecialPowers.wrap(pc._pc);

  var SpRtpSourceNowTimestamp = (pc) => {
    return SpecialPowers.wrap(pc._pc).mozGetNowInRtpSourceReferenceTime();
  };
  var SpInsertLevelForContributingSource = (pc, ...args) => {
    return SpecialPowers.wrap(pc._pc).mozInsertLevelForContributingSource(
        ...args);
  };
  // test_peerConnection_audioSynchronizationSources.html tests
  // much of the functionality of getContributingSources as the implementation
  // is shared.
  var testGetContributingSources = async (test) => {
    let remoteReceiver = test.pcRemote.getReceivers()[0];
    let localReceiver = test.pcLocal.getReceivers()[0];

    // Check that getContributingSources is empty as there is no MCU
    is(remoteReceiver.getContributingSources().length, 0,
       "remote contributing sources is empty");
    is(localReceiver.getContributingSources().length, 0,
       "local contributing sources is empty");
    // Wait for the next JS event loop iteration, to clear the cache
    await Promise.resolve().then();
    // Insert new entries as if there were an MCU
    let csrc0 = 124756;
    let timestamp0 = SpWrap(test.pcRemote).mozGetNowInRtpSourceReferenceTime();
    let timestampOffset = new Date().getTime() - timestamp0;
    let hasAudioLevel0 = true;
    // Audio level as expected to be received in RTP
    let audioLevel0 = 34;
    // Audio level as expected to be returned
    let expectedAudioLevel0 = 10 ** (-audioLevel0 / 20);

    SpWrap(test.pcRemote).mozInsertAudioLevelForContributingSource(
        remoteReceiver,
        csrc0,
        timestamp0,
        hasAudioLevel0,
        audioLevel0);

    let csrc1 = 5786;
    let timestamp1 = timestamp0 - 200;
    let hasAudioLevel1 = false;
    let audioLevel1 = 0;

    SpWrap(test.pcRemote).mozInsertAudioLevelForContributingSource(
        remoteReceiver,
        csrc1,
        timestamp1,
        hasAudioLevel1,
        audioLevel1);

    let csrc2 = 93487;
    let timestamp2 = timestamp0 - 200;
    let hasAudioLevel2 = true;
    let audioLevel2 = 127;

    SpWrap(test.pcRemote).mozInsertAudioLevelForContributingSource(
        remoteReceiver,
        csrc2,
        timestamp2,
        hasAudioLevel2,
        audioLevel2);

    let contributingSources = remoteReceiver.getContributingSources();
    is(contributingSources.length, 3,
       "Expected number of contributing sources");

    // Check that both inserted were returned
    let source0 = contributingSources.find(c => c.source == csrc0);
    ok(source0, "first csrc was found");

    let source1 = contributingSources.find(c => c.source == csrc1);
    ok(source1, "second csrsc was found");

    // Add a small margin of error in the timestamps
    let compareTimestamps = (ts1, ts2) => Math.abs(ts1 - ts2) < 100;

    // Check the CSRC with audioLevel
    let isWithinErr = Math.abs(source0.audioLevel - expectedAudioLevel0)
        < expectedAudioLevel0 / 50;
    ok(isWithinErr,
       `Contributing source has correct audio level. (${source0.audioLevel})`);
    ok(compareTimestamps(source0.timestamp, timestamp0 + timestampOffset),
       `Contributing source has correct timestamp (${source0.timestamp})`);

    // Check the CSRC without audioLevel
    is(source1.audioLevel, undefined,
       `Contributing source has no audio level. (${source1.audioLevel})`);
    ok(compareTimestamps(source1.timestamp, timestamp1 + timestampOffset),
       `Contributing source has correct timestamp (${source1.timestamp})`);
    // Check that a received RTP audio level 127 is exactly 0
    let source2 = contributingSources.find(c => c.source == csrc2);
    ok(source2, "third csrc was found");
    is(source2.audioLevel, 0,
      `Contributing source has audio level of 0 when RTP audio level is 127`);
    // Check caching
    is(JSON.stringify(contributingSources),
       JSON.stringify(remoteReceiver.getContributingSources()),
       "getContributingSources is cached");
    // Check that sources are sorted in descending order by time stamp
    const timestamp3 = SpWrap(test.pcLocal).mozGetNowInRtpSourceReferenceTime();
    // Larger offsets are further back in time
    const testOffsets = [3, 7, 5, 6, 1, 4];
    for (const offset of testOffsets) {
      SpWrap(test.pcLocal).mozInsertAudioLevelForContributingSource(
          localReceiver,
          offset, // Using offset for SSRC for convenience
          timestamp3 - offset,
          true,
          offset);
    }
    const sources = localReceiver.getContributingSources();
    const sourceOffsets = sources.map(s => s.source);
    is(JSON.stringify(sourceOffsets),
       JSON.stringify([...testOffsets].sort((a, b) => a - b)),
          `Contributing sources are sorted in descending order by timestamp:`
          + ` ${JSON.stringify(sources)}`);
  };

  var test;
  runNetworkTest(function(options) {
    test = new PeerConnectionTest(options);
    test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
      [testGetContributingSources]);
    test.setMediaConstraints([{audio: true}], [{audio: true}]);
    test.pcLocal.audioElementsOnly = true;
    SpecialPowers.pushPrefEnv(
    { "set": [["privacy.reduceTimerPrecision", false]]}, function() {
      test.run();
    });
  });
</script>
</pre>
</body>
</html>