Add VideoSendStream::Config::EncoderSettings::experiment_cpu_load_estimator.

And wire it up to methods on RTCConfiguration, via MediaConfig::Video.

Bug: webrtc:8504
Change-Id: I30805ee20c11d1d2fe552eb81f16d514db0ba4a8
Reviewed-on: https://webrtc-review.googlesource.com/39786
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21670}
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index 192a39a..a6c8c06 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -301,19 +301,19 @@
     bool operator==(const RTCConfiguration& o) const;
     bool operator!=(const RTCConfiguration& o) const;
 
-    bool dscp() { return media_config.enable_dscp; }
+    bool dscp() const { return media_config.enable_dscp; }
     void set_dscp(bool enable) { media_config.enable_dscp = enable; }
 
     // TODO(nisse): The corresponding flag in MediaConfig and
     // elsewhere should be renamed enable_cpu_adaptation.
-    bool cpu_adaptation() {
+    bool cpu_adaptation() const {
       return media_config.video.enable_cpu_overuse_detection;
     }
     void set_cpu_adaptation(bool enable) {
       media_config.video.enable_cpu_overuse_detection = enable;
     }
 
-    bool suspend_below_min_bitrate() {
+    bool suspend_below_min_bitrate() const {
       return media_config.video.suspend_below_min_bitrate;
     }
     void set_suspend_below_min_bitrate(bool enable) {
@@ -323,13 +323,19 @@
     // TODO(nisse): The negation in the corresponding MediaConfig
     // attribute is inconsistent, and it should be renamed at some
     // point.
-    bool prerenderer_smoothing() {
+    bool prerenderer_smoothing() const {
       return !media_config.video.disable_prerenderer_smoothing;
     }
     void set_prerenderer_smoothing(bool enable) {
       media_config.video.disable_prerenderer_smoothing = !enable;
     }
 
+    bool experiment_cpu_load_estimator() const {
+      return media_config.video.experiment_cpu_load_estimator;
+    }
+    void set_experiment_cpu_load_estimator(bool enable) {
+      media_config.video.experiment_cpu_load_estimator = enable;
+    }
     static const int kUndefined = -1;
     // Default maximum number of packets in the audio jitter buffer.
     static const int kAudioJitterBufferMaxPackets = 50;
diff --git a/call/video_send_stream.h b/call/video_send_stream.h
index a3c6f4f..cb83176 100644
--- a/call/video_send_stream.h
+++ b/call/video_send_stream.h
@@ -131,6 +131,10 @@
       // 30fps (for example) exactly.
       bool full_overuse_time = false;
 
+      // Enables the new method to estimate the cpu load from encoding, used for
+      // cpu adaptation.
+      bool experiment_cpu_load_estimator = false;
+
       // Uninitialized VideoEncoder instance to be used for encoding. Will be
       // initialized from inside the VideoSendStream.
       VideoEncoder* encoder = nullptr;
diff --git a/media/base/mediachannel.h b/media/base/mediachannel.h
index ed59acf..ccec53f 100644
--- a/media/base/mediachannel.h
+++ b/media/base/mediachannel.h
@@ -126,6 +126,13 @@
 
     // Enables periodic bandwidth probing in application-limited region.
     bool periodic_alr_bandwidth_probing = false;
+
+    // Enables the new method to estimate the cpu load from encoding, used for
+    // cpu adaptation. This flag is intended to be controlled primarily by a
+    // Chrome origin-trial.
+    // TODO(bugs.webrtc.org/8504): If all goes well, the flag will be removed
+    // together with the old method of estimation.
+    bool experiment_cpu_load_estimator = false;
   } video;
 
   bool operator==(const MediaConfig& o) const {
@@ -137,7 +144,9 @@
            video.disable_prerenderer_smoothing ==
                o.video.disable_prerenderer_smoothing &&
            video.periodic_alr_bandwidth_probing ==
-               o.video.periodic_alr_bandwidth_probing;
+               o.video.periodic_alr_bandwidth_probing &&
+           video.experiment_cpu_load_estimator ==
+               o.video.experiment_cpu_load_estimator;
   }
 
   bool operator!=(const MediaConfig& o) const { return !(*this == o); }
diff --git a/media/engine/webrtcvideoengine.cc b/media/engine/webrtcvideoengine.cc
index d6c51d1..411904f 100644
--- a/media/engine/webrtcvideoengine.cc
+++ b/media/engine/webrtcvideoengine.cc
@@ -1099,6 +1099,9 @@
   config.suspend_below_min_bitrate = video_config_.suspend_below_min_bitrate;
   config.periodic_alr_bandwidth_probing =
       video_config_.periodic_alr_bandwidth_probing;
+  config.encoder_settings.experiment_cpu_load_estimator =
+      video_config_.experiment_cpu_load_estimator;
+
   WebRtcVideoSendStream* stream = new WebRtcVideoSendStream(
       call_, sp, std::move(config), default_send_options_, encoder_factory_,
       video_config_.enable_cpu_overuse_detection,
diff --git a/pc/peerconnectioninterface_unittest.cc b/pc/peerconnectioninterface_unittest.cc
index a06ed50..46ac290 100644
--- a/pc/peerconnectioninterface_unittest.cc
+++ b/pc/peerconnectioninterface_unittest.cc
@@ -3744,6 +3744,7 @@
   EXPECT_TRUE(media_config.video.enable_cpu_overuse_detection);
   EXPECT_FALSE(media_config.video.disable_prerenderer_smoothing);
   EXPECT_FALSE(media_config.video.suspend_below_min_bitrate);
+  EXPECT_FALSE(media_config.video.experiment_cpu_load_estimator);
 }
 
 // This test verifies the DSCP constraint is recognized and passed to
@@ -3786,6 +3787,19 @@
   EXPECT_TRUE(media_config.video.disable_prerenderer_smoothing);
 }
 
+// This test verifies that the experiment_cpu_load_estimator flag is
+// propagated from RTCConfiguration to the PeerConnection.
+TEST_F(PeerConnectionMediaConfigTest, TestEnableExperimentCpuLoadEstimator) {
+  PeerConnectionInterface::RTCConfiguration config;
+  FakeConstraints constraints;
+
+  config.set_experiment_cpu_load_estimator(true);
+  const cricket::MediaConfig& media_config =
+      TestCreatePeerConnection(config, &constraints);
+
+  EXPECT_TRUE(media_config.video.experiment_cpu_load_estimator);
+}
+
 // This test verifies the suspend below min bitrate constraint is
 // recognized and passed to the PeerConnection.
 TEST_F(PeerConnectionMediaConfigTest,
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 7ec7ab3..65700ef 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -400,7 +400,7 @@
           overuse_detector.get()
               ? overuse_detector.release()
               : new OveruseFrameDetector(
-                    GetCpuOveruseOptions(settings.full_overuse_time),
+                    GetCpuOveruseOptions(settings),
                     this,
                     stats_proxy)),
       stats_proxy_(stats_proxy),
@@ -444,12 +444,15 @@
 // out). This should effectively turn off CPU adaptations for systems that
 // remotely cope with the load right now.
 CpuOveruseOptions VideoStreamEncoder::GetCpuOveruseOptions(
-    bool full_overuse_time) {
+    const VideoSendStream::Config::EncoderSettings& settings) {
   CpuOveruseOptions options;
-  if (full_overuse_time) {
+  if (settings.full_overuse_time) {
     options.low_encode_usage_threshold_percent = 150;
     options.high_encode_usage_threshold_percent = 200;
   }
+  if (settings.experiment_cpu_load_estimator) {
+    options.filter_time_ms = 5 * rtc::kNumMillisecsPerSec;
+  }
   return options;
 }
 
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index cbf4787..fccf208 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -116,7 +116,8 @@
   // These methods are protected for easier testing.
   void AdaptUp(AdaptReason reason) override;
   void AdaptDown(AdaptReason reason) override;
-  static CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time);
+  static CpuOveruseOptions GetCpuOveruseOptions(
+      const VideoSendStream::Config::EncoderSettings& settings);
 
  private:
   class ConfigureEncoderTask;
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index afeef02..15ce361 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -102,7 +102,7 @@
             nullptr /* pre_encode_callback */,
             std::unique_ptr<OveruseFrameDetector>(
                 overuse_detector_proxy_ = new CpuOveruseDetectorProxy(
-                    GetCpuOveruseOptions(settings.full_overuse_time),
+                    GetCpuOveruseOptions(settings),
                     this,
                     stats_proxy))) {}