Add `RTCRemoteOutboundRtpStreamStats` for audio streams

Changes:
- adding the `RTCRemoteOutboundRtpStreamStats` dictionary (see [1])
- collection of remote outbound stats (only for audio streams)
- adding `remote_id` to the inbound stats and set with the ID of the
  corresponding remote outbound stats only if the latter are available
- unit tests

[1] https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats

Tested: verified from chrome://webrtc-internals during an appr.tc call

Bug: webrtc:12529
Change-Id: Ide91dc04a3c387ba439618a9c6b64a95994a1940
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/211042
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33545}
diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc
index a285555..8b12c67 100644
--- a/pc/rtc_stats_integrationtest.cc
+++ b/pc/rtc_stats_integrationtest.cc
@@ -399,6 +399,9 @@
       } else if (stats.type() == RTCRemoteInboundRtpStreamStats::kType) {
         verify_successful &= VerifyRTCRemoteInboundRtpStreamStats(
             stats.cast_to<RTCRemoteInboundRtpStreamStats>());
+      } else if (stats.type() == RTCRemoteOutboundRtpStreamStats::kType) {
+        verify_successful &= VerifyRTCRemoteOutboundRTPStreamStats(
+            stats.cast_to<RTCRemoteOutboundRtpStreamStats>());
       } else if (stats.type() == RTCAudioSourceStats::kType) {
         // RTCAudioSourceStats::kType and RTCVideoSourceStats::kType both have
         // the value "media-source", but they are distinguishable with pointer
@@ -769,29 +772,38 @@
   }
 
   void VerifyRTCRTPStreamStats(const RTCRTPStreamStats& stream,
-                               RTCStatsVerifier* verifier) {
-    verifier->TestMemberIsDefined(stream.ssrc);
-    verifier->TestMemberIsDefined(stream.kind);
+                               RTCStatsVerifier& verifier) {
+    verifier.TestMemberIsDefined(stream.ssrc);
+    verifier.TestMemberIsDefined(stream.kind);
     // Some legacy metrics are only defined for some of the RTP types in the
     // hierarcy.
     if (stream.type() == RTCInboundRTPStreamStats::kType ||
         stream.type() == RTCOutboundRTPStreamStats::kType) {
-      verifier->TestMemberIsDefined(stream.media_type);
-      verifier->TestMemberIsIDReference(stream.track_id,
-                                        RTCMediaStreamTrackStats::kType);
+      verifier.TestMemberIsDefined(stream.media_type);
+      verifier.TestMemberIsIDReference(stream.track_id,
+                                       RTCMediaStreamTrackStats::kType);
     } else {
-      verifier->TestMemberIsUndefined(stream.media_type);
-      verifier->TestMemberIsUndefined(stream.track_id);
+      verifier.TestMemberIsUndefined(stream.media_type);
+      verifier.TestMemberIsUndefined(stream.track_id);
     }
-    verifier->TestMemberIsIDReference(stream.transport_id,
-                                      RTCTransportStats::kType);
-    verifier->TestMemberIsIDReference(stream.codec_id, RTCCodecStats::kType);
+    verifier.TestMemberIsIDReference(stream.transport_id,
+                                     RTCTransportStats::kType);
+    verifier.TestMemberIsIDReference(stream.codec_id, RTCCodecStats::kType);
+  }
+
+  void VerifyRTCSentRTPStreamStats(const RTCSentRtpStreamStats& sent_stream,
+                                   RTCStatsVerifier& verifier) {
+    VerifyRTCRTPStreamStats(sent_stream, verifier);
+    verifier.TestMemberIsDefined(sent_stream.packets_sent);
+    verifier.TestMemberIsDefined(sent_stream.bytes_sent);
   }
 
   bool VerifyRTCInboundRTPStreamStats(
       const RTCInboundRTPStreamStats& inbound_stream) {
     RTCStatsVerifier verifier(report_, &inbound_stream);
-    VerifyRTCRTPStreamStats(inbound_stream, &verifier);
+    VerifyRTCRTPStreamStats(inbound_stream, verifier);
+    verifier.TestMemberIsOptionalIDReference(
+        inbound_stream.remote_id, RTCRemoteOutboundRtpStreamStats::kType);
     if (inbound_stream.media_type.is_defined() &&
         *inbound_stream.media_type == "video") {
       verifier.TestMemberIsNonNegative<uint64_t>(inbound_stream.qp_sum);
@@ -928,7 +940,7 @@
     // TODO(https://crbug.com/webrtc/12532): Invoke
     // VerifyRTCReceivedRtpStreamStats() instead of VerifyRTCRTPStreamStats()
     // because they have a shared hierarchy now!
-    VerifyRTCRTPStreamStats(outbound_stream, &verifier);
+    VerifyRTCRTPStreamStats(outbound_stream, verifier);
     if (outbound_stream.media_type.is_defined() &&
         *outbound_stream.media_type == "video") {
       verifier.TestMemberIsIDReference(outbound_stream.media_source_id,
@@ -1021,16 +1033,16 @@
 
   void VerifyRTCReceivedRtpStreamStats(
       const RTCReceivedRtpStreamStats& received_rtp,
-      RTCStatsVerifier* verifier) {
+      RTCStatsVerifier& verifier) {
     VerifyRTCRTPStreamStats(received_rtp, verifier);
-    verifier->TestMemberIsNonNegative<double>(received_rtp.jitter);
-    verifier->TestMemberIsDefined(received_rtp.packets_lost);
+    verifier.TestMemberIsNonNegative<double>(received_rtp.jitter);
+    verifier.TestMemberIsDefined(received_rtp.packets_lost);
   }
 
   bool VerifyRTCRemoteInboundRtpStreamStats(
       const RTCRemoteInboundRtpStreamStats& remote_inbound_stream) {
     RTCStatsVerifier verifier(report_, &remote_inbound_stream);
-    VerifyRTCReceivedRtpStreamStats(remote_inbound_stream, &verifier);
+    VerifyRTCReceivedRtpStreamStats(remote_inbound_stream, verifier);
     verifier.TestMemberIsDefined(remote_inbound_stream.fraction_lost);
     verifier.TestMemberIsIDReference(remote_inbound_stream.local_id,
                                      RTCOutboundRTPStreamStats::kType);
@@ -1043,6 +1055,19 @@
     return verifier.ExpectAllMembersSuccessfullyTested();
   }
 
+  bool VerifyRTCRemoteOutboundRTPStreamStats(
+      const RTCRemoteOutboundRtpStreamStats& remote_outbound_stream) {
+    RTCStatsVerifier verifier(report_, &remote_outbound_stream);
+    VerifyRTCRTPStreamStats(remote_outbound_stream, verifier);
+    VerifyRTCSentRTPStreamStats(remote_outbound_stream, verifier);
+    verifier.TestMemberIsIDReference(remote_outbound_stream.local_id,
+                                     RTCOutboundRTPStreamStats::kType);
+    verifier.TestMemberIsNonNegative<double>(
+        remote_outbound_stream.remote_timestamp);
+    verifier.TestMemberIsDefined(remote_outbound_stream.reports_sent);
+    return verifier.ExpectAllMembersSuccessfullyTested();
+  }
+
   void VerifyRTCMediaSourceStats(const RTCMediaSourceStats& media_source,
                                  RTCStatsVerifier* verifier) {
     verifier->TestMemberIsDefined(media_source.track_identifier);