Add new more flexible VideoEncoder::SetRate() method.

This CL changes the API for webrtc::VideoEncoder.

There is a legacy method called SetRates(). This is indicated as being
deprecated, but there seem to be a number of usages still left.

Then there is the new SetRateAllocation() method which takes a
VideoBitrateAllocation instance instead of a single target bitrate.

This CL adds a new version of SetRates() which moves all the existing
parameters in a RateControlParameters struct, and adds a bandwidth
allocation signal. The intent of this signal is to allow the encoder
to know how close to the target it needs to stay. If the encoder rate
is network restricted, it will need to be more aggressive in keep the
rate down and possibly drop frames. If there is some margin for
overshoot, it might do different trade-offs.

Furthermore, the frame rate signal is changes from an integer to a
floating point type in order to get more precise rates at low frame
rates and the return type has been changed to void since the only use
of the previous values to log it and that is better done inside encoder
where the error condition originates.

The intent is to properly deprecate the "old" SetRates() /
SetRateAllocation() methods, send out a PSA and then remove them in two
weeks. Changes required by users should be trivial, as using the new
headroom signal is optional.

Bug: webrtc:10155, webrtc:10481
Change-Id: I4f797b0b0c73086111869ef4ee5f42bf530f5fde
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/129724
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27314}
diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn
index ceb8eaf..4a8a380 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -42,6 +42,7 @@
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
     "../../rtc_base/system:rtc_export",
+    "../units:data_rate",
     "../video:encoded_image",
     "../video:video_bitrate_allocation",
     "../video:video_codec_constants",
diff --git a/api/video_codecs/video_encoder.cc b/api/video_codecs/video_encoder.cc
index 233ca24..abdbf8c 100644
--- a/api/video_codecs/video_encoder.cc
+++ b/api/video_codecs/video_encoder.cc
@@ -125,6 +125,11 @@
   return SetRates(allocation.get_sum_kbps(), framerate);
 }
 
+void VideoEncoder::SetRates(const RateControlParameters& parameters) {
+  SetRateAllocation(parameters.bitrate,
+                    static_cast<uint32_t>(parameters.framerate_fps + 0.5));
+}
+
 void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
 
 void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h
index 9ff8faa..90cd822 100644
--- a/api/video_codecs/video_encoder.h
+++ b/api/video_codecs/video_encoder.h
@@ -18,6 +18,7 @@
 
 #include "absl/container/inlined_vector.h"
 #include "absl/types/optional.h"
+#include "api/units/data_rate.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "api/video/video_codec_constants.h"
@@ -192,6 +193,21 @@
         fps_allocation[kMaxSpatialLayers];
   };
 
+  struct RateControlParameters {
+    // Target bitrate, per spatial/temporal layer.
+    // A target bitrate of 0bps indicates a layer should not be encoded at all.
+    VideoBitrateAllocation bitrate;
+    // Target framerate, in fps. A value <= 0.0 is invalid and should be
+    // interpreted as framerate target not available. In this case the encoder
+    // should fall back to the max framerate specified in |codec_settings| of
+    // the last InitEncode() call.
+    double framerate_fps;
+    // The network bandwidth available for video. This is at least
+    // |bitrate.get_sum_bps()|, but may be higher if the application is not
+    // network constrained.
+    DataRate bandwidth_allocation;
+  };
+
   static VideoCodecVP8 GetDefaultVp8Settings();
   static VideoCodecVP9 GetDefaultVp9Settings();
   static VideoCodecH264 GetDefaultH264Settings();
@@ -249,20 +265,27 @@
                          const CodecSpecificInfo* codec_specific_info,
                          const std::vector<VideoFrameType>* frame_types);
 
-  // Inform the encoder about the new target bit rate.
-  //
-  // Input:
-  //          - bitrate         : New target bit rate
-  //          - framerate       : The target frame rate
-  //
-  // Return value                : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
+  // DEPRECATED! Instead use the one below:
+  // void SetRateAllocation(const VideoBitrateAllocation&, DataRate, uint32)
+  // For now has a default implementation that call RTC_NOTREACHED().
+  // TODO(bugs.webrtc.org/10481): Remove this once all usage is gone.
   virtual int32_t SetRates(uint32_t bitrate, uint32_t framerate);
 
-  // Default fallback: Just use the sum of bitrates as the single target rate.
-  // TODO(sprang): Remove this default implementation when we remove SetRates().
+  // DEPRECATED! Instead, use void SetRates(const RateControlParameters&);
+  // For now has a default implementation that calls
+  // int32_t SetRates(uin32_t, uint32_t) with |allocation.get_sum_kbps()| and
+  // |framerate| as arguments. This will be removed.
+  // TODO(bugs.webrtc.org/10481): Remove this once all usage is gone.
   virtual int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
                                     uint32_t framerate);
 
+  // Sets rate control parameters: bitrate, framerate, etc. These settings are
+  // instantaneous (i.e. not moving averages) and should apply from now until
+  // the next call to SetRates().
+  // Default implementation will call SetRateAllocation() with appropriate
+  // members of |parameters| as parameters.
+  virtual void SetRates(const RateControlParameters& parameters);
+
   // Inform the encoder when the packet loss rate changes.
   //
   // Input:   - packet_loss_rate  : The packet loss rate (0.0 to 1.0).