Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
<!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"
});
// test_peerConnection_audioSynchronizationSources.html tests
// much of the functionality of getContributingSources as the implementation
// is shared.
var testGetContributingSources = async (test) => {
const remoteReceiver = test.pcRemote.getReceivers()[0];
const 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
const csrc0 = 124756;
const timestamp0 = performance.now() + performance.timeOrigin;
const rtpTimestamp0 = 11111;
const hasAudioLevel0 = true;
// Audio level as expected to be received in RTP
const audioLevel0 = 34;
// Audio level as expected to be returned
const expectedAudioLevel0 = 10 ** (-audioLevel0 / 20);
SpecialPowers.wrap(remoteReceiver).mozInsertAudioLevelForContributingSource(
csrc0,
timestamp0,
rtpTimestamp0,
hasAudioLevel0,
audioLevel0);
const csrc1 = 5786;
const timestamp1 = timestamp0 - 200;
const rtpTimestamp1 = 22222;
const hasAudioLevel1 = false;
const audioLevel1 = 0;
SpecialPowers.wrap(remoteReceiver).mozInsertAudioLevelForContributingSource(
csrc1,
timestamp1,
rtpTimestamp1,
hasAudioLevel1,
audioLevel1);
const csrc2 = 93487;
const timestamp2 = timestamp0 - 200;
const rtpTimestamp2 = 333333;
const hasAudioLevel2 = true;
const audioLevel2 = 127;
SpecialPowers.wrap(remoteReceiver).mozInsertAudioLevelForContributingSource(
csrc2,
timestamp2,
rtpTimestamp2,
hasAudioLevel2,
audioLevel2);
const contributingSources = remoteReceiver.getContributingSources();
is(contributingSources.length, 3,
"Expected number of contributing sources");
// Check that both inserted were returned
const source0 = contributingSources.find(c => c.source == csrc0);
ok(source0, "first csrc was found");
const source1 = contributingSources.find(c => c.source == csrc1);
ok(source1, "second csrsc was found");
// Add a small margin of error in the timestamps
const compareTimestamps = (ts1, ts2) => Math.abs(ts1 - ts2) < 100;
// Check the CSRC with audioLevel
const isWithinErr = Math.abs(source0.audioLevel - expectedAudioLevel0)
< expectedAudioLevel0 / 50;
ok(isWithinErr,
`Contributing source has correct audio level. (${source0.audioLevel})`);
ok(compareTimestamps(source0.timestamp, timestamp0),
`Contributing source has correct timestamp (got ${source0.timestamp}), expected ${timestamp0}`);
is(source0.rtpTimestamp, rtpTimestamp0,
`Contributing source has correct RTP timestamp (${source0.rtpTimestamp}`);
// Check the CSRC without audioLevel
is(source1.audioLevel, undefined,
`Contributing source has no audio level. (${source1.audioLevel})`);
ok(compareTimestamps(source1.timestamp, timestamp1),
`Contributing source has correct timestamp (got ${source1.timestamp}, expected ${timestamp1})`);
is(source1.rtpTimestamp, rtpTimestamp1,
`Contributing source has correct RTP timestamp (${source1.rtpTimestamp}`);
// Check that a received RTP audio level 127 is exactly 0
const 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 = performance.now() + performance.timeOrigin;
const rtpTimestamp3 = 44444;
// Larger offsets are further back in time
const testOffsets = [3, 7, 5, 6, 1, 4];
for (const offset of testOffsets) {
SpecialPowers.wrap(localReceiver).mozInsertAudioLevelForContributingSource(
offset, // Using offset for SSRC for convenience
timestamp3 - offset,
rtpTimestamp3,
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(async 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;
await pushPrefs(["privacy.reduceTimerPrecision", false]);
await test.run();
});
</script>
</pre>
</body>
</html>