Avoid AGC2 runtime allocation and activate it on demand

This CL ensures that the AGC2 is created and initialized only when
needed.

Apart from that, the CL also avoids a runtime-reallocation that happens
each time the setting is applied.

Bug: webrtc:5298
Change-Id: Iad9eaa05a3d0baa0788cd11b2aa17ddd8e0c509b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/163987
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30139}
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index ed1715c..8195912 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -372,10 +372,6 @@
         new rtc::RefCountedObject<ResidualEchoDetector>();
   }
 
-  // TODO(alessiob): Move the injected gain controller once injection is
-  // implemented.
-  submodules_.gain_controller2.reset(new GainController2());
-
   // TODO(webrtc:5298): Remove once the use of ExperimentalNs has been
   // deprecated.
 #if !(defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS))
@@ -656,6 +652,9 @@
       config_.gain_controller1.analog_level_maximum !=
           config.gain_controller1.analog_level_maximum;
 
+  const bool agc2_config_changed =
+      config_.gain_controller2.enabled != config.gain_controller2.enabled;
+
   const bool voice_detection_config_changed =
       config_.voice_detection.enabled != config.voice_detection.enabled;
 
@@ -694,9 +693,10 @@
                       << "\nReverting to default parameter set";
     config_.gain_controller2 = AudioProcessing::Config::GainController2();
   }
-  InitializeGainController2();
+  if (agc2_config_changed) {
+    InitializeGainController2();
+  }
   InitializePreAmplifier();
-  submodules_.gain_controller2->ApplyConfig(config_.gain_controller2);
 
   if (config_.level_estimation.enabled && !submodules_.output_level_estimator) {
     submodules_.output_level_estimator = std::make_unique<LevelEstimator>();
@@ -931,7 +931,7 @@
         break;
       }
       case RuntimeSetting::Type::kCaptureFixedPostGain: {
-        if (config_.gain_controller2.enabled) {
+        if (submodules_.gain_controller2) {
           float value;
           setting.GetFloat(&value);
           config_.gain_controller2.fixed_digital.gain_db = value;
@@ -1411,7 +1411,7 @@
     submodules_.capture_analyzer->Analyze(capture_buffer);
   }
 
-  if (config_.gain_controller2.enabled) {
+  if (submodules_.gain_controller2) {
     submodules_.gain_controller2->NotifyAnalogLevel(
         recommended_stream_analog_level());
     submodules_.gain_controller2->Process(capture_buffer);
@@ -1761,7 +1761,7 @@
       config_.high_pass_filter.enabled, !!submodules_.echo_control_mobile,
       config_.residual_echo_detector.enabled,
       !!submodules_.legacy_noise_suppressor || !!submodules_.noise_suppressor,
-      submodules_.gain_control->is_enabled(), config_.gain_controller2.enabled,
+      submodules_.gain_control->is_enabled(), !!submodules_.gain_controller2,
       config_.pre_amplifier.enabled, capture_nonlocked_.echo_controller_enabled,
       config_.voice_detection.enabled, !!submodules_.transient_suppressor);
 }
@@ -1888,7 +1888,16 @@
 
 void AudioProcessingImpl::InitializeGainController2() {
   if (config_.gain_controller2.enabled) {
+    if (!submodules_.gain_controller2) {
+      // TODO(alessiob): Move the injected gain controller once injection is
+      // implemented.
+      submodules_.gain_controller2.reset(new GainController2());
+    }
+
     submodules_.gain_controller2->Initialize(proc_fullband_sample_rate_hz());
+    submodules_.gain_controller2->ApplyConfig(config_.gain_controller2);
+  } else {
+    submodules_.gain_controller2.reset();
   }
 }