Revert of Prepare for injectable SW decoders (patchset #3 id:40001 of https://codereview.webrtc.org/3009973002/ )

Reason for revert:
Tentative revert since it seems to cause problems in Chrome, MAC.

https://build.chromium.org/p/chromium.webrtc.fyi/builders/Mac%20Tester/builds/42684

Original issue's description:
> Prepare for injectable SW decoders
>
> Pretty much mirrors the work done on the encoding side in CLs:
>
> "Clean up ownership of webrtc::VideoEncoder"
> https://codereview.webrtc.org/3007643002/
>
> "Let VideoEncoderSoftwareFallbackWrapper own the wrapped encoder"
> https://codereview.webrtc.org/3007683002/
>
> "WebRtcVideoEngine: Encapsulate logic for unifying internal and external video codecs"
> https://codereview.webrtc.org/3006713002/
>
> BUG=webrtc:7925
>
> Review-Url: https://codereview.webrtc.org/3009973002
> Cr-Commit-Position: refs/heads/master@{#19641}
> Committed: https://chromium.googlesource.com/external/webrtc/+/084c55a63a2d9bdc71579458406d44f8bab9f454

TBR=magjed@webrtc.org,andersc@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7925

Review-Url: https://codereview.webrtc.org/3010953002
Cr-Original-Commit-Position: refs/heads/master@{#19647}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 1f88531038c24c5ce3b0f4cfc682b970770a71f6
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 9438e6b..0ed8fc2 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -146,8 +146,6 @@
     "engine/nullwebrtcvideoengine.h",
     "engine/payload_type_mapper.cc",
     "engine/payload_type_mapper.h",
-    "engine/scopedvideodecoder.cc",
-    "engine/scopedvideodecoder.h",
     "engine/scopedvideoencoder.cc",
     "engine/scopedvideoencoder.h",
     "engine/simulcast.cc",
diff --git a/media/engine/scopedvideodecoder.cc b/media/engine/scopedvideodecoder.cc
deleted file mode 100644
index 6dfbefa..0000000
--- a/media/engine/scopedvideodecoder.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *  Copyright (c) 2017 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 "webrtc/media/engine/scopedvideodecoder.h"
-
-#include <vector>
-
-#include "webrtc/api/video_codecs/video_decoder.h"
-
-namespace cricket {
-
-namespace {
-
-class ScopedVideoDecoder : public webrtc::VideoDecoder {
- public:
-  ScopedVideoDecoder(WebRtcVideoDecoderFactory* factory,
-                     webrtc::VideoDecoder* decoder);
-
-  int32_t InitDecode(const webrtc::VideoCodec* codec_settings,
-                     int32_t number_of_cores) override;
-  int32_t RegisterDecodeCompleteCallback(
-      webrtc::DecodedImageCallback* callback) override;
-  int32_t Release() override;
-  int32_t Decode(const webrtc::EncodedImage& input_image,
-                 bool missing_frames,
-                 const webrtc::RTPFragmentationHeader* fragmentation,
-                 const webrtc::CodecSpecificInfo* codec_specific_info,
-                 int64_t render_time_ms) override;
-  bool PrefersLateDecoding() const override;
-  const char* ImplementationName() const override;
-
-  ~ScopedVideoDecoder() override;
-
- private:
-  WebRtcVideoDecoderFactory* factory_;
-  webrtc::VideoDecoder* decoder_;
-};
-
-ScopedVideoDecoder::ScopedVideoDecoder(WebRtcVideoDecoderFactory* factory,
-                                       webrtc::VideoDecoder* decoder)
-    : factory_(factory), decoder_(decoder) {}
-
-int32_t ScopedVideoDecoder::InitDecode(const webrtc::VideoCodec* codec_settings,
-                                       int32_t number_of_cores) {
-  return decoder_->InitDecode(codec_settings, number_of_cores);
-}
-
-int32_t ScopedVideoDecoder::RegisterDecodeCompleteCallback(
-    webrtc::DecodedImageCallback* callback) {
-  return decoder_->RegisterDecodeCompleteCallback(callback);
-}
-
-int32_t ScopedVideoDecoder::Release() {
-  return decoder_->Release();
-}
-
-int32_t ScopedVideoDecoder::Decode(
-    const webrtc::EncodedImage& input_image,
-    bool missing_frames,
-    const webrtc::RTPFragmentationHeader* fragmentation,
-    const webrtc::CodecSpecificInfo* codec_specific_info,
-    int64_t render_time_ms) {
-  return decoder_->Decode(input_image, missing_frames, fragmentation,
-                          codec_specific_info, render_time_ms);
-}
-
-bool ScopedVideoDecoder::PrefersLateDecoding() const {
-  return decoder_->PrefersLateDecoding();
-}
-
-const char* ScopedVideoDecoder::ImplementationName() const {
-  return decoder_->ImplementationName();
-}
-
-ScopedVideoDecoder::~ScopedVideoDecoder() {
-  factory_->DestroyVideoDecoder(decoder_);
-}
-
-}  // namespace
-
-std::unique_ptr<webrtc::VideoDecoder> CreateScopedVideoDecoder(
-    WebRtcVideoDecoderFactory* factory,
-    webrtc::VideoCodecType type) {
-  webrtc::VideoDecoder* decoder = factory->CreateVideoDecoder(type);
-  if (!decoder)
-    return nullptr;
-  return std::unique_ptr<webrtc::VideoDecoder>(
-      new ScopedVideoDecoder(factory, decoder));
-}
-
-std::unique_ptr<webrtc::VideoDecoder> CreateScopedVideoDecoder(
-    WebRtcVideoDecoderFactory* factory,
-    webrtc::VideoCodecType type,
-    VideoDecoderParams params) {
-  webrtc::VideoDecoder* decoder =
-      factory->CreateVideoDecoderWithParams(type, params);
-  if (!decoder)
-    return nullptr;
-  return std::unique_ptr<webrtc::VideoDecoder>(
-      new ScopedVideoDecoder(factory, decoder));
-}
-
-}  // namespace cricket
diff --git a/media/engine/scopedvideodecoder.h b/media/engine/scopedvideodecoder.h
deleted file mode 100644
index f921d99..0000000
--- a/media/engine/scopedvideodecoder.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Copyright (c) 2017 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.
- */
-
-#ifndef WEBRTC_MEDIA_ENGINE_SCOPEDVIDEODECODER_H_
-#define WEBRTC_MEDIA_ENGINE_SCOPEDVIDEODECODER_H_
-
-#include <memory>
-
-#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
-
-namespace cricket {
-
-// Helper function that creates a webrtc::VideoDecoder held by an
-// std::unique_ptr instead of having to be deleted through
-// WebRtcVideoDecoderFactory::DestroyVideoDecoder. The factory passed in must
-// outlive the returned encoder.
-// TODO(andersc): This helper function will be deleted once
-// cricket::WebRtcVideoDecoderFactory is deprecated, see
-// https://bugs.chromium.org/p/webrtc/issues/detail?id=7925 for more info.
-std::unique_ptr<webrtc::VideoDecoder> CreateScopedVideoDecoder(
-    cricket::WebRtcVideoDecoderFactory* factory,
-    webrtc::VideoCodecType type);
-std::unique_ptr<webrtc::VideoDecoder> CreateScopedVideoDecoder(
-    cricket::WebRtcVideoDecoderFactory* factory,
-    webrtc::VideoCodecType type,
-    VideoDecoderParams params);
-
-}  // namespace cricket
-
-#endif  // WEBRTC_MEDIA_ENGINE_SCOPEDVIDEODECODER_H_
diff --git a/media/engine/videodecodersoftwarefallbackwrapper.cc b/media/engine/videodecodersoftwarefallbackwrapper.cc
index 0e7632b..6a234d5 100644
--- a/media/engine/videodecodersoftwarefallbackwrapper.cc
+++ b/media/engine/videodecodersoftwarefallbackwrapper.cc
@@ -22,9 +22,9 @@
 
 VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper(
     VideoCodecType codec_type,
-    std::unique_ptr<VideoDecoder> decoder)
+    VideoDecoder* decoder)
     : codec_type_(codec_type),
-      decoder_(std::move(decoder)),
+      decoder_(decoder),
       decoder_initialized_(false),
       callback_(nullptr) {}
 
diff --git a/media/engine/videodecodersoftwarefallbackwrapper.h b/media/engine/videodecodersoftwarefallbackwrapper.h
index d6c3e0e..3984e1f 100644
--- a/media/engine/videodecodersoftwarefallbackwrapper.h
+++ b/media/engine/videodecodersoftwarefallbackwrapper.h
@@ -21,10 +21,10 @@
 // Class used to wrap external VideoDecoders to provide a fallback option on
 // software decoding when a hardware decoder fails to decode a stream due to
 // hardware restrictions, such as max resolution.
-class VideoDecoderSoftwareFallbackWrapper : public VideoDecoder {
+class VideoDecoderSoftwareFallbackWrapper : public webrtc::VideoDecoder {
  public:
   VideoDecoderSoftwareFallbackWrapper(VideoCodecType codec_type,
-                                      std::unique_ptr<VideoDecoder> decoder);
+                                      VideoDecoder* decoder);
 
   int32_t InitDecode(const VideoCodec* codec_settings,
                      int32_t number_of_cores) override;
@@ -47,7 +47,7 @@
   bool InitFallbackDecoder();
 
   const VideoCodecType codec_type_;
-  std::unique_ptr<VideoDecoder> decoder_;
+  VideoDecoder* const decoder_;
   bool decoder_initialized_;
 
   VideoCodec codec_settings_;
diff --git a/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc b/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc
index 84a6a59..b4fc7ca 100644
--- a/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc
+++ b/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc
@@ -19,9 +19,7 @@
 class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
  protected:
   VideoDecoderSoftwareFallbackWrapperTest()
-      : fake_decoder_(new CountingFakeDecoder()),
-        fallback_wrapper_(kVideoCodecVP8,
-                          std::unique_ptr<VideoDecoder>(fake_decoder_)) {}
+      : fallback_wrapper_(kVideoCodecVP8, &fake_decoder_) {}
 
   class CountingFakeDecoder : public VideoDecoder {
    public:
@@ -63,41 +61,39 @@
     int release_count_ = 0;
     int reset_count_ = 0;
   };
-  // |fake_decoder_| is owned and released by |fallback_wrapper_|.
-  CountingFakeDecoder* fake_decoder_;
+  CountingFakeDecoder fake_decoder_;
   VideoDecoderSoftwareFallbackWrapper fallback_wrapper_;
 };
 
 TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) {
   VideoCodec codec = {};
   fallback_wrapper_.InitDecode(&codec, 2);
-  EXPECT_EQ(1, fake_decoder_->init_decode_count_);
+  EXPECT_EQ(1, fake_decoder_.init_decode_count_);
 
   EncodedImage encoded_image;
   encoded_image._frameType = kVideoFrameKey;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(1, fake_decoder_->init_decode_count_)
+  EXPECT_EQ(1, fake_decoder_.init_decode_count_)
       << "Initialized decoder should not be reinitialized.";
-  EXPECT_EQ(1, fake_decoder_->decode_count_);
+  EXPECT_EQ(1, fake_decoder_.decode_count_);
 }
 
 TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
        UsesFallbackDecoderAfterOnInitDecodeFailure) {
   VideoCodec codec = {};
-  fake_decoder_->init_decode_return_code_ =
-      WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+  fake_decoder_.init_decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   fallback_wrapper_.InitDecode(&codec, 2);
-  EXPECT_EQ(1, fake_decoder_->init_decode_count_);
+  EXPECT_EQ(1, fake_decoder_.init_decode_count_);
 
   EncodedImage encoded_image;
   encoded_image._frameType = kVideoFrameKey;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(2, fake_decoder_->init_decode_count_)
+  EXPECT_EQ(2, fake_decoder_.init_decode_count_)
       << "Should have attempted reinitializing the fallback decoder on "
          "keyframe.";
   // Unfortunately faking a VP8 frame is hard. Rely on no Decode -> using SW
   // decoder.
-  EXPECT_EQ(0, fake_decoder_->decode_count_)
+  EXPECT_EQ(0, fake_decoder_.decode_count_)
       << "Decoder used even though no InitDecode had succeeded.";
 }
 
@@ -107,41 +103,41 @@
   fallback_wrapper_.InitDecode(&codec, 2);
   // Unfortunately faking a VP8 frame is hard. Rely on no Decode -> using SW
   // decoder.
-  fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(1, fake_decoder_->decode_count_);
+  EXPECT_EQ(1, fake_decoder_.decode_count_);
 
   // Fail -> fake_decoder shouldn't be used anymore.
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(1, fake_decoder_->decode_count_)
+  EXPECT_EQ(1, fake_decoder_.decode_count_)
       << "Decoder used even though fallback should be active.";
 
   // Should be able to recover on a keyframe.
   encoded_image._frameType = kVideoFrameKey;
-  fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(2, fake_decoder_->decode_count_)
+  EXPECT_EQ(2, fake_decoder_.decode_count_)
       << "Wrapper did not try to decode a keyframe using registered decoder.";
 
   encoded_image._frameType = kVideoFrameDelta;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(3, fake_decoder_->decode_count_)
+  EXPECT_EQ(3, fake_decoder_.decode_count_)
       << "Decoder not used on future delta frames.";
 }
 
 TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) {
   VideoCodec codec = {};
   fallback_wrapper_.InitDecode(&codec, 2);
-  fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
+  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
   EncodedImage encoded_image;
   EXPECT_EQ(
-      fake_decoder_->decode_return_code_,
+      fake_decoder_.decode_return_code_,
       fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1));
-  EXPECT_EQ(1, fake_decoder_->decode_count_);
+  EXPECT_EQ(1, fake_decoder_.decode_count_);
 
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(2, fake_decoder_->decode_count_)
+  EXPECT_EQ(2, fake_decoder_.decode_count_)
       << "Decoder should be active even though previous decode failed.";
 }
 
@@ -149,15 +145,15 @@
   VideoCodec codec = {};
   fallback_wrapper_.InitDecode(&codec, 2);
   fallback_wrapper_.Release();
-  EXPECT_EQ(1, fake_decoder_->release_count_);
+  EXPECT_EQ(1, fake_decoder_.release_count_);
 
-  fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
-  EXPECT_EQ(1, fake_decoder_->release_count_)
+  EXPECT_EQ(1, fake_decoder_.release_count_)
       << "Decoder should not be released during fallback.";
   fallback_wrapper_.Release();
-  EXPECT_EQ(2, fake_decoder_->release_count_);
+  EXPECT_EQ(2, fake_decoder_.release_count_);
 }
 
 // TODO(pbos): Fake a VP8 frame well enough to actually receive a callback from
@@ -181,13 +177,13 @@
   VideoCodec codec = {};
   fallback_wrapper_.InitDecode(&codec, 2);
   fallback_wrapper_.RegisterDecodeCompleteCallback(&callback);
-  EXPECT_EQ(&callback, fake_decoder_->decode_complete_callback_);
+  EXPECT_EQ(&callback, fake_decoder_.decode_complete_callback_);
 
-  fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
   fallback_wrapper_.RegisterDecodeCompleteCallback(&callback2);
-  EXPECT_EQ(&callback2, fake_decoder_->decode_complete_callback_);
+  EXPECT_EQ(&callback2, fake_decoder_.decode_complete_callback_);
 }
 
 TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
@@ -195,7 +191,7 @@
   VideoCodec codec = {};
   fallback_wrapper_.InitDecode(&codec, 2);
 
-  fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
   fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
   // Hard coded expected value since libvpx is the software implementation name
diff --git a/media/engine/webrtcvideoengine.cc b/media/engine/webrtcvideoengine.cc
index dd0a7b0..00d138a 100644
--- a/media/engine/webrtcvideoengine.cc
+++ b/media/engine/webrtcvideoengine.cc
@@ -24,7 +24,6 @@
 #include "webrtc/media/engine/constants.h"
 #include "webrtc/media/engine/internaldecoderfactory.h"
 #include "webrtc/media/engine/internalencoderfactory.h"
-#include "webrtc/media/engine/scopedvideodecoder.h"
 #include "webrtc/media/engine/scopedvideoencoder.h"
 #include "webrtc/media/engine/simulcast.h"
 #include "webrtc/media/engine/simulcast_encoder_adapter.h"
@@ -72,17 +71,6 @@
   virtual std::unique_ptr<EncoderFactoryAdapter> clone() const = 0;
 };
 
-class DecoderFactoryAdapter {
- public:
-  virtual ~DecoderFactoryAdapter() {}
-
-  virtual std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
-      webrtc::VideoCodecType type,
-      const VideoDecoderParams& decoder_params) const = 0;
-
-  virtual std::unique_ptr<DecoderFactoryAdapter> clone() const = 0;
-};
-
 namespace {
 
 // Wraps cricket::WebRtcVideoEncoderFactory* into common EncoderFactoryAdapter
@@ -116,31 +104,6 @@
   WebRtcVideoEncoderFactory* const external_encoder_factory_;
 };
 
-class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter {
- public:
-  explicit CricketDecoderFactoryAdapter(
-      WebRtcVideoDecoderFactory* external_decoder_factory)
-      : internal_decoder_factory_(new InternalDecoderFactory()),
-        external_decoder_factory_(external_decoder_factory) {}
-
- private:
-  explicit CricketDecoderFactoryAdapter(
-      const CricketDecoderFactoryAdapter& other)
-      : CricketDecoderFactoryAdapter(other.external_decoder_factory_) {}
-
-  std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
-      webrtc::VideoCodecType type,
-      const VideoDecoderParams& decoder_params) const override;
-
-  std::unique_ptr<DecoderFactoryAdapter> clone() const override {
-    return std::unique_ptr<DecoderFactoryAdapter>(
-        new CricketDecoderFactoryAdapter(*this));
-  }
-
-  const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_;
-  WebRtcVideoDecoderFactory* const external_decoder_factory_;
-};
-
 // If this field trial is enabled, we will enable sending FlexFEC and disable
 // sending ULPFEC whenever the former has been negotiated in the SDPs.
 bool IsFlexfecFieldTrialEnabled() {
@@ -404,8 +367,7 @@
 
 WebRtcVideoEngine::WebRtcVideoEngine()
     : initialized_(false),
-      decoder_factory_(new CricketDecoderFactoryAdapter(
-          nullptr /* external_decoder_factory */)),
+      external_decoder_factory_(NULL),
       encoder_factory_(new CricketEncoderFactoryAdapter(
           nullptr /* external_encoder_factory */)) {
   LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()";
@@ -427,7 +389,7 @@
   RTC_DCHECK(initialized_);
   LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString();
   return new WebRtcVideoChannel(call, config, options, *encoder_factory_,
-                                *decoder_factory_);
+                                external_decoder_factory_);
 }
 
 std::vector<VideoCodec> WebRtcVideoEngine::codecs() const {
@@ -463,7 +425,7 @@
 void WebRtcVideoEngine::SetExternalDecoderFactory(
     WebRtcVideoDecoderFactory* decoder_factory) {
   RTC_DCHECK(!initialized_);
-  decoder_factory_.reset(new CricketDecoderFactoryAdapter(decoder_factory));
+  external_decoder_factory_ = decoder_factory;
 }
 
 void WebRtcVideoEngine::SetExternalEncoderFactory(
@@ -541,13 +503,13 @@
     const MediaConfig& config,
     const VideoOptions& options,
     const EncoderFactoryAdapter& encoder_factory,
-    const DecoderFactoryAdapter& decoder_factory)
+    WebRtcVideoDecoderFactory* external_decoder_factory)
     : VideoMediaChannel(config),
       call_(call),
       unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
       video_config_(config.video),
       encoder_factory_(encoder_factory.clone()),
-      decoder_factory_(decoder_factory.clone()),
+      external_decoder_factory_(external_decoder_factory),
       default_send_options_(options),
       last_stats_log_ms_(-1) {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
@@ -1163,7 +1125,7 @@
   config.sync_group = sp.sync_label;
 
   receive_streams_[ssrc] = new WebRtcVideoReceiveStream(
-      call_, sp, std::move(config), *decoder_factory_, default_stream,
+      call_, sp, std::move(config), external_decoder_factory_, default_stream,
       recv_codecs_, flexfec_config);
 
   return true;
@@ -2101,7 +2063,7 @@
     webrtc::Call* call,
     const StreamParams& sp,
     webrtc::VideoReceiveStream::Config config,
-    const DecoderFactoryAdapter& decoder_factory,
+    WebRtcVideoDecoderFactory* external_decoder_factory,
     bool default_stream,
     const std::vector<VideoCodecSettings>& recv_codecs,
     const webrtc::FlexfecReceiveStream::Config& flexfec_config)
@@ -2112,13 +2074,12 @@
       config_(std::move(config)),
       flexfec_config_(flexfec_config),
       flexfec_stream_(nullptr),
-      decoder_factory_(decoder_factory.clone()),
+      external_decoder_factory_(external_decoder_factory),
       sink_(NULL),
       first_frame_timestamp_(-1),
       estimated_remote_start_ntp_time_ms_(0) {
   config_.renderer = this;
-  std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>
-      old_decoders;
+  std::vector<AllocatedDecoder> old_decoders;
   ConfigureCodecs(recv_codecs, &old_decoders);
   ConfigureFlexfecCodec(flexfec_config.payload_type);
   MaybeRecreateWebRtcFlexfecStream();
@@ -2126,13 +2087,28 @@
   RTC_DCHECK(old_decoders.empty());
 }
 
+WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder::
+    AllocatedDecoder(webrtc::VideoDecoder* decoder,
+                     webrtc::VideoCodecType type,
+                     bool external)
+    : decoder(decoder),
+      external_decoder(nullptr),
+      type(type),
+      external(external) {
+  if (external) {
+    external_decoder = decoder;
+    this->decoder =
+        new webrtc::VideoDecoderSoftwareFallbackWrapper(type, external_decoder);
+  }
+}
+
 WebRtcVideoChannel::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() {
   if (flexfec_stream_) {
     MaybeDissociateFlexfecFromVideo();
     call_->DestroyFlexfecReceiveStream(flexfec_stream_);
   }
   call_->DestroyVideoReceiveStream(stream_);
-  allocated_decoders_.clear();
+  ClearDecoders(&allocated_decoders_);
 }
 
 const std::vector<uint32_t>&
@@ -2153,59 +2129,53 @@
   }
 }
 
-std::unique_ptr<webrtc::VideoDecoder>
-CricketDecoderFactoryAdapter::CreateVideoDecoder(
-    webrtc::VideoCodecType type,
-    const VideoDecoderParams& decoder_params) const {
-  if (external_decoder_factory_ != nullptr) {
-    std::unique_ptr<webrtc::VideoDecoder> external_decoder =
-        CreateScopedVideoDecoder(external_decoder_factory_, type,
-                                 decoder_params);
-    if (external_decoder) {
-      std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
-          new webrtc::VideoDecoderSoftwareFallbackWrapper(
-              type, std::move(external_decoder)));
-      return internal_decoder;
+WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder
+WebRtcVideoChannel::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder(
+    std::vector<AllocatedDecoder>* old_decoders,
+    const VideoCodec& codec) {
+  webrtc::VideoCodecType type = webrtc::PayloadStringToCodecType(codec.name);
+
+  for (size_t i = 0; i < old_decoders->size(); ++i) {
+    if ((*old_decoders)[i].type == type) {
+      AllocatedDecoder decoder = (*old_decoders)[i];
+      (*old_decoders)[i] = old_decoders->back();
+      old_decoders->pop_back();
+      return decoder;
     }
   }
 
-  std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
-      internal_decoder_factory_->CreateVideoDecoderWithParams(type,
-                                                              decoder_params));
-  return internal_decoder;
+  if (external_decoder_factory_ != NULL) {
+    webrtc::VideoDecoder* decoder =
+        external_decoder_factory_->CreateVideoDecoderWithParams(
+            type, {stream_params_.id});
+    if (decoder != NULL) {
+      return AllocatedDecoder(decoder, type, true /* is_external */);
+    }
+  }
+
+  InternalDecoderFactory internal_decoder_factory;
+  return AllocatedDecoder(internal_decoder_factory.CreateVideoDecoderWithParams(
+                              type, {stream_params_.id}),
+                          type, false /* is_external */);
 }
 
 void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
     const std::vector<VideoCodecSettings>& recv_codecs,
-    std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>*
-        old_decoders) {
-  *old_decoders = std::move(allocated_decoders_);
+    std::vector<AllocatedDecoder>* old_decoders) {
+  *old_decoders = allocated_decoders_;
   allocated_decoders_.clear();
   config_.decoders.clear();
   for (size_t i = 0; i < recv_codecs.size(); ++i) {
-    webrtc::VideoCodecType type =
-        webrtc::PayloadStringToCodecType(recv_codecs[i].codec.name);
-    std::unique_ptr<webrtc::VideoDecoder> new_decoder;
-
-    auto it = old_decoders->find(type);
-    if (it != old_decoders->end()) {
-      new_decoder = std::move(it->second);
-      old_decoders->erase(it);
-    }
-
-    if (!new_decoder) {
-      new_decoder =
-          decoder_factory_->CreateVideoDecoder(type, {stream_params_.id});
-    }
+    AllocatedDecoder allocated_decoder =
+        CreateOrReuseVideoDecoder(old_decoders, recv_codecs[i].codec);
+    allocated_decoders_.push_back(allocated_decoder);
 
     webrtc::VideoReceiveStream::Decoder decoder;
-    decoder.decoder = new_decoder.get();
+    decoder.decoder = allocated_decoder.decoder;
     decoder.payload_type = recv_codecs[i].codec.id;
     decoder.payload_name = recv_codecs[i].codec.name;
     decoder.codec_params = recv_codecs[i].codec.params;
     config_.decoders.push_back(decoder);
-
-    allocated_decoders_.insert(std::make_pair(type, std::move(new_decoder)));
   }
 
   config_.rtp.rtx_associated_payload_types.clear();
@@ -2283,8 +2253,7 @@
     const ChangedRecvParameters& params) {
   bool video_needs_recreation = false;
   bool flexfec_needs_recreation = false;
-  std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>
-      old_decoders;
+  std::vector<AllocatedDecoder> old_decoders;
   if (params.codec_settings) {
     ConfigureCodecs(*params.codec_settings, &old_decoders);
     video_needs_recreation = true;
@@ -2308,6 +2277,7 @@
     LOG(LS_INFO)
         << "RecreateWebRtcVideoStream (recv) because of SetRecvParameters";
     RecreateWebRtcVideoStream();
+    ClearDecoders(&old_decoders);
   }
 }
 
@@ -2352,6 +2322,18 @@
   }
 }
 
+void WebRtcVideoChannel::WebRtcVideoReceiveStream::ClearDecoders(
+    std::vector<AllocatedDecoder>* allocated_decoders) {
+  for (size_t i = 0; i < allocated_decoders->size(); ++i) {
+    if ((*allocated_decoders)[i].external) {
+      external_decoder_factory_->DestroyVideoDecoder(
+          (*allocated_decoders)[i].external_decoder);
+    }
+    delete (*allocated_decoders)[i].decoder;
+  }
+  allocated_decoders->clear();
+}
+
 void WebRtcVideoChannel::WebRtcVideoReceiveStream::OnFrame(
     const webrtc::VideoFrame& frame) {
   rtc::CritScope crit(&sink_lock_);
diff --git a/media/engine/webrtcvideoengine.h b/media/engine/webrtcvideoengine.h
index 8f7a790..3224d00 100644
--- a/media/engine/webrtcvideoengine.h
+++ b/media/engine/webrtcvideoengine.h
@@ -47,7 +47,6 @@
 
 namespace cricket {
 
-class DecoderFactoryAdapter;
 class EncoderFactoryAdapter;
 class VideoCapturer;
 class VideoProcessor;
@@ -122,7 +121,7 @@
  private:
   bool initialized_;
 
-  std::unique_ptr<DecoderFactoryAdapter> decoder_factory_;
+  WebRtcVideoDecoderFactory* external_decoder_factory_;
   std::unique_ptr<EncoderFactoryAdapter> encoder_factory_;
 };
 
@@ -132,7 +131,7 @@
                      const MediaConfig& config,
                      const VideoOptions& options,
                      const EncoderFactoryAdapter& encoder_factory,
-                     const DecoderFactoryAdapter& decoder_factory);
+                     WebRtcVideoDecoderFactory* external_decoder_factory);
   ~WebRtcVideoChannel() override;
 
   // VideoMediaChannel implementation
@@ -370,7 +369,7 @@
         webrtc::Call* call,
         const StreamParams& sp,
         webrtc::VideoReceiveStream::Config config,
-        const DecoderFactoryAdapter& decoder_factory,
+        WebRtcVideoDecoderFactory* external_decoder_factory,
         bool default_stream,
         const std::vector<VideoCodecSettings>& recv_codecs,
         const webrtc::FlexfecReceiveStream::Config& flexfec_config);
@@ -395,17 +394,30 @@
     VideoReceiverInfo GetVideoReceiverInfo(bool log_stats);
 
    private:
+    struct AllocatedDecoder {
+      AllocatedDecoder(webrtc::VideoDecoder* decoder,
+                       webrtc::VideoCodecType type,
+                       bool external);
+      webrtc::VideoDecoder* decoder;
+      // Decoder wrapped into a fallback decoder to permit software fallback.
+      webrtc::VideoDecoder* external_decoder;
+      webrtc::VideoCodecType type;
+      bool external;
+    };
+
     void RecreateWebRtcVideoStream();
     void MaybeRecreateWebRtcFlexfecStream();
 
     void MaybeAssociateFlexfecWithVideo();
     void MaybeDissociateFlexfecFromVideo();
 
-    void ConfigureCodecs(
-        const std::vector<VideoCodecSettings>& recv_codecs,
-        std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>*
-            old_codecs);
+    void ConfigureCodecs(const std::vector<VideoCodecSettings>& recv_codecs,
+                         std::vector<AllocatedDecoder>* old_codecs);
     void ConfigureFlexfecCodec(int flexfec_payload_type);
+    AllocatedDecoder CreateOrReuseVideoDecoder(
+        std::vector<AllocatedDecoder>* old_decoder,
+        const VideoCodec& codec);
+    void ClearDecoders(std::vector<AllocatedDecoder>* allocated_decoders);
 
     std::string GetCodecNameFromPayloadType(int payload_type);
 
@@ -421,9 +433,8 @@
     webrtc::FlexfecReceiveStream::Config flexfec_config_;
     webrtc::FlexfecReceiveStream* flexfec_stream_;
 
-    std::unique_ptr<DecoderFactoryAdapter> decoder_factory_;
-    std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>
-        allocated_decoders_;
+    WebRtcVideoDecoderFactory* const external_decoder_factory_;
+    std::vector<AllocatedDecoder> allocated_decoders_;
 
     rtc::CriticalSection sink_lock_;
     rtc::VideoSinkInterface<webrtc::VideoFrame>* sink_ GUARDED_BY(sink_lock_);
@@ -486,7 +497,7 @@
   rtc::Optional<std::vector<webrtc::RtpExtension>> send_rtp_extensions_;
 
   std::unique_ptr<EncoderFactoryAdapter> encoder_factory_;
-  std::unique_ptr<DecoderFactoryAdapter> decoder_factory_;
+  WebRtcVideoDecoderFactory* const external_decoder_factory_;
   std::vector<VideoCodecSettings> recv_codecs_;
   std::vector<webrtc::RtpExtension> recv_rtp_extensions_;
   // See reason for keeping track of the FlexFEC payload type separately in