Adds field trial to AudioPriorityBitrateAllocationStrategy.

Bug: webrtc:9718
Change-Id: I6419616c27c581e47fdb78ad6594496fad5cec76
Reviewed-on: https://webrtc-review.googlesource.com/c/106261
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25252}
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index a4c2205..300b872 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -76,9 +76,12 @@
     ":checks",
     ":rtc_task_queue",
     ":safe_compare",
+    ":safe_minmax",
     ":type_traits",
     "..:webrtc_common",
     "../api:array_view",
+    "../system_wrappers:field_trial",
+    "experiments:field_trial_parser",
     "system:arch",
     "system:unused",
     "third_party/base64",
diff --git a/rtc_base/bitrateallocationstrategy.cc b/rtc_base/bitrateallocationstrategy.cc
index 7c65c12..c9fa937 100644
--- a/rtc_base/bitrateallocationstrategy.cc
+++ b/rtc_base/bitrateallocationstrategy.cc
@@ -9,10 +9,29 @@
  */
 
 #include "rtc_base/bitrateallocationstrategy.h"
+
 #include <algorithm>
 #include <map>
 #include <utility>
 
+#include "rtc_base/numerics/safe_minmax.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+AudioPriorityConfig::AudioPriorityConfig()
+    : min_rate("min"), max_rate("max"), target_rate("target") {
+  std::string trial_string;
+// TODO(bugs.webrtc.org/9889): Remove this when Chromium build has been fixed.
+#if !defined(WEBRTC_CHROMIUM_BUILD)
+  trial_string = field_trial::FindFullName("WebRTC-Bwe-AudioPriority");
+#endif
+  ParseFieldTrial({&min_rate, &max_rate, &target_rate}, trial_string);
+}
+AudioPriorityConfig::AudioPriorityConfig(const AudioPriorityConfig&) = default;
+AudioPriorityConfig::~AudioPriorityConfig() = default;
+
+}  // namespace webrtc
+
 namespace rtc {
 
 // The purpose of this is to allow video streams to use extra bandwidth for FEC.
@@ -83,22 +102,33 @@
     std::string audio_track_id,
     uint32_t sufficient_audio_bitrate)
     : audio_track_id_(audio_track_id),
-      sufficient_audio_bitrate_(sufficient_audio_bitrate) {}
+      sufficient_audio_bitrate_(sufficient_audio_bitrate) {
+  if (config_.target_rate) {
+    sufficient_audio_bitrate_ = config_.target_rate->bps();
+  }
+}
 
 std::vector<uint32_t> AudioPriorityBitrateAllocationStrategy::AllocateBitrates(
     uint32_t available_bitrate,
     const ArrayView<const TrackConfig*> track_configs) {
-  const TrackConfig* audio_track_config = NULL;
+  absl::optional<TrackConfig> audio_track_config;
   size_t audio_config_index = 0;
   uint32_t sum_min_bitrates = 0;
   uint32_t sum_max_bitrates = 0;
 
   for (const auto*& track_config : track_configs) {
-    sum_min_bitrates += track_config->min_bitrate_bps;
-    sum_max_bitrates += track_config->max_bitrate_bps;
     if (track_config->track_id == audio_track_id_) {
-      audio_track_config = track_config;
       audio_config_index = &track_config - &track_configs[0];
+      audio_track_config = *track_config;
+      if (config_.min_rate)
+        audio_track_config->min_bitrate_bps = config_.min_rate->bps();
+      if (config_.max_rate)
+        audio_track_config->max_bitrate_bps = config_.max_rate->bps();
+      sum_min_bitrates += audio_track_config->min_bitrate_bps;
+      sum_max_bitrates += audio_track_config->max_bitrate_bps;
+    } else {
+      sum_min_bitrates += track_config->min_bitrate_bps;
+      sum_max_bitrates += track_config->max_bitrate_bps;
     }
   }
   if (sum_max_bitrates < available_bitrate) {
@@ -120,11 +150,11 @@
     return DistributeBitratesEvenly(increased_track_configs_ptr,
                                     available_bitrate);
   }
-  if (audio_track_config == nullptr) {
+  if (!audio_track_config) {
     return DistributeBitratesEvenly(track_configs, available_bitrate);
   }
-  auto safe_sufficient_audio_bitrate = std::min(
-      std::max(audio_track_config->min_bitrate_bps, sufficient_audio_bitrate_),
+  auto safe_sufficient_audio_bitrate = rtc::SafeClamp(
+      sufficient_audio_bitrate_, audio_track_config->min_bitrate_bps,
       audio_track_config->max_bitrate_bps);
   if (available_bitrate <= sum_min_bitrates) {
     return SetAllBitratesToMinimum(track_configs);
diff --git a/rtc_base/bitrateallocationstrategy.h b/rtc_base/bitrateallocationstrategy.h
index a4a17f80..e1e47ba 100644
--- a/rtc_base/bitrateallocationstrategy.h
+++ b/rtc_base/bitrateallocationstrategy.h
@@ -14,6 +14,8 @@
 #include <string>
 #include <vector>
 #include "api/array_view.h"
+#include "rtc_base/experiments/field_trial_parser.h"
+#include "rtc_base/experiments/field_trial_units.h"
 
 namespace rtc {
 
@@ -75,7 +77,21 @@
 
   virtual ~BitrateAllocationStrategy() = default;
 };
+}  // namespace rtc
 
+namespace webrtc {
+struct AudioPriorityConfig {
+  FieldTrialOptional<DataRate> min_rate;
+  FieldTrialOptional<DataRate> max_rate;
+  FieldTrialOptional<DataRate> target_rate;
+  AudioPriorityConfig();
+  AudioPriorityConfig(const AudioPriorityConfig&);
+  AudioPriorityConfig& operator=(const AudioPriorityConfig&) = default;
+  ~AudioPriorityConfig();
+};
+}  // namespace webrtc
+
+namespace rtc {
 // Simple allocation strategy giving priority to audio until
 // sufficient_audio_bitrate is reached. Bitrate is distributed evenly between
 // the tracks after sufficient_audio_bitrate is reached. This implementation
@@ -90,6 +106,7 @@
       const ArrayView<const TrackConfig*> track_configs) override;
 
  private:
+  webrtc::AudioPriorityConfig config_;
   std::string audio_track_id_;
   uint32_t sufficient_audio_bitrate_;
 };