Refactor NetEqTestFactory to not use "external" decoders

Bug: webrtc:10080
Change-Id: Icfca98d6d91fc5139e678c1aa3de1e2c35abff5c
Reviewed-on: https://webrtc-review.googlesource.com/c/115240
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26090}
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 6583376..7b50c19 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -1492,6 +1492,7 @@
         "../..:webrtc_common",
         "../../api/audio_codecs:builtin_audio_decoder_factory",
         "../../rtc_base:rtc_base_approved",
+        "../../test:audio_codec_mocks",
         "../../test:test_support",
         "//third_party/abseil-cpp/absl/memory",
       ]
diff --git a/modules/audio_coding/neteq/neteq_decoder_enum.cc b/modules/audio_coding/neteq/neteq_decoder_enum.cc
index e3b633e..27806ef 100644
--- a/modules/audio_coding/neteq/neteq_decoder_enum.cc
+++ b/modules/audio_coding/neteq/neteq_decoder_enum.cc
@@ -77,6 +77,8 @@
       return SdpAudioFormat("cn", 32000, 1);
     case NetEqDecoder::kDecoderCNGswb48kHz:
       return SdpAudioFormat("cn", 48000, 1);
+    case NetEqDecoder::kDecoderReplacementForTest:
+      return SdpAudioFormat("replacement", 48000, 1);
     default:
       return absl::nullopt;
   }
diff --git a/modules/audio_coding/neteq/neteq_decoder_enum.h b/modules/audio_coding/neteq/neteq_decoder_enum.h
index 00629bc..12c970a 100644
--- a/modules/audio_coding/neteq/neteq_decoder_enum.h
+++ b/modules/audio_coding/neteq/neteq_decoder_enum.h
@@ -16,6 +16,7 @@
 
 namespace webrtc {
 
+// TODO(bugs.webrtc.org/10080): Delete, together with RegisterExternalDecoder.
 enum class NetEqDecoder {
   kDecoderPCMu,
   kDecoderPCMa,
@@ -47,6 +48,8 @@
   kDecoderArbitrary,
   kDecoderOpus,
   kDecoderOpus_2ch,
+  // Used in NetEqTestFactory
+  kDecoderReplacementForTest,
 };
 
 absl::optional<SdpAudioFormat> NetEqDecoderToSdpAudioFormat(NetEqDecoder nd);
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.cc b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
index 47c3e47..94e9bb1 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
@@ -38,6 +38,8 @@
 #include "modules/audio_coding/neteq/tools/rtp_file_source.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/flags.h"
+#include "rtc_base/refcountedobject.h"
+#include "test/function_audio_decoder_factory.h"
 #include "test/testsupport/fileutils.h"
 
 namespace webrtc {
@@ -431,12 +433,14 @@
      std::make_pair(NetEqDecoder::kDecoderCNGswb48kHz, "cng-swb48")}
   };
 
+  rtc::scoped_refptr<AudioDecoderFactory> decoder_factory =
+      CreateBuiltinAudioDecoderFactory();
+
   // Check if a replacement audio file was provided.
   if (strlen(FLAG_replacement_audio_file) > 0) {
     // Find largest unused payload type.
     int replacement_pt = 127;
-    while (!(codecs.find(replacement_pt) == codecs.end() &&
-             ext_codecs_.find(replacement_pt) == ext_codecs_.end())) {
+    while (codecs.find(replacement_pt) != codecs.end()) {
       --replacement_pt;
       RTC_CHECK_GE(replacement_pt, 0);
     }
@@ -456,14 +460,23 @@
     input.reset(new NetEqReplacementInput(std::move(input), replacement_pt,
                                           cn_types, forbidden_types));
 
-    replacement_decoder_.reset(new FakeDecodeFromFile(
-        std::unique_ptr<InputAudioFile>(
-            new InputAudioFile(FLAG_replacement_audio_file)),
-        48000, false));
-    NetEqTest::ExternalDecoderInfo ext_dec_info = {
-        replacement_decoder_.get(), NetEqDecoder::kDecoderArbitrary,
-        "replacement codec"};
-    ext_codecs_[replacement_pt] = ext_dec_info;
+    // Note that capture-by-copy implies that the lambda captures the value of
+    // decoder_factory before it's reassigned on the left-hand side.
+    decoder_factory = new rtc::RefCountedObject<FunctionAudioDecoderFactory>(
+        [decoder_factory](const SdpAudioFormat& format,
+                          absl::optional<AudioCodecPairId> codec_pair_id) {
+          std::unique_ptr<AudioDecoder> decoder =
+              decoder_factory->MakeAudioDecoder(format, codec_pair_id);
+          if (!decoder && format.name == "replacement") {
+            decoder = absl::make_unique<FakeDecodeFromFile>(
+                absl::make_unique<InputAudioFile>(FLAG_replacement_audio_file),
+                format.clockrate_hz, format.num_channels > 1);
+          }
+          return decoder;
+        });
+
+    codecs[replacement_pt] = {NetEqDecoder::kDecoderReplacementForTest,
+                              "replacement codec"};
   }
 
   // Create a text log file if needed.
@@ -487,9 +500,10 @@
   config.sample_rate_hz = *sample_rate_hz;
   config.max_packets_in_buffer = FLAG_max_nr_packets_in_buffer;
   config.enable_fast_accelerate = FLAG_enable_fast_accelerate;
+  NetEqTest::ExtDecoderMap ext_codecs;
   return absl::make_unique<NetEqTest>(
-      config, CreateBuiltinAudioDecoderFactory(), codecs, ext_codecs_,
-      std::move(text_log), std::move(input), std::move(output), callbacks);
+      config, decoder_factory, codecs, ext_codecs, std::move(text_log),
+      std::move(input), std::move(output), callbacks);
 }
 
 }  // namespace test
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.h b/modules/audio_coding/neteq/tools/neteq_test_factory.h
index a249186..f853c1d 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.h
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.h
@@ -34,8 +34,6 @@
                                             std::string output_filename);
 
  private:
-  std::unique_ptr<AudioDecoder> replacement_decoder_;
-  NetEqTest::ExtDecoderMap ext_codecs_;
   std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_;
   std::unique_ptr<NetEqStatsPlotter> stats_plotter_;
 };