test_peerConnection_audioContributingSources.html (5609B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <script type="application/javascript" src="pc.js"></script> 5 </head> 6 <body> 7 <pre id="test"> 8 <script type="application/javascript"> 9 createHTML({ 10 bug: "1363667", 11 title: "Test audio receiver getContributingSources" 12 }); 13 14 // test_peerConnection_audioSynchronizationSources.html tests 15 // much of the functionality of getContributingSources as the implementation 16 // is shared. 17 var testGetContributingSources = async (test) => { 18 const remoteReceiver = test.pcRemote.getReceivers()[0]; 19 const localReceiver = test.pcLocal.getReceivers()[0]; 20 21 // Check that getContributingSources is empty as there is no MCU 22 is(remoteReceiver.getContributingSources().length, 0, 23 "remote contributing sources is empty"); 24 is(localReceiver.getContributingSources().length, 0, 25 "local contributing sources is empty"); 26 // Wait for the next JS event loop iteration, to clear the cache 27 // eslint-disable-next-line promise/valid-params 28 await Promise.resolve().then(); 29 // Insert new entries as if there were an MCU 30 const csrc0 = 124756; 31 const timestamp0 = performance.now() + performance.timeOrigin; 32 const rtpTimestamp0 = 11111; 33 const hasAudioLevel0 = true; 34 // Audio level as expected to be received in RTP 35 const audioLevel0 = 34; 36 // Audio level as expected to be returned 37 const expectedAudioLevel0 = 10 ** (-audioLevel0 / 20); 38 39 SpecialPowers.wrap(remoteReceiver).mozInsertAudioLevelForContributingSource( 40 csrc0, 41 timestamp0, 42 rtpTimestamp0, 43 hasAudioLevel0, 44 audioLevel0); 45 46 const csrc1 = 5786; 47 const timestamp1 = timestamp0 - 200; 48 const rtpTimestamp1 = 22222; 49 const hasAudioLevel1 = false; 50 const audioLevel1 = 0; 51 52 SpecialPowers.wrap(remoteReceiver).mozInsertAudioLevelForContributingSource( 53 csrc1, 54 timestamp1, 55 rtpTimestamp1, 56 hasAudioLevel1, 57 audioLevel1); 58 59 const csrc2 = 93487; 60 const timestamp2 = timestamp0 - 200; 61 const rtpTimestamp2 = 333333; 62 const hasAudioLevel2 = true; 63 const audioLevel2 = 127; 64 65 SpecialPowers.wrap(remoteReceiver).mozInsertAudioLevelForContributingSource( 66 csrc2, 67 timestamp2, 68 rtpTimestamp2, 69 hasAudioLevel2, 70 audioLevel2); 71 72 const contributingSources = remoteReceiver.getContributingSources(); 73 is(contributingSources.length, 3, 74 "Expected number of contributing sources"); 75 76 // Check that both inserted were returned 77 const source0 = contributingSources.find(c => c.source == csrc0); 78 ok(source0, "first csrc was found"); 79 80 const source1 = contributingSources.find(c => c.source == csrc1); 81 ok(source1, "second csrsc was found"); 82 83 // Add a small margin of error in the timestamps 84 const compareTimestamps = (ts1, ts2) => Math.abs(ts1 - ts2) < 100; 85 86 // Check the CSRC with audioLevel 87 const isWithinErr = Math.abs(source0.audioLevel - expectedAudioLevel0) 88 < expectedAudioLevel0 / 50; 89 ok(isWithinErr, 90 `Contributing source has correct audio level. (${source0.audioLevel})`); 91 ok(compareTimestamps(source0.timestamp, timestamp0), 92 `Contributing source has correct timestamp (got ${source0.timestamp}), expected ${timestamp0}`); 93 is(source0.rtpTimestamp, rtpTimestamp0, 94 `Contributing source has correct RTP timestamp (${source0.rtpTimestamp}`); 95 // Check the CSRC without audioLevel 96 is(source1.audioLevel, undefined, 97 `Contributing source has no audio level. (${source1.audioLevel})`); 98 ok(compareTimestamps(source1.timestamp, timestamp1), 99 `Contributing source has correct timestamp (got ${source1.timestamp}, expected ${timestamp1})`); 100 is(source1.rtpTimestamp, rtpTimestamp1, 101 `Contributing source has correct RTP timestamp (${source1.rtpTimestamp}`); 102 // Check that a received RTP audio level 127 is exactly 0 103 const source2 = contributingSources.find(c => c.source == csrc2); 104 ok(source2, "third csrc was found"); 105 is(source2.audioLevel, 0, 106 `Contributing source has audio level of 0 when RTP audio level is 127`); 107 // Check caching 108 is(JSON.stringify(contributingSources), 109 JSON.stringify(remoteReceiver.getContributingSources()), 110 "getContributingSources is cached"); 111 // Check that sources are sorted in descending order by time stamp 112 const timestamp3 = performance.now() + performance.timeOrigin; 113 const rtpTimestamp3 = 44444; 114 // Larger offsets are further back in time 115 const testOffsets = [3, 7, 5, 6, 1, 4]; 116 for (const offset of testOffsets) { 117 SpecialPowers.wrap(localReceiver).mozInsertAudioLevelForContributingSource( 118 offset, // Using offset for SSRC for convenience 119 timestamp3 - offset, 120 rtpTimestamp3, 121 true, 122 offset); 123 } 124 const sources = localReceiver.getContributingSources(); 125 const sourceOffsets = sources.map(s => s.source); 126 is(JSON.stringify(sourceOffsets), 127 JSON.stringify([...testOffsets].sort((a, b) => a - b)), 128 `Contributing sources are sorted in descending order by timestamp:` 129 + ` ${JSON.stringify(sources)}`); 130 }; 131 132 var test; 133 runNetworkTest(async function(options) { 134 test = new PeerConnectionTest(options); 135 test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW", 136 [testGetContributingSources]); 137 test.setMediaConstraints([{audio: true}], [{audio: true}]); 138 test.pcLocal.audioElementsOnly = true; 139 await pushPrefs(["privacy.reduceTimerPrecision", false]); 140 await test.run(); 141 }); 142 </script> 143 </pre> 144 </body> 145 </html>