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}
This commit is contained in:
Philipp Hancke 2023-07-28 12:27:13 +02:00 committed by WebRTC LUCI CQ
parent 73ae5ca594
commit 9b82b2f8d6
5 changed files with 33 additions and 2 deletions

View File

@ -256,6 +256,8 @@ class RTC_EXPORT RTCInboundRtpStreamStats final
// possible to distinguish retransmissions. // possible to distinguish retransmissions.
RTCStatsMember<uint64_t> retransmitted_packets_received; RTCStatsMember<uint64_t> retransmitted_packets_received;
RTCStatsMember<uint64_t> retransmitted_bytes_received; RTCStatsMember<uint64_t> retransmitted_bytes_received;
RTCStatsMember<uint32_t> rtx_ssrc;
RTCStatsMember<double> last_packet_received_timestamp; RTCStatsMember<double> last_packet_received_timestamp;
RTCStatsMember<double> jitter_buffer_delay; RTCStatsMember<double> jitter_buffer_delay;
RTCStatsMember<double> jitter_buffer_target_delay; RTCStatsMember<double> jitter_buffer_target_delay;
@ -368,6 +370,9 @@ class RTC_EXPORT RTCOutboundRtpStreamStats final
// In JavaScript, this is only exposed if HW exposure is allowed. // In JavaScript, this is only exposed if HW exposure is allowed.
RTCStatsMember<bool> power_efficient_encoder; RTCStatsMember<bool> power_efficient_encoder;
RTCStatsMember<std::string> scalability_mode; 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* // https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*

View File

@ -677,6 +677,12 @@ CreateInboundRTPStreamStatsFromVideoReceiverInfo(
inbound_video->power_efficient_decoder = inbound_video->power_efficient_decoder =
*video_receiver_info.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; return inbound_video;
} }
@ -826,6 +832,12 @@ CreateOutboundRTPStreamStatsFromVideoSenderInfo(
outbound_video->scalability_mode = std::string( outbound_video->scalability_mode = std::string(
ScalabilityModeToString(*video_sender_info.scalability_mode)); 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; return outbound_video;
} }

View File

@ -2368,6 +2368,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Video) {
video_media_info.receivers[0].retransmitted_bytes_received = 62; video_media_info.receivers[0].retransmitted_bytes_received = 62;
video_media_info.receivers[0].fec_packets_received = 32; video_media_info.receivers[0].fec_packets_received = 32;
video_media_info.receivers[0].fec_bytes_received = 54; 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, // Note: these two values intentionally differ,
// only the decoded one should show up. // only the decoded one should show up.
@ -2434,6 +2436,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Video) {
expected_video.retransmitted_bytes_received = 62; expected_video.retransmitted_bytes_received = 62;
expected_video.fec_packets_received = 32; expected_video.fec_packets_received = 32;
expected_video.fec_bytes_received = 54; expected_video.fec_bytes_received = 54;
expected_video.rtx_ssrc = 4404;
ASSERT_TRUE(report->Get(expected_video.id())); ASSERT_TRUE(report->Get(expected_video.id()));
EXPECT_EQ( EXPECT_EQ(
@ -2629,6 +2632,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Video) {
video_media_info.senders[0].huge_frames_sent = 2; video_media_info.senders[0].huge_frames_sent = 2;
video_media_info.senders[0].active = false; video_media_info.senders[0].active = false;
video_media_info.senders[0].scalability_mode = ScalabilityMode::kL3T3_KEY; 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]); video_media_info.aggregated_senders.push_back(video_media_info.senders[0]);
RtpCodecParameters codec_parameters; RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42; codec_parameters.payload_type = 42;
@ -2684,6 +2689,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Video) {
expected_video.active = false; expected_video.active = false;
expected_video.power_efficient_encoder = false; expected_video.power_efficient_encoder = false;
expected_video.scalability_mode = "L3T3_KEY"; expected_video.scalability_mode = "L3T3_KEY";
expected_video.rtx_ssrc = 4404;
// `expected_video.content_type` should be undefined. // `expected_video.content_type` should be undefined.
// `expected_video.qp_sum` should be undefined. // `expected_video.qp_sum` should be undefined.
// `expected_video.encoder_implementation` should be undefined. // `expected_video.encoder_implementation` should be undefined.

View File

@ -693,11 +693,13 @@ class RTCStatsReportVerifier {
inbound_stream.retransmitted_packets_received); inbound_stream.retransmitted_packets_received);
verifier.TestMemberIsNonNegative<uint64_t>( verifier.TestMemberIsNonNegative<uint64_t>(
inbound_stream.retransmitted_bytes_received); inbound_stream.retransmitted_bytes_received);
verifier.TestMemberIsNonNegative<uint32_t>(inbound_stream.rtx_ssrc);
} else { } else {
verifier.TestMemberIsUndefined( verifier.TestMemberIsUndefined(
inbound_stream.retransmitted_packets_received); inbound_stream.retransmitted_packets_received);
verifier.TestMemberIsUndefined( verifier.TestMemberIsUndefined(
inbound_stream.retransmitted_bytes_received); inbound_stream.retransmitted_bytes_received);
verifier.TestMemberIsUndefined(inbound_stream.rtx_ssrc);
} }
// Test runtime too short to get an estimate (at least two RTCP sender // Test runtime too short to get an estimate (at least two RTCP sender
@ -849,6 +851,7 @@ class RTCStatsReportVerifier {
outbound_stream.huge_frames_sent); outbound_stream.huge_frames_sent);
verifier.MarkMemberTested(outbound_stream.rid, true); verifier.MarkMemberTested(outbound_stream.rid, true);
verifier.TestMemberIsDefined(outbound_stream.scalability_mode); verifier.TestMemberIsDefined(outbound_stream.scalability_mode);
verifier.TestMemberIsNonNegative<uint32_t>(outbound_stream.rtx_ssrc);
} else { } else {
verifier.TestMemberIsUndefined(outbound_stream.frames_encoded); verifier.TestMemberIsUndefined(outbound_stream.frames_encoded);
verifier.TestMemberIsUndefined(outbound_stream.key_frames_encoded); verifier.TestMemberIsUndefined(outbound_stream.key_frames_encoded);
@ -871,6 +874,7 @@ class RTCStatsReportVerifier {
verifier.TestMemberIsUndefined(outbound_stream.frames_sent); verifier.TestMemberIsUndefined(outbound_stream.frames_sent);
verifier.TestMemberIsUndefined(outbound_stream.huge_frames_sent); verifier.TestMemberIsUndefined(outbound_stream.huge_frames_sent);
verifier.TestMemberIsUndefined(outbound_stream.scalability_mode); verifier.TestMemberIsUndefined(outbound_stream.scalability_mode);
verifier.TestMemberIsUndefined(outbound_stream.rtx_ssrc);
} }
return verifier.ExpectAllMembersSuccessfullyTested(); return verifier.ExpectAllMembersSuccessfullyTested();
} }

View File

@ -313,6 +313,7 @@ WEBRTC_RTCSTATS_IMPL(
&header_bytes_received, &header_bytes_received,
&retransmitted_packets_received, &retransmitted_packets_received,
&retransmitted_bytes_received, &retransmitted_bytes_received,
&rtx_ssrc,
&last_packet_received_timestamp, &last_packet_received_timestamp,
&jitter_buffer_delay, &jitter_buffer_delay,
&jitter_buffer_target_delay, &jitter_buffer_target_delay,
@ -378,6 +379,7 @@ RTCInboundRtpStreamStats::RTCInboundRtpStreamStats(std::string id,
header_bytes_received("headerBytesReceived"), header_bytes_received("headerBytesReceived"),
retransmitted_packets_received("retransmittedPacketsReceived"), retransmitted_packets_received("retransmittedPacketsReceived"),
retransmitted_bytes_received("retransmittedBytesReceived"), retransmitted_bytes_received("retransmittedBytesReceived"),
rtx_ssrc("rtxSsrc"),
last_packet_received_timestamp("lastPacketReceivedTimestamp"), last_packet_received_timestamp("lastPacketReceivedTimestamp"),
jitter_buffer_delay("jitterBufferDelay"), jitter_buffer_delay("jitterBufferDelay"),
jitter_buffer_target_delay("jitterBufferTargetDelay"), jitter_buffer_target_delay("jitterBufferTargetDelay"),
@ -462,7 +464,8 @@ WEBRTC_RTCSTATS_IMPL(
&qp_sum, &qp_sum,
&active, &active,
&power_efficient_encoder, &power_efficient_encoder,
&scalability_mode) &scalability_mode,
&rtx_ssrc)
// clang-format on // clang-format on
RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(std::string id, RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(std::string id,
@ -498,7 +501,8 @@ RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(std::string id,
qp_sum("qpSum"), qp_sum("qpSum"),
active("active"), active("active"),
power_efficient_encoder("powerEfficientEncoder"), power_efficient_encoder("powerEfficientEncoder"),
scalability_mode("scalabilityMode") {} scalability_mode("scalabilityMode"),
rtx_ssrc("rtxSsrc") {}
RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats( RTCOutboundRtpStreamStats::RTCOutboundRtpStreamStats(
const RTCOutboundRtpStreamStats& other) = default; const RTCOutboundRtpStreamStats& other) = default;