WebRTC-DeprecateGlobalFieldTrialString/Enabled/ - part 19/inf

Convert most field trials used in PCLF tests.

Change-Id: I26c0c4b1164bb0870aae1a488942cde888cb459d
Bug: webrtc:10335
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/322703
Commit-Queue: Jeremy Leconte <jleconte@google.com>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40909}
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 22eb02a..28822a1 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -339,8 +339,10 @@
   deps = [
     ":rtc_media_base",
     "../api:fec_controller_api",
+    "../api:field_trials_view",
     "../api:scoped_refptr",
     "../api:sequence_checker",
+    "../api/transport:field_trial_based_config",
     "../api/video:video_codec_constants",
     "../api/video:video_frame",
     "../api/video:video_rtp_headers",
@@ -357,7 +359,6 @@
     "../rtc_base/system:no_unique_address",
     "../rtc_base/system:rtc_export",
     "../system_wrappers",
-    "../system_wrappers:field_trial",
   ]
   absl_deps = [
     "//third_party/abseil-cpp/absl/algorithm:container",
@@ -813,6 +814,7 @@
         ":stream_params",
         ":turn_utils",
         "../api:create_simulcast_test_fixture_api",
+        "../api:field_trials_view",
         "../api:libjingle_peerconnection_api",
         "../api:mock_encoder_selector",
         "../api:mock_video_bitrate_allocator",
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index 7ee95b1..147d1fd 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -19,7 +19,9 @@
 #include <utility>
 
 #include "absl/algorithm/container.h"
+#include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
+#include "api/transport/field_trial_based_config.h"
 #include "api/video/i420_buffer.h"
 #include "api/video/video_codec_constants.h"
 #include "api/video/video_frame_buffer.h"
@@ -33,7 +35,6 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/experiments/rate_control_settings.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace {
 
@@ -42,9 +43,10 @@
 // Max qp for lowest spatial resolution when doing simulcast.
 const unsigned int kLowestResMaxQp = 45;
 
-absl::optional<unsigned int> GetScreenshareBoostedQpValue() {
+absl::optional<unsigned int> GetScreenshareBoostedQpValue(
+    const webrtc::FieldTrialsView& field_trials) {
   std::string experiment_group =
-      webrtc::field_trial::FindFullName("WebRTC-BoostedScreenshareQp");
+      field_trials.Lookup("WebRTC-BoostedScreenshareQp");
   unsigned int qp;
   if (sscanf(experiment_group.c_str(), "%u", &qp) != 1)
     return absl::nullopt;
@@ -244,12 +246,25 @@
 
 SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory,
                                                  const SdpVideoFormat& format)
-    : SimulcastEncoderAdapter(factory, nullptr, format) {}
+    : SimulcastEncoderAdapter(factory,
+                              nullptr,
+                              format,
+                              FieldTrialBasedConfig()) {}
 
 SimulcastEncoderAdapter::SimulcastEncoderAdapter(
     VideoEncoderFactory* primary_factory,
     VideoEncoderFactory* fallback_factory,
     const SdpVideoFormat& format)
+    : SimulcastEncoderAdapter(primary_factory,
+                              fallback_factory,
+                              format,
+                              FieldTrialBasedConfig()) {}
+
+SimulcastEncoderAdapter::SimulcastEncoderAdapter(
+    VideoEncoderFactory* primary_factory,
+    VideoEncoderFactory* fallback_factory,
+    const SdpVideoFormat& format,
+    const FieldTrialsView& field_trials)
     : inited_(0),
       primary_encoder_factory_(primary_factory),
       fallback_encoder_factory_(fallback_factory),
@@ -257,10 +272,12 @@
       total_streams_count_(0),
       bypass_mode_(false),
       encoded_complete_callback_(nullptr),
-      experimental_boosted_screenshare_qp_(GetScreenshareBoostedQpValue()),
-      boost_base_layer_quality_(RateControlSettings::ParseFromFieldTrials()
-                                    .Vp8BoostBaseLayerQuality()),
-      prefer_temporal_support_on_base_layer_(field_trial::IsEnabled(
+      experimental_boosted_screenshare_qp_(
+          GetScreenshareBoostedQpValue(field_trials)),
+      boost_base_layer_quality_(
+          RateControlSettings::ParseFromKeyValueConfig(&field_trials)
+              .Vp8BoostBaseLayerQuality()),
+      prefer_temporal_support_on_base_layer_(field_trials.IsEnabled(
           "WebRTC-Video-PreferTemporalSupportOnBaseLayer")) {
   RTC_DCHECK(primary_factory);
 
diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h
index ef8205e..a51ab61 100644
--- a/media/engine/simulcast_encoder_adapter.h
+++ b/media/engine/simulcast_encoder_adapter.h
@@ -22,6 +22,7 @@
 
 #include "absl/types/optional.h"
 #include "api/fec_controller_override.h"
+#include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "api/video_codecs/sdp_video_format.h"
 #include "api/video_codecs/video_encoder.h"
@@ -49,6 +50,10 @@
   SimulcastEncoderAdapter(VideoEncoderFactory* primary_factory,
                           VideoEncoderFactory* fallback_factory,
                           const SdpVideoFormat& format);
+  SimulcastEncoderAdapter(VideoEncoderFactory* primary_factory,
+                          VideoEncoderFactory* fallback_factory,
+                          const SdpVideoFormat& format,
+                          const FieldTrialsView& field_trials);
   ~SimulcastEncoderAdapter() override;
 
   // Implements VideoEncoder.
diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc
index d1ea7c5..e2ac5ea 100644
--- a/media/engine/simulcast_encoder_adapter_unittest.cc
+++ b/media/engine/simulcast_encoder_adapter_unittest.cc
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "api/field_trials_view.h"
 #include "api/test/create_simulcast_test_fixture.h"
 #include "api/test/simulcast_test_fixture.h"
 #include "api/test/video/function_video_decoder_factory.h"
@@ -29,9 +30,9 @@
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
 #include "rtc_base/checks.h"
-#include "test/field_trial.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 using ::testing::_;
 using ::testing::Return;
@@ -402,17 +403,20 @@
  public:
   explicit TestSimulcastEncoderAdapterFakeHelper(
       bool use_fallback_factory,
-      const SdpVideoFormat& video_format)
+      const SdpVideoFormat& video_format,
+      const FieldTrialsView& field_trials)
       : primary_factory_(new MockVideoEncoderFactory()),
         fallback_factory_(use_fallback_factory ? new MockVideoEncoderFactory()
                                                : nullptr),
-        video_format_(video_format) {}
+        video_format_(video_format),
+        field_trials_(field_trials) {}
 
   // Can only be called once as the SimulcastEncoderAdapter will take the
   // ownership of `factory_`.
   VideoEncoder* CreateMockEncoderAdapter() {
     return new SimulcastEncoderAdapter(primary_factory_.get(),
-                                       fallback_factory_.get(), video_format_);
+                                       fallback_factory_.get(), video_format_,
+                                       field_trials_);
   }
 
   MockVideoEncoderFactory* factory() { return primary_factory_.get(); }
@@ -424,6 +428,7 @@
   std::unique_ptr<MockVideoEncoderFactory> primary_factory_;
   std::unique_ptr<MockVideoEncoderFactory> fallback_factory_;
   SdpVideoFormat video_format_;
+  const FieldTrialsView& field_trials_;
 };
 
 static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
@@ -441,7 +446,8 @@
 
   void SetUp() override {
     helper_.reset(new TestSimulcastEncoderAdapterFakeHelper(
-        use_fallback_factory_, SdpVideoFormat("VP8", sdp_video_parameters_)));
+        use_fallback_factory_, SdpVideoFormat("VP8", sdp_video_parameters_),
+        field_trials_));
     adapter_.reset(helper_->CreateMockEncoderAdapter());
     last_encoded_image_width_ = absl::nullopt;
     last_encoded_image_height_ = absl::nullopt;
@@ -581,6 +587,7 @@
   std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
   bool use_fallback_factory_;
   SdpVideoFormat::Parameters sdp_video_parameters_;
+  test::ScopedKeyValueConfig field_trials_;
 };
 
 TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
@@ -1435,12 +1442,14 @@
 TEST_F(
     TestSimulcastEncoderAdapterFake,
     EncoderInfoFromFieldTrialDoesNotOverrideExistingBitrateLimitsInSinglecast) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
+      field_trials_,
       "WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride/"
       "frame_size_pixels:123|456|789,"
       "min_start_bitrate_bps:11000|22000|33000,"
       "min_bitrate_bps:44000|55000|66000,"
       "max_bitrate_bps:77000|88000|99000/");
+  SetUp();
 
   std::vector<VideoEncoder::ResolutionBitrateLimits> bitrate_limits;
   bitrate_limits.push_back(
@@ -1463,7 +1472,8 @@
 }
 
 TEST_F(TestSimulcastEncoderAdapterFake, EncoderInfoFromFieldTrial) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
+      field_trials_,
       "WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride/"
       "requested_resolution_alignment:8,"
       "apply_alignment_to_all_simulcast_layers/");
@@ -1483,7 +1493,8 @@
 
 TEST_F(TestSimulcastEncoderAdapterFake,
        EncoderInfoFromFieldTrialForSingleStream) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
+      field_trials_,
       "WebRTC-SimulcastEncoderAdapter-GetEncoderInfoOverride/"
       "requested_resolution_alignment:9,"
       "frame_size_pixels:123|456|789,"
@@ -1798,8 +1809,8 @@
   // Normally SEA reuses encoders. But, when TL-based SW fallback is enabled,
   // the encoder which served the lowest stream should be recreated before it
   // can be used to process an upper layer and vice-versa.
-  test::ScopedFieldTrials field_trials(
-      "WebRTC-Video-PreferTemporalSupportOnBaseLayer/Enabled/");
+  test::ScopedKeyValueConfig field_trials(
+      field_trials_, "WebRTC-Video-PreferTemporalSupportOnBaseLayer/Enabled/");
   use_fallback_factory_ = true;
   ReSetUp();
 
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index e305ddf..cca9d88 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -409,6 +409,7 @@
     ":video_codec_interface",
     "../../api:array_view",
     "../../api:field_trials_view",
+    "../../api:field_trials_view",
     "../../api:scoped_refptr",
     "../../api:sequence_checker",
     "../../api/units:time_delta",
@@ -1263,6 +1264,7 @@
       "../../api:array_view",
       "../../api:create_simulcast_test_fixture_api",
       "../../api:fec_controller_api",
+      "../../api:field_trials_view",
       "../../api:mock_fec_controller_override",
       "../../api:mock_video_decoder",
       "../../api:mock_video_encoder",
diff --git a/modules/video_coding/utility/quality_scaler.cc b/modules/video_coding/utility/quality_scaler.cc
index 9fb41a0..7ecb340 100644
--- a/modules/video_coding/utility/quality_scaler.cc
+++ b/modules/video_coding/utility/quality_scaler.cc
@@ -13,6 +13,7 @@
 #include <memory>
 #include <utility>
 
+#include "api/field_trials_view.h"
 #include "api/units/time_delta.h"
 #include "api/video/video_adaptation_reason.h"
 #include "rtc_base/checks.h"
@@ -175,37 +176,38 @@
 };
 
 QualityScaler::QualityScaler(QualityScalerQpUsageHandlerInterface* handler,
-                             VideoEncoder::QpThresholds thresholds)
-    : QualityScaler(handler, thresholds, kMeasureMs) {}
+                             VideoEncoder::QpThresholds thresholds,
+                             const FieldTrialsView& field_trials)
+    : QualityScaler(handler, thresholds, field_trials, kMeasureMs) {}
 
 // Protected ctor, should not be called directly.
 QualityScaler::QualityScaler(QualityScalerQpUsageHandlerInterface* handler,
                              VideoEncoder::QpThresholds thresholds,
+                             const FieldTrialsView& field_trials,
                              int64_t default_sampling_period_ms)
     : handler_(handler),
       thresholds_(thresholds),
-      sampling_period_ms_(QualityScalerSettings::ParseFromFieldTrials()
+      sampling_period_ms_(QualityScalerSettings(field_trials)
                               .SamplingPeriodMs()
                               .value_or(default_sampling_period_ms)),
       fast_rampup_(true),
       // Arbitrarily choose size based on 30 fps for 5 seconds.
-      average_qp_(QualityScalerSettings::ParseFromFieldTrials()
+      average_qp_(QualityScalerSettings(field_trials)
                       .AverageQpWindow()
                       .value_or(5 * 30)),
       framedrop_percent_media_opt_(5 * 30),
       framedrop_percent_all_(5 * 30),
-      experiment_enabled_(QualityScalingExperiment::Enabled()),
-      min_frames_needed_(
-          QualityScalerSettings::ParseFromFieldTrials().MinFrames().value_or(
-              kMinFramesNeededToScale)),
-      initial_scale_factor_(QualityScalerSettings::ParseFromFieldTrials()
+      experiment_enabled_(QualityScalingExperiment::Enabled(field_trials)),
+      min_frames_needed_(QualityScalerSettings(field_trials)
+                             .MinFrames()
+                             .value_or(kMinFramesNeededToScale)),
+      initial_scale_factor_(QualityScalerSettings(field_trials)
                                 .InitialScaleFactor()
                                 .value_or(kSamplePeriodScaleFactor)),
-      scale_factor_(
-          QualityScalerSettings::ParseFromFieldTrials().ScaleFactor()) {
+      scale_factor_(QualityScalerSettings(field_trials).ScaleFactor()) {
   RTC_DCHECK_RUN_ON(&task_checker_);
   if (experiment_enabled_) {
-    config_ = QualityScalingExperiment::GetConfig();
+    config_ = QualityScalingExperiment::GetConfig(field_trials);
     qp_smoother_high_.reset(new QpSmoother(config_.alpha_high));
     qp_smoother_low_.reset(new QpSmoother(config_.alpha_low));
   }
diff --git a/modules/video_coding/utility/quality_scaler.h b/modules/video_coding/utility/quality_scaler.h
index 93014e3..14623ff 100644
--- a/modules/video_coding/utility/quality_scaler.h
+++ b/modules/video_coding/utility/quality_scaler.h
@@ -17,6 +17,7 @@
 #include <memory>
 
 #include "absl/types/optional.h"
+#include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/sequence_checker.h"
 #include "api/video_codecs/video_encoder.h"
@@ -40,7 +41,8 @@
   // This starts the quality scaler periodically checking what the average QP
   // has been recently.
   QualityScaler(QualityScalerQpUsageHandlerInterface* handler,
-                VideoEncoder::QpThresholds thresholds);
+                VideoEncoder::QpThresholds thresholds,
+                const FieldTrialsView& field_trials);
   virtual ~QualityScaler();
   // Should be called each time a frame is dropped at encoding.
   void ReportDroppedFrameByMediaOpt();
@@ -55,6 +57,7 @@
  protected:
   QualityScaler(QualityScalerQpUsageHandlerInterface* handler,
                 VideoEncoder::QpThresholds thresholds,
+                const FieldTrialsView& field_trials,
                 int64_t sampling_period_ms);
 
  private:
diff --git a/modules/video_coding/utility/quality_scaler_unittest.cc b/modules/video_coding/utility/quality_scaler_unittest.cc
index 50410dd..1142947 100644
--- a/modules/video_coding/utility/quality_scaler_unittest.cc
+++ b/modules/video_coding/utility/quality_scaler_unittest.cc
@@ -13,12 +13,13 @@
 #include <memory>
 #include <string>
 
+#include "api/field_trials_view.h"
 #include "api/units/time_delta.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/event.h"
 #include "rtc_base/task_queue_for_test.h"
-#include "test/field_trial.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 namespace webrtc {
 namespace {
@@ -53,8 +54,9 @@
 class QualityScalerUnderTest : public QualityScaler {
  public:
   explicit QualityScalerUnderTest(QualityScalerQpUsageHandlerInterface* handler,
-                                  VideoEncoder::QpThresholds thresholds)
-      : QualityScaler(handler, thresholds, 5) {}
+                                  VideoEncoder::QpThresholds thresholds,
+                                  const FieldTrialsView& field_trials)
+      : QualityScaler(handler, thresholds, field_trials, 5) {}
 };
 
 class QualityScalerTest : public ::testing::Test,
@@ -74,7 +76,8 @@
         handler_(std::make_unique<FakeQpUsageHandler>()) {
     task_queue_.SendTask([this] {
       qs_ = std::unique_ptr<QualityScaler>(new QualityScalerUnderTest(
-          handler_.get(), VideoEncoder::QpThresholds(kLowQp, kHighQp)));
+          handler_.get(), VideoEncoder::QpThresholds(kLowQp, kHighQp),
+          scoped_field_trial_));
     });
   }
 
@@ -104,7 +107,7 @@
     }
   }
 
-  test::ScopedFieldTrials scoped_field_trial_;
+  test::ScopedKeyValueConfig scoped_field_trial_;
   TaskQueueForTest task_queue_;
   std::unique_ptr<QualityScaler> qs_;
   std::unique_ptr<FakeQpUsageHandler> handler_;
diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn
index ac542cc..185d593 100644
--- a/rtc_base/experiments/BUILD.gn
+++ b/rtc_base/experiments/BUILD.gn
@@ -75,8 +75,6 @@
     ":field_trial_parser",
     "..:logging",
     "../../api:field_trials_view",
-    "../../api/transport:field_trial_based_config",
-    "../../system_wrappers:field_trial",
   ]
   absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
@@ -103,10 +101,14 @@
   ]
   deps = [
     "..:logging",
+    "../../api:field_trials_view",
+    "../../api/transport:field_trial_based_config",
     "../../api/video_codecs:video_codecs_api",
-    "../../system_wrappers:field_trial",
   ]
-  absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+  absl_deps = [
+    "//third_party/abseil-cpp/absl/strings:strings",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
 }
 
 rtc_library("normalize_simulcast_size_experiment") {
diff --git a/rtc_base/experiments/quality_scaler_settings.cc b/rtc_base/experiments/quality_scaler_settings.cc
index 85c9925..24da211 100644
--- a/rtc_base/experiments/quality_scaler_settings.cc
+++ b/rtc_base/experiments/quality_scaler_settings.cc
@@ -10,7 +10,7 @@
 
 #include "rtc_base/experiments/quality_scaler_settings.h"
 
-#include "api/transport/field_trial_based_config.h"
+#include "api/field_trials_view.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
@@ -20,7 +20,7 @@
 }  // namespace
 
 QualityScalerSettings::QualityScalerSettings(
-    const FieldTrialsView* const key_value_config)
+    const FieldTrialsView& field_trials)
     : sampling_period_ms_("sampling_period_ms"),
       average_qp_window_("average_qp_window"),
       min_frames_("min_frames"),
@@ -28,16 +28,10 @@
       scale_factor_("scale_factor"),
       initial_bitrate_interval_ms_("initial_bitrate_interval_ms"),
       initial_bitrate_factor_("initial_bitrate_factor") {
-  ParseFieldTrial(
-      {&sampling_period_ms_, &average_qp_window_, &min_frames_,
-       &initial_scale_factor_, &scale_factor_, &initial_bitrate_interval_ms_,
-       &initial_bitrate_factor_},
-      key_value_config->Lookup("WebRTC-Video-QualityScalerSettings"));
-}
-
-QualityScalerSettings QualityScalerSettings::ParseFromFieldTrials() {
-  FieldTrialBasedConfig field_trial_config;
-  return QualityScalerSettings(&field_trial_config);
+  ParseFieldTrial({&sampling_period_ms_, &average_qp_window_, &min_frames_,
+                   &initial_scale_factor_, &scale_factor_,
+                   &initial_bitrate_interval_ms_, &initial_bitrate_factor_},
+                  field_trials.Lookup("WebRTC-Video-QualityScalerSettings"));
 }
 
 absl::optional<int> QualityScalerSettings::SamplingPeriodMs() const {
diff --git a/rtc_base/experiments/quality_scaler_settings.h b/rtc_base/experiments/quality_scaler_settings.h
index 99827aa..1085816 100644
--- a/rtc_base/experiments/quality_scaler_settings.h
+++ b/rtc_base/experiments/quality_scaler_settings.h
@@ -19,7 +19,7 @@
 
 class QualityScalerSettings final {
  public:
-  static QualityScalerSettings ParseFromFieldTrials();
+  explicit QualityScalerSettings(const FieldTrialsView& field_trials);
 
   absl::optional<int> SamplingPeriodMs() const;
   absl::optional<int> AverageQpWindow() const;
@@ -30,8 +30,6 @@
   absl::optional<double> InitialBitrateFactor() const;
 
  private:
-  explicit QualityScalerSettings(const FieldTrialsView* const key_value_config);
-
   FieldTrialOptional<int> sampling_period_ms_;
   FieldTrialOptional<int> average_qp_window_;
   FieldTrialOptional<int> min_frames_;
diff --git a/rtc_base/experiments/quality_scaler_settings_unittest.cc b/rtc_base/experiments/quality_scaler_settings_unittest.cc
index 9da770c..578fe97 100644
--- a/rtc_base/experiments/quality_scaler_settings_unittest.cc
+++ b/rtc_base/experiments/quality_scaler_settings_unittest.cc
@@ -10,14 +10,15 @@
 
 #include "rtc_base/experiments/quality_scaler_settings.h"
 
-#include "test/field_trial.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 namespace webrtc {
 namespace {
 
 TEST(QualityScalerSettingsTest, ValuesNotSetByDefault) {
-  const auto settings = QualityScalerSettings::ParseFromFieldTrials();
+  webrtc::test::ScopedKeyValueConfig field_trials("");
+  const auto settings = QualityScalerSettings(field_trials);
   EXPECT_FALSE(settings.MinFrames());
   EXPECT_FALSE(settings.InitialScaleFactor());
   EXPECT_FALSE(settings.ScaleFactor());
@@ -26,46 +27,42 @@
 }
 
 TEST(QualityScalerSettingsTest, ParseMinFrames) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/min_frames:100/");
-  EXPECT_EQ(100, QualityScalerSettings::ParseFromFieldTrials().MinFrames());
+  EXPECT_EQ(100, QualityScalerSettings(field_trials).MinFrames());
 }
 
 TEST(QualityScalerSettingsTest, ParseInitialScaleFactor) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/initial_scale_factor:1.5/");
-  EXPECT_EQ(1.5,
-            QualityScalerSettings::ParseFromFieldTrials().InitialScaleFactor());
+  EXPECT_EQ(1.5, QualityScalerSettings(field_trials).InitialScaleFactor());
 }
 
 TEST(QualityScalerSettingsTest, ParseScaleFactor) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/scale_factor:1.1/");
-  EXPECT_EQ(1.1, QualityScalerSettings::ParseFromFieldTrials().ScaleFactor());
+  EXPECT_EQ(1.1, QualityScalerSettings(field_trials).ScaleFactor());
 }
 
 TEST(QualityScalerSettingsTest, ParseInitialBitrateInterval) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/initial_bitrate_interval_ms:1000/");
-  EXPECT_EQ(
-      1000,
-      QualityScalerSettings::ParseFromFieldTrials().InitialBitrateIntervalMs());
+  EXPECT_EQ(1000,
+            QualityScalerSettings(field_trials).InitialBitrateIntervalMs());
 }
 
 TEST(QualityScalerSettingsTest, ParseInitialBitrateFactor) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/initial_bitrate_factor:0.75/");
-  EXPECT_EQ(
-      0.75,
-      QualityScalerSettings::ParseFromFieldTrials().InitialBitrateFactor());
+  EXPECT_EQ(0.75, QualityScalerSettings(field_trials).InitialBitrateFactor());
 }
 
 TEST(QualityScalerSettingsTest, ParseAll) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/"
       "min_frames:100,initial_scale_factor:1.5,scale_factor:0.9,"
       "initial_bitrate_interval_ms:5500,initial_bitrate_factor:0.7/");
-  const auto settings = QualityScalerSettings::ParseFromFieldTrials();
+  const auto settings = QualityScalerSettings(field_trials);
   EXPECT_EQ(100, settings.MinFrames());
   EXPECT_EQ(1.5, settings.InitialScaleFactor());
   EXPECT_EQ(0.9, settings.ScaleFactor());
@@ -74,11 +71,11 @@
 }
 
 TEST(QualityScalerSettingsTest, DoesNotParseIncorrectValue) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/"
       "min_frames:a,initial_scale_factor:b,scale_factor:c,"
       "initial_bitrate_interval_ms:d,initial_bitrate_factor:e/");
-  const auto settings = QualityScalerSettings::ParseFromFieldTrials();
+  const auto settings = QualityScalerSettings(field_trials);
   EXPECT_FALSE(settings.MinFrames());
   EXPECT_FALSE(settings.InitialScaleFactor());
   EXPECT_FALSE(settings.ScaleFactor());
@@ -87,11 +84,11 @@
 }
 
 TEST(QualityScalerSettingsTest, DoesNotReturnTooSmallValue) {
-  test::ScopedFieldTrials field_trials(
+  test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScalerSettings/"
       "min_frames:0,initial_scale_factor:0.0,scale_factor:0.0,"
       "initial_bitrate_interval_ms:-1,initial_bitrate_factor:0.0/");
-  const auto settings = QualityScalerSettings::ParseFromFieldTrials();
+  const auto settings = QualityScalerSettings(field_trials);
   EXPECT_FALSE(settings.MinFrames());
   EXPECT_FALSE(settings.InitialScaleFactor());
   EXPECT_FALSE(settings.ScaleFactor());
diff --git a/rtc_base/experiments/quality_scaling_experiment.cc b/rtc_base/experiments/quality_scaling_experiment.cc
index 0c4ec22..ee3d7c0 100644
--- a/rtc_base/experiments/quality_scaling_experiment.cc
+++ b/rtc_base/experiments/quality_scaling_experiment.cc
@@ -13,8 +13,10 @@
 
 #include <string>
 
+#include "absl/strings/match.h"
+#include "api/field_trials_view.h"
+#include "api/transport/field_trial_based_config.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 namespace {
@@ -42,17 +44,17 @@
 }
 }  // namespace
 
-bool QualityScalingExperiment::Enabled() {
+bool QualityScalingExperiment::Enabled(const FieldTrialsView& field_trials) {
 #if defined(WEBRTC_IOS)
-  return webrtc::field_trial::IsEnabled(kFieldTrial);
+  return absl::StartsWith(field_trials.Lookup(kFieldTrial), "Enabled");
 #else
-  return !webrtc::field_trial::IsDisabled(kFieldTrial);
+  return !absl::StartsWith(field_trials.Lookup(kFieldTrial), "Disabled");
 #endif
 }
 
 absl::optional<QualityScalingExperiment::Settings>
-QualityScalingExperiment::ParseSettings() {
-  std::string group = webrtc::field_trial::FindFullName(kFieldTrial);
+QualityScalingExperiment::ParseSettings(const FieldTrialsView& field_trials) {
+  std::string group = field_trials.Lookup(kFieldTrial);
   // TODO(http://crbug.com/webrtc/12401): Completely remove the experiment code
   // after few releases.
 #if !defined(WEBRTC_IOS)
@@ -71,8 +73,9 @@
 }
 
 absl::optional<VideoEncoder::QpThresholds>
-QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type) {
-  const auto settings = ParseSettings();
+QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type,
+                                          const FieldTrialsView& field_trials) {
+  const auto settings = ParseSettings(field_trials);
   if (!settings)
     return absl::nullopt;
 
@@ -93,8 +96,9 @@
   }
 }
 
-QualityScalingExperiment::Config QualityScalingExperiment::GetConfig() {
-  const auto settings = ParseSettings();
+QualityScalingExperiment::Config QualityScalingExperiment::GetConfig(
+    const FieldTrialsView& field_trials) {
+  const auto settings = ParseSettings(field_trials);
   if (!settings)
     return Config();
 
diff --git a/rtc_base/experiments/quality_scaling_experiment.h b/rtc_base/experiments/quality_scaling_experiment.h
index 31d8292..bd24c06 100644
--- a/rtc_base/experiments/quality_scaling_experiment.h
+++ b/rtc_base/experiments/quality_scaling_experiment.h
@@ -11,6 +11,7 @@
 #define RTC_BASE_EXPERIMENTS_QUALITY_SCALING_EXPERIMENT_H_
 
 #include "absl/types/optional.h"
+#include "api/field_trials_view.h"
 #include "api/video_codecs/video_encoder.h"
 
 namespace webrtc {
@@ -40,17 +41,19 @@
   };
 
   // Returns true if the experiment is enabled.
-  static bool Enabled();
+  static bool Enabled(const FieldTrialsView& field_trials);
 
   // Returns settings from field trial.
-  static absl::optional<Settings> ParseSettings();
+  static absl::optional<Settings> ParseSettings(
+      const FieldTrialsView& field_trials);
 
   // Returns QpThresholds for the `codec_type`.
   static absl::optional<VideoEncoder::QpThresholds> GetQpThresholds(
-      VideoCodecType codec_type);
+      VideoCodecType codec_type,
+      const FieldTrialsView& field_trials);
 
   // Returns parsed values. If the parsing fails, default values are returned.
-  static Config GetConfig();
+  static Config GetConfig(const FieldTrialsView& field_trials);
 };
 
 }  // namespace webrtc
diff --git a/rtc_base/experiments/quality_scaling_experiment_unittest.cc b/rtc_base/experiments/quality_scaling_experiment_unittest.cc
index 4507f15..0c14505 100644
--- a/rtc_base/experiments/quality_scaling_experiment_unittest.cc
+++ b/rtc_base/experiments/quality_scaling_experiment_unittest.cc
@@ -10,8 +10,8 @@
 
 #include "rtc_base/experiments/quality_scaling_experiment.h"
 
-#include "test/field_trial.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 namespace webrtc {
 namespace {
@@ -41,28 +41,28 @@
 #if !defined(WEBRTC_IOS)
 // TODO(bugs.webrtc.org/12401): investigate why QualityScaler kicks in on iOS.
 TEST(QualityScalingExperimentTest, DefaultEnabledWithoutFieldTrial) {
-  webrtc::test::ScopedFieldTrials field_trials("");
-  EXPECT_TRUE(QualityScalingExperiment::Enabled());
+  webrtc::test::ScopedKeyValueConfig field_trials("");
+  EXPECT_TRUE(QualityScalingExperiment::Enabled(field_trials));
 }
 #else
 TEST(QualityScalingExperimentTest, DefaultDisabledWithoutFieldTrialIOS) {
-  webrtc::test::ScopedFieldTrials field_trials("");
-  EXPECT_FALSE(QualityScalingExperiment::Enabled());
+  webrtc::test::ScopedKeyValueConfig field_trials("");
+  EXPECT_FALSE(QualityScalingExperiment::Enabled(field_trials));
 }
 #endif
 
 TEST(QualityScalingExperimentTest, EnabledWithFieldTrial) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled/");
-  EXPECT_TRUE(QualityScalingExperiment::Enabled());
+  EXPECT_TRUE(QualityScalingExperiment::Enabled(field_trials));
 }
 
 TEST(QualityScalingExperimentTest, ParseSettings) {
   const QualityScalingExperiment::Settings kExpected = {1, 2, 3,    4,     5, 6,
                                                         7, 8, 0.9f, 0.99f, 1};
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,7,8,0.9,0.99,1/");
-  const auto settings = QualityScalingExperiment::ParseSettings();
+  const auto settings = QualityScalingExperiment::ParseSettings(field_trials);
   EXPECT_TRUE(settings);
   ExpectEqualSettings(kExpected, *settings);
 }
@@ -70,117 +70,117 @@
 #if !defined(WEBRTC_IOS)
 // TODO(bugs.webrtc.org/12401): investigate why QualityScaler kicks in on iOS.
 TEST(QualityScalingExperimentTest, ParseSettingsUsesDefaultsWithoutFieldTrial) {
-  webrtc::test::ScopedFieldTrials field_trials("");
+  webrtc::test::ScopedKeyValueConfig field_trials("");
   // Uses some default hard coded values.
-  EXPECT_TRUE(QualityScalingExperiment::ParseSettings());
+  EXPECT_TRUE(QualityScalingExperiment::ParseSettings(field_trials));
 }
 #else
 TEST(QualityScalingExperimentTest, ParseSettingsFailsWithoutFieldTrial) {
-  webrtc::test::ScopedFieldTrials field_trials("");
-  EXPECT_FALSE(QualityScalingExperiment::ParseSettings());
+  webrtc::test::ScopedKeyValueConfig field_trials("");
+  EXPECT_FALSE(QualityScalingExperiment::ParseSettings(field_trials));
 }
 #endif
 
 TEST(QualityScalingExperimentTest, ParseSettingsFailsWithInvalidFieldTrial) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-invalid/");
-  EXPECT_FALSE(QualityScalingExperiment::ParseSettings());
+  EXPECT_FALSE(QualityScalingExperiment::ParseSettings(field_trials));
 }
 
 TEST(QualityScalingExperimentTest, GetConfig) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,7,8,0.9,0.99,0/");
-  const auto config = QualityScalingExperiment::GetConfig();
+  const auto config = QualityScalingExperiment::GetConfig(field_trials);
   EXPECT_EQ(0.9f, config.alpha_high);
   EXPECT_EQ(0.99f, config.alpha_low);
   EXPECT_FALSE(config.use_all_drop_reasons);
 }
 
 TEST(QualityScalingExperimentTest, GetsDefaultConfigForInvalidFieldTrial) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-invalid/");
-  const auto config = QualityScalingExperiment::GetConfig();
+  const auto config = QualityScalingExperiment::GetConfig(field_trials);
   ExpectEqualConfig(config, QualityScalingExperiment::Config());
 }
 
 TEST(QualityScalingExperimentTest, GetsDefaultAlphaForInvalidValue) {
   QualityScalingExperiment::Config expected_config;
   expected_config.use_all_drop_reasons = true;
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,7,8,0.99,0.9,1/");
-  const auto config = QualityScalingExperiment::GetConfig();
+  const auto config = QualityScalingExperiment::GetConfig(field_trials);
   ExpectEqualConfig(config, expected_config);
 }
 
 TEST(QualityScalingExperimentTest, GetVp8Thresholds) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/");
   const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8);
+      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8, field_trials);
   EXPECT_TRUE(thresholds);
   EXPECT_EQ(1, thresholds->low);
   EXPECT_EQ(2, thresholds->high);
 }
 
 TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidVp8Value) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-0,0,3,4,5,6,7,8,0.9,0.99,1/");
   const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8);
+      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP8, field_trials);
   EXPECT_FALSE(thresholds);
 }
 
 TEST(QualityScalingExperimentTest, GetVp9Thresholds) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/");
   const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9);
+      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9, field_trials);
   EXPECT_TRUE(thresholds);
   EXPECT_EQ(3, thresholds->low);
   EXPECT_EQ(4, thresholds->high);
 }
 
 TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidVp9Value) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,0,0,5,6,7,8,0.9,0.99,1/");
   const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9);
+      QualityScalingExperiment::GetQpThresholds(kVideoCodecVP9, field_trials);
   EXPECT_FALSE(thresholds);
 }
 
 TEST(QualityScalingExperimentTest, GetH264Thresholds) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/");
   const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecH264);
+      QualityScalingExperiment::GetQpThresholds(kVideoCodecH264, field_trials);
   EXPECT_TRUE(thresholds);
   EXPECT_EQ(5, thresholds->low);
   EXPECT_EQ(6, thresholds->high);
 }
 
 TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidH264Value) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,0,0,7,8,0.9,0.99,1/");
   const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecH264);
+      QualityScalingExperiment::GetQpThresholds(kVideoCodecH264, field_trials);
   EXPECT_FALSE(thresholds);
 }
 
 TEST(QualityScalingExperimentTest, GetGenericThresholds) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,0,0,7,8,0.9,0.99,1/");
-  const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecGeneric);
+  const auto thresholds = QualityScalingExperiment::GetQpThresholds(
+      kVideoCodecGeneric, field_trials);
   EXPECT_TRUE(thresholds);
   EXPECT_EQ(7, thresholds->low);
   EXPECT_EQ(8, thresholds->high);
 }
 
 TEST(QualityScalingExperimentTest, GetThresholdsFailsForInvalidGenericValue) {
-  webrtc::test::ScopedFieldTrials field_trials(
+  webrtc::test::ScopedKeyValueConfig field_trials(
       "WebRTC-Video-QualityScaling/Enabled-1,2,3,4,5,6,0,0,0.9,0.99,1/");
-  const auto thresholds =
-      QualityScalingExperiment::GetQpThresholds(kVideoCodecGeneric);
+  const auto thresholds = QualityScalingExperiment::GetQpThresholds(
+      kVideoCodecGeneric, field_trials);
   EXPECT_FALSE(thresholds);
 }
 }  // namespace webrtc
diff --git a/video/adaptation/quality_scaler_resource.cc b/video/adaptation/quality_scaler_resource.cc
index 68d56fe..a24a3e8 100644
--- a/video/adaptation/quality_scaler_resource.cc
+++ b/video/adaptation/quality_scaler_resource.cc
@@ -12,6 +12,7 @@
 
 #include <utility>
 
+#include "api/field_trials_view.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/experiments/balanced_degradation_settings.h"
 #include "rtc_base/time_utils.h"
@@ -37,11 +38,12 @@
 }
 
 void QualityScalerResource::StartCheckForOveruse(
-    VideoEncoder::QpThresholds qp_thresholds) {
+    VideoEncoder::QpThresholds qp_thresholds,
+    const FieldTrialsView& field_trials) {
   RTC_DCHECK_RUN_ON(encoder_queue());
   RTC_DCHECK(!is_started());
-  quality_scaler_ =
-      std::make_unique<QualityScaler>(this, std::move(qp_thresholds));
+  quality_scaler_ = std::make_unique<QualityScaler>(
+      this, std::move(qp_thresholds), field_trials);
 }
 
 void QualityScalerResource::StopCheckForOveruse() {
diff --git a/video/adaptation/quality_scaler_resource.h b/video/adaptation/quality_scaler_resource.h
index cbb6d3d..a1ed34a 100644
--- a/video/adaptation/quality_scaler_resource.h
+++ b/video/adaptation/quality_scaler_resource.h
@@ -16,6 +16,7 @@
 #include <string>
 
 #include "absl/types/optional.h"
+#include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/video/video_adaptation_reason.h"
 #include "api/video_codecs/video_encoder.h"
@@ -37,7 +38,8 @@
 
   bool is_started() const;
 
-  void StartCheckForOveruse(VideoEncoder::QpThresholds qp_thresholds);
+  void StartCheckForOveruse(VideoEncoder::QpThresholds qp_thresholds,
+                            const FieldTrialsView& field_trials);
   void StopCheckForOveruse();
   void SetQpThresholds(VideoEncoder::QpThresholds qp_thresholds);
   bool QpFastFilterLow();
diff --git a/video/adaptation/video_stream_encoder_resource_manager.cc b/video/adaptation/video_stream_encoder_resource_manager.cc
index 183aa41..eaeb0d5 100644
--- a/video/adaptation/video_stream_encoder_resource_manager.cc
+++ b/video/adaptation/video_stream_encoder_resource_manager.cc
@@ -21,6 +21,7 @@
 #include "absl/algorithm/container.h"
 #include "absl/base/macros.h"
 #include "api/adaptation/resource.h"
+#include "api/field_trials_view.h"
 #include "api/sequence_checker.h"
 #include "api/task_queue/task_queue_base.h"
 #include "api/video/video_adaptation_reason.h"
@@ -116,9 +117,10 @@
 class VideoStreamEncoderResourceManager::InitialFrameDropper {
  public:
   explicit InitialFrameDropper(
-      rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource)
+      rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource,
+      const FieldTrialsView& field_trials)
       : quality_scaler_resource_(quality_scaler_resource),
-        quality_scaler_settings_(QualityScalerSettings::ParseFromFieldTrials()),
+        quality_scaler_settings_(field_trials),
         has_seen_first_bwe_drop_(false),
         set_start_bitrate_(DataRate::Zero()),
         set_start_bitrate_time_ms_(0),
@@ -289,8 +291,10 @@
       clock_(clock),
       experiment_cpu_load_estimator_(experiment_cpu_load_estimator),
       initial_frame_dropper_(
-          std::make_unique<InitialFrameDropper>(quality_scaler_resource_)),
-      quality_scaling_experiment_enabled_(QualityScalingExperiment::Enabled()),
+          std::make_unique<InitialFrameDropper>(quality_scaler_resource_,
+                                                field_trials)),
+      quality_scaling_experiment_enabled_(
+          QualityScalingExperiment::Enabled(field_trials_)),
       pixel_limit_resource_experiment_enabled_(
           field_trials.IsEnabled(kPixelLimitResourceFieldTrialName)),
       encoder_target_bitrate_bps_(absl::nullopt),
@@ -561,7 +565,8 @@
     if (quality_scaler_resource_->is_started()) {
       quality_scaler_resource_->SetQpThresholds(qp_thresholds.value());
     } else {
-      quality_scaler_resource_->StartCheckForOveruse(qp_thresholds.value());
+      quality_scaler_resource_->StartCheckForOveruse(qp_thresholds.value(),
+                                                     field_trials_);
       AddResource(quality_scaler_resource_, VideoAdaptationReason::kQuality);
     }
   } else if (quality_scaler_resource_->is_started()) {
@@ -615,7 +620,7 @@
       absl::optional<VideoEncoder::QpThresholds> experimental_thresholds;
       if (quality_scaling_experiment_enabled_) {
         experimental_thresholds = QualityScalingExperiment::GetQpThresholds(
-            GetVideoCodecTypeOrGeneric(encoder_settings_));
+            GetVideoCodecTypeOrGeneric(encoder_settings_), field_trials_);
       }
       UpdateQualityScalerSettings(experimental_thresholds.has_value()
                                       ? experimental_thresholds
diff --git a/video/encoder_bitrate_adjuster.cc b/video/encoder_bitrate_adjuster.cc
index 30bfcd5..02468cb 100644
--- a/video/encoder_bitrate_adjuster.cc
+++ b/video/encoder_bitrate_adjuster.cc
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "api/field_trials_view.h"
 #include "rtc_base/experiments/rate_control_settings.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/time_utils.h"
@@ -43,9 +44,12 @@
 constexpr size_t EncoderBitrateAdjuster::kMinFramesSinceLayoutChange;
 constexpr double EncoderBitrateAdjuster::kDefaultUtilizationFactor;
 
-EncoderBitrateAdjuster::EncoderBitrateAdjuster(const VideoCodec& codec_settings)
-    : utilize_bandwidth_headroom_(RateControlSettings::ParseFromFieldTrials()
-                                      .BitrateAdjusterCanUseNetworkHeadroom()),
+EncoderBitrateAdjuster::EncoderBitrateAdjuster(
+    const VideoCodec& codec_settings,
+    const FieldTrialsView& field_trials)
+    : utilize_bandwidth_headroom_(
+          RateControlSettings::ParseFromKeyValueConfig(&field_trials)
+              .BitrateAdjusterCanUseNetworkHeadroom()),
       frames_since_layout_change_(0),
       min_bitrates_bps_{},
       frame_size_pixels_{},
diff --git a/video/encoder_bitrate_adjuster.h b/video/encoder_bitrate_adjuster.h
index 53f4b03..0ddd20b 100644
--- a/video/encoder_bitrate_adjuster.h
+++ b/video/encoder_bitrate_adjuster.h
@@ -13,6 +13,7 @@
 
 #include <memory>
 
+#include "api/field_trials_view.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_bitrate_allocation.h"
 #include "api/video_codecs/video_encoder.h"
@@ -34,7 +35,8 @@
   // build too much queue at the very start.
   static constexpr double kDefaultUtilizationFactor = 1.2;
 
-  explicit EncoderBitrateAdjuster(const VideoCodec& codec_settings);
+  EncoderBitrateAdjuster(const VideoCodec& codec_settings,
+                         const FieldTrialsView& field_trials);
   ~EncoderBitrateAdjuster();
 
   // Adjusts the given rate allocation to make it paceable within the target
diff --git a/video/encoder_bitrate_adjuster_unittest.cc b/video/encoder_bitrate_adjuster_unittest.cc
index ef6b564..e0f6de3 100644
--- a/video/encoder_bitrate_adjuster_unittest.cc
+++ b/video/encoder_bitrate_adjuster_unittest.cc
@@ -13,11 +13,12 @@
 #include <memory>
 #include <vector>
 
+#include "api/field_trials_view.h"
 #include "api/units/data_rate.h"
 #include "rtc_base/fake_clock.h"
 #include "rtc_base/numerics/safe_conversions.h"
-#include "test/field_trial.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 namespace webrtc {
 namespace test {
@@ -82,7 +83,8 @@
       }
     }
 
-    adjuster_ = std::make_unique<EncoderBitrateAdjuster>(codec_);
+    adjuster_ =
+        std::make_unique<EncoderBitrateAdjuster>(codec_, scoped_field_trial_);
     adjuster_->OnEncoderInfo(encoder_info_);
     current_adjusted_allocation_ =
         adjuster_->AdjustRateAllocation(VideoEncoder::RateControlParameters(
@@ -234,6 +236,7 @@
   double target_framerate_fps_;
   int tl_pattern_idx_[kMaxSpatialLayers];
   int sequence_idx_[kMaxSpatialLayers][kMaxTemporalStreams];
+  test::ScopedKeyValueConfig scoped_field_trial_;
 
   const std::vector<int> kTlPatterns[kMaxTemporalStreams] = {
       {0},
@@ -422,7 +425,8 @@
 TEST_F(EncoderBitrateAdjusterTest, HeadroomAllowsOvershootToMediaRate) {
   // Two streams, both with three temporal layers.
   // Media rate is 1.0, but network rate is higher.
-  ScopedFieldTrials field_trial(
+  test::ScopedKeyValueConfig field_trial(
+      scoped_field_trial_,
       "WebRTC-VideoRateControl/adjuster_use_headroom:true/");
 
   const uint32_t kS0Bitrate = 300000;
@@ -464,7 +468,8 @@
 TEST_F(EncoderBitrateAdjusterTest, DontExceedMediaRateEvenWithHeadroom) {
   // Two streams, both with three temporal layers.
   // Media rate is 1.1, but network rate is higher.
-  ScopedFieldTrials field_trial(
+  test::ScopedKeyValueConfig field_trial(
+      scoped_field_trial_,
       "WebRTC-VideoRateControl/adjuster_use_headroom:true/");
 
   const uint32_t kS0Bitrate = 300000;
diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc
index d0a96ce..ee023d9 100644
--- a/video/video_send_stream_impl.cc
+++ b/video/video_send_stream_impl.cc
@@ -165,7 +165,8 @@
 absl::optional<float> GetConfiguredPacingFactor(
     const VideoSendStream::Config& config,
     VideoEncoderConfig::ContentType content_type,
-    const PacingConfig& default_pacing_config) {
+    const PacingConfig& default_pacing_config,
+    const FieldTrialsView& field_trials) {
   if (!TransportSeqNumExtensionConfigured(config))
     return absl::nullopt;
 
@@ -175,7 +176,7 @@
     return alr_settings->pacing_factor;
 
   RateControlSettings rate_control_settings =
-      RateControlSettings::ParseFromFieldTrials();
+      RateControlSettings::ParseFromKeyValueConfig(&field_trials);
   return rate_control_settings.GetPacingFactor().value_or(
       default_pacing_config.pacing_factor);
 }
@@ -246,8 +247,10 @@
       encoder_bitrate_priority_(initial_encoder_bitrate_priority),
       video_stream_encoder_(video_stream_encoder),
       rtp_video_sender_(rtp_video_sender),
-      configured_pacing_factor_(
-          GetConfiguredPacingFactor(*config_, content_type, pacing_config_)) {
+      configured_pacing_factor_(GetConfiguredPacingFactor(*config_,
+                                                          content_type,
+                                                          pacing_config_,
+                                                          field_trials)) {
   RTC_DCHECK_GE(config_->rtp.payload_type, 0);
   RTC_DCHECK_LE(config_->rtp.payload_type, 127);
   RTC_DCHECK(!config_->rtp.ssrcs.empty());
@@ -281,7 +284,7 @@
       queue_time_limit_ms = alr_settings->max_paced_queue_time;
     } else {
       RateControlSettings rate_control_settings =
-          RateControlSettings::ParseFromFieldTrials();
+          RateControlSettings::ParseFromKeyValueConfig(&field_trials);
       enable_alr_bw_probing = rate_control_settings.UseAlrProbing();
       queue_time_limit_ms = pacing_config_.max_pacing_delay.Get().ms();
     }
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 84f6108..2e5a120 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -650,7 +650,8 @@
       sink_(nullptr),
       settings_(settings),
       allocation_cb_type_(allocation_cb_type),
-      rate_control_settings_(RateControlSettings::ParseFromFieldTrials()),
+      rate_control_settings_(
+          RateControlSettings::ParseFromKeyValueConfig(&field_trials)),
       encoder_selector_from_constructor_(encoder_selector),
       encoder_selector_from_factory_(
           encoder_selector_from_constructor_
@@ -1368,7 +1369,8 @@
 
   const VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
   if (rate_control_settings_.UseEncoderBitrateAdjuster()) {
-    bitrate_adjuster_ = std::make_unique<EncoderBitrateAdjuster>(codec);
+    bitrate_adjuster_ =
+        std::make_unique<EncoderBitrateAdjuster>(codec, field_trials_);
     bitrate_adjuster_->OnEncoderInfo(info);
   }