Several subcomponents inside APM copy render audio from
the render side to the capture side using the same
pattern. Currently this is done independently for the
submodules.

This CL moves the the AECM functionality for this into
APM.

BUG=webrtc:5298, webrtc:6540

Review-Url: https://codereview.webrtc.org/2444793005
Cr-Commit-Position: refs/heads/master@{#14768}
diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc
index 93e43f7..ace788e 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/webrtc/modules/audio_processing/audio_processing_impl.cc
@@ -708,7 +708,6 @@
     // getters that need the capture lock held when being called.
     rtc::CritScope cs_capture(&crit_capture_);
     EmptyQueuedRenderAudio();
-    public_submodules_->echo_control_mobile->ReadQueuedRenderData();
     public_submodules_->gain_control->ReadQueuedRenderData();
 
     if (!src || !dest) {
@@ -770,52 +769,103 @@
 void AudioProcessingImpl::QueueRenderAudio(const AudioBuffer* audio) {
   EchoCancellationImpl::PackRenderAudioBuffer(audio, num_output_channels(),
                                               num_reverse_channels(),
-                                              &render_queue_buffer_);
+                                              &float_render_queue_buffer_);
 
   RTC_DCHECK_GE(160u, audio->num_frames_per_band());
 
   // Insert the samples into the queue.
-  if (!render_signal_queue_->Insert(&render_queue_buffer_)) {
+  if (!float_render_signal_queue_->Insert(&float_render_queue_buffer_)) {
     // The data queue is full and needs to be emptied.
     EmptyQueuedRenderAudio();
 
     // Retry the insert (should always work).
-    bool result = render_signal_queue_->Insert(&render_queue_buffer_);
+    bool result =
+        float_render_signal_queue_->Insert(&float_render_queue_buffer_);
+    RTC_DCHECK(result);
+  }
+
+  EchoControlMobileImpl::PackRenderAudioBuffer(audio, num_output_channels(),
+                                               num_reverse_channels(),
+                                               &int16_render_queue_buffer_);
+
+  // Insert the samples into the queue.
+  if (!int16_render_signal_queue_->Insert(&int16_render_queue_buffer_)) {
+    // The data queue is full and needs to be emptied.
+    EmptyQueuedRenderAudio();
+
+    // Retry the insert (should always work).
+    bool result =
+        int16_render_signal_queue_->Insert(&int16_render_queue_buffer_);
     RTC_DCHECK(result);
   }
 }
 
 void AudioProcessingImpl::AllocateRenderQueue() {
-  const size_t new_render_queue_element_max_size =
+  const size_t new_float_render_queue_element_max_size =
       std::max(static_cast<size_t>(1),
                kMaxAllowedValuesOfSamplesPerFrame *
                    EchoCancellationImpl::NumCancellersRequired(
                        num_output_channels(), num_reverse_channels()));
 
-  // Reallocate the queue if the queue item size is too small to fit the
-  // data to put in the queue.
-  if (render_queue_element_max_size_ < new_render_queue_element_max_size) {
-    render_queue_element_max_size_ = new_render_queue_element_max_size;
+  const size_t new_int16_render_queue_element_max_size =
+      std::max(static_cast<size_t>(1),
+               kMaxAllowedValuesOfSamplesPerFrame *
+                   EchoControlMobileImpl::NumCancellersRequired(
+                       num_output_channels(), num_reverse_channels()));
 
-    std::vector<float> template_queue_element(render_queue_element_max_size_);
+  // Reallocate the queues if the queue item sizes are too small to fit the
+  // data to put in the queues.
+  if (float_render_queue_element_max_size_ <
+      new_float_render_queue_element_max_size) {
+    float_render_queue_element_max_size_ =
+        new_float_render_queue_element_max_size;
 
-    render_signal_queue_.reset(
+    std::vector<float> template_queue_element(
+        float_render_queue_element_max_size_);
+
+    float_render_signal_queue_.reset(
         new SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>(
             kMaxNumFramesToBuffer, template_queue_element,
-            RenderQueueItemVerifier<float>(render_queue_element_max_size_)));
+            RenderQueueItemVerifier<float>(
+                float_render_queue_element_max_size_)));
 
-    render_queue_buffer_.resize(render_queue_element_max_size_);
-    capture_queue_buffer_.resize(render_queue_element_max_size_);
+    float_render_queue_buffer_.resize(float_render_queue_element_max_size_);
+    float_capture_queue_buffer_.resize(float_render_queue_element_max_size_);
   } else {
-    render_signal_queue_->Clear();
+    float_render_signal_queue_->Clear();
+  }
+
+  if (int16_render_queue_element_max_size_ <
+      new_int16_render_queue_element_max_size) {
+    int16_render_queue_element_max_size_ =
+        new_int16_render_queue_element_max_size;
+
+    std::vector<int16_t> template_queue_element(
+        int16_render_queue_element_max_size_);
+
+    int16_render_signal_queue_.reset(
+        new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>(
+            kMaxNumFramesToBuffer, template_queue_element,
+            RenderQueueItemVerifier<int16_t>(
+                int16_render_queue_element_max_size_)));
+
+    int16_render_queue_buffer_.resize(int16_render_queue_element_max_size_);
+    int16_capture_queue_buffer_.resize(int16_render_queue_element_max_size_);
+  } else {
+    int16_render_signal_queue_->Clear();
   }
 }
 
 void AudioProcessingImpl::EmptyQueuedRenderAudio() {
   rtc::CritScope cs_capture(&crit_capture_);
-  while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
+  while (float_render_signal_queue_->Remove(&float_capture_queue_buffer_)) {
     public_submodules_->echo_cancellation->ProcessRenderAudio(
-        capture_queue_buffer_);
+        float_capture_queue_buffer_);
+  }
+
+  while (int16_render_signal_queue_->Remove(&int16_capture_queue_buffer_)) {
+    public_submodules_->echo_control_mobile->ProcessRenderAudio(
+        int16_capture_queue_buffer_);
   }
 }
 
@@ -830,7 +880,6 @@
     // as well.
     rtc::CritScope cs_capture(&crit_capture_);
     EmptyQueuedRenderAudio();
-    public_submodules_->echo_control_mobile->ReadQueuedRenderData();
     public_submodules_->gain_control->ReadQueuedRenderData();
   }
 
@@ -1193,8 +1242,6 @@
 #endif
 
   QueueRenderAudio(render_buffer);
-  RETURN_ON_ERR(public_submodules_->echo_control_mobile->ProcessRenderAudio(
-      render_buffer));
   if (!constants_.use_experimental_agc) {
     RETURN_ON_ERR(
         public_submodules_->gain_control->ProcessRenderAudio(render_buffer));