From e26e77694f6ccf42c78c61b773ad3dca5b4ede42 Mon Sep 17 00:00:00 2001 From: Nico Grunbaum Date: Tue, 6 Nov 2018 04:55:43 +0000 Subject: [PATCH] Correct WebRTC getStats WPT to wait for remote stats before comparing If care is not taken to wait for remote stats on senders and receivers, then the contents of the stats reports will not be stable. Waiting for this stability should fix our intermittent failures checking that RTCRtpSender/Receiver.getStats() returns the same dictionaries that RTCPeerConnection.getStats(sender/receiver.track) does. Differential Revision: https://phabricator.services.mozilla.com/D5804 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1457129 gecko-commit: 0874b793fc046bf31ca80c673d5dfa0bb38ea343 gecko-integration-branch: autoland gecko-reviewers: jib --- webrtc/RTCPeerConnection-helper.js | 13 +++++++++++++ webrtc/RTCPeerConnection-track-stats.https.html | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/webrtc/RTCPeerConnection-helper.js b/webrtc/RTCPeerConnection-helper.js index 8529fb4ef3cdf5..df277ff6d35585 100644 --- a/webrtc/RTCPeerConnection-helper.js +++ b/webrtc/RTCPeerConnection-helper.js @@ -249,6 +249,19 @@ function createDataChannelPair( }); } +// Wait for RTP and RTCP stats to arrive +async function waitForRtpAndRtcpStats(pc) { + while (true) { + const report = await pc.getStats(); + const stats = [...report.values()].filter(({type}) => type.endsWith("bound-rtp")); + // Each RTP and RTCP stat has a reference + // to the matching stat in the other direction + if (stats.length && stats.every(({localId, remoteId}) => localId || remoteId)) { + break; + } + } +} + // Wait for a single message event and return // a promise that resolve when the event fires function awaitMessage(channel) { diff --git a/webrtc/RTCPeerConnection-track-stats.https.html b/webrtc/RTCPeerConnection-track-stats.https.html index 682e7e57e465cc..3809530b74cac3 100644 --- a/webrtc/RTCPeerConnection-track-stats.https.html +++ b/webrtc/RTCPeerConnection-track-stats.https.html @@ -1,5 +1,6 @@ + RTCPeerConnection.prototype.getStats @@ -12,6 +13,7 @@ // The following helper functions are called from RTCPeerConnection-helper.js: // doSignalingHandshake // getUserMediaTracksAndStreams + // waitForRtpAndRtcpStats // The following helper functions are called from RTCStats-helper.js // (depends on dictionary-helper.js): @@ -504,6 +506,10 @@ await doSignalingHandshake(caller, callee); await onIceConnectionStateCompleted(caller); + // Wait until RTCP has arrived so that it can not arrive between + // the two get stats calls. + await waitForRtpAndRtcpStats(caller); + let senderReport = await sender.getStats(); let trackReport = await caller.getStats(sender.track); @@ -532,6 +538,10 @@ await onIceConnectionStateCompleted(caller); let receiver = caller.getReceivers()[0]; + // Wait until RTCP has arrived so that it can not arrive between + // the two get stats calls. + await waitForRtpAndRtcpStats(caller); + let receiverReport = await receiver.getStats(); let trackReport = await caller.getStats(receiver.track);