stats: implement RTX ssrc on inbound-rtp/outbound-rtp
spec change:
https://github.com/w3c/webrtc-stats/pull/765
BUG=webrtc:15096
Change-Id: I7c72193c23460330b6bb612a9568641d187ee638
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/312362
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40510}
diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h
index 0b5d8d2..4861f8a 100644
--- a/api/stats/rtcstats_objects.h
+++ b/api/stats/rtcstats_objects.h
@@ -256,6 +256,8 @@
// possible to distinguish retransmissions.
RTCStatsMember<uint64_t> retransmitted_packets_received;
RTCStatsMember<uint64_t> retransmitted_bytes_received;
+ RTCStatsMember<uint32_t> rtx_ssrc;
+
RTCStatsMember<double> last_packet_received_timestamp;
RTCStatsMember<double> jitter_buffer_delay;
RTCStatsMember<double> jitter_buffer_target_delay;
@@ -368,6 +370,9 @@
// In JavaScript, this is only exposed if HW exposure is allowed.
RTCStatsMember<bool> power_efficient_encoder;
RTCStatsMember<std::string> scalability_mode;
+
+ // RTX ssrc. Only present if RTX is negotiated.
+ RTCStatsMember<uint32_t> rtx_ssrc;
};
// https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index 07e8771..0c4df20 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -677,6 +677,12 @@
inbound_video->power_efficient_decoder =
*video_receiver_info.power_efficient_decoder;
}
+ for (const auto& ssrc_group : video_receiver_info.ssrc_groups) {
+ if (ssrc_group.semantics == cricket::kFidSsrcGroupSemantics &&
+ ssrc_group.ssrcs.size() == 2) {
+ inbound_video->rtx_ssrc = ssrc_group.ssrcs[1];
+ }
+ }
return inbound_video;
}
@@ -826,6 +832,12 @@
outbound_video->scalability_mode = std::string(
ScalabilityModeToString(*video_sender_info.scalability_mode));
}
+ for (const auto& ssrc_group : video_sender_info.ssrc_groups) {
+ if (ssrc_group.semantics == cricket::kFidSsrcGroupSemantics &&
+ ssrc_group.ssrcs.size() == 2) {
+ outbound_video->rtx_ssrc = ssrc_group.ssrcs[1];
+ }
+ }
return outbound_video;
}
diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc
index 8781b32..788c884 100644
--- a/pc/rtc_stats_collector_unittest.cc
+++ b/pc/rtc_stats_collector_unittest.cc
@@ -2368,6 +2368,8 @@
video_media_info.receivers[0].retransmitted_bytes_received = 62;
video_media_info.receivers[0].fec_packets_received = 32;
video_media_info.receivers[0].fec_bytes_received = 54;
+ video_media_info.receivers[0].ssrc_groups.push_back(
+ {cricket::kFidSsrcGroupSemantics, {1, 4404}});
// Note: these two values intentionally differ,
// only the decoded one should show up.
@@ -2434,6 +2436,7 @@
expected_video.retransmitted_bytes_received = 62;
expected_video.fec_packets_received = 32;
expected_video.fec_bytes_received = 54;
+ expected_video.rtx_ssrc = 4404;
ASSERT_TRUE(report->Get(expected_video.id()));
EXPECT_EQ(
@@ -2629,6 +2632,8 @@
video_media_info.senders[0].huge_frames_sent = 2;
video_media_info.senders[0].active = false;
video_media_info.senders[0].scalability_mode = ScalabilityMode::kL3T3_KEY;
+ video_media_info.senders[0].ssrc_groups.push_back(
+ {cricket::kFidSsrcGroupSemantics, {1, 4404}});
video_media_info.aggregated_senders.push_back(video_media_info.senders[0]);
RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42;
@@ -2684,6 +2689,7 @@
expected_video.active = false;
expected_video.power_efficient_encoder = false;
expected_video.scalability_mode = "L3T3_KEY";
+ expected_video.rtx_ssrc = 4404;
// `expected_video.content_type` should be undefined.
// `expected_video.qp_sum` should be undefined.
// `expected_video.encoder_implementation` should be undefined.
diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc
index fd47865..3e767a7 100644
--- a/pc/rtc_stats_integrationtest.cc
+++ b/pc/rtc_stats_integrationtest.cc
@@ -693,11 +693,13 @@
inbound_stream.retransmitted_packets_received);
verifier.TestMemberIsNonNegative<uint64_t>(
inbound_stream.retransmitted_bytes_received);
+ verifier.TestMemberIsNonNegative<uint32_t>(inbound_stream.rtx_ssrc);
} else {
verifier.TestMemberIsUndefined(
inbound_stream.retransmitted_packets_received);
verifier.TestMemberIsUndefined(
inbound_stream.retransmitted_bytes_received);
+ verifier.TestMemberIsUndefined(inbound_stream.rtx_ssrc);
}
// Test runtime too short to get an estimate (at least two RTCP sender
@@ -849,6 +851,7 @@
outbound_stream.huge_frames_sent);
verifier.MarkMemberTested(outbound_stream.rid, true);
verifier.TestMemberIsDefined(outbound_stream.scalability_mode);
+ verifier.TestMemberIsNonNegative<uint32_t>(outbound_stream.rtx_ssrc);
} else {
verifier.TestMemberIsUndefined(outbound_stream.frames_encoded);
verifier.TestMemberIsUndefined(outbound_stream.key_frames_encoded);
@@ -871,6 +874,7 @@
verifier.TestMemberIsUndefined(outbound_stream.frames_sent);
verifier.TestMemberIsUndefined(outbound_stream.huge_frames_sent);
verifier.TestMemberIsUndefined(outbound_stream.scalability_mode);
+ verifier.TestMemberIsUndefined(outbound_stream.rtx_ssrc);
}
return verifier.ExpectAllMembersSuccessfullyTested();
}
diff --git a/stats/rtcstats_objects.cc b/stats/rtcstats_objects.cc
index 97786f9..fbd597c 100644
--- a/stats/rtcstats_objects.cc
+++ b/stats/rtcstats_objects.cc
@@ -313,6 +313,7 @@
&header_bytes_received,
&retransmitted_packets_received,
&retransmitted_bytes_received,
+ &rtx_ssrc,
&last_packet_received_timestamp,
&jitter_buffer_delay,
&jitter_buffer_target_delay,
@@ -378,6 +379,7 @@
header_bytes_received("headerBytesReceived"),
retransmitted_packets_received("retransmittedPacketsReceived"),
retransmitted_bytes_received("retransmittedBytesReceived"),
+ rtx_ssrc("rtxSsrc"),
last_packet_received_timestamp("lastPacketReceivedTimestamp"),
jitter_buffer_delay("jitterBufferDelay"),
jitter_buffer_target_delay("jitterBufferTargetDelay"),
@@ -462,7 +464,8 @@
&qp_sum,
&active,
&power_efficient_encoder,
- &scalability_mode)
+ &scalability_mode,
+ &rtx_ssrc)
// clang-format on
RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(std::string id,
@@ -498,7 +501,8 @@
qp_sum("qpSum"),
active("active"),
power_efficient_encoder("powerEfficientEncoder"),
- scalability_mode("scalabilityMode") {}
+ scalability_mode("scalabilityMode"),
+ rtx_ssrc("rtxSsrc") {}
RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(
const RTCOutboundRtpStreamStats& other) = default;