Propagate field trials for WebRTC-Video-MinVideoBitrate

Instead of relying on the global field trial string

Bug: webrtc:10335
Change-Id: I491be089ffc725fd28483edf10eae4ae5d17d651
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/346263
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42021}
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 374370d..6e15396 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -1251,8 +1251,8 @@
       "../../rtc_base/synchronization:mutex",
       "../../rtc_base/system:unused",
       "../../system_wrappers",
-      "../../system_wrappers:field_trial",
       "../../system_wrappers:metrics",
+      "../../test:explicit_key_value_config",
       "../../test:fake_encoded_frame",
       "../../test:fake_video_codecs",
       "../../test:field_trial",
diff --git a/modules/video_coding/include/video_codec_initializer.h b/modules/video_coding/include/video_codec_initializer.h
index 2d10ee4..d040001 100644
--- a/modules/video_coding/include/video_codec_initializer.h
+++ b/modules/video_coding/include/video_codec_initializer.h
@@ -11,28 +11,21 @@
 #ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODEC_INITIALIZER_H_
 #define MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODEC_INITIALIZER_H_
 
-#include <memory>
-#include <string>
 #include <vector>
 
+#include "api/field_trials_view.h"
+#include "api/video_codecs/video_codec.h"
 #include "video/config/video_encoder_config.h"
 
 namespace webrtc {
 
-class VideoCodec;
-
 class VideoCodecInitializer {
  public:
   // Takes a VideoEncoderConfig and the VideoStream configuration and
   // translates them into the old school VideoCodec type.
-  static bool SetupCodec(const VideoEncoderConfig& config,
-                         const std::vector<VideoStream>& streams,
-                         VideoCodec* codec);
-
- private:
-  static VideoCodec VideoEncoderConfigToVideoCodec(
-      const VideoEncoderConfig& config,
-      const std::vector<VideoStream>& streams);
+  static VideoCodec SetupCodec(const FieldTrialsView& field_trials,
+                               const VideoEncoderConfig& config,
+                               const std::vector<VideoStream>& streams);
 };
 
 }  // namespace webrtc
diff --git a/modules/video_coding/video_codec_initializer.cc b/modules/video_coding/video_codec_initializer.cc
index f454d87..2ec419a 100644
--- a/modules/video_coding/video_codec_initializer.cc
+++ b/modules/video_coding/video_codec_initializer.cc
@@ -16,6 +16,8 @@
 #include <algorithm>
 
 #include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/units/data_rate.h"
 #include "api/video_codecs/video_encoder.h"
@@ -31,15 +33,9 @@
 
 namespace webrtc {
 
-bool VideoCodecInitializer::SetupCodec(const VideoEncoderConfig& config,
-                                       const std::vector<VideoStream>& streams,
-                                       VideoCodec* codec) {
-  *codec = VideoEncoderConfigToVideoCodec(config, streams);
-  return true;
-}
-
 // TODO(sprang): Split this up and separate the codec specific parts.
-VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
+VideoCodec VideoCodecInitializer::SetupCodec(
+    const FieldTrialsView& field_trials,
     const VideoEncoderConfig& config,
     const std::vector<VideoStream>& streams) {
   static const int kEncoderMinBitrateKbps = 30;
@@ -335,7 +331,7 @@
   }
 
   const absl::optional<DataRate> experimental_min_bitrate =
-      GetExperimentalMinVideoBitrate(video_codec.codecType);
+      GetExperimentalMinVideoBitrate(field_trials, video_codec.codecType);
   if (experimental_min_bitrate) {
     const int experimental_min_bitrate_kbps =
         rtc::saturated_cast<int>(experimental_min_bitrate->kbps());
diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc
index 30078eb..b4858bf 100644
--- a/modules/video_coding/video_codec_initializer_unittest.cc
+++ b/modules/video_coding/video_codec_initializer_unittest.cc
@@ -27,6 +27,7 @@
 #include "api/video_codecs/vp8_temporal_layers_factory.h"
 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
 #include "rtc_base/checks.h"
+#include "test/explicit_key_value_config.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
@@ -89,12 +90,10 @@
     }
   }
 
-  bool InitializeCodec() {
-    codec_out_ = VideoCodec();
+  void InitializeCodec() {
     frame_buffer_controller_.reset();
-    if (!VideoCodecInitializer::SetupCodec(config_, streams_, &codec_out_)) {
-      return false;
-    }
+    codec_out_ =
+        VideoCodecInitializer::SetupCodec(field_trials_, config_, streams_);
     bitrate_allocator_ = CreateBuiltinVideoBitrateAllocatorFactory()
                              ->CreateVideoBitrateAllocator(codec_out_);
     RTC_CHECK(bitrate_allocator_);
@@ -107,7 +106,6 @@
       frame_buffer_controller_ =
           factory.Create(codec_out_, settings, &fec_controller_override_);
     }
-    return true;
   }
 
   VideoStream DefaultStream(
@@ -139,6 +137,7 @@
     return stream;
   }
 
+  const test::ExplicitKeyValueConfig field_trials_{""};
   MockFecControllerOverride fec_controller_override_;
 
   // Input settings.
@@ -154,7 +153,7 @@
 TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
   SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 1, true);
   streams_.push_back(DefaultStream());
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
 
   VideoBitrateAllocation bitrate_allocation =
       bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
@@ -169,7 +168,7 @@
   VideoStream inactive_stream = DefaultStream();
   inactive_stream.active = false;
   streams_.push_back(inactive_stream);
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
 
   VideoBitrateAllocation bitrate_allocation =
       bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
@@ -182,7 +181,7 @@
 TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8ScreenshareConference) {
   SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 2, true);
   streams_.push_back(DefaultScreenshareStream());
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   bitrate_allocator_->SetLegacyConferenceMode(true);
 
   EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
@@ -199,7 +198,7 @@
 TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8Screenshare) {
   SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 2, true);
   streams_.push_back(DefaultScreenshareStream());
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
 
   EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
   EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
@@ -217,7 +216,7 @@
   VideoStream video_stream = DefaultStream();
   video_stream.max_framerate = kScreenshareDefaultFramerate;
   streams_.push_back(video_stream);
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
 
   EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
   EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
@@ -242,7 +241,7 @@
   inactive_video_stream.active = false;
   inactive_video_stream.max_framerate = kScreenshareDefaultFramerate;
   streams_.push_back(inactive_video_stream);
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
 
   EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
   EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
@@ -266,7 +265,7 @@
   VideoStream video_stream = DefaultStream();
   video_stream.num_temporal_layers = 3;
   streams_.push_back(video_stream);
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
 
   EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
   EXPECT_EQ(3u, codec_out_.VP8()->numberOfTemporalLayers);
@@ -290,7 +289,7 @@
   stream.num_temporal_layers = 3;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3u);
   EXPECT_EQ(codec_out_.VP9()->numberOfTemporalLayers, 3u);
 }
@@ -305,7 +304,7 @@
 
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2u);
 }
 
@@ -316,7 +315,7 @@
   stream.num_temporal_layers = 3;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate,
             kDefaultMaxBitrateBps / 1000);
 }
@@ -329,7 +328,7 @@
   stream.scalability_mode = ScalabilityMode::kL1T1;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(1u, codec_out_.VP9()->numberOfSpatialLayers);
   EXPECT_EQ(codec_out_.spatialLayers[0].minBitrate,
             kDefaultMinBitrateBps / 1000);
@@ -344,7 +343,7 @@
   stream.num_temporal_layers = 1;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.spatialLayers[0].targetBitrate,
             kDefaultMaxBitrateBps / 1000);
 }
@@ -361,7 +360,7 @@
   stream.num_temporal_layers = 3;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate,
             kDefaultMaxBitrateBps / 1000);
 }
@@ -379,7 +378,7 @@
   stream.scalability_mode = ScalabilityMode::kL3T1;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(1u, codec_out_.VP9()->numberOfSpatialLayers);
   EXPECT_LT(codec_out_.spatialLayers[0].minBitrate,
             kDefaultMinBitrateBps / 1000);
@@ -398,7 +397,7 @@
   config_.simulcast_layers[0].active = true;
   config_.simulcast_layers[1].active = true;
   config_.simulcast_layers[2].active = true;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
   EXPECT_TRUE(codec_out_.spatialLayers[1].active);
@@ -408,7 +407,7 @@
   config_.simulcast_layers[0].active = true;
   config_.simulcast_layers[1].active = true;
   config_.simulcast_layers[2].active = false;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
   EXPECT_TRUE(codec_out_.spatialLayers[1].active);
@@ -418,7 +417,7 @@
   config_.simulcast_layers[0].active = true;
   config_.simulcast_layers[1].active = false;
   config_.simulcast_layers[2].active = true;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
   EXPECT_FALSE(codec_out_.spatialLayers[1].active);
@@ -428,7 +427,7 @@
   config_.simulcast_layers[0].active = false;
   config_.simulcast_layers[1].active = true;
   config_.simulcast_layers[2].active = true;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
   EXPECT_TRUE(codec_out_.spatialLayers[1].active);
@@ -437,7 +436,7 @@
   config_.simulcast_layers[0].active = false;
   config_.simulcast_layers[1].active = false;
   config_.simulcast_layers[2].active = true;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 1);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
 
@@ -445,7 +444,7 @@
   config_.simulcast_layers[0].active = false;
   config_.simulcast_layers[1].active = true;
   config_.simulcast_layers[2].active = false;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
   EXPECT_FALSE(codec_out_.spatialLayers[1].active);
@@ -454,7 +453,7 @@
   config_.simulcast_layers[0].active = true;
   config_.simulcast_layers[1].active = false;
   config_.simulcast_layers[2].active = false;
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
   EXPECT_TRUE(codec_out_.spatialLayers[0].active);
   EXPECT_FALSE(codec_out_.spatialLayers[1].active);
@@ -469,7 +468,7 @@
   stream.num_temporal_layers = 3;
   streams_.push_back(stream);
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   EXPECT_EQ(codec_out_.width, 1280);
   EXPECT_EQ(codec_out_.height, 720);
   EXPECT_EQ(codec_out_.numberOfSimulcastStreams, 1);
@@ -485,7 +484,7 @@
               DefaultStream(640, 360, ScalabilityMode::kL1T3),
               DefaultStream(1280, 720, ScalabilityMode::kL1T3)};
 
-  EXPECT_TRUE(InitializeCodec());
+  InitializeCodec();
   // This is expected to be the largest layer.
   EXPECT_EQ(codec_out_.width, 1280);
   EXPECT_EQ(codec_out_.height, 720);
@@ -505,8 +504,8 @@
   std::vector<VideoStream> streams = {DefaultStream()};
   streams[0].scalability_mode = ScalabilityMode::kL1T2;
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_GE(codec.spatialLayers[0].targetBitrate,
             codec.spatialLayers[0].minBitrate);
@@ -520,8 +519,8 @@
   std::vector<VideoStream> streams = {DefaultStream()};
   streams[0].scalability_mode = ScalabilityMode::kL2T2;
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_GE(codec.spatialLayers[0].targetBitrate,
             codec.spatialLayers[0].minBitrate);
@@ -541,8 +540,8 @@
   streams[0].scalability_mode = ScalabilityMode::kL2T2;
   config.spatial_layers = {};
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_TRUE(codec.spatialLayers[0].active);
   EXPECT_TRUE(codec.spatialLayers[1].active);
@@ -557,8 +556,8 @@
   config.spatial_layers[0].active = true;
   config.spatial_layers[1].active = false;
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_TRUE(codec.spatialLayers[0].active);
   EXPECT_FALSE(codec.spatialLayers[1].active);
@@ -575,8 +574,8 @@
   std::vector<VideoStream> streams = {DefaultStream()};
   streams[0].scalability_mode = ScalabilityMode::kL1T2;
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_EQ(1u, codec.VP9()->numberOfSpatialLayers);
   // Target is consistent with min and max (min <= target <= max).
@@ -603,8 +602,8 @@
   std::vector<VideoStream> streams = {DefaultStream()};
   streams[0].scalability_mode = ScalabilityMode::kL2T2;
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_EQ(2u, codec.VP9()->numberOfSpatialLayers);
   EXPECT_GE(codec.spatialLayers[0].targetBitrate,
@@ -627,15 +626,15 @@
   std::vector<VideoStream> streams = {DefaultStream()};
   streams[0].scalability_mode = ScalabilityMode::kL2T3_KEY;
 
-  VideoCodec codec;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  VideoCodec codec =
+      VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 2u);
   EXPECT_EQ(codec.VP9()->numberOfTemporalLayers, 3u);
   EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOnKeyPic);
 
   streams[0].scalability_mode = ScalabilityMode::kS3T1;
-  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+  codec = VideoCodecInitializer::SetupCodec(field_trials_, config, streams);
 
   EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 3u);
   EXPECT_EQ(codec.VP9()->numberOfTemporalLayers, 1u);
diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn
index a908c3a..57c9fb7 100644
--- a/rtc_base/experiments/BUILD.gn
+++ b/rtc_base/experiments/BUILD.gn
@@ -222,11 +222,11 @@
   ]
   deps = [
     ":field_trial_parser",
+    "../../api:field_trials_view",
     "../../api/units:data_rate",
     "../../api/video:video_frame",
     "../../rtc_base:checks",
     "../../rtc_base:logging",
-    "../../system_wrappers:field_trial",
   ]
   absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
diff --git a/rtc_base/experiments/min_video_bitrate_experiment.cc b/rtc_base/experiments/min_video_bitrate_experiment.cc
index 8d4d18a..179d4db 100644
--- a/rtc_base/experiments/min_video_bitrate_experiment.cc
+++ b/rtc_base/experiments/min_video_bitrate_experiment.cc
@@ -12,10 +12,10 @@
 
 #include <string>
 
+#include "api/field_trials_view.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/experiments/field_trial_parser.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
@@ -26,17 +26,18 @@
     "WebRTC-VP8-Forced-Fallback-Encoder-v2";
 const char kMinVideoBitrateExperiment[] = "WebRTC-Video-MinVideoBitrate";
 
-absl::optional<int> GetFallbackMinBpsFromFieldTrial(VideoCodecType type) {
+absl::optional<int> GetFallbackMinBpsFromFieldTrial(
+    const FieldTrialsView& field_trials,
+    VideoCodecType type) {
   if (type != kVideoCodecVP8) {
     return absl::nullopt;
   }
 
-  if (!webrtc::field_trial::IsEnabled(kForcedFallbackFieldTrial)) {
+  if (!field_trials.IsEnabled(kForcedFallbackFieldTrial)) {
     return absl::nullopt;
   }
 
-  const std::string group =
-      webrtc::field_trial::FindFullName(kForcedFallbackFieldTrial);
+  const std::string group = field_trials.Lookup(kForcedFallbackFieldTrial);
   if (group.empty()) {
     return absl::nullopt;
   }
@@ -57,14 +58,16 @@
 }
 }  // namespace
 
-absl::optional<DataRate> GetExperimentalMinVideoBitrate(VideoCodecType type) {
+absl::optional<DataRate> GetExperimentalMinVideoBitrate(
+    const FieldTrialsView& field_trials,
+    VideoCodecType type) {
   const absl::optional<int> fallback_min_bitrate_bps =
-      GetFallbackMinBpsFromFieldTrial(type);
+      GetFallbackMinBpsFromFieldTrial(field_trials, type);
   if (fallback_min_bitrate_bps) {
     return DataRate::BitsPerSec(*fallback_min_bitrate_bps);
   }
 
-  if (webrtc::field_trial::IsEnabled(kMinVideoBitrateExperiment)) {
+  if (field_trials.IsEnabled(kMinVideoBitrateExperiment)) {
     webrtc::FieldTrialFlag enabled("Enabled");
 
     // Backwards-compatibility with an old experiment - a generic minimum which,
@@ -80,7 +83,7 @@
     webrtc::ParseFieldTrial(
         {&enabled, &min_video_bitrate, &min_bitrate_vp8, &min_bitrate_vp9,
          &min_bitrate_av1, &min_bitrate_h264},
-        webrtc::field_trial::FindFullName(kMinVideoBitrateExperiment));
+        field_trials.Lookup(kMinVideoBitrateExperiment));
 
     if (min_video_bitrate) {
       if (min_bitrate_vp8 || min_bitrate_vp9 || min_bitrate_av1 ||
diff --git a/rtc_base/experiments/min_video_bitrate_experiment.h b/rtc_base/experiments/min_video_bitrate_experiment.h
index 9ea8783..ac1335f 100644
--- a/rtc_base/experiments/min_video_bitrate_experiment.h
+++ b/rtc_base/experiments/min_video_bitrate_experiment.h
@@ -12,6 +12,7 @@
 #define RTC_BASE_EXPERIMENTS_MIN_VIDEO_BITRATE_EXPERIMENT_H_
 
 #include "absl/types/optional.h"
+#include "api/field_trials_view.h"
 #include "api/units/data_rate.h"
 #include "api/video/video_codec_type.h"
 
@@ -21,7 +22,9 @@
 
 // Return the experiment-driven minimum video bitrate.
 // If no experiment is effective, returns nullopt.
-absl::optional<DataRate> GetExperimentalMinVideoBitrate(VideoCodecType type);
+absl::optional<DataRate> GetExperimentalMinVideoBitrate(
+    const FieldTrialsView& field_trials,
+    VideoCodecType type);
 
 }  // namespace webrtc
 
diff --git a/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc b/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc
index ff0da71..b8a5809 100644
--- a/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc
+++ b/rtc_base/experiments/min_video_bitrate_experiment_unittest.cc
@@ -13,127 +13,129 @@
 #include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "api/video/video_codec_type.h"
-#include "test/field_trial.h"
+#include "test/explicit_key_value_config.h"
 #include "test/gtest.h"
 
 namespace webrtc {
 namespace {
 
+using test::ExplicitKeyValueConfig;
+
 TEST(GetExperimentalMinVideoBitrateTest,
      NulloptForAllCodecsIfFieldTrialUndefined) {
-  test::ScopedFieldTrials field_trials("");
+  ExplicitKeyValueConfig field_trials("");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
             absl::nullopt);
 }
 
 TEST(GetExperimentalMinVideoBitrateTest,
      NulloptForAllCodecsIfFieldTrialDisabled) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/Disabled,br:123kbps/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
             absl::nullopt);
 }
 
 TEST(GetExperimentalMinVideoBitrateTest, BrForAllCodecsIfDefined) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/Enabled,br:123kbps/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
+            DataRate::KilobitsPerSec(123));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
+            DataRate::KilobitsPerSec(123));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
+            DataRate::KilobitsPerSec(123));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
+            DataRate::KilobitsPerSec(123));
 }
 
 TEST(GetExperimentalMinVideoBitrateTest, BrTrumpsSpecificCodecConfigs) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/"
       "Enabled,br:123kbps,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
-            absl::make_optional(DataRate::KilobitsPerSec(123)));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
+            DataRate::KilobitsPerSec(123));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
+            DataRate::KilobitsPerSec(123));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
+            DataRate::KilobitsPerSec(123));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
+            DataRate::KilobitsPerSec(123));
 }
 
 TEST(GetExperimentalMinVideoBitrateTest,
      SpecificCodecConfigsIgnoredIfExpDisabled) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/"
       "Disabled,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
             absl::nullopt);
 }
 
 TEST(GetExperimentalMinVideoBitrateTest, SpecificCodecConfigsUsedIfExpEnabled) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/"
       "Enabled,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
-            absl::make_optional(DataRate::KilobitsPerSec(100)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
-            absl::make_optional(DataRate::KilobitsPerSec(200)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
-            absl::make_optional(DataRate::KilobitsPerSec(300)));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
+            DataRate::KilobitsPerSec(100));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
+            DataRate::KilobitsPerSec(200));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
+            DataRate::KilobitsPerSec(300));
 }
 
 TEST(GetExperimentalMinVideoBitrateTest,
      Vp8BitrateValueTakenFromFallbackIfAvailable) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/"
       "Enabled,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/"
       "WebRTC-VP8-Forced-Fallback-Encoder-v2/"
       "Enabled-444444,555555,666666/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP8),
-            absl::make_optional(DataRate::BitsPerSec(666666)));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP8),
+            DataRate::BitsPerSec(666666));
 }
 
 TEST(GetExperimentalMinVideoBitrateTest,
      NonVp8BitrateValuesTakenFromMinVideoBitrate) {
-  test::ScopedFieldTrials field_trials(
+  ExplicitKeyValueConfig field_trials(
       "WebRTC-Video-MinVideoBitrate/"
       "Enabled,vp8_br:100kbps,vp9_br:200kbps,h264_br:300kbps/"
       "WebRTC-VP8-Forced-Fallback-Encoder-v2/"
       "Enabled-444444,555555,666666/");
 
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecGeneric),
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecGeneric),
             absl::nullopt);
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecVP9),
-            absl::make_optional(DataRate::KilobitsPerSec(200)));
-  EXPECT_EQ(GetExperimentalMinVideoBitrate(VideoCodecType::kVideoCodecH264),
-            absl::make_optional(DataRate::KilobitsPerSec(300)));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecVP9),
+            DataRate::KilobitsPerSec(200));
+  EXPECT_EQ(GetExperimentalMinVideoBitrate(field_trials, kVideoCodecH264),
+            DataRate::KilobitsPerSec(300));
 }
 
 }  // namespace
diff --git a/video/config/encoder_stream_factory.cc b/video/config/encoder_stream_factory.cc
index 1302ba8..499fdb5 100644
--- a/video/config/encoder_stream_factory.cc
+++ b/video/config/encoder_stream_factory.cc
@@ -136,7 +136,7 @@
                 encoder_config.number_of_streams);
 
   const absl::optional<webrtc::DataRate> experimental_min_bitrate =
-      GetExperimentalMinVideoBitrate(encoder_config.codec_type);
+      GetExperimentalMinVideoBitrate(trials_, encoder_config.codec_type);
 
   bool is_simulcast = (encoder_config.number_of_streams > 1);
   // If scalability mode was specified, don't treat {active,inactive,inactive}
diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc
index 03d3950..6f146e3 100644
--- a/video/video_send_stream_impl.cc
+++ b/video/video_send_stream_impl.cc
@@ -801,7 +801,7 @@
         PayloadStringToCodecType(config_.rtp.payload_name);
 
     const absl::optional<DataRate> experimental_min_bitrate =
-        GetExperimentalMinVideoBitrate(codec_type);
+        GetExperimentalMinVideoBitrate(env_.field_trials(), codec_type);
     encoder_min_bitrate_bps_ =
         experimental_min_bitrate
             ? experimental_min_bitrate->bps()
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 4390fe3..a791225 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -1177,10 +1177,8 @@
           encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_),
       encoder_config_.simulcast_layers, &streams);
 
-  VideoCodec codec;
-  if (!VideoCodecInitializer::SetupCodec(encoder_config_, streams, &codec)) {
-    RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
-  }
+  VideoCodec codec = VideoCodecInitializer::SetupCodec(
+      env_.field_trials(), encoder_config_, streams);
 
   if (encoder_config_.codec_type == kVideoCodecVP9 ||
       encoder_config_.codec_type == kVideoCodecAV1) {