Add a Config struct to AcmReceiver, and a ctor using it

This is a prerequisite step to break apart AudioCodingModule and AcmReceiver.

Bug: webrtc:14867
Change-Id: Iba589c7a31b6346ff4acb727793d84077162c8c8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291534
Auto-Submit: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Tomas Lundqvist <tomasl@google.com>
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39235}
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index b078af1..a8fded6 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -48,19 +48,37 @@
 
 }  // namespace
 
-AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config)
+AcmReceiver::Config::Config(
+    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
+    : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) {
+  // Post-decode VAD is disabled by default in NetEq, however, Audio
+  // Conference Mixer relies on VAD decisions and fails without them.
+  neteq_config.enable_post_decode_vad = true;
+}
+
+AcmReceiver::Config::Config(const AudioCodingModule::Config& acm_config)
+    : neteq_config(acm_config.neteq_config),
+      clock(*acm_config.clock),
+      decoder_factory(acm_config.decoder_factory) {}
+
+AcmReceiver::Config::Config(const Config&) = default;
+AcmReceiver::Config::~Config() = default;
+
+AcmReceiver::AcmReceiver(const Config& config)
     : last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
       neteq_(CreateNetEq(config.neteq_factory,
                          config.neteq_config,
-                         config.clock,
+                         &config.clock,
                          config.decoder_factory)),
       clock_(config.clock),
       resampled_last_output_frame_(true) {
-  RTC_DCHECK(clock_);
   memset(last_audio_buffer_.get(), 0,
          sizeof(int16_t) * AudioFrame::kMaxDataSizeSamples);
 }
 
+AcmReceiver::AcmReceiver(const AudioCodingModule::Config& acm_config)
+    : AcmReceiver(Config(acm_config)) {}
+
 AcmReceiver::~AcmReceiver() = default;
 
 int AcmReceiver::SetMinimumDelay(int delay_ms) {
@@ -337,7 +355,7 @@
   // We masked 6 most significant bits of 32-bit so there is no overflow in
   // the conversion from milliseconds to timestamp.
   const uint32_t now_in_ms =
-      static_cast<uint32_t>(clock_->TimeInMilliseconds() & 0x03ffffff);
+      static_cast<uint32_t>(clock_.TimeInMilliseconds() & 0x03ffffff);
   return static_cast<uint32_t>((decoder_sampling_rate / 1000) * now_in_ms);
 }
 
diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h
index 18b662a..25105ec 100644
--- a/modules/audio_coding/acm2/acm_receiver.h
+++ b/modules/audio_coding/acm2/acm_receiver.h
@@ -22,10 +22,14 @@
 #include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/audio_codecs/audio_format.h"
+#include "api/neteq/neteq.h"
+#include "api/neteq/neteq_factory.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/acm2/call_statistics.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
+#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
 #include "rtc_base/synchronization/mutex.h"
 #include "rtc_base/thread_annotations.h"
 
@@ -39,8 +43,24 @@
 
 class AcmReceiver {
  public:
+  struct Config {
+    explicit Config(
+        rtc::scoped_refptr<AudioDecoderFactory> decoder_factory = nullptr);
+    explicit Config(const AudioCodingModule::Config& acm_config);
+    Config(const Config&);
+    ~Config();
+
+    NetEq::Config neteq_config;
+    Clock& clock;
+    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory;
+    NetEqFactory* neteq_factory = nullptr;
+  };
+
   // Constructor of the class
-  explicit AcmReceiver(const AudioCodingModule::Config& config);
+  explicit AcmReceiver(const Config& config);
+  // Deprecated constructor.
+  // TODO(webrtc:14867): Remove when downstream projects are ready.
+  explicit AcmReceiver(const AudioCodingModule::Config& acm_config);
 
   // Destructor of the class.
   ~AcmReceiver();
@@ -219,7 +239,7 @@
   std::unique_ptr<int16_t[]> last_audio_buffer_ RTC_GUARDED_BY(mutex_);
   CallStatistics call_stats_ RTC_GUARDED_BY(mutex_);
   const std::unique_ptr<NetEq> neteq_;  // NetEq is thread-safe; no lock needed.
-  Clock* const clock_;
+  Clock& clock_;
   bool resampled_last_output_frame_ RTC_GUARDED_BY(mutex_);
 };