ResourceAdaptationModule HasInputVideo+DegradationPreference setters.

The "has_input_video_ logic" is simplified to abort AdaptUp() and
AdaptDown() directly rather than in each calling place of the
VideoSourceRestrictor. The intent is no change in behavior.
The degradation_preference_ is removed from the VideoSourceRestrictor
as its only usage was DCHECKing (not worth it).

ResourceAdaptationModuleInterface gets SetHasInputVideo() and
SetDegradationPreference(), making these things controllable without
knowing implementation details.

StartCheckForOveruse() and StopCheckForOveruse() are renamed to
StartResourceAdaptation() and StopResourceAdaptation().

Bug: webrtc:11222
Change-Id: Id2d7f34d427dfb3ecd4831b1a245d07becae6520
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166173
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30296}
diff --git a/call/adaptation/BUILD.gn b/call/adaptation/BUILD.gn
index 80b2c05..ef1c6e6 100644
--- a/call/adaptation/BUILD.gn
+++ b/call/adaptation/BUILD.gn
@@ -24,6 +24,7 @@
     "video_source_restrictions.h",
   ]
   deps = [
+    "../../api:rtp_parameters",
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
     "//third_party/abseil-cpp/absl/types:optional",
@@ -34,9 +35,7 @@
   rtc_library("resource_adaptation_tests") {
     testonly = true
 
-    sources = [
-      "resource_adaptation_processor_unittest.cc",
-    ]
+    sources = [ "resource_adaptation_processor_unittest.cc" ]
     deps = [
       ":resource_adaptation",
       ":resource_adaptation_test_utilities",
diff --git a/call/adaptation/resource_adaptation_module_interface.h b/call/adaptation/resource_adaptation_module_interface.h
index 825b914..e73adce 100644
--- a/call/adaptation/resource_adaptation_module_interface.h
+++ b/call/adaptation/resource_adaptation_module_interface.h
@@ -11,6 +11,7 @@
 #ifndef CALL_ADAPTATION_RESOURCE_ADAPTATION_MODULE_INTERFACE_H_
 #define CALL_ADAPTATION_RESOURCE_ADAPTATION_MODULE_INTERFACE_H_
 
+#include "api/rtp_parameters.h"
 #include "call/adaptation/video_source_restrictions.h"
 
 namespace webrtc {
@@ -49,9 +50,17 @@
   // in a VideoStreamEncoder here directly then have a dependency on a different
   // build target). For the multi-stream use case we may consider making
   // ResourceAdaptationModuleInterface reference counted.
-  virtual void StartCheckForOveruse(
+  virtual void StartResourceAdaptation(
       ResourceAdaptationModuleListener* adaptation_listener) = 0;
-  virtual void StopCheckForOveruse() = 0;
+  virtual void StopResourceAdaptation() = 0;
+
+  // The following methods are callable whether or not adaption is started.
+
+  // Informs the module whether we have input video. By default, the module must
+  // assume the value is false.
+  virtual void SetHasInputVideo(bool has_input_video) = 0;
+  virtual void SetDegradationPreference(
+      DegradationPreference degradation_preference) = 0;
 };
 
 }  // namespace webrtc
diff --git a/video/overuse_frame_detector_resource_adaptation_module.cc b/video/overuse_frame_detector_resource_adaptation_module.cc
index c30f08f..20c1709 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.cc
+++ b/video/overuse_frame_detector_resource_adaptation_module.cc
@@ -76,21 +76,12 @@
 // source/sink, it is only a keeper of desired restrictions.
 class OveruseFrameDetectorResourceAdaptationModule::VideoSourceRestrictor {
  public:
-  VideoSourceRestrictor()
-      : has_input_video_(false),
-        degradation_preference_(DegradationPreference::DISABLED) {}
+  VideoSourceRestrictor() {}
 
   VideoSourceRestrictions source_restrictions() {
     return source_restrictions_;
   }
 
-  void SetHasInputVideoAndDegradationPreference(
-      bool has_input_video,
-      DegradationPreference degradation_preference) {
-    has_input_video_ = has_input_video;
-    degradation_preference_ = degradation_preference;
-  }
-
   // Updates the source_restrictions(). The source/sink has to be informed of
   // this separately.
   void ClearRestrictions() {
@@ -102,9 +93,6 @@
   bool RequestResolutionLowerThan(int pixel_count,
                                   int min_pixels_per_frame,
                                   bool* min_pixels_reached) {
-    RTC_DCHECK(IsResolutionScalingEnabled(degradation_preference_));
-    if (!has_input_video_)
-      return false;
     // The input video frame size will have a resolution less than or equal to
     // |max_pixel_count| depending on how the source can scale the frame size.
     const int pixels_wanted = (pixel_count * 3) / 5;
@@ -149,9 +137,6 @@
   // Updates the source_restrictions(). The source/sink has to be informed of
   // this separately.
   bool RequestHigherResolutionThan(int pixel_count) {
-    RTC_DCHECK(IsResolutionScalingEnabled(degradation_preference_));
-    if (!has_input_video_)
-      return false;
     int max_pixels_wanted = pixel_count;
     if (max_pixels_wanted != std::numeric_limits<int>::max())
       max_pixels_wanted = pixel_count * 4;
@@ -194,10 +179,6 @@
   // Updates the source_restrictions(). The source/sink has to be informed of
   // this separately.
   bool RestrictFramerate(int fps) {
-    RTC_DCHECK(IsFramerateScalingEnabled(degradation_preference_));
-    if (!has_input_video_)
-      return false;
-
     const int fps_wanted = std::max(kMinFramerateFps, fps);
     if (fps_wanted >=
         rtc::dchecked_cast<int>(source_restrictions_.max_frame_rate().value_or(
@@ -215,10 +196,6 @@
   // Updates the source_restrictions(). The source/sink has to be informed of
   // this separately.
   bool IncreaseFramerate(int fps) {
-    RTC_DCHECK(IsFramerateScalingEnabled(degradation_preference_));
-    if (!has_input_video_)
-      return false;
-
     const int fps_wanted = std::max(kMinFramerateFps, fps);
     if (fps_wanted <=
         rtc::dchecked_cast<int>(source_restrictions_.max_frame_rate().value_or(
@@ -235,8 +212,6 @@
 
  private:
   VideoSourceRestrictions source_restrictions_;
-  bool has_input_video_;
-  DegradationPreference degradation_preference_;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceRestrictor);
 };
@@ -372,6 +347,7 @@
         ResourceAdaptationModuleListener* adaptation_listener)
     : adaptation_listener_(adaptation_listener),
       video_stream_encoder_(video_stream_encoder),
+      has_input_video_(false),
       degradation_preference_(DegradationPreference::DISABLED),
       adapt_counters_(),
       balanced_settings_(),
@@ -399,7 +375,7 @@
   encoder_ = encoder;
 }
 
-void OveruseFrameDetectorResourceAdaptationModule::StartCheckForOveruse(
+void OveruseFrameDetectorResourceAdaptationModule::StartResourceAdaptation(
     ResourceAdaptationModuleListener* adaptation_listener) {
   RTC_DCHECK(encoder_);
   // TODO(hbos): When AdaptUp() and AdaptDown() are no longer invoked outside
@@ -414,10 +390,34 @@
       this);
 }
 
-void OveruseFrameDetectorResourceAdaptationModule::StopCheckForOveruse() {
+void OveruseFrameDetectorResourceAdaptationModule::StopResourceAdaptation() {
   overuse_detector_->StopCheckForOveruse();
 }
 
+void OveruseFrameDetectorResourceAdaptationModule::SetHasInputVideo(
+    bool has_input_video) {
+  // While false, AdaptUp() and AdaptDown() are NO-OPS.
+  has_input_video_ = has_input_video;
+}
+
+void OveruseFrameDetectorResourceAdaptationModule::SetDegradationPreference(
+    DegradationPreference degradation_preference) {
+  if (degradation_preference_ != degradation_preference) {
+    // Reset adaptation state, so that we're not tricked into thinking there's
+    // an already pending request of the same type.
+    last_adaptation_request_.reset();
+    if (degradation_preference == DegradationPreference::BALANCED ||
+        degradation_preference_ == DegradationPreference::BALANCED) {
+      // TODO(asapersson): Consider removing |adapt_counters_| map and use one
+      // AdaptCounter for all modes.
+      source_restrictor_->ClearRestrictions();
+      adapt_counters_.clear();
+    }
+  }
+  degradation_preference_ = degradation_preference;
+  MaybeUpdateVideoSourceRestrictions();
+}
+
 void OveruseFrameDetectorResourceAdaptationModule::FrameCaptured(
     const VideoFrame& frame,
     int64_t time_when_first_seen_us) {
@@ -458,28 +458,6 @@
   is_quality_scaler_enabled_ = is_quality_scaler_enabled;
 }
 
-void OveruseFrameDetectorResourceAdaptationModule::
-    SetHasInputVideoAndDegradationPreference(
-        bool has_input_video,
-        DegradationPreference degradation_preference) {
-  if (degradation_preference_ != degradation_preference) {
-    // Reset adaptation state, so that we're not tricked into thinking there's
-    // an already pending request of the same type.
-    last_adaptation_request_.reset();
-    if (degradation_preference == DegradationPreference::BALANCED ||
-        degradation_preference_ == DegradationPreference::BALANCED) {
-      // TODO(asapersson): Consider removing |adapt_counters_| map and use one
-      // AdaptCounter for all modes.
-      source_restrictor_->ClearRestrictions();
-      adapt_counters_.clear();
-    }
-  }
-  degradation_preference_ = degradation_preference;
-  source_restrictor_->SetHasInputVideoAndDegradationPreference(
-      has_input_video, degradation_preference_);
-  MaybeUpdateVideoSourceRestrictions();
-}
-
 void OveruseFrameDetectorResourceAdaptationModule::RefreshTargetFramerate() {
   absl::optional<double> restricted_frame_rate =
       ApplyDegradationPreference(source_restrictor_->source_restrictions(),
@@ -506,6 +484,8 @@
 }
 
 void OveruseFrameDetectorResourceAdaptationModule::AdaptUp(AdaptReason reason) {
+  if (!has_input_video_)
+    return;
   const AdaptCounter& adapt_counter = GetConstAdaptCounter();
   int num_downgrades = adapt_counter.TotalCount(reason);
   if (num_downgrades == 0)
@@ -620,6 +600,8 @@
 
 bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown(
     AdaptReason reason) {
+  if (!has_input_video_)
+    return false;
   AdaptationRequest adaptation_request = {
       *last_frame_pixel_count_, encoder_stats_observer_->GetInputFrameRate(),
       AdaptationRequest::Mode::kAdaptDown};
diff --git a/video/overuse_frame_detector_resource_adaptation_module.h b/video/overuse_frame_detector_resource_adaptation_module.h
index 28902cf..82f0c27 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.h
+++ b/video/overuse_frame_detector_resource_adaptation_module.h
@@ -71,9 +71,12 @@
   }
 
   // ResourceAdaptationModuleInterface implementation.
-  void StartCheckForOveruse(
+  void StartResourceAdaptation(
       ResourceAdaptationModuleListener* adaptation_listener) override;
-  void StopCheckForOveruse() override;
+  void StopResourceAdaptation() override;
+  void SetHasInputVideo(bool has_input_video) override;
+  void SetDegradationPreference(
+      DegradationPreference degradation_preference) override;
 
   // Input to the OveruseFrameDetector, which are required for this module to
   // function. These map to OveruseFrameDetector methods.
@@ -101,10 +104,6 @@
   // method is called incorrectly.
   void SetIsQualityScalerEnabled(bool is_quality_scaler_enabled);
 
-  void SetHasInputVideoAndDegradationPreference(
-      bool has_input_video,
-      DegradationPreference degradation_preference);
-
   // TODO(hbos): Can we get rid of this? Seems we should know whether the frame
   // rate has updated.
   void RefreshTargetFramerate();
@@ -201,6 +200,7 @@
   VideoSourceRestrictions video_source_restrictions_;
   // Used to query CpuOveruseOptions at StartCheckForOveruse().
   VideoStreamEncoder* video_stream_encoder_;
+  bool has_input_video_;
   DegradationPreference degradation_preference_;
   // Counters used for deciding if the video resolution or framerate is
   // currently restricted, and if so, why, on a per degradation preference
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index d8ac0fa..6d603f3 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -347,7 +347,7 @@
   video_source_sink_controller_->SetSource(nullptr);
   encoder_queue_.PostTask([this] {
     RTC_DCHECK_RUN_ON(&encoder_queue_);
-    resource_adaptation_module_->StopCheckForOveruse();
+    resource_adaptation_module_->StopResourceAdaptation();
     rate_allocator_ = nullptr;
     bitrate_observer_ = nullptr;
     ReleaseEncoder();
@@ -388,8 +388,9 @@
   video_source_sink_controller_->SetSource(source);
   encoder_queue_.PostTask([this, source, degradation_preference] {
     RTC_DCHECK_RUN_ON(&encoder_queue_);
-    resource_adaptation_module_->SetHasInputVideoAndDegradationPreference(
-        source, degradation_preference);
+    resource_adaptation_module_->SetHasInputVideo(source);
+    resource_adaptation_module_->SetDegradationPreference(
+        degradation_preference);
     if (encoder_)
       ConfigureQualityScaler(encoder_->GetEncoderInfo());
 
@@ -693,8 +694,8 @@
   }
 
   if (pending_encoder_creation_) {
-    resource_adaptation_module_->StopCheckForOveruse();
-    resource_adaptation_module_->StartCheckForOveruse(this);
+    resource_adaptation_module_->StopResourceAdaptation();
+    resource_adaptation_module_->StartResourceAdaptation(this);
     pending_encoder_creation_ = false;
   }