Replace VideoEncoderFactory::QueryVideoEncoder with VideoEncoder::GetEncoderInfo

Make implementation of VideoEncoderFactory::QueryVideoEncoder optional
until it is removed downstream and remove all implementations of it.

Bug: webrtc:10065
Change-Id: Ibb1f9612234e536651ce53f05ee048a5d172a41f
Reviewed-on: https://webrtc-review.googlesource.com/c/113065
Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25924}
diff --git a/api/test/mock_video_encoder_factory.h b/api/test/mock_video_encoder_factory.h
index a694b63..845251b 100644
--- a/api/test/mock_video_encoder_factory.h
+++ b/api/test/mock_video_encoder_factory.h
@@ -24,8 +24,6 @@
  public:
   MOCK_CONST_METHOD0(GetSupportedFormats,
                      std::vector<webrtc::SdpVideoFormat>());
-  MOCK_CONST_METHOD1(QueryVideoEncoder,
-                     CodecInfo(const webrtc::SdpVideoFormat&));
 
   // We need to proxy to a return type that is copyable.
   std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
diff --git a/api/test/video/function_video_encoder_factory.h b/api/test/video/function_video_encoder_factory.h
index 85f848c..514bd48 100644
--- a/api/test/video/function_video_encoder_factory.h
+++ b/api/test/video/function_video_encoder_factory.h
@@ -41,14 +41,6 @@
     return {};
   }
 
-  CodecInfo QueryVideoEncoder(
-      const SdpVideoFormat& /* format */) const override {
-    CodecInfo codec_info;
-    codec_info.is_hardware_accelerated = false;
-    codec_info.has_internal_source = false;
-    return codec_info;
-  }
-
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override {
     return create_(format);
diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn
index 534a34e..0fd0b99 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -27,6 +27,7 @@
     "video_encoder.h",
     "video_encoder_config.cc",
     "video_encoder_config.h",
+    "video_encoder_factory.cc",
     "video_encoder_factory.h",
     "vp8_temporal_layers.h",
   ]
diff --git a/api/video_codecs/builtin_video_encoder_factory.cc b/api/video_codecs/builtin_video_encoder_factory.cc
index 1778c21..e687871 100644
--- a/api/video_codecs/builtin_video_encoder_factory.cc
+++ b/api/video_codecs/builtin_video_encoder_factory.cc
@@ -44,17 +44,6 @@
   BuiltinVideoEncoderFactory()
       : internal_encoder_factory_(new InternalEncoderFactory()) {}
 
-  VideoEncoderFactory::CodecInfo QueryVideoEncoder(
-      const SdpVideoFormat& format) const override {
-    // Format must be one of the internal formats.
-    RTC_DCHECK(IsFormatSupported(
-        internal_encoder_factory_->GetSupportedFormats(), format));
-    VideoEncoderFactory::CodecInfo info;
-    info.has_internal_source = false;
-    info.is_hardware_accelerated = false;
-    return info;
-  }
-
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override {
     // Try creating internal encoder.
diff --git a/api/video_codecs/video_encoder_factory.cc b/api/video_codecs/video_encoder_factory.cc
new file mode 100644
index 0000000..de71aa6
--- /dev/null
+++ b/api/video_codecs/video_encoder_factory.cc
@@ -0,0 +1,26 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_encoder_factory.h"
+
+// TODO(webrtc:10065) Remove once downstream projects have been updated.
+namespace webrtc {
+
+VideoEncoderFactory::CodecInfo::CodecInfo()
+    : is_hardware_accelerated(false), has_internal_source(false) {}
+
+VideoEncoderFactory::CodecInfo::~CodecInfo() = default;
+
+VideoEncoderFactory::CodecInfo VideoEncoderFactory::QueryVideoEncoder(
+    const SdpVideoFormat& format) const {
+  return CodecInfo();
+}
+
+}  // namespace webrtc
diff --git a/api/video_codecs/video_encoder_factory.h b/api/video_codecs/video_encoder_factory.h
index 7958d16..7b2b156 100644
--- a/api/video_codecs/video_encoder_factory.h
+++ b/api/video_codecs/video_encoder_factory.h
@@ -25,6 +25,9 @@
  public:
   // TODO(magjed): Try to get rid of this struct.
   struct CodecInfo {
+    CodecInfo();
+    ~CodecInfo();
+
     // |is_hardware_accelerated| is true if the encoders created by this factory
     // of the given codec will use hardware support.
     bool is_hardware_accelerated;
@@ -43,7 +46,7 @@
   // Returns information about how this format will be encoded. The specified
   // format must be one of the supported formats by this factory.
   // TODO(magjed): Try to get rid of this method.
-  virtual CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const = 0;
+  virtual CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const;
 
   // Creates a VideoEncoder for the specified format.
   virtual std::unique_ptr<VideoEncoder> CreateVideoEncoder(
diff --git a/media/engine/convert_legacy_video_factory.cc b/media/engine/convert_legacy_video_factory.cc
index 4c30dc2..e9a21d1 100644
--- a/media/engine/convert_legacy_video_factory.cc
+++ b/media/engine/convert_legacy_video_factory.cc
@@ -60,21 +60,6 @@
       std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory)
       : external_encoder_factory_(std::move(external_encoder_factory)) {}
 
-  webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
-      const webrtc::SdpVideoFormat& format) const override {
-    CodecInfo info;
-    info.has_internal_source = false;
-    info.is_hardware_accelerated = false;
-    if (!external_encoder_factory_)
-      return info;
-
-    info.has_internal_source =
-        external_encoder_factory_->EncoderTypeHasInternalSource(
-            webrtc::PayloadStringToCodecType(format.name));
-    info.is_hardware_accelerated = true;
-    return info;
-  }
-
   std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
     if (!external_encoder_factory_)
       return std::vector<webrtc::SdpVideoFormat>();
@@ -113,22 +98,6 @@
       : internal_encoder_factory_(new webrtc::InternalEncoderFactory()),
         external_encoder_factory_(std::move(external_encoder_factory)) {}
 
-  webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
-      const webrtc::SdpVideoFormat& format) const override {
-    if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(),
-                          format)) {
-      return external_encoder_factory_->QueryVideoEncoder(format);
-    }
-
-    // Format must be one of the internal formats.
-    RTC_DCHECK(IsFormatSupported(
-        internal_encoder_factory_->GetSupportedFormats(), format));
-    webrtc::VideoEncoderFactory::CodecInfo info;
-    info.has_internal_source = false;
-    info.is_hardware_accelerated = false;
-    return info;
-  }
-
   std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
       const webrtc::SdpVideoFormat& format) override {
     // Try creating internal encoder.
diff --git a/media/engine/fakewebrtcvideoengine.cc b/media/engine/fakewebrtcvideoengine.cc
index 897f8f4..331516a 100644
--- a/media/engine/fakewebrtcvideoengine.cc
+++ b/media/engine/fakewebrtcvideoengine.cc
@@ -187,10 +187,17 @@
   return num_frames_encoded_;
 }
 
+webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()
+    const {
+  EncoderInfo info;
+  info.is_hardware_accelerated = true;
+  info.has_internal_source = false;
+  return info;
+}
+
 // Video encoder factory.
 FakeWebRtcVideoEncoderFactory::FakeWebRtcVideoEncoderFactory()
     : num_created_encoders_(0),
-      encoders_have_internal_sources_(false),
       vp8_factory_mode_(false) {}
 
 std::vector<webrtc::SdpVideoFormat>
@@ -230,15 +237,6 @@
   return encoder;
 }
 
-webrtc::VideoEncoderFactory::CodecInfo
-FakeWebRtcVideoEncoderFactory::QueryVideoEncoder(
-    const webrtc::SdpVideoFormat& format) const {
-  webrtc::VideoEncoderFactory::CodecInfo info;
-  info.has_internal_source = encoders_have_internal_sources_;
-  info.is_hardware_accelerated = true;
-  return info;
-}
-
 bool FakeWebRtcVideoEncoderFactory::WaitForCreatedVideoEncoders(
     int num_encoders) {
   int64_t start_offset_ms = rtc::TimeMillis();
@@ -258,11 +256,6 @@
                   encoders_.end());
 }
 
-void FakeWebRtcVideoEncoderFactory::set_encoders_have_internal_sources(
-    bool internal_source) {
-  encoders_have_internal_sources_ = internal_source;
-}
-
 void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodec(
     const webrtc::SdpVideoFormat& format) {
   formats_.push_back(format);
diff --git a/media/engine/fakewebrtcvideoengine.h b/media/engine/fakewebrtcvideoengine.h
index 1d1839a..0f06c33 100644
--- a/media/engine/fakewebrtcvideoengine.h
+++ b/media/engine/fakewebrtcvideoengine.h
@@ -96,6 +96,7 @@
   int32_t Release() override;
   int32_t SetRateAllocation(const webrtc::VideoBitrateAllocation& allocation,
                             uint32_t framerate) override;
+  webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
 
   bool WaitForInitEncode();
   webrtc::VideoCodec GetCodecSettings();
@@ -117,8 +118,6 @@
   std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override;
   std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
       const webrtc::SdpVideoFormat& format) override;
-  CodecInfo QueryVideoEncoder(
-      const webrtc::SdpVideoFormat& format) const override;
 
   bool WaitForCreatedVideoEncoders(int num_encoders);
   void EncoderDestroyed(FakeWebRtcVideoEncoder* encoder);
diff --git a/media/engine/internalencoderfactory.cc b/media/engine/internalencoderfactory.cc
index bf940a1..8c6b360 100644
--- a/media/engine/internalencoderfactory.cc
+++ b/media/engine/internalencoderfactory.cc
@@ -34,14 +34,6 @@
   return supported_codecs;
 }
 
-VideoEncoderFactory::CodecInfo InternalEncoderFactory::QueryVideoEncoder(
-    const SdpVideoFormat& format) const {
-  CodecInfo info;
-  info.is_hardware_accelerated = false;
-  info.has_internal_source = false;
-  return info;
-}
-
 std::unique_ptr<VideoEncoder> InternalEncoderFactory::CreateVideoEncoder(
     const SdpVideoFormat& format) {
   if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName))
diff --git a/media/engine/internalencoderfactory.h b/media/engine/internalencoderfactory.h
index d30335e..0373a88 100644
--- a/media/engine/internalencoderfactory.h
+++ b/media/engine/internalencoderfactory.h
@@ -24,8 +24,6 @@
  public:
   std::vector<SdpVideoFormat> GetSupportedFormats() const override;
 
-  CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
-
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override;
 };
diff --git a/media/engine/multiplexcodecfactory.cc b/media/engine/multiplexcodecfactory.cc
index 76f60ec..38a0d53 100644
--- a/media/engine/multiplexcodecfactory.cc
+++ b/media/engine/multiplexcodecfactory.cc
@@ -57,14 +57,6 @@
   return formats;
 }
 
-VideoEncoderFactory::CodecInfo MultiplexEncoderFactory::QueryVideoEncoder(
-    const SdpVideoFormat& format) const {
-  if (!IsMultiplexCodec(cricket::VideoCodec(format)))
-    return factory_->QueryVideoEncoder(format);
-  return factory_->QueryVideoEncoder(
-      SdpVideoFormat(kMultiplexAssociatedCodecName));
-}
-
 std::unique_ptr<VideoEncoder> MultiplexEncoderFactory::CreateVideoEncoder(
     const SdpVideoFormat& format) {
   if (!IsMultiplexCodec(cricket::VideoCodec(format)))
diff --git a/media/engine/multiplexcodecfactory.h b/media/engine/multiplexcodecfactory.h
index 48a2984..d5bf3fb 100644
--- a/media/engine/multiplexcodecfactory.h
+++ b/media/engine/multiplexcodecfactory.h
@@ -49,7 +49,6 @@
                           bool supports_augmenting_data = false);
 
   std::vector<SdpVideoFormat> GetSupportedFormats() const override;
-  CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override;
 
diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc
index 88a247e..32e6e74 100644
--- a/media/engine/simulcast_encoder_adapter_unittest.cc
+++ b/media/engine/simulcast_encoder_adapter_unittest.cc
@@ -159,8 +159,6 @@
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override;
 
-  CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
-
   const std::vector<MockVideoEncoder*>& encoders() const;
   void SetEncoderNames(const std::vector<const char*>& encoder_names);
   void set_init_encode_return_value(int32_t value);
@@ -310,11 +308,6 @@
   }
 }
 
-VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
-    const SdpVideoFormat& format) const {
-  return CodecInfo();
-}
-
 const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
     const {
   return encoders_;
diff --git a/media/engine/webrtcvideoengine_unittest.cc b/media/engine/webrtcvideoengine_unittest.cc
index 4ba3c48..d4213ff 100644
--- a/media/engine/webrtcvideoengine_unittest.cc
+++ b/media/engine/webrtcvideoengine_unittest.cc
@@ -1090,12 +1090,7 @@
   VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
 
   // Mock encoder creation. |engine| take ownership of the encoder.
-  webrtc::VideoEncoderFactory::CodecInfo codec_info;
-  codec_info.is_hardware_accelerated = false;
-  codec_info.has_internal_source = false;
   const webrtc::SdpVideoFormat format("VP8");
-  EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
-      .WillRepeatedly(testing::Return(codec_info));
   FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
   rtc::Event encoder_created;
   EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
diff --git a/sdk/android/src/jni/videoencoderfactorywrapper.cc b/sdk/android/src/jni/videoencoderfactorywrapper.cc
index 4402666..bd725a8 100644
--- a/sdk/android/src/jni/videoencoderfactorywrapper.cc
+++ b/sdk/android/src/jni/videoencoderfactorywrapper.cc
@@ -50,20 +50,5 @@
   return supported_formats_;
 }
 
-VideoEncoderFactory::CodecInfo VideoEncoderFactoryWrapper::QueryVideoEncoder(
-    const SdpVideoFormat& format) const {
-  JNIEnv* jni = AttachCurrentThreadIfNeeded();
-  ScopedJavaLocalRef<jobject> j_codec_info =
-      SdpVideoFormatToVideoCodecInfo(jni, format);
-  ScopedJavaLocalRef<jobject> encoder = Java_VideoEncoderFactory_createEncoder(
-      jni, encoder_factory_, j_codec_info);
-
-  CodecInfo codec_info;
-  // Check if this is a wrapped native software encoder implementation.
-  codec_info.is_hardware_accelerated = IsHardwareVideoEncoder(jni, encoder);
-  codec_info.has_internal_source = false;
-  return codec_info;
-}
-
 }  // namespace jni
 }  // namespace webrtc
diff --git a/sdk/android/src/jni/videoencoderfactorywrapper.h b/sdk/android/src/jni/videoencoderfactorywrapper.h
index 2c2dadc..7fe9dca 100644
--- a/sdk/android/src/jni/videoencoderfactorywrapper.h
+++ b/sdk/android/src/jni/videoencoderfactorywrapper.h
@@ -35,8 +35,6 @@
   // Returns a list of supported codecs in order of preference.
   std::vector<SdpVideoFormat> GetSupportedFormats() const override;
 
-  CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
-
  private:
   const ScopedJavaGlobalRef<jobject> encoder_factory_;
   std::vector<SdpVideoFormat> supported_formats_;
diff --git a/sdk/objc/native/src/objc_video_encoder_factory.h b/sdk/objc/native/src/objc_video_encoder_factory.h
index 7bf56bd..e9e615b 100644
--- a/sdk/objc/native/src/objc_video_encoder_factory.h
+++ b/sdk/objc/native/src/objc_video_encoder_factory.h
@@ -29,7 +29,6 @@
   std::vector<SdpVideoFormat> GetSupportedFormats() const override;
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override;
-  CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
 
  private:
   id<RTCVideoEncoderFactory> encoder_factory_;
diff --git a/sdk/objc/native/src/objc_video_encoder_factory.mm b/sdk/objc/native/src/objc_video_encoder_factory.mm
index ca61c4d..4eed67d 100644
--- a/sdk/objc/native/src/objc_video_encoder_factory.mm
+++ b/sdk/objc/native/src/objc_video_encoder_factory.mm
@@ -129,19 +129,6 @@
   return supported_formats;
 }
 
-VideoEncoderFactory::CodecInfo ObjCVideoEncoderFactory::QueryVideoEncoder(
-    const SdpVideoFormat &format) const {
-  // TODO(andersc): This is a hack until we figure out how this should be done properly.
-  NSString *formatName = [NSString stringForStdString:format.name];
-  NSSet *wrappedSoftwareFormats =
-      [NSSet setWithObjects:kRTCVideoCodecVp8Name, kRTCVideoCodecVp9Name, nil];
-
-  CodecInfo codec_info;
-  codec_info.is_hardware_accelerated = ![wrappedSoftwareFormats containsObject:formatName];
-  codec_info.has_internal_source = false;
-  return codec_info;
-}
-
 std::unique_ptr<VideoEncoder> ObjCVideoEncoderFactory::CreateVideoEncoder(
     const SdpVideoFormat &format) {
   RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithNativeSdpVideoFormat:format];
diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc
index 06329c6..8707c17 100644
--- a/test/fake_encoder.cc
+++ b/test/fake_encoder.cc
@@ -54,6 +54,8 @@
       max_target_bitrate_kbps_(-1),
       pending_keyframe_(true),
       counter_(0),
+      is_hardware_accelerated_(false),
+      has_internal_source_(false),
       debt_bytes_(0) {
   // Generate some arbitrary not-all-zero data
   for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
@@ -267,9 +269,19 @@
 VideoEncoder::EncoderInfo FakeEncoder::GetEncoderInfo() const {
   EncoderInfo info;
   info.implementation_name = kImplementationName;
+  info.is_hardware_accelerated = is_hardware_accelerated_;
+  info.has_internal_source = has_internal_source_;
   return info;
 }
 
+void FakeEncoder::SetIsHardwareAccelerated(bool is_hardware_accelerated) {
+  is_hardware_accelerated_ = is_hardware_accelerated;
+}
+
+void FakeEncoder::SetHasInternalSource(bool has_internal_source) {
+  has_internal_source_ = has_internal_source;
+}
+
 int FakeEncoder::GetConfiguredInputFramerate() const {
   rtc::CritScope cs(&crit_sect_);
   return configured_input_framerate_;
diff --git a/test/fake_encoder.h b/test/fake_encoder.h
index 753b1ea..a3f5a7a 100644
--- a/test/fake_encoder.h
+++ b/test/fake_encoder.h
@@ -55,6 +55,9 @@
   int GetConfiguredInputFramerate() const;
   EncoderInfo GetEncoderInfo() const override;
 
+  void SetIsHardwareAccelerated(bool is_hardware_accelerated);
+  void SetHasInternalSource(bool has_internal_source);
+
   static const char* kImplementationName;
 
  protected:
@@ -91,6 +94,9 @@
   uint32_t counter_ RTC_GUARDED_BY(crit_sect_);
   rtc::CriticalSection crit_sect_;
 
+  bool is_hardware_accelerated_;
+  bool has_internal_source_;
+
   uint8_t encoded_buffer_[100000];
   bool used_layers_[kMaxSimulcastStreams];
 
diff --git a/test/video_encoder_proxy_factory.h b/test/video_encoder_proxy_factory.h
index 9e5ea12..888200b 100644
--- a/test/video_encoder_proxy_factory.h
+++ b/test/video_encoder_proxy_factory.h
@@ -26,10 +26,8 @@
 // a proxy for the same encoder, typically an instance of FakeEncoder.
 class VideoEncoderProxyFactory final : public VideoEncoderFactory {
  public:
-  explicit VideoEncoderProxyFactory(VideoEncoder* encoder) : encoder_(encoder) {
-    codec_info_.is_hardware_accelerated = false;
-    codec_info_.has_internal_source = false;
-  }
+  explicit VideoEncoderProxyFactory(VideoEncoder* encoder)
+      : encoder_(encoder) {}
 
   // Unused by tests.
   std::vector<SdpVideoFormat> GetSupportedFormats() const override {
@@ -37,22 +35,11 @@
     return {};
   }
 
-  CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override {
-    return codec_info_;
-  }
-
   std::unique_ptr<VideoEncoder> CreateVideoEncoder(
       const SdpVideoFormat& format) override {
     return absl::make_unique<EncoderProxy>(encoder_);
   }
 
-  void SetIsHardwareAccelerated(bool is_hardware_accelerated) {
-    codec_info_.is_hardware_accelerated = is_hardware_accelerated;
-  }
-  void SetHasInternalSource(bool has_internal_source) {
-    codec_info_.has_internal_source = has_internal_source;
-  }
-
  private:
   // Wrapper class, since CreateVideoEncoder needs to surrender
   // ownership to the object it returns.
@@ -88,7 +75,6 @@
   };
 
   VideoEncoder* const encoder_;
-  CodecInfo codec_info_;
 };
 
 }  // namespace test
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index ea77cd6..75ce726 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -2043,10 +2043,10 @@
       bitrate_config);
 
   StartBitrateObserver encoder;
-  test::VideoEncoderProxyFactory encoder_factory(&encoder);
   // Since this test does not use a capturer, set |internal_source| = true.
   // Encoder configuration is otherwise updated on the next video frame.
-  encoder_factory.SetHasInternalSource(true);
+  encoder.SetHasInternalSource(true);
+  test::VideoEncoderProxyFactory encoder_factory(&encoder);
   GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
 
   CreateVideoStreams();
@@ -2125,8 +2125,8 @@
 TEST_P(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
   test::NullTransport transport;
   StartStopBitrateObserver encoder;
+  encoder.SetHasInternalSource(true);
   test::VideoEncoderProxyFactory encoder_factory(&encoder);
-  encoder_factory.SetHasInternalSource(true);
   test::FrameForwarder forwarder;
 
   task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
@@ -2168,8 +2168,8 @@
 TEST_P(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
   test::NullTransport transport;
   StartStopBitrateObserver encoder;
+  encoder.SetHasInternalSource(true);
   test::VideoEncoderProxyFactory encoder_factory(&encoder);
-  encoder_factory.SetHasInternalSource(true);
   test::FrameForwarder forwarder;
 
   task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 410c331..d6d3ba1 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -363,7 +363,6 @@
       pre_encode_callback_(pre_encode_callback),
       max_framerate_(-1),
       pending_encoder_reconfiguration_(false),
-      pending_encoder_creation_(false),
       crop_width_(0),
       crop_height_(0),
       encoder_start_bitrate_bps_(0),
@@ -439,8 +438,9 @@
     }
     degradation_preference_ = degradation_preference;
 
-    if (encoder_)
+    if (encoder_) {
       ConfigureQualityScaler();
+    }
 
     if (!IsFramerateScalingEnabled(degradation_preference) &&
         max_framerate_ != -1) {
@@ -491,8 +491,13 @@
   RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
 
   max_data_payload_length_ = max_data_payload_length;
-  pending_encoder_creation_ =
-      (!encoder_ || encoder_config_.video_format != config.video_format);
+  if (!encoder_ || encoder_config_.video_format != config.video_format) {
+    pending_encoder_ =
+        settings_.encoder_factory->CreateVideoEncoder(config.video_format);
+    // TODO(nisse): What to do if creating the encoder fails? Crash,
+    // or just discard incoming frames?
+    RTC_CHECK(pending_encoder_);
+  }
   encoder_config_ = std::move(config);
   pending_encoder_reconfiguration_ = true;
 
@@ -502,11 +507,13 @@
   // The codec configuration depends on incoming video frame size.
   if (last_frame_info_) {
     ReconfigureEncoder();
-  } else if (settings_.encoder_factory
-                 ->QueryVideoEncoder(encoder_config_.video_format)
-                 .has_internal_source) {
-    last_frame_info_ = VideoFrameInfo(176, 144, false);
-    ReconfigureEncoder();
+  } else {
+    VideoEncoder* encoder =
+        pending_encoder_ ? pending_encoder_.get() : encoder_.get();
+    if (encoder->GetEncoderInfo().has_internal_source) {
+      last_frame_info_ = VideoFrameInfo(176, 144, false);
+      ReconfigureEncoder();
+    }
   }
 }
 
@@ -584,28 +591,21 @@
   source_proxy_->SetMaxFramerate(max_framerate);
 
   // Keep the same encoder, as long as the video_format is unchanged.
-  if (pending_encoder_creation_) {
-    pending_encoder_creation_ = false;
+  if (pending_encoder_) {
     if (encoder_) {
       video_sender_.RegisterExternalEncoder(nullptr, false);
     }
+    encoder_ = std::move(pending_encoder_);
 
-    encoder_ = settings_.encoder_factory->CreateVideoEncoder(
-        encoder_config_.video_format);
-    // TODO(nisse): What to do if creating the encoder fails? Crash,
-    // or just discard incoming frames?
-    RTC_CHECK(encoder_);
-
-    const webrtc::VideoEncoderFactory::CodecInfo info =
-        settings_.encoder_factory->QueryVideoEncoder(
-            encoder_config_.video_format);
+    const VideoEncoder::EncoderInfo& encoder_info = encoder_->GetEncoderInfo();
 
     overuse_detector_->StopCheckForOveruse();
     overuse_detector_->StartCheckForOveruse(
-        GetCpuOveruseOptions(settings_, info.is_hardware_accelerated), this);
+        GetCpuOveruseOptions(settings_, encoder_info.is_hardware_accelerated),
+        this);
 
     video_sender_.RegisterExternalEncoder(encoder_.get(),
-                                          info.has_internal_source);
+                                          encoder_info.has_internal_source);
   }
   // RegisterSendCodec implies an unconditional call to
   // encoder_->InitEncode().
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 8c5efbe..04d22de 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -202,6 +202,9 @@
   rtc::ThreadChecker thread_checker_;
 
   VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(&encoder_queue_);
+  // Pending encoder object (e.g. because of a codec change).
+  std::unique_ptr<VideoEncoder> pending_encoder_ RTC_GUARDED_BY(&encoder_queue_)
+      RTC_PT_GUARDED_BY(&encoder_queue_);
   std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(&encoder_queue_)
       RTC_PT_GUARDED_BY(&encoder_queue_);
   std::unique_ptr<VideoBitrateAllocator> rate_allocator_
@@ -213,9 +216,6 @@
   // Set when ConfigureEncoder has been called in order to lazy reconfigure the
   // encoder on the next frame.
   bool pending_encoder_reconfiguration_ RTC_GUARDED_BY(&encoder_queue_);
-  // Set when configuration must create a new encoder object, e.g.,
-  // because of a codec change.
-  bool pending_encoder_creation_ RTC_GUARDED_BY(&encoder_queue_);
   absl::optional<VideoFrameInfo> last_frame_info_
       RTC_GUARDED_BY(&encoder_queue_);
   int crop_width_ RTC_GUARDED_BY(&encoder_queue_);
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 05a23c0..684b432 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -511,8 +511,8 @@
     }
 
     VideoEncoder::EncoderInfo GetEncoderInfo() const override {
-      EncoderInfo info;
       rtc::CritScope lock(&local_crit_sect_);
+      EncoderInfo info = FakeEncoder::GetEncoderInfo();
       if (quality_scaling_) {
         info.scaling_settings =
             VideoEncoder::ScalingSettings(1, 2, kMinPixelsPerFrame);
@@ -3198,7 +3198,7 @@
   CpuOveruseOptions hardware_options;
   hardware_options.low_encode_usage_threshold_percent = 150;
   hardware_options.high_encode_usage_threshold_percent = 200;
-  encoder_factory_.SetIsHardwareAccelerated(true);
+  fake_encoder_.SetIsHardwareAccelerated(true);
 
   video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
   video_source_.IncomingCapturedFrame(