Updating AsyncAudioProcessing API, part 1.

Add an API to pass AudioFrameProcessor as a unique_ptr.

Bug: webrtc:15111
Change-Id: I4cefa35399c05c6e81c496e0b0387b95809bd8f8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301984
Reviewed-by: Olga Sharonova <olka@webrtc.org>
Reviewed-by: Markus Handell <handellm@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Commit-Queue: Peter Hanspers <peterhanspers@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40187}
diff --git a/api/create_peerconnection_factory.cc b/api/create_peerconnection_factory.cc
index f9cc7ad..b7f9eb7 100644
--- a/api/create_peerconnection_factory.cc
+++ b/api/create_peerconnection_factory.cc
@@ -39,6 +39,7 @@
     rtc::scoped_refptr<AudioMixer> audio_mixer,
     rtc::scoped_refptr<AudioProcessing> audio_processing,
     AudioFrameProcessor* audio_frame_processor,
+    std::unique_ptr<AudioFrameProcessor> owned_audio_frame_processor,
     std::unique_ptr<FieldTrialsView> field_trials) {
   if (!field_trials) {
     field_trials = std::make_unique<webrtc::FieldTrialBasedConfig>();
@@ -64,7 +65,12 @@
   media_dependencies.adm = std::move(default_adm);
   media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory);
   media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory);
-  media_dependencies.audio_frame_processor = audio_frame_processor;
+  if (audio_frame_processor) {
+    media_dependencies.audio_frame_processor = audio_frame_processor;
+  } else if (owned_audio_frame_processor) {
+    media_dependencies.owned_audio_frame_processor =
+        std::move(owned_audio_frame_processor);
+  }
   if (audio_processing) {
     media_dependencies.audio_processing = std::move(audio_processing);
   } else {
@@ -80,4 +86,44 @@
   return CreateModularPeerConnectionFactory(std::move(dependencies));
 }
 
+rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+    rtc::Thread* network_thread,
+    rtc::Thread* worker_thread,
+    rtc::Thread* signaling_thread,
+    rtc::scoped_refptr<AudioDeviceModule> default_adm,
+    rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
+    rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+    std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
+    std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
+    rtc::scoped_refptr<AudioMixer> audio_mixer,
+    rtc::scoped_refptr<AudioProcessing> audio_processing,
+    AudioFrameProcessor* audio_frame_processor) {
+  return CreatePeerConnectionFactory(
+      network_thread, worker_thread, signaling_thread, default_adm,
+      audio_encoder_factory, audio_decoder_factory,
+      std::move(video_encoder_factory), std::move(video_decoder_factory),
+      audio_mixer, audio_processing, audio_frame_processor, nullptr, nullptr);
+}
+
+rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+    rtc::Thread* network_thread,
+    rtc::Thread* worker_thread,
+    rtc::Thread* signaling_thread,
+    rtc::scoped_refptr<AudioDeviceModule> default_adm,
+    rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
+    rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+    std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
+    std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
+    rtc::scoped_refptr<AudioMixer> audio_mixer,
+    rtc::scoped_refptr<AudioProcessing> audio_processing,
+    std::unique_ptr<AudioFrameProcessor> owned_audio_frame_processor,
+    std::unique_ptr<FieldTrialsView> field_trials) {
+  return CreatePeerConnectionFactory(
+      network_thread, worker_thread, signaling_thread, default_adm,
+      audio_encoder_factory, audio_decoder_factory,
+      std::move(video_encoder_factory), std::move(video_decoder_factory),
+      audio_mixer, audio_processing, nullptr,
+      std::move(owned_audio_frame_processor), std::move(field_trials));
+}
+
 }  // namespace webrtc
diff --git a/api/create_peerconnection_factory.h b/api/create_peerconnection_factory.h
index efebc5f..f8f52a0 100644
--- a/api/create_peerconnection_factory.h
+++ b/api/create_peerconnection_factory.h
@@ -37,6 +37,9 @@
 // Create a new instance of PeerConnectionFactoryInterface with optional video
 // codec factories. These video factories represents all video codecs, i.e. no
 // extra internal video codecs will be added.
+// TODO(bugs.webrtc.org/15111):
+//   Remove the method with the raw AudioFrameProcessor pointer in the
+//   follow-up.
 RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
 CreatePeerConnectionFactory(
     rtc::Thread* network_thread,
@@ -49,7 +52,21 @@
     std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
     rtc::scoped_refptr<AudioMixer> audio_mixer,
     rtc::scoped_refptr<AudioProcessing> audio_processing,
-    AudioFrameProcessor* audio_frame_processor = nullptr,
+    AudioFrameProcessor* audio_frame_processor = nullptr);
+
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
+    rtc::Thread* network_thread,
+    rtc::Thread* worker_thread,
+    rtc::Thread* signaling_thread,
+    rtc::scoped_refptr<AudioDeviceModule> default_adm,
+    rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
+    rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+    std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
+    std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
+    rtc::scoped_refptr<AudioMixer> audio_mixer,
+    rtc::scoped_refptr<AudioProcessing> audio_processing,
+    std::unique_ptr<AudioFrameProcessor> owned_audio_frame_processor,
     std::unique_ptr<FieldTrialsView> field_trials = nullptr);
 
 }  // namespace webrtc
diff --git a/media/engine/null_webrtc_video_engine_unittest.cc b/media/engine/null_webrtc_video_engine_unittest.cc
index 9515d44..31c442d 100644
--- a/media/engine/null_webrtc_video_engine_unittest.cc
+++ b/media/engine/null_webrtc_video_engine_unittest.cc
@@ -37,7 +37,7 @@
       task_queue_factory.get(), adm.get(),
       webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
       webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr,
-      webrtc::AudioProcessingBuilder().Create(), nullptr, trials);
+      webrtc::AudioProcessingBuilder().Create(), nullptr, nullptr, trials);
 
   CompositeMediaEngine engine(std::move(audio_engine),
                               std::make_unique<NullWebRtcVideoEngine>());
diff --git a/media/engine/webrtc_media_engine.cc b/media/engine/webrtc_media_engine.cc
index 514e228..99d7dd2 100644
--- a/media/engine/webrtc_media_engine.cc
+++ b/media/engine/webrtc_media_engine.cc
@@ -46,7 +46,8 @@
       std::move(dependencies.audio_decoder_factory),
       std::move(dependencies.audio_mixer),
       std::move(dependencies.audio_processing),
-      dependencies.audio_frame_processor, trials);
+      dependencies.audio_frame_processor,
+      std::move(dependencies.owned_audio_frame_processor), trials);
 #ifdef HAVE_WEBRTC_VIDEO
   auto video_engine = std::make_unique<WebRtcVideoEngine>(
       std::move(dependencies.video_encoder_factory),
diff --git a/media/engine/webrtc_media_engine.h b/media/engine/webrtc_media_engine.h
index e65824b..0f6dce3 100644
--- a/media/engine/webrtc_media_engine.h
+++ b/media/engine/webrtc_media_engine.h
@@ -49,7 +49,10 @@
   rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory;
   rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer;
   rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing;
+  // TODO(bugs.webrtc.org/15111):
+  //   Remove the raw AudioFrameProcessor pointer in the follow-up.
   webrtc::AudioFrameProcessor* audio_frame_processor = nullptr;
+  std::unique_ptr<webrtc::AudioFrameProcessor> owned_audio_frame_processor;
 
   std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory;
   std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory;
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index be1f3a7..a763ddb 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -313,7 +313,10 @@
     const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
     rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
     rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing,
+    // TODO(bugs.webrtc.org/15111):
+    //   Remove the raw AudioFrameProcessor pointer in the follow-up.
     webrtc::AudioFrameProcessor* audio_frame_processor,
+    std::unique_ptr<webrtc::AudioFrameProcessor> owned_audio_frame_processor,
     const webrtc::FieldTrialsView& trials)
     : task_queue_factory_(task_queue_factory),
       adm_(adm),
@@ -322,6 +325,7 @@
       audio_mixer_(audio_mixer),
       apm_(audio_processing),
       audio_frame_processor_(audio_frame_processor),
+      owned_audio_frame_processor_(std::move(owned_audio_frame_processor)),
       minimized_remsampling_on_mobile_trial_enabled_(
           IsEnabled(trials, "WebRTC-Audio-MinimizeResamplingOnMobile")) {
   RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
@@ -387,10 +391,15 @@
     }
     config.audio_processing = apm_;
     config.audio_device_module = adm_;
-    if (audio_frame_processor_)
+    if (audio_frame_processor_) {
       config.async_audio_processing_factory =
           rtc::make_ref_counted<webrtc::AsyncAudioProcessing::Factory>(
               *audio_frame_processor_, *task_queue_factory_);
+    } else if (owned_audio_frame_processor_) {
+      config.async_audio_processing_factory =
+          rtc::make_ref_counted<webrtc::AsyncAudioProcessing::Factory>(
+              std::move(owned_audio_frame_processor_), *task_queue_factory_);
+    }
     audio_state_ = webrtc::AudioState::Create(config);
   }
 
diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h
index 48fb95a..e73c24c 100644
--- a/media/engine/webrtc_voice_engine.h
+++ b/media/engine/webrtc_voice_engine.h
@@ -89,7 +89,10 @@
       const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
       rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
       rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing,
+      // TODO(bugs.webrtc.org/15111):
+      //   Remove the raw AudioFrameProcessor pointer in the follow-up.
       webrtc::AudioFrameProcessor* audio_frame_processor,
+      std::unique_ptr<webrtc::AudioFrameProcessor> owned_audio_frame_processor,
       const webrtc::FieldTrialsView& trials);
 
   WebRtcVoiceEngine() = delete;
@@ -156,7 +159,10 @@
   // The audio processing module.
   rtc::scoped_refptr<webrtc::AudioProcessing> apm_;
   // Asynchronous audio processing.
+  // TODO(bugs.webrtc.org/15111):
+  //   Remove the raw AudioFrameProcessor pointer in the follow-up.
   webrtc::AudioFrameProcessor* const audio_frame_processor_;
+  std::unique_ptr<webrtc::AudioFrameProcessor> owned_audio_frame_processor_;
   // The primary instance of WebRtc VoiceEngine.
   rtc::scoped_refptr<webrtc::AudioState> audio_state_;
   std::vector<AudioCodec> send_codecs_;
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index d151715..e993111 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -167,7 +167,7 @@
           task_queue_factory.get(), adm.get(),
           webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
           webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
-          nullptr, trials);
+          nullptr, nullptr, trials);
       engine.Init();
     }
   }
@@ -213,7 +213,7 @@
     auto decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
     engine_.reset(new cricket::WebRtcVoiceEngine(
         task_queue_factory_.get(), adm_.get(), encoder_factory, decoder_factory,
-        nullptr, apm_, nullptr, field_trials_));
+        nullptr, apm_, nullptr, nullptr, field_trials_));
     engine_->Init();
     send_parameters_.codecs.push_back(kPcmuCodec);
     recv_parameters_.codecs.push_back(kPcmuCodec);
@@ -3641,7 +3641,7 @@
         task_queue_factory.get(), adm.get(),
         webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
         webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
-        nullptr, field_trials);
+        nullptr, nullptr, field_trials);
     engine.Init();
     webrtc::RtcEventLogNull event_log;
     webrtc::Call::Config call_config(&event_log);
@@ -3673,7 +3673,7 @@
           task_queue_factory.get(), adm.get(),
           webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
           webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
-          nullptr, field_trials);
+          nullptr, nullptr, field_trials);
       engine.Init();
       webrtc::RtcEventLogNull event_log;
       webrtc::Call::Config call_config(&event_log);
@@ -3709,7 +3709,7 @@
         task_queue_factory.get(), adm.get(),
         webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
         webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
-        nullptr, field_trials);
+        nullptr, nullptr, field_trials);
     engine.Init();
     for (const cricket::AudioCodec& codec : engine.send_codecs()) {
       auto is_codec = [&codec](const char* name, int clockrate = 0) {
@@ -3759,7 +3759,7 @@
         task_queue_factory.get(), adm.get(),
         webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
         webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, apm,
-        nullptr, field_trials);
+        nullptr, nullptr, field_trials);
     engine.Init();
     webrtc::RtcEventLogNull event_log;
     webrtc::Call::Config call_config(&event_log);
@@ -3810,7 +3810,7 @@
         task_queue_factory.get(), adm.get(),
         webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
         webrtc::CreateBuiltinAudioDecoderFactory(), nullptr, apm, nullptr,
-        field_trials);
+        nullptr, field_trials);
     engine.Init();
     webrtc::RtcEventLogNull event_log;
     webrtc::Call::Config call_config(&event_log);
@@ -3838,7 +3838,8 @@
   cricket::WebRtcVoiceEngine engine(task_queue_factory.get(), adm.get(),
                                     webrtc::CreateBuiltinAudioEncoderFactory(),
                                     webrtc::CreateBuiltinAudioDecoderFactory(),
-                                    nullptr, nullptr, nullptr, field_trials);
+                                    nullptr, nullptr, nullptr, nullptr,
+                                    field_trials);
   engine.Init();
   webrtc::RtcEventLogNull event_log;
   webrtc::Call::Config call_config(&event_log);
@@ -3914,7 +3915,7 @@
     webrtc::FieldTrialBasedConfig field_trials;
     cricket::WebRtcVoiceEngine engine(
         task_queue_factory.get(), adm.get(), unused_encoder_factory,
-        mock_decoder_factory, nullptr, apm, nullptr, field_trials);
+        mock_decoder_factory, nullptr, apm, nullptr, nullptr, field_trials);
     engine.Init();
     auto codecs = engine.recv_codecs();
     EXPECT_EQ(11u, codecs.size());
diff --git a/modules/async_audio_processing/async_audio_processing.cc b/modules/async_audio_processing/async_audio_processing.cc
index 9452f3b..19c08dc 100644
--- a/modules/async_audio_processing/async_audio_processing.cc
+++ b/modules/async_audio_processing/async_audio_processing.cc
@@ -24,16 +24,33 @@
     : frame_processor_(frame_processor),
       task_queue_factory_(task_queue_factory) {}
 
+AsyncAudioProcessing::Factory::Factory(
+    std::unique_ptr<AudioFrameProcessor> frame_processor,
+    TaskQueueFactory& task_queue_factory)
+    : frame_processor_(*frame_processor),
+      owned_frame_processor_(std::move(frame_processor)),
+      task_queue_factory_(task_queue_factory) {}
+
 std::unique_ptr<AsyncAudioProcessing>
 AsyncAudioProcessing::Factory::CreateAsyncAudioProcessing(
     AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback) {
-  return std::make_unique<AsyncAudioProcessing>(
-      frame_processor_, task_queue_factory_,
-      std::move(on_frame_processed_callback));
+  if (owned_frame_processor_) {
+    return std::make_unique<AsyncAudioProcessing>(
+        std::move(owned_frame_processor_), task_queue_factory_,
+        std::move(on_frame_processed_callback));
+  } else {
+    return std::make_unique<AsyncAudioProcessing>(
+        frame_processor_, task_queue_factory_,
+        std::move(on_frame_processed_callback));
+  }
 }
 
 AsyncAudioProcessing::~AsyncAudioProcessing() {
-  frame_processor_.SetSink(nullptr);
+  if (owned_frame_processor_) {
+    owned_frame_processor_->SetSink(nullptr);
+  } else {
+    frame_processor_.SetSink(nullptr);
+  }
 }
 
 AsyncAudioProcessing::AsyncAudioProcessing(
@@ -52,10 +69,33 @@
   });
 }
 
-void AsyncAudioProcessing::Process(std::unique_ptr<AudioFrame> frame) {
-  task_queue_.PostTask([this, frame = std::move(frame)]() mutable {
-    frame_processor_.Process(std::move(frame));
+AsyncAudioProcessing::AsyncAudioProcessing(
+    std::unique_ptr<AudioFrameProcessor> frame_processor,
+    TaskQueueFactory& task_queue_factory,
+    AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback)
+    : on_frame_processed_callback_(std::move(on_frame_processed_callback)),
+      frame_processor_(*frame_processor),
+      owned_frame_processor_(std::move(frame_processor)),
+      task_queue_(task_queue_factory.CreateTaskQueue(
+          "AsyncAudioProcessing",
+          TaskQueueFactory::Priority::NORMAL)) {
+  owned_frame_processor_->SetSink([this](std::unique_ptr<AudioFrame> frame) {
+    task_queue_.PostTask([this, frame = std::move(frame)]() mutable {
+      on_frame_processed_callback_(std::move(frame));
+    });
   });
 }
 
+void AsyncAudioProcessing::Process(std::unique_ptr<AudioFrame> frame) {
+  if (owned_frame_processor_) {
+    task_queue_.PostTask([this, frame = std::move(frame)]() mutable {
+      owned_frame_processor_->Process(std::move(frame));
+    });
+  } else {
+    task_queue_.PostTask([this, frame = std::move(frame)]() mutable {
+      frame_processor_.Process(std::move(frame));
+    });
+  }
+}
+
 }  // namespace webrtc
diff --git a/modules/async_audio_processing/async_audio_processing.h b/modules/async_audio_processing/async_audio_processing.h
index bbd0f69..f3ed969 100644
--- a/modules/async_audio_processing/async_audio_processing.h
+++ b/modules/async_audio_processing/async_audio_processing.h
@@ -38,12 +38,23 @@
     ~Factory();
     Factory(AudioFrameProcessor& frame_processor,
             TaskQueueFactory& task_queue_factory);
+    Factory(std::unique_ptr<AudioFrameProcessor> frame_processor,
+            TaskQueueFactory& task_queue_factory);
 
     std::unique_ptr<AsyncAudioProcessing> CreateAsyncAudioProcessing(
         AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback);
 
    private:
+    // TODO(bugs.webrtc.org/15111):
+    //   Remove 'AudioFrameProcessor& frame_processor_' in favour of
+    //   std::unique_ptr in the follow-up.
+    //   While transitioning this API from using AudioFrameProcessor& to using
+    //   std::unique_ptr<AudioFrameProcessor>, we have two member variable both
+    //   referencing the same object. Throughout the lifetime of the Factory
+    //   only one of the variables is used, depending on which constructor was
+    //   called.
     AudioFrameProcessor& frame_processor_;
+    std::unique_ptr<AudioFrameProcessor> owned_frame_processor_;
     TaskQueueFactory& task_queue_factory_;
   };
 
@@ -57,17 +68,39 @@
   // into `on_frame_processed_callback`, which is posted back onto
   // `task_queue_`. `task_queue_` is created using the provided
   // `task_queue_factory`.
+  // TODO(bugs.webrtc.org/15111):
+  //   Remove this method in favour of the method taking the
+  //   unique_ptr<AudioFrameProcessor> in the follow-up.
   AsyncAudioProcessing(
       AudioFrameProcessor& frame_processor,
       TaskQueueFactory& task_queue_factory,
       AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback);
 
+  // Creates AsyncAudioProcessing which will pass audio frames to
+  // `frame_processor` on `task_queue_` and reply with processed frames passed
+  // into `on_frame_processed_callback`, which is posted back onto
+  // `task_queue_`. `task_queue_` is created using the provided
+  // `task_queue_factory`.
+  AsyncAudioProcessing(
+      std::unique_ptr<AudioFrameProcessor> frame_processor,
+      TaskQueueFactory& task_queue_factory,
+      AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback);
+
   // Accepts `frame` for asynchronous processing. Thread-safe.
   void Process(std::unique_ptr<AudioFrame> frame);
 
  private:
   AudioFrameProcessor::OnAudioFrameCallback on_frame_processed_callback_;
+  // TODO(bugs.webrtc.org/15111):
+  //   Remove 'AudioFrameProcessor& frame_processor_' in favour of
+  //   std::unique_ptr in the follow-up.
+  //   While transitioning this API from using AudioFrameProcessor& to using
+  //   std::unique_ptr<AudioFrameProcessor>, we have two member variable both
+  //   referencing the same object. Throughout the lifetime of the Factory
+  //   only one of the variables is used, depending on which constructor was
+  //   called.
   AudioFrameProcessor& frame_processor_;
+  std::unique_ptr<AudioFrameProcessor> owned_frame_processor_;
   rtc::TaskQueue task_queue_;
 };