[Overuse] Setting the target bitrate through the interface.

The poorly named SetEncoderStartBitrate() is renamed
SetEncoderTargetBitrate() and added to the abstract resource adaptation
module interface.

The so-called "start bitrate" was updated to match the target bitrate,
so this was only ever a "start bitrate" until we had any estimates. The
variable is renamed in VideoStreamEncoder as well, and usage of optional
types are introduced to avoid magical values in a few places in the
existing code.

Bug: webrtc:11222
Change-Id: Idde92f68f34616aa3c34ab77a791fdbe7ea7af26
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166880
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30347}
diff --git a/call/adaptation/resource_adaptation_module_interface.h b/call/adaptation/resource_adaptation_module_interface.h
index bc64b8e..61380b9 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 "absl/types/optional.h"
 #include "api/rtp_parameters.h"
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/video_encoder_config.h"
@@ -84,6 +85,8 @@
   virtual void SetDegradationPreference(
       DegradationPreference degradation_preference) = 0;
   virtual void SetEncoderSettings(EncoderSettings encoder_settings) = 0;
+  virtual void SetEncoderTargetBitrate(
+      absl::optional<uint32_t> target_bitrate_bps) = 0;
   // Removes all restrictions; the module will need to adapt all over again.
   // TODO(hbos): It's not clear why anybody should be able to tell the module to
   // reset like this; can we get rid of this method?
diff --git a/video/overuse_frame_detector_resource_adaptation_module.cc b/video/overuse_frame_detector_resource_adaptation_module.cc
index bd27eda..1ba33e1 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.cc
+++ b/video/overuse_frame_detector_resource_adaptation_module.cc
@@ -357,7 +357,7 @@
       overuse_detector_(std::move(overuse_detector)),
       overuse_detector_is_started_(false),
       target_frame_rate_(absl::nullopt),
-      encoder_start_bitrate_bps_(0),
+      target_bitrate_bps_(absl::nullopt),
       is_quality_scaler_enabled_(false),
       encoder_settings_(absl::nullopt),
       encoder_stats_observer_(encoder_stats_observer) {
@@ -426,6 +426,11 @@
   MaybeUpdateTargetFrameRate();
 }
 
+void OveruseFrameDetectorResourceAdaptationModule::SetEncoderTargetBitrate(
+    absl::optional<uint32_t> target_bitrate_bps) {
+  target_bitrate_bps_ = target_bitrate_bps;
+}
+
 void OveruseFrameDetectorResourceAdaptationModule::
     ResetVideoSourceRestrictions() {
   last_adaptation_request_.reset();
@@ -472,11 +477,6 @@
   last_frame_pixel_count_ = last_frame_pixel_count;
 }
 
-void OveruseFrameDetectorResourceAdaptationModule::SetEncoderStartBitrateBps(
-    uint32_t encoder_start_bitrate_bps) {
-  encoder_start_bitrate_bps_ = encoder_start_bitrate_bps;
-}
-
 void OveruseFrameDetectorResourceAdaptationModule::SetIsQualityScalerEnabled(
     bool is_quality_scaler_enabled) {
   is_quality_scaler_enabled_ = is_quality_scaler_enabled;
@@ -516,7 +516,7 @@
       if (reason == kQuality &&
           !balanced_settings_.CanAdaptUp(GetVideoCodecTypeOrGeneric(),
                                          *last_frame_pixel_count_,
-                                         encoder_start_bitrate_bps_)) {
+                                         target_bitrate_bps_.value_or(0))) {
         return;
       }
       // Try scale up framerate, if higher.
@@ -537,7 +537,7 @@
       if (reason == kQuality &&
           !balanced_settings_.CanAdaptUpResolution(
               GetVideoCodecTypeOrGeneric(), *last_frame_pixel_count_,
-              encoder_start_bitrate_bps_)) {
+              target_bitrate_bps_.value_or(0))) {
         return;
       }
       // Scale up resolution.
@@ -548,7 +548,7 @@
       // limits specified by encoder capabilities.
       if (reason == kQuality &&
           !CanAdaptUpResolution(*last_frame_pixel_count_,
-                                encoder_start_bitrate_bps_)) {
+                                target_bitrate_bps_.value_or(0))) {
         return;
       }
 
diff --git a/video/overuse_frame_detector_resource_adaptation_module.h b/video/overuse_frame_detector_resource_adaptation_module.h
index efc2ec8..f4080bd 100644
--- a/video/overuse_frame_detector_resource_adaptation_module.h
+++ b/video/overuse_frame_detector_resource_adaptation_module.h
@@ -73,6 +73,8 @@
   void SetDegradationPreference(
       DegradationPreference degradation_preference) override;
   void SetEncoderSettings(EncoderSettings encoder_settings) override;
+  void SetEncoderTargetBitrate(
+      absl::optional<uint32_t> target_bitrate_bps) override;
   void ResetVideoSourceRestrictions() override;
 
   // Input to the OveruseFrameDetector, which are required for this module to
@@ -92,7 +94,6 @@
   // resource adaptation module. Unify code paths where possible. Do we really
   // need this many public methods?
   void SetLastFramePixelCount(absl::optional<int> last_frame_pixel_count);
-  void SetEncoderStartBitrateBps(uint32_t encoder_start_bitrate_bps);
   // Inform the detector whether or not the quality scaler is enabled. This
   // helps GetActiveCounts() return absl::nullopt when appropriate.
   // TODO(hbos): This feels really hacky, can we report the right values without
@@ -215,7 +216,7 @@
   const std::unique_ptr<OveruseFrameDetector> overuse_detector_;
   bool overuse_detector_is_started_;
   absl::optional<double> target_frame_rate_;
-  uint32_t encoder_start_bitrate_bps_;
+  absl::optional<uint32_t> target_bitrate_bps_;
   bool is_quality_scaler_enabled_;
   absl::optional<EncoderSettings> encoder_settings_;
   VideoStreamEncoderObserver* const encoder_stats_observer_;
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 65e81c1..486143c 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -279,7 +279,7 @@
       pending_encoder_creation_(false),
       crop_width_(0),
       crop_height_(0),
-      encoder_start_bitrate_bps_(0),
+      encoder_target_bitrate_bps_(absl::nullopt),
       set_start_bitrate_bps_(0),
       set_start_bitrate_time_ms_(0),
       has_seen_first_bwe_drop_(false),
@@ -405,9 +405,11 @@
 void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
   encoder_queue_.PostTask([this, start_bitrate_bps] {
     RTC_DCHECK_RUN_ON(&encoder_queue_);
-    encoder_start_bitrate_bps_ = start_bitrate_bps;
-    resource_adaptation_module_->SetEncoderStartBitrateBps(
-        encoder_start_bitrate_bps_);
+    encoder_target_bitrate_bps_ =
+        start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
+                               : absl::nullopt;
+    resource_adaptation_module_->SetEncoderTargetBitrate(
+        encoder_target_bitrate_bps_);
     set_start_bitrate_bps_ = start_bitrate_bps;
     set_start_bitrate_time_ms_ = clock_->TimeInMilliseconds();
   });
@@ -619,8 +621,8 @@
   }
   RTC_LOG(LS_INFO) << log_stream.str();
 
-  codec.startBitrate =
-      std::max(encoder_start_bitrate_bps_ / 1000, codec.minBitrate);
+  codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000,
+                                codec.minBitrate);
   codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate);
   codec.expect_encode_from_texture = last_frame_info_->is_texture;
   // Make sure the start bit rate is sane...
@@ -1617,11 +1619,11 @@
 
   // On significant changes to BWE at the start of the call,
   // enable frame drops to quickly react to jumps in available bandwidth.
-  if (encoder_start_bitrate_bps_ != 0 &&
+  if (encoder_target_bitrate_bps_.has_value() &&
       !has_seen_first_significant_bwe_change_ && quality_scaler_ &&
       initial_framedrop_on_bwe_enabled_ &&
-      abs_diff(target_bitrate.bps(), encoder_start_bitrate_bps_) >=
-          kFramedropThreshold * encoder_start_bitrate_bps_) {
+      abs_diff(target_bitrate.bps(), encoder_target_bitrate_bps_.value()) >=
+          kFramedropThreshold * encoder_target_bitrate_bps_.value()) {
     // Reset initial framedrop feature when first real BW estimate arrives.
     // TODO(kthelgason): Update BitrateAllocator to not call OnBitrateUpdated
     // without an actual BW estimate.
@@ -1659,11 +1661,10 @@
       link_allocation, target_bitrate, stable_target_bitrate};
   SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(new_rate_settings));
 
-  encoder_start_bitrate_bps_ = target_bitrate.bps() != 0
-                                   ? target_bitrate.bps()
-                                   : encoder_start_bitrate_bps_;
-  resource_adaptation_module_->SetEncoderStartBitrateBps(
-      encoder_start_bitrate_bps_);
+  if (target_bitrate.bps() != 0)
+    encoder_target_bitrate_bps_ = target_bitrate.bps();
+  resource_adaptation_module_->SetEncoderTargetBitrate(
+      encoder_target_bitrate_bps_);
 
   if (video_suspension_changed) {
     RTC_LOG(LS_INFO) << "Video suspend state changed to: "
@@ -1681,7 +1682,7 @@
 
 bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
   if (initial_framedrop_ >= kMaxInitialFramedrop ||
-      encoder_start_bitrate_bps_ == 0) {
+      !encoder_target_bitrate_bps_.has_value()) {
     return false;
   }
 
@@ -1690,13 +1691,13 @@
 
   if (encoder_bitrate_limits.has_value()) {
     // Use bitrate limits provided by encoder.
-    return encoder_start_bitrate_bps_ <
+    return encoder_target_bitrate_bps_.value() <
            static_cast<uint32_t>(encoder_bitrate_limits->min_start_bitrate_bps);
   }
 
-  if (encoder_start_bitrate_bps_ < 300000 /* qvga */) {
+  if (encoder_target_bitrate_bps_.value() < 300000 /* qvga */) {
     return pixel_count > 320 * 240;
-  } else if (encoder_start_bitrate_bps_ < 500000 /* vga */) {
+  } else if (encoder_target_bitrate_bps_.value() < 500000 /* vga */) {
     return pixel_count > 640 * 480;
   }
   return false;
@@ -1713,7 +1714,8 @@
 
   if (quality_rampup_experiment_.BwHigh(now_ms, bw_kbps)) {
     // Verify that encoder is at max bitrate and the QP is low.
-    if (encoder_start_bitrate_bps_ == send_codec_.maxBitrate * 1000 &&
+    if (encoder_target_bitrate_bps_.value_or(0) ==
+            send_codec_.maxBitrate * 1000 &&
         quality_scaler_->QpFastFilterLow()) {
       return true;
     }
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index bd76ee5..5ac6db8 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -251,7 +251,8 @@
       RTC_GUARDED_BY(&encoder_queue_);
   int crop_width_ RTC_GUARDED_BY(&encoder_queue_);
   int crop_height_ RTC_GUARDED_BY(&encoder_queue_);
-  uint32_t encoder_start_bitrate_bps_ RTC_GUARDED_BY(&encoder_queue_);
+  absl::optional<uint32_t> encoder_target_bitrate_bps_
+      RTC_GUARDED_BY(&encoder_queue_);
   int set_start_bitrate_bps_ RTC_GUARDED_BY(&encoder_queue_);
   int64_t set_start_bitrate_time_ms_ RTC_GUARDED_BY(&encoder_queue_);
   bool has_seen_first_bwe_drop_ RTC_GUARDED_BY(&encoder_queue_);