Populate qualityLimitationDurations stats for outbound RTP streams
Spec: https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationdurations
Tested in chromium using wpt/webrtc-stats.
Bug: webrtc:10686
Change-Id: I05ac344e6caa7a663675de4c06ccfd17e1efb6ee
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219300
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34179}
diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h
index 60ff8c2..fe6d658 100644
--- a/api/stats/rtcstats_objects.h
+++ b/api/stats/rtcstats_objects.h
@@ -13,6 +13,7 @@
#include <stdint.h>
+#include <map>
#include <memory>
#include <string>
#include <vector>
@@ -542,10 +543,8 @@
// implement it for audio as well.
RTCStatsMember<double> total_packet_send_delay;
// Enum type RTCQualityLimitationReason
- // TODO(https://crbug.com/webrtc/10686): Also expose
- // qualityLimitationDurations. Requires RTCStatsMember support for
- // "record<DOMString, double>", see https://crbug.com/webrtc/10685.
RTCStatsMember<std::string> quality_limitation_reason;
+ RTCStatsMember<std::map<std::string, double>> quality_limitation_durations;
// https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationresolutionchanges
RTCStatsMember<uint32_t> quality_limitation_resolution_changes;
// https://henbos.github.io/webrtc-provisional-stats/#dom-rtcoutboundrtpstreamstats-contenttype
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index f3a94b0..d7b7ba7 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -265,6 +265,17 @@
RTC_CHECK_NOTREACHED();
}
+std::map<std::string, double>
+QualityLimitationDurationToRTCQualityLimitationDuration(
+ std::map<webrtc::QualityLimitationReason, int64_t> durations_ms) {
+ std::map<std::string, double> result;
+ for (const auto& elem : durations_ms) {
+ result[QualityLimitationReasonToRTCQualityLimitationReason(elem.first)] =
+ elem.second;
+ }
+ return result;
+}
+
double DoubleAudioLevelFromIntAudioLevel(int audio_level) {
RTC_DCHECK_GE(audio_level, 0);
RTC_DCHECK_LE(audio_level, 32767);
@@ -568,6 +579,9 @@
outbound_video->quality_limitation_reason =
QualityLimitationReasonToRTCQualityLimitationReason(
video_sender_info.quality_limitation_reason);
+ outbound_video->quality_limitation_durations =
+ QualityLimitationDurationToRTCQualityLimitationDuration(
+ video_sender_info.quality_limitation_durations_ms);
outbound_video->quality_limitation_resolution_changes =
video_sender_info.quality_limitation_resolution_changes;
// TODO(https://crbug.com/webrtc/10529): When info's |content_info| is
diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc
index def98d4..92f7377 100644
--- a/pc/rtc_stats_collector_unittest.cc
+++ b/pc/rtc_stats_collector_unittest.cc
@@ -2199,6 +2199,8 @@
video_media_info.senders[0].total_packet_send_delay_ms = 10000;
video_media_info.senders[0].quality_limitation_reason =
QualityLimitationReason::kBandwidth;
+ video_media_info.senders[0].quality_limitation_durations_ms
+ [webrtc::QualityLimitationReason::kBandwidth] = 300;
video_media_info.senders[0].quality_limitation_resolution_changes = 56u;
video_media_info.senders[0].qp_sum = absl::nullopt;
video_media_info.senders[0].content_type = VideoContentType::UNSPECIFIED;
@@ -2254,6 +2256,9 @@
expected_video.total_encoded_bytes_target = 1234;
expected_video.total_packet_send_delay = 10.0;
expected_video.quality_limitation_reason = "bandwidth";
+ expected_video.quality_limitation_durations = std::map<std::string, double>{
+ std::pair<std::string, double>{"bandwidth", 300.0},
+ };
expected_video.quality_limitation_resolution_changes = 56u;
expected_video.frame_width = 200u;
expected_video.frame_height = 100u;
diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc
index d92e7ff..032cbe9 100644
--- a/pc/rtc_stats_integrationtest.cc
+++ b/pc/rtc_stats_integrationtest.cc
@@ -973,6 +973,8 @@
verifier.TestMemberIsNonNegative<double>(
outbound_stream.total_packet_send_delay);
verifier.TestMemberIsDefined(outbound_stream.quality_limitation_reason);
+ verifier.TestMemberIsDefined(
+ outbound_stream.quality_limitation_durations);
verifier.TestMemberIsNonNegative<uint32_t>(
outbound_stream.quality_limitation_resolution_changes);
// The integration test is not set up to test screen share; don't require
@@ -1006,6 +1008,8 @@
verifier.TestMemberIsUndefined(outbound_stream.total_packet_send_delay);
verifier.TestMemberIsUndefined(outbound_stream.quality_limitation_reason);
verifier.TestMemberIsUndefined(
+ outbound_stream.quality_limitation_durations);
+ verifier.TestMemberIsUndefined(
outbound_stream.quality_limitation_resolution_changes);
verifier.TestMemberIsUndefined(outbound_stream.content_type);
// TODO(hbos): Implement for audio as well.
diff --git a/stats/rtcstats_objects.cc b/stats/rtcstats_objects.cc
index dcd2aeb..0db833c 100644
--- a/stats/rtcstats_objects.cc
+++ b/stats/rtcstats_objects.cc
@@ -811,6 +811,7 @@
&huge_frames_sent,
&total_packet_send_delay,
&quality_limitation_reason,
+ &quality_limitation_durations,
&quality_limitation_resolution_changes,
&content_type,
&encoder_implementation,
@@ -847,6 +848,7 @@
huge_frames_sent("hugeFramesSent"),
total_packet_send_delay("totalPacketSendDelay"),
quality_limitation_reason("qualityLimitationReason"),
+ quality_limitation_durations("qualityLimitationDurations"),
quality_limitation_resolution_changes(
"qualityLimitationResolutionChanges"),
content_type("contentType"),
@@ -879,6 +881,7 @@
huge_frames_sent(other.huge_frames_sent),
total_packet_send_delay(other.total_packet_send_delay),
quality_limitation_reason(other.quality_limitation_reason),
+ quality_limitation_durations(other.quality_limitation_durations),
quality_limitation_resolution_changes(
other.quality_limitation_resolution_changes),
content_type(other.content_type),