Report payload byte counts in PC-level quality tests

Bug: None
Change-Id: I3908a065dd0d66802c7f8de64cdc03687ac7f9e1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/154521
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29322}
diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn
index 3d34e7b..c6a5409 100644
--- a/test/pc/e2e/BUILD.gn
+++ b/test/pc/e2e/BUILD.gn
@@ -375,6 +375,8 @@
       "../../../rtc_base:gunit_helpers",
       "../../../rtc_base:logging",
       "../../../rtc_base:rtc_event",
+      "../../../system_wrappers:field_trial",
+      "../../../test:field_trial",
       "../../../test:fileutils",
       "../../../test:test_support",
     ]
@@ -486,9 +488,12 @@
   ]
   deps = [
     "../..:perf_test",
+    "../../../api:libjingle_peerconnection_api",
     "../../../api:network_emulation_manager_api",
     "../../../api:peer_connection_quality_test_fixture_api",
+    "../../../rtc_base:criticalsection",
     "../../../rtc_base:rtc_event",
+    "../../../system_wrappers:field_trial",
   ]
 }
 
diff --git a/test/pc/e2e/network_quality_metrics_reporter.cc b/test/pc/e2e/network_quality_metrics_reporter.cc
index 085fc78..95dc0dd 100644
--- a/test/pc/e2e/network_quality_metrics_reporter.cc
+++ b/test/pc/e2e/network_quality_metrics_reporter.cc
@@ -11,7 +11,9 @@
 
 #include <utility>
 
+#include "api/stats_types.h"
 #include "rtc_base/event.h"
+#include "system_wrappers/include/field_trial.h"
 #include "test/testsupport/perf_test.h"
 
 namespace webrtc {
@@ -20,6 +22,10 @@
 
 constexpr int kStatsWaitTimeoutMs = 1000;
 
+// Field trial which controls whether to report standard-compliant bytes
+// sent/received per stream.  If enabled, padding and headers are not included
+// in bytes sent or received.
+constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats";
 }
 
 void NetworkQualityMetricsReporter::Start(absl::string_view test_case_name) {
@@ -33,6 +39,24 @@
   RTC_CHECK_EQ(bob_stats.packets_received, 0);
 }
 
+void NetworkQualityMetricsReporter::OnStatsReports(
+    const std::string& pc_label,
+    const StatsReports& reports) {
+  rtc::CritScope cs(&lock_);
+  PCStats& stats = pc_stats_[pc_label];
+  for (const StatsReport* report : reports) {
+    const auto* received =
+        report->FindValue(StatsReport::kStatsValueNameBytesReceived);
+    if (received) {
+      stats.payload_bytes_received = received->int64_val();
+    }
+    const auto* sent = report->FindValue(StatsReport::kStatsValueNameBytesSent);
+    if (sent) {
+      stats.payload_bytes_sent = sent->int64_val();
+    }
+  }
+}
+
 void NetworkQualityMetricsReporter::StopAndReportResults() {
   EmulatedNetworkStats alice_stats = PopulateStats(alice_network_);
   EmulatedNetworkStats bob_stats = PopulateStats(bob_network_);
@@ -40,6 +64,16 @@
               alice_stats.packets_sent - bob_stats.packets_received);
   ReportStats("bob", bob_stats,
               bob_stats.packets_sent - alice_stats.packets_received);
+
+  if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) {
+    RTC_LOG(LS_ERROR)
+        << "Non-standard GetStats; \"payload\" counts include RTP headers";
+  }
+
+  rtc::CritScope cs(&lock_);
+  for (const auto& pair : pc_stats_) {
+    ReportPCStats(pair.first, pair.second);
+  }
 }
 
 EmulatedNetworkStats NetworkQualityMetricsReporter::PopulateStats(
@@ -82,6 +116,14 @@
   ReportResult("sent_packets_loss", network_label, packet_loss, "unitless");
 }
 
+void NetworkQualityMetricsReporter::ReportPCStats(const std::string& pc_label,
+                                                  const PCStats& stats) {
+  ReportResult("payload_bytes_received", pc_label, stats.payload_bytes_received,
+               "sizeInBytes");
+  ReportResult("payload_bytes_sent", pc_label, stats.payload_bytes_sent,
+               "sizeInBytes");
+}
+
 void NetworkQualityMetricsReporter::ReportResult(
     const std::string& metric_name,
     const std::string& network_label,
diff --git a/test/pc/e2e/network_quality_metrics_reporter.h b/test/pc/e2e/network_quality_metrics_reporter.h
index bee20fd..6454f17 100644
--- a/test/pc/e2e/network_quality_metrics_reporter.h
+++ b/test/pc/e2e/network_quality_metrics_reporter.h
@@ -15,6 +15,7 @@
 
 #include "api/test/network_emulation_manager.h"
 #include "api/test/peerconnection_quality_test_fixture.h"
+#include "rtc_base/critical_section.h"
 
 namespace webrtc {
 namespace webrtc_pc_e2e {
@@ -30,15 +31,23 @@
   // Network stats must be empty when this method will be invoked.
   void Start(absl::string_view test_case_name) override;
   void OnStatsReports(const std::string& pc_label,
-                      const StatsReports& reports) override {}
+                      const StatsReports& reports) override;
   void StopAndReportResults() override;
 
  private:
+  struct PCStats {
+    // TODO(nisse): Separate audio and video counters. Depends on standard stat
+    // counters, enabled by field trial "WebRTC-UseStandardBytesStats".
+    int64_t payload_bytes_received = 0;
+    int64_t payload_bytes_sent = 0;
+  };
+
   static EmulatedNetworkStats PopulateStats(
       EmulatedNetworkManagerInterface* network);
   void ReportStats(const std::string& network_label,
                    const EmulatedNetworkStats& stats,
                    int64_t packet_loss);
+  void ReportPCStats(const std::string& pc_label, const PCStats& stats);
   void ReportResult(const std::string& metric_name,
                     const std::string& network_label,
                     const double value,
@@ -49,6 +58,8 @@
 
   EmulatedNetworkManagerInterface* alice_network_;
   EmulatedNetworkManagerInterface* bob_network_;
+  rtc::CriticalSection lock_;
+  std::map<std::string, PCStats> pc_stats_ RTC_GUARDED_BY(lock_);
 };
 
 }  // namespace webrtc_pc_e2e
diff --git a/test/pc/e2e/peer_connection_e2e_smoke_test.cc b/test/pc/e2e/peer_connection_e2e_smoke_test.cc
index f60f058..c7fad1e 100644
--- a/test/pc/e2e/peer_connection_e2e_smoke_test.cc
+++ b/test/pc/e2e/peer_connection_e2e_smoke_test.cc
@@ -16,6 +16,8 @@
 #include "api/test/network_emulation_manager.h"
 #include "api/test/peerconnection_quality_test_fixture.h"
 #include "call/simulated_network.h"
+#include "system_wrappers/include/field_trial.h"
+#include "test/field_trial.h"
 #include "test/gtest.h"
 #include "test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h"
 #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer.h"
@@ -136,6 +138,9 @@
   run_params.use_flex_fec = true;
   run_params.use_ulp_fec = true;
   run_params.video_encoder_bitrate_multiplier = 1.1;
+  test::ScopedFieldTrials field_trials(
+      std::string(field_trial::GetFieldTrialString()) +
+      "WebRTC-UseStandardBytesStats/Enabled/");
   RunTest(
       "smoke", run_params,
       [](PeerConfigurer* alice) {