Revert "Replace VideoEncoderFactory::QueryVideoEncoder with VideoEncoder::GetEncoderInfo"

This reverts commit cdc5eb0de179dcc866ef770ea303879c64466879.

Reason for revert: Causes wrong CPU adaptation to be used for some HW codecs since GetEncoderInfo() is polled before InitEncode().

Original change's description:
> 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}

TBR=brandtr@webrtc.org,sakal@webrtc.org,kthelgason@webrtc.org,sprang@webrtc.org,srte@webrtc.org,perkj@webrtc.org,mirtad@webrtc.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: webrtc:10065
Change-Id: Idaa452e1d8c1c58cdb4ec69b88fce9042589cc3c
Reviewed-on: https://webrtc-review.googlesource.com/c/113800
Reviewed-by: Mirta Dvornicic <mirtad@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25943}
diff --git a/api/test/mock_video_encoder_factory.h b/api/test/mock_video_encoder_factory.h
index 845251b..a694b63 100644
--- a/api/test/mock_video_encoder_factory.h
+++ b/api/test/mock_video_encoder_factory.h
@@ -24,6 +24,8 @@
  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 514bd48..85f848c 100644
--- a/api/test/video/function_video_encoder_factory.h
+++ b/api/test/video/function_video_encoder_factory.h
@@ -41,6 +41,14 @@
     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 0fd0b99..534a34e 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -27,7 +27,6 @@
     "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 e687871..1778c21 100644
--- a/api/video_codecs/builtin_video_encoder_factory.cc
+++ b/api/video_codecs/builtin_video_encoder_factory.cc
@@ -44,6 +44,17 @@
   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
deleted file mode 100644
index de71aa6..0000000
--- a/api/video_codecs/video_encoder_factory.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  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 7b2b156..7958d16 100644
--- a/api/video_codecs/video_encoder_factory.h
+++ b/api/video_codecs/video_encoder_factory.h
@@ -25,9 +25,6 @@
  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;
@@ -46,7 +43,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;
+  virtual CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const = 0;
 
   // 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 e9a21d1..4c30dc2 100644
--- a/media/engine/convert_legacy_video_factory.cc
+++ b/media/engine/convert_legacy_video_factory.cc
@@ -60,6 +60,21 @@
       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>();
@@ -98,6 +113,22 @@
       : 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 331516a..897f8f4 100644
--- a/media/engine/fakewebrtcvideoengine.cc
+++ b/media/engine/fakewebrtcvideoengine.cc
@@ -187,17 +187,10 @@
   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>
@@ -237,6 +230,15 @@
   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();
@@ -256,6 +258,11 @@
                   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 0f06c33..1d1839a 100644
--- a/media/engine/fakewebrtcvideoengine.h
+++ b/media/engine/fakewebrtcvideoengine.h
@@ -96,7 +96,6 @@
   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();
@@ -118,6 +117,8 @@
   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 8c6b360..bf940a1 100644
--- a/media/engine/internalencoderfactory.cc
+++ b/media/engine/internalencoderfactory.cc
@@ -34,6 +34,14 @@
   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 0373a88..d30335e 100644
--- a/media/engine/internalencoderfactory.h
+++ b/media/engine/internalencoderfactory.h
@@ -24,6 +24,8 @@
  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 38a0d53..76f60ec 100644
--- a/media/engine/multiplexcodecfactory.cc
+++ b/media/engine/multiplexcodecfactory.cc
@@ -57,6 +57,14 @@
   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 d5bf3fb..48a2984 100644
--- a/media/engine/multiplexcodecfactory.h
+++ b/media/engine/multiplexcodecfactory.h
@@ -49,6 +49,7 @@
                           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 32e6e74..88a247e 100644
--- a/media/engine/simulcast_encoder_adapter_unittest.cc
+++ b/media/engine/simulcast_encoder_adapter_unittest.cc
@@ -159,6 +159,8 @@
   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);
@@ -308,6 +310,11 @@
   }
 }
 
+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 d4213ff..4ba3c48 100644
--- a/media/engine/webrtcvideoengine_unittest.cc
+++ b/media/engine/webrtcvideoengine_unittest.cc
@@ -1090,7 +1090,12 @@
   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 bd725a8..4402666 100644
--- a/sdk/android/src/jni/videoencoderfactorywrapper.cc
+++ b/sdk/android/src/jni/videoencoderfactorywrapper.cc
@@ -50,5 +50,20 @@
   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 7fe9dca..2c2dadc 100644
--- a/sdk/android/src/jni/videoencoderfactorywrapper.h
+++ b/sdk/android/src/jni/videoencoderfactorywrapper.h
@@ -35,6 +35,8 @@
   // 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 e9e615b..7bf56bd 100644
--- a/sdk/objc/native/src/objc_video_encoder_factory.h
+++ b/sdk/objc/native/src/objc_video_encoder_factory.h
@@ -29,6 +29,7 @@
   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 4eed67d..ca61c4d 100644
--- a/sdk/objc/native/src/objc_video_encoder_factory.mm
+++ b/sdk/objc/native/src/objc_video_encoder_factory.mm
@@ -129,6 +129,19 @@
   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 8707c17..06329c6 100644
--- a/test/fake_encoder.cc
+++ b/test/fake_encoder.cc
@@ -54,8 +54,6 @@
       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) {
@@ -269,19 +267,9 @@
 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 a3f5a7a..753b1ea 100644
--- a/test/fake_encoder.h
+++ b/test/fake_encoder.h
@@ -55,9 +55,6 @@
   int GetConfiguredInputFramerate() const;
   EncoderInfo GetEncoderInfo() const override;
 
-  void SetIsHardwareAccelerated(bool is_hardware_accelerated);
-  void SetHasInternalSource(bool has_internal_source);
-
   static const char* kImplementationName;
 
  protected:
@@ -94,9 +91,6 @@
   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 888200b..9e5ea12 100644
--- a/test/video_encoder_proxy_factory.h
+++ b/test/video_encoder_proxy_factory.h
@@ -26,8 +26,10 @@
 // a proxy for the same encoder, typically an instance of FakeEncoder.
 class VideoEncoderProxyFactory final : public VideoEncoderFactory {
  public:
-  explicit VideoEncoderProxyFactory(VideoEncoder* encoder)
-      : encoder_(encoder) {}
+  explicit VideoEncoderProxyFactory(VideoEncoder* encoder) : encoder_(encoder) {
+    codec_info_.is_hardware_accelerated = false;
+    codec_info_.has_internal_source = false;
+  }
 
   // Unused by tests.
   std::vector<SdpVideoFormat> GetSupportedFormats() const override {
@@ -35,11 +37,22 @@
     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.
@@ -75,6 +88,7 @@
   };
 
   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 75ce726..ea77cd6 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.SetHasInternalSource(true);
-  test::VideoEncoderProxyFactory encoder_factory(&encoder);
+  encoder_factory.SetHasInternalSource(true);
   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 d6d3ba1..410c331 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -363,6 +363,7 @@
       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),
@@ -438,9 +439,8 @@
     }
     degradation_preference_ = degradation_preference;
 
-    if (encoder_) {
+    if (encoder_)
       ConfigureQualityScaler();
-    }
 
     if (!IsFramerateScalingEnabled(degradation_preference) &&
         max_framerate_ != -1) {
@@ -491,13 +491,8 @@
   RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
 
   max_data_payload_length_ = max_data_payload_length;
-  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_);
-  }
+  pending_encoder_creation_ =
+      (!encoder_ || encoder_config_.video_format != config.video_format);
   encoder_config_ = std::move(config);
   pending_encoder_reconfiguration_ = true;
 
@@ -507,13 +502,11 @@
   // The codec configuration depends on incoming video frame size.
   if (last_frame_info_) {
     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();
-    }
+  } else if (settings_.encoder_factory
+                 ->QueryVideoEncoder(encoder_config_.video_format)
+                 .has_internal_source) {
+    last_frame_info_ = VideoFrameInfo(176, 144, false);
+    ReconfigureEncoder();
   }
 }
 
@@ -591,21 +584,28 @@
   source_proxy_->SetMaxFramerate(max_framerate);
 
   // Keep the same encoder, as long as the video_format is unchanged.
-  if (pending_encoder_) {
+  if (pending_encoder_creation_) {
+    pending_encoder_creation_ = false;
     if (encoder_) {
       video_sender_.RegisterExternalEncoder(nullptr, false);
     }
-    encoder_ = std::move(pending_encoder_);
 
-    const VideoEncoder::EncoderInfo& encoder_info = encoder_->GetEncoderInfo();
+    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);
 
     overuse_detector_->StopCheckForOveruse();
     overuse_detector_->StartCheckForOveruse(
-        GetCpuOveruseOptions(settings_, encoder_info.is_hardware_accelerated),
-        this);
+        GetCpuOveruseOptions(settings_, info.is_hardware_accelerated), this);
 
     video_sender_.RegisterExternalEncoder(encoder_.get(),
-                                          encoder_info.has_internal_source);
+                                          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 04d22de..8c5efbe 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -202,9 +202,6 @@
   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_
@@ -216,6 +213,9 @@
   // 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 684b432..05a23c0 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;
-  fake_encoder_.SetIsHardwareAccelerated(true);
+  encoder_factory_.SetIsHardwareAccelerated(true);
 
   video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
   video_source_.IncomingCapturedFrame(