Add factory functions to pass Environment to VideoEncoders

Bug: webrtc:15860
Change-Id: I4a9d2678dcfe5b0f178863242e27600fcc95325d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/342480
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41879}
diff --git a/modules/video_coding/codecs/av1/BUILD.gn b/modules/video_coding/codecs/av1/BUILD.gn
index 6465306..8999b32 100644
--- a/modules/video_coding/codecs/av1/BUILD.gn
+++ b/modules/video_coding/codecs/av1/BUILD.gn
@@ -56,6 +56,7 @@
     "../..:video_codec_interface",
     "../../../../api:field_trials_view",
     "../../../../api:scoped_refptr",
+    "../../../../api/environment",
     "../../../../api/transport:field_trial_based_config",
     "../../../../api/video:encoded_image",
     "../../../../api/video:video_frame",
@@ -73,6 +74,7 @@
   absl_deps = [
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/base:nullability",
     "//third_party/abseil-cpp/absl/strings:strings",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
@@ -102,10 +104,12 @@
         "../../../../api:create_frame_generator",
         "../../../../api:frame_generator_api",
         "../../../../api:mock_video_encoder",
+        "../../../../api/environment",
+        "../../../../api/environment:environment_factory",
         "../../../../api/units:data_size",
         "../../../../api/units:time_delta",
         "../../../../api/video:video_frame",
-        "../../../../test:field_trial",
+        "../../../../test:scoped_key_value_config",
         "../../svc:scalability_mode_util",
         "../../svc:scalability_structures",
         "../../svc:scalable_video_controller",
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
index 745471e..4e2d9bd 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
@@ -18,8 +18,10 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/base/macros.h"
+#include "absl/base/nullability.h"
 #include "absl/strings/match.h"
 #include "absl/types/optional.h"
+#include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/scoped_refptr.h"
 #include "api/transport/field_trial_based_config.h"
@@ -872,6 +874,17 @@
 
 }  // namespace
 
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateLibaomAv1Encoder(
+    const Environment& env,
+    LibaomAv1EncoderSettings settings) {
+  if (settings.max_pixel_count_to_cpu_speed.empty()) {
+    return std::make_unique<LibaomAv1Encoder>(absl::nullopt,
+                                              env.field_trials());
+  } else {
+    return std::make_unique<LibaomAv1Encoder>(settings, env.field_trials());
+  }
+}
+
 std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder() {
   return std::make_unique<LibaomAv1Encoder>(absl::nullopt,
                                             FieldTrialBasedConfig());
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.h b/modules/video_coding/codecs/av1/libaom_av1_encoder.h
index 2fd1d5a..cc804aa 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder.h
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.h
@@ -13,15 +13,22 @@
 #include <map>
 #include <memory>
 
-#include "absl/strings/string_view.h"
+#include "absl/base/nullability.h"
+#include "api/environment/environment.h"
 #include "api/video_codecs/video_encoder.h"
 
 namespace webrtc {
-struct LibaomAv1EncoderAuxConfig {
+
+struct LibaomAv1EncoderSettings {
   // A map of max pixel count --> cpu speed.
   std::map<int, int> max_pixel_count_to_cpu_speed;
 };
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateLibaomAv1Encoder(
+    const Environment& env,
+    LibaomAv1EncoderSettings settings = {});
 
+// Deprecated, Use CreateLibaomAv1Encoder above, bugs.webrtc.org/15860
+using LibaomAv1EncoderAuxConfig = LibaomAv1EncoderSettings;
 std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder();
 std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder(
     const LibaomAv1EncoderAuxConfig& aux_config);
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
index 127aadb..5b022592 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
@@ -12,22 +12,26 @@
 
 #include <limits>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/environment/environment.h"
+#include "api/environment/environment_factory.h"
 #include "api/test/create_frame_generator.h"
 #include "api/test/frame_generator_interface.h"
 #include "api/video_codecs/video_codec.h"
 #include "api/video_codecs/video_encoder.h"
 #include "modules/video_coding/codecs/test/encoded_video_frame_producer.h"
 #include "modules/video_coding/include/video_error_codes.h"
-#include "test/field_trial.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
 
 namespace webrtc {
 namespace {
 
+using test::ScopedKeyValueConfig;
 using ::testing::ElementsAre;
 using ::testing::Eq;
 using ::testing::Field;
@@ -52,12 +56,14 @@
 }
 
 TEST(LibaomAv1EncoderTest, CanCreate) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   EXPECT_TRUE(encoder);
 }
 
 TEST(LibaomAv1EncoderTest, InitAndRelease) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   ASSERT_TRUE(encoder);
   VideoCodec codec_settings = DefaultCodecSettings();
   EXPECT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
@@ -67,7 +73,8 @@
 
 TEST(LibaomAv1EncoderTest, NoBitrateOnTopLayerRefecltedInActiveDecodeTargets) {
   // Configure encoder with 2 temporal layers.
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL1T2);
   ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
@@ -93,7 +100,8 @@
 
 TEST(LibaomAv1EncoderTest,
      SpatialScalabilityInTemporalUnitReportedAsDeltaFrame) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
   ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
@@ -115,7 +123,8 @@
 }
 
 TEST(LibaomAv1EncoderTest, NoBitrateOnTopSpatialLayerProduceDeltaFrames) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
   ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
@@ -142,7 +151,8 @@
   allocation.SetBitrate(1, 0, 40000);
   allocation.SetBitrate(2, 0, 30000);
 
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   // Configure encoder with 3 spatial layers.
   codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
@@ -169,7 +179,8 @@
   allocation.SetBitrate(0, 0, 30000);
   allocation.SetBitrate(1, 0, 40000);
   allocation.SetBitrate(2, 0, 30000);
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   // Configure encoder with 3 spatial layers.
   codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
@@ -189,11 +200,12 @@
 }
 
 TEST(LibaomAv1EncoderTest, WithMaximumConsecutiveFrameDrop) {
-  test::ScopedFieldTrials field_trials(
+  auto field_trials = std::make_unique<ScopedKeyValueConfig>(
       "WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop/maxdrop:2/");
+  const Environment env = CreateEnvironment(std::move(field_trials));
   VideoBitrateAllocation allocation;
   allocation.SetBitrate(0, 0, 1000);  // some very low bitrate
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder(env);
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetFrameDropEnabled(true);
   codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
@@ -214,18 +226,20 @@
 }
 
 TEST(LibaomAv1EncoderTest, EncoderInfoWithoutResolutionBitrateLimits) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   EXPECT_TRUE(encoder->GetEncoderInfo().resolution_bitrate_limits.empty());
 }
 
 TEST(LibaomAv1EncoderTest, EncoderInfoWithBitrateLimitsFromFieldTrial) {
-  test::ScopedFieldTrials field_trials(
+  auto field_trials = std::make_unique<ScopedKeyValueConfig>(
       "WebRTC-Av1-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/");
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  const Environment env = CreateEnvironment(std::move(field_trials));
+  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder(env);
 
   EXPECT_THAT(
       encoder->GetEncoderInfo().resolution_bitrate_limits,
@@ -236,7 +250,8 @@
 }
 
 TEST(LibaomAv1EncoderTest, EncoderInfoProvidesFpsAllocation) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL3T3);
   codec_settings.maxFramerate = 60;
@@ -258,7 +273,8 @@
   allocation.SetBitrate(0, 0, 30000);
   allocation.SetBitrate(1, 0, 40000);
   allocation.SetBitrate(2, 0, 30000);
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.startBitrate = allocation.get_sum_kbps();
   ASSERT_GT(codec_settings.width, 4);
@@ -291,7 +307,8 @@
 }
 
 TEST(LibaomAv1EncoderTest, RtpTimestampWrap) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
   ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
@@ -315,7 +332,8 @@
 }
 
 TEST(LibaomAv1EncoderTest, TestCaptureTimeId) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   const Timestamp capture_time_id = Timestamp::Micros(2000);
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
@@ -347,7 +365,8 @@
 }
 
 TEST(LibaomAv1EncoderTest, AdheresToTargetBitrateDespiteUnevenFrameTiming) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
   codec_settings.startBitrate = 300;  // kbps
@@ -425,7 +444,8 @@
 }
 
 TEST(LibaomAv1EncoderTest, DisableAutomaticResize) {
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   ASSERT_TRUE(encoder);
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.AV1()->automatic_resize_on = false;
diff --git a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
index 6a135e2..763e399 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
@@ -18,6 +18,8 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/environment/environment.h"
+#include "api/environment/environment_factory.h"
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
 #include "api/video_codecs/video_codec.h"
@@ -134,8 +136,9 @@
 };
 
 TEST(LibaomAv1Test, EncodeDecode) {
+  const Environment env = CreateEnvironment();
   TestAv1Decoder decoder(0);
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder(env);
   VideoCodec codec_settings = DefaultCodecSettings();
   ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
             WEBRTC_VIDEO_CODEC_OK);
@@ -216,7 +219,8 @@
   size_t num_decode_targets =
       svc_controller->DependencyStructure().num_decode_targets;
 
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(GetParam().GetScalabilityMode());
   ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
@@ -287,7 +291,8 @@
                           kv.second.bps());
   }
 
-  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  std::unique_ptr<VideoEncoder> encoder =
+      CreateLibaomAv1Encoder(CreateEnvironment());
   ASSERT_TRUE(encoder);
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.SetScalabilityMode(param.GetScalabilityMode());
diff --git a/modules/video_coding/codecs/h264/h264.cc b/modules/video_coding/codecs/h264/h264.cc
index 5b9f033..0c6c434 100644
--- a/modules/video_coding/codecs/h264/h264.cc
+++ b/modules/video_coding/codecs/h264/h264.cc
@@ -121,6 +121,18 @@
   return supportedCodecs;
 }
 
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateH264Encoder(
+    const Environment& env,
+    H264EncoderSettings settings) {
+#if defined(WEBRTC_USE_H264)
+  RTC_CHECK(g_rtc_use_h264);
+  RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
+  return std::make_unique<H264EncoderImpl>(env, settings);
+#else
+  RTC_CHECK_NOTREACHED();
+#endif
+}
+
 std::unique_ptr<H264Encoder> H264Encoder::Create() {
   return Create(cricket::CreateVideoCodec(cricket::kH264CodecName));
 }
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
index ee69b9b..71e80aa 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
@@ -170,20 +170,31 @@
   }
 }
 
+H264EncoderImpl::H264EncoderImpl(const Environment& env,
+                                 H264EncoderSettings settings)
+    : H264EncoderImpl(settings.packetization_mode) {}
+
 H264EncoderImpl::H264EncoderImpl(const cricket::VideoCodec& codec)
-    : packetization_mode_(H264PacketizationMode::SingleNalUnit),
+    : H264EncoderImpl([&] {
+        std::string packetization_mode_string;
+        if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
+                           &packetization_mode_string) &&
+            packetization_mode_string == "1") {
+          return H264PacketizationMode::NonInterleaved;
+        } else {
+          return H264PacketizationMode::SingleNalUnit;
+        }
+      }()) {
+  RTC_CHECK(absl::EqualsIgnoreCase(codec.name, cricket::kH264CodecName));
+}
+
+H264EncoderImpl::H264EncoderImpl(H264PacketizationMode packetization_mode)
+    : packetization_mode_(packetization_mode),
       max_payload_size_(0),
       number_of_cores_(0),
       encoded_image_callback_(nullptr),
       has_reported_init_(false),
       has_reported_error_(false) {
-  RTC_CHECK(absl::EqualsIgnoreCase(codec.name, cricket::kH264CodecName));
-  std::string packetization_mode_string;
-  if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
-                     &packetization_mode_string) &&
-      packetization_mode_string == "1") {
-    packetization_mode_ = H264PacketizationMode::NonInterleaved;
-  }
   downscaled_buffers_.reserve(kMaxSimulcastStreams - 1);
   encoded_images_.reserve(kMaxSimulcastStreams);
   encoders_.reserve(kMaxSimulcastStreams);
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.h b/modules/video_coding/codecs/h264/h264_encoder_impl.h
index 19c16f3..e89f9f9 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.h
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.h
@@ -58,7 +58,9 @@
     void SetStreamState(bool send_stream);
   };
 
- public:
+  H264EncoderImpl(const Environment& env, H264EncoderSettings settings);
+
+  // Deprecated, bugs.webrtc.org/15860
   explicit H264EncoderImpl(const cricket::VideoCodec& codec);
   ~H264EncoderImpl() override;
 
@@ -90,6 +92,8 @@
   }
 
  private:
+  explicit H264EncoderImpl(H264PacketizationMode packetization_mode);
+
   SEncParamExt CreateEncoderParams(size_t i) const;
 
   webrtc::H264BitstreamParser h264_bitstream_parser_;
diff --git a/modules/video_coding/codecs/h264/include/h264.h b/modules/video_coding/codecs/h264/include/h264.h
index 025a6ba..2dab731 100644
--- a/modules/video_coding/codecs/h264/include/h264.h
+++ b/modules/video_coding/codecs/h264/include/h264.h
@@ -16,8 +16,11 @@
 #include <string>
 #include <vector>
 
+#include "absl/base/nullability.h"
+#include "api/environment/environment.h"
 #include "api/video_codecs/h264_profile_level_id.h"
 #include "api/video_codecs/scalability_mode.h"
+#include "api/video_codecs/video_encoder.h"
 #include "media/base/codec.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "rtc_base/system/rtc_export.h"
@@ -60,6 +63,14 @@
   ~H264Encoder() override {}
 };
 
+struct H264EncoderSettings {
+  H264PacketizationMode packetization_mode =
+      H264PacketizationMode::NonInterleaved;
+};
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateH264Encoder(
+    const Environment& env,
+    H264EncoderSettings settings = {});
+
 class RTC_EXPORT H264Decoder : public VideoDecoder {
  public:
   static std::unique_ptr<H264Decoder> Create();
diff --git a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
index b8a9add..9bc72b2 100644
--- a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
+++ b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
@@ -34,7 +34,7 @@
 class TestH264Impl : public VideoCodecUnitTest {
  protected:
   std::unique_ptr<VideoEncoder> CreateEncoder() override {
-    return H264Encoder::Create();
+    return CreateH264Encoder(env_);
   }
 
   std::unique_ptr<VideoDecoder> CreateDecoder() override {
diff --git a/modules/video_coding/codecs/test/video_codec_unittest.h b/modules/video_coding/codecs/test/video_codec_unittest.h
index 7d05882..6ad46ba 100644
--- a/modules/video_coding/codecs/test/video_codec_unittest.h
+++ b/modules/video_coding/codecs/test/video_codec_unittest.h
@@ -14,6 +14,8 @@
 #include <memory>
 #include <vector>
 
+#include "api/environment/environment.h"
+#include "api/environment/environment_factory.h"
 #include "api/test/frame_generator_interface.h"
 #include "api/video_codecs/video_decoder.h"
 #include "api/video_codecs/video_encoder.h"
@@ -30,7 +32,8 @@
 class VideoCodecUnitTest : public ::testing::Test {
  public:
   VideoCodecUnitTest()
-      : encode_complete_callback_(this),
+      : env_(CreateEnvironment()),
+        encode_complete_callback_(this),
         decode_complete_callback_(this),
         wait_for_encoded_frames_threshold_(1),
         last_input_frame_timestamp_(0) {}
@@ -96,6 +99,7 @@
 
   size_t GetNumEncodedFrames();
 
+  const Environment env_;
   VideoCodec codec_settings_;
 
   std::unique_ptr<VideoEncoder> encoder_;
diff --git a/modules/video_coding/codecs/vp8/include/vp8.h b/modules/video_coding/codecs/vp8/include/vp8.h
index cb49516..625e5ac 100644
--- a/modules/video_coding/codecs/vp8/include/vp8.h
+++ b/modules/video_coding/codecs/vp8/include/vp8.h
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "absl/base/nullability.h"
 #include "api/environment/environment.h"
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/vp8_frame_buffer_controller.h"
@@ -21,21 +22,25 @@
 
 namespace webrtc {
 
-// TODO(brandtr): Move these interfaces to the api/ folder.
+struct Vp8EncoderSettings {
+  // Allows for overriding the Vp8FrameBufferController used by the encoder.
+  // If unset, a default Vp8FrameBufferController will be instantiated
+  // internally.
+  absl::Nullable<std::unique_ptr<Vp8FrameBufferControllerFactory>>
+      frame_buffer_controller_factory;
+
+  // Allows for overriding the resolution/bitrate limits exposed through
+  // VideoEncoder::GetEncoderInfo(). No override is done if empty.
+  std::vector<VideoEncoder::ResolutionBitrateLimits> resolution_bitrate_limits;
+};
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateVp8Encoder(
+    const Environment& env,
+    Vp8EncoderSettings settings = {});
+
+// Deprecated, use CreateVp8Encoder above, bugs.webrtc.org/15860
 class VP8Encoder {
  public:
-  struct Settings {
-    // Allows for overriding the Vp8FrameBufferController used by the encoder.
-    // If unset, a default Vp8FrameBufferController will be instantiated
-    // internally.
-    std::unique_ptr<Vp8FrameBufferControllerFactory>
-        frame_buffer_controller_factory = nullptr;
-
-    // Allows for overriding the resolution/bitrate limits exposed through
-    // VideoEncoder::GetEncoderInfo(). No override is done if empty.
-    std::vector<VideoEncoder::ResolutionBitrateLimits>
-        resolution_bitrate_limits = {};
-  };
+  using Settings = Vp8EncoderSettings;
 
   static std::unique_ptr<VideoEncoder> Create();
   static std::unique_ptr<VideoEncoder> Create(Settings settings);
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index a9e3661..3368b07 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -264,6 +264,12 @@
 
 }  // namespace
 
+std::unique_ptr<VideoEncoder> CreateVp8Encoder(const Environment& env,
+                                               Vp8EncoderSettings settings) {
+  return std::make_unique<LibvpxVp8Encoder>(env, std::move(settings),
+                                            LibvpxInterface::Create());
+}
+
 std::unique_ptr<VideoEncoder> VP8Encoder::Create() {
   return std::make_unique<LibvpxVp8Encoder>(LibvpxInterface::Create(),
                                             VP8Encoder::Settings());
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
index 5850aa4..3d9dca7 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
@@ -13,6 +13,7 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "api/fec_controller_override.h"
@@ -38,6 +39,14 @@
 
 class LibvpxVp8Encoder : public VideoEncoder {
  public:
+  LibvpxVp8Encoder(const Environment& env,
+                   Vp8EncoderSettings settings,
+                   std::unique_ptr<LibvpxInterface> interface)
+      // TODO: bugs.webrtc.org/15860 - Save `env` and use field trials from it
+      // when constructor below can be removed.
+      : LibvpxVp8Encoder(std::move(interface), std::move(settings)) {}
+
+  // Deprecated, bugs.webrtc.org/15860
   LibvpxVp8Encoder(std::unique_ptr<LibvpxInterface> interface,
                    VP8Encoder::Settings settings);
   ~LibvpxVp8Encoder() override;
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index 514d3d7..6ecba2a 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -67,11 +67,11 @@
 class TestVp8Impl : public VideoCodecUnitTest {
  protected:
   std::unique_ptr<VideoEncoder> CreateEncoder() override {
-    return VP8Encoder::Create();
+    return CreateVp8Encoder(env_);
   }
 
   std::unique_ptr<VideoDecoder> CreateDecoder() override {
-    return CreateVp8Decoder(CreateEnvironment());
+    return CreateVp8Decoder(env_);
   }
 
   void ModifyCodecSettings(VideoCodec* codec_settings) override {
diff --git a/modules/video_coding/codecs/vp9/include/vp9.h b/modules/video_coding/codecs/vp9/include/vp9.h
index 79d403d..ab080c0 100644
--- a/modules/video_coding/codecs/vp9/include/vp9.h
+++ b/modules/video_coding/codecs/vp9/include/vp9.h
@@ -15,8 +15,12 @@
 #include <memory>
 #include <vector>
 
+#include "absl/base/nullability.h"
+#include "api/environment/environment.h"
 #include "api/video_codecs/scalability_mode.h"
 #include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/vp9_profile.h"
 #include "media/base/codec.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 
@@ -31,13 +35,19 @@
 // preference. These will be availble for receive-only connections.
 std::vector<SdpVideoFormat> SupportedVP9DecoderCodecs();
 
+struct Vp9EncoderSettings {
+  VP9Profile profile = VP9Profile::kProfile0;
+};
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateVp9Encoder(
+    const Environment& env,
+    Vp9EncoderSettings settings = {});
+
 class VP9Encoder : public VideoEncoder {
  public:
-  // Deprecated. Returns default implementation using VP9 Profile 0.
-  // TODO(emircan): Remove once this is no longer used.
+  // Deprecated. Use CreateVp9Encoder above, bugs.webrtc.org/15860
   static std::unique_ptr<VP9Encoder> Create();
-  // Parses VP9 Profile from `codec` and returns the appropriate implementation.
   static std::unique_ptr<VP9Encoder> Create(const cricket::VideoCodec& codec);
+
   static bool SupportsScalabilityMode(ScalabilityMode scalability_mode);
 
   ~VP9Encoder() override {}
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
index 20c29ab..56267be 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
@@ -223,14 +223,28 @@
   enc->GetEncodedLayerFrame(pkt);
 }
 
+LibvpxVp9Encoder::LibvpxVp9Encoder(const Environment& env,
+                                   Vp9EncoderSettings settings,
+                                   std::unique_ptr<LibvpxInterface> interface)
+    : LibvpxVp9Encoder(std::move(interface),
+                       settings.profile,
+                       env.field_trials()) {}
+
 LibvpxVp9Encoder::LibvpxVp9Encoder(const cricket::VideoCodec& codec,
                                    std::unique_ptr<LibvpxInterface> interface,
                                    const FieldTrialsView& trials)
+    : LibvpxVp9Encoder(
+          std::move(interface),
+          ParseSdpForVP9Profile(codec.params).value_or(VP9Profile::kProfile0),
+          trials) {}
+
+LibvpxVp9Encoder::LibvpxVp9Encoder(std::unique_ptr<LibvpxInterface> interface,
+                                   VP9Profile profile,
+                                   const FieldTrialsView& trials)
     : libvpx_(std::move(interface)),
       encoded_image_(),
       encoded_complete_callback_(nullptr),
-      profile_(
-          ParseSdpForVP9Profile(codec.params).value_or(VP9Profile::kProfile0)),
+      profile_(profile),
       inited_(false),
       timestamp_(0),
       rc_max_intra_target_(0),
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
index 3ccaa5f..349ab0e2 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
@@ -37,6 +37,11 @@
 
 class LibvpxVp9Encoder : public VP9Encoder {
  public:
+  LibvpxVp9Encoder(const Environment& env,
+                   Vp9EncoderSettings settings,
+                   std::unique_ptr<LibvpxInterface> interface);
+
+  // Deprecated, bugs.webrtc.org/15860
   LibvpxVp9Encoder(const cricket::VideoCodec& codec,
                    std::unique_ptr<LibvpxInterface> interface,
                    const FieldTrialsView& trials);
@@ -61,6 +66,10 @@
   EncoderInfo GetEncoderInfo() const override;
 
  private:
+  LibvpxVp9Encoder(std::unique_ptr<LibvpxInterface> interface,
+                   VP9Profile profile,
+                   const FieldTrialsView& trials);
+
   // Determine number of encoder threads to use.
   int NumberOfThreads(int width, int height, int number_of_cores);
 
diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index 50e9cf2..396e64d 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -102,7 +102,7 @@
 class TestVp9Impl : public VideoCodecUnitTest {
  protected:
   std::unique_ptr<VideoEncoder> CreateEncoder() override {
-    return VP9Encoder::Create();
+    return CreateVp9Encoder(env_);
   }
 
   std::unique_ptr<VideoDecoder> CreateDecoder() override {
@@ -255,7 +255,7 @@
 }
 
 TEST(Vp9ImplTest, ParserQpEqualsEncodedQp) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   encoder->InitEncode(&codec_settings, kSettings);
 
@@ -272,7 +272,7 @@
 }
 
 TEST(Vp9ImplTest, EncodeAttachesTemplateStructureWithSvcController) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
             WEBRTC_VIDEO_CODEC_OK);
@@ -292,7 +292,7 @@
 }
 
 TEST(Vp9ImplTest, EncoderWith2TemporalLayers) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.VP9()->numberOfTemporalLayers = 2;
   // Tl0PidIdx is only used in non-flexible mode.
@@ -314,7 +314,7 @@
 }
 
 TEST(Vp9ImplTest, EncodeTemporalLayersWithSvcController) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.VP9()->numberOfTemporalLayers = 2;
   EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
@@ -343,7 +343,7 @@
 }
 
 TEST(Vp9ImplTest, EncoderWith2SpatialLayers) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.VP9()->numberOfSpatialLayers = 2;
   EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
@@ -361,7 +361,7 @@
 }
 
 TEST(Vp9ImplTest, EncodeSpatialLayersWithSvcController) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.VP9()->numberOfSpatialLayers = 2;
   EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
@@ -503,7 +503,7 @@
   // Note: bit rate allocation is high to avoid frame dropping due to rate
   // control, the encoder should always produce a frame. A dropped
   // frame indicates a problem and the test will fail.
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   ConfigureSvc(codec_settings, num_spatial_layers);
   codec_settings.SetFrameDropEnabled(true);
@@ -570,7 +570,7 @@
 }
 
 TEST(Vp9ImplTest, SpatialUpswitchNotAtGOFBoundary) {
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   ConfigureSvc(codec_settings, /*num_spatial_layers=*/3,
                /*num_temporal_layers=*/3);
@@ -774,7 +774,7 @@
   // Must not be multiple of temporal period to exercise all code paths.
   const size_t num_frames_to_encode = 5;
 
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   ConfigureSvc(codec_settings, num_spatial_layers, num_temporal_layers);
   codec_settings.SetFrameDropEnabled(false);
@@ -1851,7 +1851,7 @@
   // encoder and writes it into RTP payload descriptor. Check that reference
   // list in payload descriptor matches the predefined one, which is used
   // in non-flexible mode.
-  std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
+  std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
   VideoCodec codec_settings = DefaultCodecSettings();
   codec_settings.VP9()->flexibleMode = true;
   codec_settings.SetFrameDropEnabled(false);
@@ -2040,11 +2040,7 @@
   }
 
   std::unique_ptr<VideoEncoder> CreateEncoder() override {
-    cricket::VideoCodec profile2_codec =
-        cricket::CreateVideoCodec(cricket::kVp9CodecName);
-    profile2_codec.SetParam(kVP9FmtpProfileId,
-                            VP9ProfileToString(VP9Profile::kProfile2));
-    return VP9Encoder::Create(profile2_codec);
+    return CreateVp9Encoder(env_, {.profile = VP9Profile::kProfile2});
   }
 
   std::unique_ptr<VideoDecoder> CreateDecoder() override {
diff --git a/modules/video_coding/codecs/vp9/vp9.cc b/modules/video_coding/codecs/vp9/vp9.cc
index c1dbf3a..8799f2c 100644
--- a/modules/video_coding/codecs/vp9/vp9.cc
+++ b/modules/video_coding/codecs/vp9/vp9.cc
@@ -81,6 +81,17 @@
 #endif
 }
 
+absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateVp9Encoder(
+    const Environment& env,
+    Vp9EncoderSettings settings) {
+#ifdef RTC_ENABLE_VP9
+  return std::make_unique<LibvpxVp9Encoder>(env, settings,
+                                            LibvpxInterface::Create());
+#else
+  RTC_CHECK_NOTREACHED();
+#endif
+}
+
 std::unique_ptr<VP9Encoder> VP9Encoder::Create() {
 #ifdef RTC_ENABLE_VP9
   return std::make_unique<LibvpxVp9Encoder>(