summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc162
1 files changed, 162 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
new file mode 100644
index 0000000000..8049af308e
--- /dev/null
+++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h"
+
+#include <map>
+#include <string>
+
+#include "api/stats/rtc_stats.h"
+#include "api/stats/rtcstats_objects.h"
+#include "api/test/metrics/metric.h"
+#include "api/units/data_rate.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/checks.h"
+#include "test/pc/e2e/metric_metadata_keys.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+namespace {
+
+using ::webrtc::test::ImprovementDirection;
+using ::webrtc::test::Unit;
+using ::webrtc::webrtc_pc_e2e::MetricMetadataKey;
+
+SamplesStatsCounter BytesPerSecondToKbps(const SamplesStatsCounter& counter) {
+ return counter * 0.008;
+}
+
+} // namespace
+
+VideoQualityMetricsReporter::VideoQualityMetricsReporter(
+ Clock* const clock,
+ test::MetricsLogger* const metrics_logger)
+ : clock_(clock), metrics_logger_(metrics_logger) {
+ RTC_CHECK(metrics_logger_);
+}
+
+void VideoQualityMetricsReporter::Start(
+ absl::string_view test_case_name,
+ const TrackIdStreamInfoMap* /*reporter_helper*/) {
+ test_case_name_ = std::string(test_case_name);
+ start_time_ = Now();
+}
+
+void VideoQualityMetricsReporter::OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) {
+ RTC_CHECK(start_time_)
+ << "Please invoke Start(...) method before calling OnStatsReports(...)";
+
+ auto transport_stats = report->GetStatsOfType<RTCTransportStats>();
+ if (transport_stats.size() == 0u ||
+ !transport_stats[0]->selected_candidate_pair_id.is_defined()) {
+ return;
+ }
+ RTC_DCHECK_EQ(transport_stats.size(), 1);
+ std::string selected_ice_id =
+ transport_stats[0]->selected_candidate_pair_id.ValueToString();
+ // Use the selected ICE candidate pair ID to get the appropriate ICE stats.
+ const RTCIceCandidatePairStats ice_candidate_pair_stats =
+ report->Get(selected_ice_id)->cast_to<const RTCIceCandidatePairStats>();
+
+ auto outbound_rtp_stats = report->GetStatsOfType<RTCOutboundRTPStreamStats>();
+ StatsSample sample;
+ for (auto& s : outbound_rtp_stats) {
+ if (!s->kind.is_defined()) {
+ continue;
+ }
+ if (!(*s->kind == RTCMediaStreamTrackKind::kVideo)) {
+ continue;
+ }
+ if (s->timestamp() > sample.sample_time) {
+ sample.sample_time = s->timestamp();
+ }
+ sample.retransmitted_bytes_sent +=
+ DataSize::Bytes(s->retransmitted_bytes_sent.ValueOrDefault(0ul));
+ sample.bytes_sent += DataSize::Bytes(s->bytes_sent.ValueOrDefault(0ul));
+ sample.header_bytes_sent +=
+ DataSize::Bytes(s->header_bytes_sent.ValueOrDefault(0ul));
+ }
+
+ MutexLock lock(&video_bwe_stats_lock_);
+ VideoBweStats& video_bwe_stats = video_bwe_stats_[std::string(pc_label)];
+ if (ice_candidate_pair_stats.available_outgoing_bitrate.is_defined()) {
+ video_bwe_stats.available_send_bandwidth.AddSample(
+ DataRate::BitsPerSec(
+ *ice_candidate_pair_stats.available_outgoing_bitrate)
+ .bytes_per_sec());
+ }
+
+ StatsSample prev_sample = last_stats_sample_[std::string(pc_label)];
+ if (prev_sample.sample_time.IsZero()) {
+ prev_sample.sample_time = start_time_.value();
+ }
+ last_stats_sample_[std::string(pc_label)] = sample;
+
+ TimeDelta time_between_samples = sample.sample_time - prev_sample.sample_time;
+ if (time_between_samples.IsZero()) {
+ return;
+ }
+
+ DataRate retransmission_bitrate =
+ (sample.retransmitted_bytes_sent - prev_sample.retransmitted_bytes_sent) /
+ time_between_samples;
+ video_bwe_stats.retransmission_bitrate.AddSample(
+ retransmission_bitrate.bytes_per_sec());
+ DataRate transmission_bitrate =
+ (sample.bytes_sent + sample.header_bytes_sent - prev_sample.bytes_sent -
+ prev_sample.header_bytes_sent) /
+ time_between_samples;
+ video_bwe_stats.transmission_bitrate.AddSample(
+ transmission_bitrate.bytes_per_sec());
+}
+
+void VideoQualityMetricsReporter::StopAndReportResults() {
+ MutexLock video_bwemutex_(&video_bwe_stats_lock_);
+ for (const auto& item : video_bwe_stats_) {
+ ReportVideoBweResults(item.first, item.second);
+ }
+}
+
+std::string VideoQualityMetricsReporter::GetTestCaseName(
+ const std::string& peer_name) const {
+ return test_case_name_ + "/" + peer_name;
+}
+
+void VideoQualityMetricsReporter::ReportVideoBweResults(
+ const std::string& peer_name,
+ const VideoBweStats& video_bwe_stats) {
+ std::string test_case_name = GetTestCaseName(peer_name);
+ // TODO(bugs.webrtc.org/14757): Remove kExperimentalTestNameMetadataKey.
+ std::map<std::string, std::string> metric_metadata{
+ {MetricMetadataKey::kPeerMetadataKey, peer_name},
+ {MetricMetadataKey::kExperimentalTestNameMetadataKey, test_case_name_}};
+
+ metrics_logger_->LogMetric(
+ "available_send_bandwidth", test_case_name,
+ BytesPerSecondToKbps(video_bwe_stats.available_send_bandwidth),
+ Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter,
+ metric_metadata);
+ metrics_logger_->LogMetric(
+ "transmission_bitrate", test_case_name,
+ BytesPerSecondToKbps(video_bwe_stats.transmission_bitrate),
+ Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter,
+ metric_metadata);
+ metrics_logger_->LogMetric(
+ "retransmission_bitrate", test_case_name,
+ BytesPerSecondToKbps(video_bwe_stats.retransmission_bitrate),
+ Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter,
+ metric_metadata);
+}
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc