Add cpu_usage metrics.

Implemented an analogue of the cpu_usage metrics from third_party/webrtc/video/video_analyzer.h for third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h

Bug: webrtc:11496
Change-Id: Ifdc9daa3351f1df5db98beb8f7dc7156fc7c2a16
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174020
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31141}
diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn
index 00c69f8..5c1ee9d 100644
--- a/test/pc/e2e/BUILD.gn
+++ b/test/pc/e2e/BUILD.gn
@@ -575,8 +575,10 @@
     "../../../rtc_base:criticalsection",
     "../../../rtc_base:logging",
     "../../../rtc_base:rtc_base_approved",
+    "../../../rtc_base:rtc_base_tests_utils",
     "../../../rtc_base:rtc_event",
     "../../../rtc_base:rtc_numerics",
+    "../../../rtc_base:timeutils",
     "../../../system_wrappers",
   ]
 }
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
index 40a885f..239d7e1 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
@@ -17,7 +17,9 @@
 #include "api/units/time_delta.h"
 #include "api/video/i420_buffer.h"
 #include "common_video/libyuv/include/webrtc_libyuv.h"
+#include "rtc_base/cpu_time.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/time_utils.h"
 
 namespace webrtc {
 namespace webrtc_pc_e2e {
@@ -92,6 +94,7 @@
     state_ = State::kActive;
     start_time_ = Now();
   }
+  StartMeasuringCpuProcessTime();
 }
 
 uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured(
@@ -336,6 +339,7 @@
 }
 
 void DefaultVideoQualityAnalyzer::Stop() {
+  StopMeasuringCpuProcessTime();
   {
     rtc::CritScope crit(&lock_);
     if (state_ == State::kStopped) {
@@ -429,6 +433,7 @@
     absl::optional<VideoFrame> rendered,
     bool dropped,
     FrameStats frame_stats) {
+  StartExcludingCpuThreadTime();
   rtc::CritScope crit(&comparison_lock_);
   analyzer_stats_.comparisons_queue_size.AddSample(comparisons_.size());
   // If there too many computations waiting in the queue, we won't provide
@@ -445,6 +450,7 @@
                               frame_stats, overload_reason);
   }
   comparison_available_event_.Set();
+  StopExcludingCpuThreadTime();
 }
 
 void DefaultVideoQualityAnalyzer::ProcessComparisonsThread(void* obj) {
@@ -481,7 +487,9 @@
       continue;
     }
 
+    StartExcludingCpuThreadTime();
     ProcessComparison(comparison.value());
+    StopExcludingCpuThreadTime();
   }
 }
 
@@ -565,12 +573,16 @@
 }
 
 void DefaultVideoQualityAnalyzer::ReportResults() {
+  using ::webrtc::test::ImproveDirection;
+
   rtc::CritScope crit1(&lock_);
   rtc::CritScope crit2(&comparison_lock_);
   for (auto& item : stream_stats_) {
     ReportResults(GetTestCaseName(item.first), item.second,
                   stream_frame_counters_.at(item.first));
   }
+  test::PrintResult("cpu_usage", "", test_label_.c_str(), GetCpuUsagePercent(),
+                    "%", false, ImproveDirection::kSmallerIsBetter);
   LogFrameCounters("Global", frame_counters_);
   for (auto& item : stream_stats_) {
     LogFrameCounters(item.first, stream_frame_counters_.at(item.first));
@@ -702,6 +714,33 @@
   return clock_->CurrentTime();
 }
 
+void DefaultVideoQualityAnalyzer::StartMeasuringCpuProcessTime() {
+  rtc::CritScope lock(&cpu_measurement_lock_);
+  cpu_time_ -= rtc::GetProcessCpuTimeNanos();
+  wallclock_time_ -= rtc::SystemTimeNanos();
+}
+
+void DefaultVideoQualityAnalyzer::StopMeasuringCpuProcessTime() {
+  rtc::CritScope lock(&cpu_measurement_lock_);
+  cpu_time_ += rtc::GetProcessCpuTimeNanos();
+  wallclock_time_ += rtc::SystemTimeNanos();
+}
+
+void DefaultVideoQualityAnalyzer::StartExcludingCpuThreadTime() {
+  rtc::CritScope lock(&cpu_measurement_lock_);
+  cpu_time_ += rtc::GetThreadCpuTimeNanos();
+}
+
+void DefaultVideoQualityAnalyzer::StopExcludingCpuThreadTime() {
+  rtc::CritScope lock(&cpu_measurement_lock_);
+  cpu_time_ -= rtc::GetThreadCpuTimeNanos();
+}
+
+double DefaultVideoQualityAnalyzer::GetCpuUsagePercent() {
+  rtc::CritScope lock(&cpu_measurement_lock_);
+  return static_cast<double>(cpu_time_) / wallclock_time_ * 100.0;
+}
+
 DefaultVideoQualityAnalyzer::FrameStats::FrameStats(std::string stream_label,
                                                     Timestamp captured_time)
     : stream_label(std::move(stream_label)), captured_time(captured_time) {}
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
index 778ccb3..6bebb0f 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
@@ -293,6 +293,12 @@
   std::string GetTestCaseName(const std::string& stream_label) const;
   Timestamp Now();
 
+  void StartMeasuringCpuProcessTime();
+  void StopMeasuringCpuProcessTime();
+  void StartExcludingCpuThreadTime();
+  void StopExcludingCpuThreadTime();
+  double GetCpuUsagePercent();
+
   const bool heavy_metrics_computation_enabled_;
   const int max_frames_in_flight_per_stream_count_;
   webrtc::Clock* const clock_;
@@ -337,6 +343,10 @@
 
   std::vector<std::unique_ptr<rtc::PlatformThread>> thread_pool_;
   rtc::Event comparison_available_event_;
+
+  rtc::CriticalSection cpu_measurement_lock_;
+  int64_t cpu_time_ RTC_GUARDED_BY(cpu_measurement_lock_) = 0;
+  int64_t wallclock_time_ RTC_GUARDED_BY(cpu_measurement_lock_) = 0;
 };
 
 }  // namespace webrtc_pc_e2e