Sync to webrtc Tot

Update to commit "Implement data channels over media transport."

https://webrtc.googlesource.com/src/+/175aa2e95c19a1e02786b09602c6f62b3554f1a2

BUG=chromium:906512
TEST=Build and test on nocturne

Change-Id: I963d31a7fe51ce1bb706459bafad3e688278340b
Reviewed-on: https://chromium-review.googlesource.com/1337171
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Hsinyu Chao <hychao@chromium.org>
Reviewed-by: Cheng-Yi Chiang <cychiang@chromium.org>
Reviewed-by: Per Ã…hgren <peah@chromium.org>
diff --git a/api/audio/echo_canceller3_config.cc b/api/audio/echo_canceller3_config.cc
index 036ef9c..29d0b9a 100644
--- a/api/audio/echo_canceller3_config.cc
+++ b/api/audio/echo_canceller3_config.cc
@@ -10,14 +10,16 @@
 #include "api/audio/echo_canceller3_config.h"
 
 #include <algorithm>
+#include <cmath>
 
-#include "rtc_base/logging.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 
 namespace webrtc {
 namespace {
 bool Limit(float* value, float min, float max) {
   float clamped = rtc::SafeClamp(*value, min, max);
+  clamped = std::isfinite(clamped) ? clamped : min;
   bool res = *value == clamped;
   *value = clamped;
   return res;
@@ -45,9 +47,6 @@
 EchoCanceller3Config::Delay::Delay(const EchoCanceller3Config::Delay& e) =
     default;
 
-EchoCanceller3Config::Mask::Mask() = default;
-EchoCanceller3Config::Mask::Mask(const EchoCanceller3Config::Mask& m) = default;
-
 EchoCanceller3Config::EchoModel::EchoModel() = default;
 EchoCanceller3Config::EchoModel::EchoModel(
     const EchoCanceller3Config::EchoModel& e) = default;
@@ -88,180 +87,161 @@
     c->delay.down_sampling_factor = 4;
     res = false;
   }
-
-  if (c->delay.num_filters == 0) {
-    c->delay.num_filters = 1;
-    res = false;
-  }
-  if (c->delay.api_call_jitter_blocks == 0) {
-    c->delay.api_call_jitter_blocks = 1;
-    res = false;
-  }
-
-  if (c->delay.api_call_jitter_blocks == 0) {
-    c->delay.api_call_jitter_blocks = 1;
-    res = false;
-  }
   if (c->delay.delay_headroom_blocks <= 1 &&
       c->delay.hysteresis_limit_1_blocks == 1) {
     c->delay.hysteresis_limit_1_blocks = 0;
     res = false;
   }
-  res = res && Limit(&c->delay.delay_estimate_smoothing, 0.f, 1.f);
-  res = res && Limit(&c->delay.delay_candidate_detection_threshold, 0.f, 1.f);
-  res = res && Limit(&c->delay.delay_selection_thresholds.initial, 1, 250);
-  res = res && Limit(&c->delay.delay_selection_thresholds.converged, 1, 250);
+  res = res & Limit(&c->delay.default_delay, 0, 5000);
+  res = res & Limit(&c->delay.num_filters, 0, 5000);
+  res = res & Limit(&c->delay.api_call_jitter_blocks, 1, 5000);
+  res = res & Limit(&c->delay.min_echo_path_delay_blocks, 0, 5000);
+  res = res & Limit(&c->delay.delay_headroom_blocks, 0, 5000);
+  res = res & Limit(&c->delay.hysteresis_limit_1_blocks, 0, 5000);
+  res = res & Limit(&c->delay.hysteresis_limit_2_blocks, 0, 5000);
+  res = res & Limit(&c->delay.skew_hysteresis_blocks, 0, 5000);
+  res = res & Limit(&c->delay.fixed_capture_delay_samples, 0, 5000);
+  res = res & Limit(&c->delay.delay_estimate_smoothing, 0.f, 1.f);
+  res = res & Limit(&c->delay.delay_candidate_detection_threshold, 0.f, 1.f);
+  res = res & Limit(&c->delay.delay_selection_thresholds.initial, 1, 250);
+  res = res & Limit(&c->delay.delay_selection_thresholds.converged, 1, 250);
 
-  res = res && Limit(&c->filter.main.length_blocks, 1, 50);
-  res = res && Limit(&c->filter.main.leakage_converged, 0.f, 1000.f);
-  res = res && Limit(&c->filter.main.leakage_diverged, 0.f, 1000.f);
-  res = res && Limit(&c->filter.main.error_floor, 0.f, 1000.f);
-  res = res && Limit(&c->filter.main.noise_gate, 0.f, 100000000.f);
+  res = res & Limit(&c->filter.main.length_blocks, 1, 50);
+  res = res & Limit(&c->filter.main.leakage_converged, 0.f, 1000.f);
+  res = res & Limit(&c->filter.main.leakage_diverged, 0.f, 1000.f);
+  res = res & Limit(&c->filter.main.error_floor, 0.f, 1000.f);
+  res = res & Limit(&c->filter.main.error_ceil, 0.f, 100000000.f);
+  res = res & Limit(&c->filter.main.noise_gate, 0.f, 100000000.f);
 
-  res = res && Limit(&c->filter.main_initial.length_blocks, 1, 50);
-  res = res && Limit(&c->filter.main_initial.leakage_converged, 0.f, 1000.f);
-  res = res && Limit(&c->filter.main_initial.leakage_diverged, 0.f, 1000.f);
-  res = res && Limit(&c->filter.main_initial.error_floor, 0.f, 1000.f);
-  res = res && Limit(&c->filter.main_initial.noise_gate, 0.f, 100000000.f);
+  res = res & Limit(&c->filter.main_initial.length_blocks, 1, 50);
+  res = res & Limit(&c->filter.main_initial.leakage_converged, 0.f, 1000.f);
+  res = res & Limit(&c->filter.main_initial.leakage_diverged, 0.f, 1000.f);
+  res = res & Limit(&c->filter.main_initial.error_floor, 0.f, 1000.f);
+  res = res & Limit(&c->filter.main_initial.error_ceil, 0.f, 100000000.f);
+  res = res & Limit(&c->filter.main_initial.noise_gate, 0.f, 100000000.f);
 
   if (c->filter.main.length_blocks < c->filter.main_initial.length_blocks) {
     c->filter.main_initial.length_blocks = c->filter.main.length_blocks;
     res = false;
   }
 
-  res = res && Limit(&c->filter.shadow.length_blocks, 1, 50);
-  res = res && Limit(&c->filter.shadow.rate, 0.f, 1.f);
-  res = res && Limit(&c->filter.shadow.noise_gate, 0.f, 100000000.f);
+  res = res & Limit(&c->filter.shadow.length_blocks, 1, 50);
+  res = res & Limit(&c->filter.shadow.rate, 0.f, 1.f);
+  res = res & Limit(&c->filter.shadow.noise_gate, 0.f, 100000000.f);
 
-  res = res && Limit(&c->filter.shadow_initial.length_blocks, 1, 50);
-  res = res && Limit(&c->filter.shadow_initial.rate, 0.f, 1.f);
-  res = res && Limit(&c->filter.shadow_initial.noise_gate, 0.f, 100000000.f);
+  res = res & Limit(&c->filter.shadow_initial.length_blocks, 1, 50);
+  res = res & Limit(&c->filter.shadow_initial.rate, 0.f, 1.f);
+  res = res & Limit(&c->filter.shadow_initial.noise_gate, 0.f, 100000000.f);
 
   if (c->filter.shadow.length_blocks < c->filter.shadow_initial.length_blocks) {
     c->filter.shadow_initial.length_blocks = c->filter.shadow.length_blocks;
     res = false;
   }
 
-  res = res && Limit(&c->filter.config_change_duration_blocks, 0, 100000);
-  res = res && Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
+  res = res & Limit(&c->filter.config_change_duration_blocks, 0, 100000);
+  res = res & Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
 
-  res = res && Limit(&c->erle.min, 1.f, 100000.f);
-  res = res && Limit(&c->erle.max_l, 1.f, 100000.f);
-  res = res && Limit(&c->erle.max_h, 1.f, 100000.f);
+  res = res & Limit(&c->erle.min, 1.f, 100000.f);
+  res = res & Limit(&c->erle.max_l, 1.f, 100000.f);
+  res = res & Limit(&c->erle.max_h, 1.f, 100000.f);
   if (c->erle.min > c->erle.max_l || c->erle.min > c->erle.max_h) {
     c->erle.min = std::min(c->erle.max_l, c->erle.max_h);
     res = false;
   }
 
-  res = res && Limit(&c->ep_strength.lf, 0.f, 1000000.f);
-  res = res && Limit(&c->ep_strength.mf, 0.f, 1000000.f);
-  res = res && Limit(&c->ep_strength.hf, 0.f, 1000000.f);
-  res = res && Limit(&c->ep_strength.default_len, 0.f, 1.f);
-
-  res = res && Limit(&c->gain_mask.m0, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m1, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m2, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m3, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m5, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m6, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m7, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m8, 0.f, 1.f);
-  res = res && Limit(&c->gain_mask.m9, 0.f, 1.f);
-
-  res = res && Limit(&c->gain_mask.gain_curve_offset, 0.f, 1000.f);
-  res = res && Limit(&c->gain_mask.gain_curve_slope, 0.f, 1000.f);
-  res = res && Limit(&c->gain_mask.temporal_masking_lf, 0.f, 1000.f);
-  res = res && Limit(&c->gain_mask.temporal_masking_hf, 0.f, 1000.f);
-  res = res && Limit(&c->gain_mask.temporal_masking_lf_bands, 0, 65);
-
-  res = res &&
-        Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
-  res = res &&
-        Limit(&c->echo_audibility.normal_render_limit, 0.f, 32768.f * 32768.f);
-  res = res && Limit(&c->echo_audibility.floor_power, 0.f, 32768.f * 32768.f);
-  res = res && Limit(&c->echo_audibility.audibility_threshold_lf, 0.f,
-                     32768.f * 32768.f);
-  res = res && Limit(&c->echo_audibility.audibility_threshold_mf, 0.f,
-                     32768.f * 32768.f);
-  res = res && Limit(&c->echo_audibility.audibility_threshold_hf, 0.f,
-                     32768.f * 32768.f);
-
-  res = res &&
-        Limit(&c->render_levels.active_render_limit, 0.f, 32768.f * 32768.f);
-  res = res && Limit(&c->render_levels.poor_excitation_render_limit, 0.f,
-                     32768.f * 32768.f);
-  res = res && Limit(&c->render_levels.poor_excitation_render_limit_ds8, 0.f,
-                     32768.f * 32768.f);
+  res = res & Limit(&c->ep_strength.lf, 0.f, 1000000.f);
+  res = res & Limit(&c->ep_strength.mf, 0.f, 1000000.f);
+  res = res & Limit(&c->ep_strength.hf, 0.f, 1000000.f);
+  res = res & Limit(&c->ep_strength.default_len, 0.f, 1.f);
 
   res =
-      res && Limit(&c->echo_removal_control.gain_rampup.initial_gain, 0.f, 1.f);
-  res = res && Limit(&c->echo_removal_control.gain_rampup.first_non_zero_gain,
-                     0.f, 1.f);
-  res = res && Limit(&c->echo_removal_control.gain_rampup.non_zero_gain_blocks,
-                     0, 100000);
-  res = res &&
+      res & Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
+  res = res &
+        Limit(&c->echo_audibility.normal_render_limit, 0.f, 32768.f * 32768.f);
+  res = res & Limit(&c->echo_audibility.floor_power, 0.f, 32768.f * 32768.f);
+  res = res & Limit(&c->echo_audibility.audibility_threshold_lf, 0.f,
+                    32768.f * 32768.f);
+  res = res & Limit(&c->echo_audibility.audibility_threshold_mf, 0.f,
+                    32768.f * 32768.f);
+  res = res & Limit(&c->echo_audibility.audibility_threshold_hf, 0.f,
+                    32768.f * 32768.f);
+
+  res = res &
+        Limit(&c->render_levels.active_render_limit, 0.f, 32768.f * 32768.f);
+  res = res & Limit(&c->render_levels.poor_excitation_render_limit, 0.f,
+                    32768.f * 32768.f);
+  res = res & Limit(&c->render_levels.poor_excitation_render_limit_ds8, 0.f,
+                    32768.f * 32768.f);
+
+  res =
+      res & Limit(&c->echo_removal_control.gain_rampup.initial_gain, 0.f, 1.f);
+  res = res & Limit(&c->echo_removal_control.gain_rampup.first_non_zero_gain,
+                    0.f, 1.f);
+  res = res & Limit(&c->echo_removal_control.gain_rampup.non_zero_gain_blocks,
+                    0, 100000);
+  res = res &
         Limit(&c->echo_removal_control.gain_rampup.full_gain_blocks, 0, 100000);
 
-  res = res && Limit(&c->echo_model.noise_floor_hold, 0, 1000);
-  res = res && Limit(&c->echo_model.min_noise_floor_power, 0, 2000000.f);
-  res = res && Limit(&c->echo_model.stationary_gate_slope, 0, 1000000.f);
-  res = res && Limit(&c->echo_model.noise_gate_power, 0, 1000000.f);
-  res = res && Limit(&c->echo_model.noise_gate_slope, 0, 1000000.f);
-  res = res && Limit(&c->echo_model.render_pre_window_size, 0, 100);
-  res = res && Limit(&c->echo_model.render_post_window_size, 0, 100);
-  res = res && Limit(&c->echo_model.render_pre_window_size_init, 0, 100);
-  res = res && Limit(&c->echo_model.render_post_window_size_init, 0, 100);
-  res = res && Limit(&c->echo_model.nonlinear_hold, 0, 100);
-  res = res && Limit(&c->echo_model.nonlinear_release, 0, 1.f);
+  res = res & Limit(&c->echo_model.noise_floor_hold, 0, 1000);
+  res = res & Limit(&c->echo_model.min_noise_floor_power, 0, 2000000.f);
+  res = res & Limit(&c->echo_model.stationary_gate_slope, 0, 1000000.f);
+  res = res & Limit(&c->echo_model.noise_gate_power, 0, 1000000.f);
+  res = res & Limit(&c->echo_model.noise_gate_slope, 0, 1000000.f);
+  res = res & Limit(&c->echo_model.render_pre_window_size, 0, 100);
+  res = res & Limit(&c->echo_model.render_post_window_size, 0, 100);
+  res = res & Limit(&c->echo_model.render_pre_window_size_init, 0, 100);
+  res = res & Limit(&c->echo_model.render_post_window_size_init, 0, 100);
+  res = res & Limit(&c->echo_model.nonlinear_hold, 0, 100);
+  res = res & Limit(&c->echo_model.nonlinear_release, 0, 1.f);
 
-  res = res &&
+  res = res & Limit(&c->suppressor.nearend_average_blocks, 1, 5000);
+
+  res = res &
         Limit(&c->suppressor.normal_tuning.mask_lf.enr_transparent, 0.f, 100.f);
-  res = res &&
+  res = res &
         Limit(&c->suppressor.normal_tuning.mask_lf.enr_suppress, 0.f, 100.f);
-  res = res &&
+  res = res &
         Limit(&c->suppressor.normal_tuning.mask_lf.emr_transparent, 0.f, 100.f);
-  res = res &&
+  res = res &
         Limit(&c->suppressor.normal_tuning.mask_hf.enr_transparent, 0.f, 100.f);
-  res = res &&
+  res = res &
         Limit(&c->suppressor.normal_tuning.mask_hf.enr_suppress, 0.f, 100.f);
-  res = res &&
+  res = res &
         Limit(&c->suppressor.normal_tuning.mask_hf.emr_transparent, 0.f, 100.f);
-  res = res && Limit(&c->suppressor.normal_tuning.max_inc_factor, 0.f, 100.f);
-  res =
-      res && Limit(&c->suppressor.normal_tuning.max_dec_factor_lf, 0.f, 100.f);
+  res = res & Limit(&c->suppressor.normal_tuning.max_inc_factor, 0.f, 100.f);
+  res = res & Limit(&c->suppressor.normal_tuning.max_dec_factor_lf, 0.f, 100.f);
 
-  res = res && Limit(&c->suppressor.nearend_tuning.mask_lf.enr_transparent, 0.f,
-                     100.f);
-  res = res &&
+  res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.enr_transparent, 0.f,
+                    100.f);
+  res = res &
         Limit(&c->suppressor.nearend_tuning.mask_lf.enr_suppress, 0.f, 100.f);
-  res = res && Limit(&c->suppressor.nearend_tuning.mask_lf.emr_transparent, 0.f,
-                     100.f);
-  res = res && Limit(&c->suppressor.nearend_tuning.mask_hf.enr_transparent, 0.f,
-                     100.f);
-  res = res &&
+  res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.emr_transparent, 0.f,
+                    100.f);
+  res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.enr_transparent, 0.f,
+                    100.f);
+  res = res &
         Limit(&c->suppressor.nearend_tuning.mask_hf.enr_suppress, 0.f, 100.f);
-  res = res && Limit(&c->suppressor.nearend_tuning.mask_hf.emr_transparent, 0.f,
-                     100.f);
-  res = res && Limit(&c->suppressor.nearend_tuning.max_inc_factor, 0.f, 100.f);
+  res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.emr_transparent, 0.f,
+                    100.f);
+  res = res & Limit(&c->suppressor.nearend_tuning.max_inc_factor, 0.f, 100.f);
   res =
-      res && Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
+      res & Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
 
-  res = res && Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
-                     0.f, 1000000.f);
-  res = res && Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,
-                     0.f, 1000000.f);
-  res = res && Limit(&c->suppressor.dominant_nearend_detection.hold_duration, 0,
-                     10000);
-  res =
-      res && Limit(&c->suppressor.dominant_nearend_detection.trigger_threshold,
-                   0, 10000);
+  res = res & Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
+                    0.f, 1000000.f);
+  res = res & Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,
+                    0.f, 1000000.f);
+  res = res & Limit(&c->suppressor.dominant_nearend_detection.hold_duration, 0,
+                    10000);
+  res = res & Limit(&c->suppressor.dominant_nearend_detection.trigger_threshold,
+                    0, 10000);
 
-  res = res && Limit(&c->suppressor.high_bands_suppression.enr_threshold, 0.f,
-                     1000000.f);
-  res = res && Limit(&c->suppressor.high_bands_suppression.max_gain_during_echo,
-                     0.f, 1.f);
+  res = res & Limit(&c->suppressor.high_bands_suppression.enr_threshold, 0.f,
+                    1000000.f);
+  res = res & Limit(&c->suppressor.high_bands_suppression.max_gain_during_echo,
+                    0.f, 1.f);
 
-  res = res && Limit(&c->suppressor.floor_first_increase, 0.f, 1000000.f);
+  res = res & Limit(&c->suppressor.floor_first_increase, 0.f, 1000000.f);
 
   return res;
 }
diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h
index 59a84ba..251f282 100644
--- a/api/audio/echo_canceller3_config.h
+++ b/api/audio/echo_canceller3_config.h
@@ -19,7 +19,7 @@
 
 // Configuration struct for EchoCanceller3
 struct RTC_EXPORT EchoCanceller3Config {
-  // Checks and updates the parameters in a config to lie within reasonable
+  // Checks and updates the config parameters to lie within (mostly) reasonable
   // ranges. Returns true if and only of the config did not need to be changed.
   static bool Validate(EchoCanceller3Config* config);
 
@@ -99,26 +99,6 @@
     bool bounded_erl = false;
   } ep_strength;
 
-  struct Mask {
-    Mask();
-    Mask(const Mask& m);
-    float m0 = 0.1f;
-    float m1 = 0.01f;
-    float m2 = 0.0001f;
-    float m3 = 0.01f;
-    float m5 = 0.01f;
-    float m6 = 0.0001f;
-    float m7 = 0.01f;
-    float m8 = 0.0001f;
-    float m9 = 0.1f;
-
-    float gain_curve_offset = 1.45f;
-    float gain_curve_slope = 5.f;
-    float temporal_masking_lf = 0.9f;
-    float temporal_masking_hf = 0.6f;
-    size_t temporal_masking_lf_bands = 3;
-  } gain_mask;
-
   struct EchoAudibility {
     float low_render_limit = 4 * 64.f;
     float normal_render_limit = 64.f;
@@ -126,8 +106,8 @@
     float audibility_threshold_lf = 10;
     float audibility_threshold_mf = 10;
     float audibility_threshold_hf = 10;
-    bool use_stationary_properties = false;
-    bool use_stationarity_properties_at_init = false;
+    bool use_stationary_properties = true;
+    bool use_stationarity_properties_at_init = true;
   } echo_audibility;
 
   struct RenderLevels {
diff --git a/api/audio/echo_canceller3_config_json.cc b/api/audio/echo_canceller3_config_json.cc
index a27f20c..d039c8b 100644
--- a/api/audio/echo_canceller3_config_json.cc
+++ b/api/audio/echo_canceller3_config_json.cc
@@ -30,6 +30,7 @@
   RTC_DCHECK(param);
   int v;
   if (rtc::GetIntFromJsonObject(root, param_name, &v)) {
+    RTC_DCHECK_GE(v, 0);
     *param = v;
   }
 }
@@ -108,21 +109,29 @@
 }
 }  // namespace
 
-EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string) {
-  EchoCanceller3Config cfg;
+void Aec3ConfigFromJsonString(absl::string_view json_string,
+                              EchoCanceller3Config* config,
+                              bool* parsing_successful) {
+  RTC_DCHECK(config);
+  RTC_DCHECK(parsing_successful);
+  EchoCanceller3Config& cfg = *config;
+  cfg = EchoCanceller3Config();
+  *parsing_successful = true;
 
   Json::Value root;
   bool success = Json::Reader().parse(std::string(json_string), root);
   if (!success) {
     RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << json_string;
-    return EchoCanceller3Config();
+    *parsing_successful = false;
+    return;
   }
 
   Json::Value aec3_root;
   success = rtc::GetValueFromJsonObject(root, "aec3", &aec3_root);
   if (!success) {
     RTC_LOG(LS_ERROR) << "Missing AEC3 config field: " << json_string;
-    return EchoCanceller3Config();
+    *parsing_successful = false;
+    return;
   }
 
   Json::Value section;
@@ -201,26 +210,6 @@
     ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl);
   }
 
-  if (rtc::GetValueFromJsonObject(aec3_root, "gain_mask", &section)) {
-    ReadParam(section, "m1", &cfg.gain_mask.m1);
-    ReadParam(section, "m2", &cfg.gain_mask.m2);
-    ReadParam(section, "m3", &cfg.gain_mask.m3);
-    ReadParam(section, "m5", &cfg.gain_mask.m5);
-    ReadParam(section, "m6", &cfg.gain_mask.m6);
-    ReadParam(section, "m7", &cfg.gain_mask.m7);
-    ReadParam(section, "m8", &cfg.gain_mask.m8);
-    ReadParam(section, "m9", &cfg.gain_mask.m9);
-
-    ReadParam(section, "gain_curve_offset", &cfg.gain_mask.gain_curve_offset);
-    ReadParam(section, "gain_curve_slope", &cfg.gain_mask.gain_curve_slope);
-    ReadParam(section, "temporal_masking_lf",
-              &cfg.gain_mask.temporal_masking_lf);
-    ReadParam(section, "temporal_masking_hf",
-              &cfg.gain_mask.temporal_masking_hf);
-    ReadParam(section, "temporal_masking_lf_bands",
-              &cfg.gain_mask.temporal_masking_lf_bands);
-  }
-
   if (rtc::GetValueFromJsonObject(aec3_root, "echo_audibility", &section)) {
     ReadParam(section, "low_render_limit",
               &cfg.echo_audibility.low_render_limit);
@@ -236,10 +225,19 @@
               &cfg.echo_audibility.audibility_threshold_hf);
     ReadParam(section, "use_stationary_properties",
               &cfg.echo_audibility.use_stationary_properties);
-    ReadParam(section, "use_stationary_properties_at_init",
+    ReadParam(section, "use_stationarity_properties_at_init",
               &cfg.echo_audibility.use_stationarity_properties_at_init);
   }
 
+  if (rtc::GetValueFromJsonObject(aec3_root, "render_levels", &section)) {
+    ReadParam(section, "active_render_limit",
+              &cfg.render_levels.active_render_limit);
+    ReadParam(section, "poor_excitation_render_limit",
+              &cfg.render_levels.poor_excitation_render_limit);
+    ReadParam(section, "poor_excitation_render_limit_ds8",
+              &cfg.render_levels.poor_excitation_render_limit_ds8);
+  }
+
   if (rtc::GetValueFromJsonObject(aec3_root, "echo_removal_control",
                                   &section)) {
     Json::Value subsection;
@@ -315,6 +313,9 @@
                 &cfg.suppressor.dominant_nearend_detection.hold_duration);
       ReadParam(subsection, "trigger_threshold",
                 &cfg.suppressor.dominant_nearend_detection.trigger_threshold);
+      ReadParam(
+          subsection, "use_during_initial_phase",
+          &cfg.suppressor.dominant_nearend_detection.use_during_initial_phase);
     }
 
     if (rtc::GetValueFromJsonObject(section, "high_bands_suppression",
@@ -332,6 +333,12 @@
     ReadParam(section, "enforce_empty_higher_bands",
               &cfg.suppressor.enforce_empty_higher_bands);
   }
+}
+
+EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string) {
+  EchoCanceller3Config cfg;
+  bool not_used;
+  Aec3ConfigFromJsonString(json_string, &cfg, &not_used);
   return cfg;
 }
 
@@ -435,26 +442,6 @@
 
   ost << "},";
 
-  ost << "\"gain_mask\": {";
-  ost << "\"m0\": " << config.gain_mask.m0 << ",";
-  ost << "\"m1\": " << config.gain_mask.m1 << ",";
-  ost << "\"m2\": " << config.gain_mask.m2 << ",";
-  ost << "\"m3\": " << config.gain_mask.m3 << ",";
-  ost << "\"m5\": " << config.gain_mask.m5 << ",";
-  ost << "\"m6\": " << config.gain_mask.m6 << ",";
-  ost << "\"m7\": " << config.gain_mask.m7 << ",";
-  ost << "\"m8\": " << config.gain_mask.m8 << ",";
-  ost << "\"m9\": " << config.gain_mask.m9 << ",";
-  ost << "\"gain_curve_offset\": " << config.gain_mask.gain_curve_offset << ",";
-  ost << "\"gain_curve_slope\": " << config.gain_mask.gain_curve_slope << ",";
-  ost << "\"temporal_masking_lf\": " << config.gain_mask.temporal_masking_lf
-      << ",";
-  ost << "\"temporal_masking_hf\": " << config.gain_mask.temporal_masking_hf
-      << ",";
-  ost << "\"temporal_masking_lf_bands\": "
-      << config.gain_mask.temporal_masking_lf_bands;
-  ost << "},";
-
   ost << "\"echo_audibility\": {";
   ost << "\"low_render_limit\": " << config.echo_audibility.low_render_limit
       << ",";
@@ -569,7 +556,9 @@
   ost << "\"hold_duration\": "
       << config.suppressor.dominant_nearend_detection.hold_duration << ",";
   ost << "\"trigger_threshold\": "
-      << config.suppressor.dominant_nearend_detection.trigger_threshold;
+      << config.suppressor.dominant_nearend_detection.trigger_threshold << ",";
+  ost << "\"use_during_initial_phase\": "
+      << config.suppressor.dominant_nearend_detection.use_during_initial_phase;
   ost << "},";
   ost << "\"high_bands_suppression\": {";
   ost << "\"enr_threshold\": "
diff --git a/api/audio/echo_canceller3_config_json.h b/api/audio/echo_canceller3_config_json.h
index b315bf0..8973650 100644
--- a/api/audio/echo_canceller3_config_json.h
+++ b/api/audio/echo_canceller3_config_json.h
@@ -15,13 +15,25 @@
 
 #include "absl/strings/string_view.h"
 #include "api/audio/echo_canceller3_config.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 // Parses a JSON-encoded string into an Aec3 config. Fields corresponds to
 // substruct names, with the addition that there must be a top-level node
+// "aec3". Produces default config values for anything that cannot be parsed
+// from the string. If any error was found in the parsing, parsing_successful is
+// set to false.
+RTC_EXPORT void Aec3ConfigFromJsonString(absl::string_view json_string,
+                                         EchoCanceller3Config* config,
+                                         bool* parsing_successful);
+
+// To be deprecated.
+// Parses a JSON-encoded string into an Aec3 config. Fields corresponds to
+// substruct names, with the addition that there must be a top-level node
 // "aec3". Returns default config values for anything that cannot be parsed from
 // the string.
-EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string);
+RTC_EXPORT EchoCanceller3Config
+Aec3ConfigFromJsonString(absl::string_view json_string);
 
 // Encodes an Aec3 config in JSON format. Fields corresponds to substruct names,
 // with the addition that the top-level node is named "aec3".
diff --git a/api/audio_options.cc b/api/audio_options.cc
index a4a37d2..d464118 100644
--- a/api/audio_options.cc
+++ b/api/audio_options.cc
@@ -50,7 +50,6 @@
   SetFrom(&audio_jitter_buffer_fast_accelerate,
           change.audio_jitter_buffer_fast_accelerate);
   SetFrom(&typing_detection, change.typing_detection);
-  SetFrom(&aecm_generate_comfort_noise, change.aecm_generate_comfort_noise);
   SetFrom(&experimental_agc, change.experimental_agc);
   SetFrom(&extended_filter_aec, change.extended_filter_aec);
   SetFrom(&delay_agnostic_aec, change.delay_agnostic_aec);
@@ -78,7 +77,6 @@
          audio_jitter_buffer_fast_accelerate ==
              o.audio_jitter_buffer_fast_accelerate &&
          typing_detection == o.typing_detection &&
-         aecm_generate_comfort_noise == o.aecm_generate_comfort_noise &&
          experimental_agc == o.experimental_agc &&
          extended_filter_aec == o.extended_filter_aec &&
          delay_agnostic_aec == o.delay_agnostic_aec &&
@@ -110,7 +108,6 @@
   ToStringIfSet(&result, "audio_jitter_buffer_fast_accelerate",
                 audio_jitter_buffer_fast_accelerate);
   ToStringIfSet(&result, "typing", typing_detection);
-  ToStringIfSet(&result, "comfort_noise", aecm_generate_comfort_noise);
   ToStringIfSet(&result, "experimental_agc", experimental_agc);
   ToStringIfSet(&result, "extended_filter_aec", extended_filter_aec);
   ToStringIfSet(&result, "delay_agnostic_aec", delay_agnostic_aec);
diff --git a/api/audio_options.h b/api/audio_options.h
index aecff41..8ae8319 100644
--- a/api/audio_options.h
+++ b/api/audio_options.h
@@ -11,6 +11,7 @@
 #ifndef API_AUDIO_OPTIONS_H_
 #define API_AUDIO_OPTIONS_H_
 
+#include <stdint.h>
 #include <string>
 
 #include "absl/types/optional.h"
@@ -55,7 +56,6 @@
   absl::optional<bool> audio_jitter_buffer_fast_accelerate;
   // Audio processing to detect typing.
   absl::optional<bool> typing_detection;
-  absl::optional<bool> aecm_generate_comfort_noise;
   absl::optional<bool> experimental_agc;
   absl::optional<bool> extended_filter_aec;
   absl::optional<bool> delay_agnostic_aec;
diff --git a/api/candidate.cc b/api/candidate.cc
index 10751ae..275b173 100644
--- a/api/candidate.cc
+++ b/api/candidate.cc
@@ -11,6 +11,7 @@
 #include "api/candidate.h"
 
 #include "rtc_base/helpers.h"
+#include "rtc_base/ipaddress.h"
 #include "rtc_base/strings/string_builder.h"
 
 namespace cricket {
diff --git a/api/candidate.h b/api/candidate.h
index 0a84591..4c650d9 100644
--- a/api/candidate.h
+++ b/api/candidate.h
@@ -20,13 +20,14 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/network_constants.h"
 #include "rtc_base/socketaddress.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace cricket {
 
 // Candidate for ICE based connection discovery.
 // TODO(phoglund): remove things in here that are not needed in the public API.
 
-class Candidate {
+class RTC_EXPORT Candidate {
  public:
   Candidate();
   // TODO(pthatcher): Match the ordering and param list as per RFC 5245
diff --git a/api/cryptoparams.h b/api/cryptoparams.h
index 2350528..abe9055 100644
--- a/api/cryptoparams.h
+++ b/api/cryptoparams.h
@@ -16,6 +16,8 @@
 namespace cricket {
 
 // Parameters for SRTP negotiation, as described in RFC 4568.
+// TODO(benwright) - Rename to SrtpCryptoParams as these only apply to SRTP and
+// not generic crypto parameters for WebRTC.
 struct CryptoParams {
   CryptoParams() : tag(0) {}
   CryptoParams(int t,
diff --git a/api/datachannelinterface.h b/api/datachannelinterface.h
index a0d2b3b..7cb5582 100644
--- a/api/datachannelinterface.h
+++ b/api/datachannelinterface.h
@@ -14,6 +14,8 @@
 #ifndef API_DATACHANNELINTERFACE_H_
 #define API_DATACHANNELINTERFACE_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <string>
 
 #include "rtc_base/checks.h"
diff --git a/api/jsep.cc b/api/jsep.cc
index 52a60f9..01f5720 100644
--- a/api/jsep.cc
+++ b/api/jsep.cc
@@ -38,4 +38,32 @@
   OnFailure(RTCError(RTCErrorType::INTERNAL_ERROR, std::string(error)));
 }
 
+const char SessionDescriptionInterface::kOffer[] = "offer";
+const char SessionDescriptionInterface::kPrAnswer[] = "pranswer";
+const char SessionDescriptionInterface::kAnswer[] = "answer";
+
+const char* SdpTypeToString(SdpType type) {
+  switch (type) {
+    case SdpType::kOffer:
+      return SessionDescriptionInterface::kOffer;
+    case SdpType::kPrAnswer:
+      return SessionDescriptionInterface::kPrAnswer;
+    case SdpType::kAnswer:
+      return SessionDescriptionInterface::kAnswer;
+  }
+  return "";
+}
+
+absl::optional<SdpType> SdpTypeFromString(const std::string& type_str) {
+  if (type_str == SessionDescriptionInterface::kOffer) {
+    return SdpType::kOffer;
+  } else if (type_str == SessionDescriptionInterface::kPrAnswer) {
+    return SdpType::kPrAnswer;
+  } else if (type_str == SessionDescriptionInterface::kAnswer) {
+    return SdpType::kAnswer;
+  } else {
+    return absl::nullopt;
+  }
+}
+
 }  // namespace webrtc
diff --git a/api/jsep.h b/api/jsep.h
index 4d4bcc0..1c50455 100644
--- a/api/jsep.h
+++ b/api/jsep.h
@@ -29,6 +29,7 @@
 #include "absl/types/optional.h"
 #include "api/rtcerror.h"
 #include "rtc_base/refcount.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace cricket {
 class Candidate;
@@ -73,13 +74,13 @@
 // Creates a IceCandidateInterface based on SDP string.
 // Returns null if the sdp string can't be parsed.
 // |error| may be null.
-IceCandidateInterface* CreateIceCandidate(const std::string& sdp_mid,
-                                          int sdp_mline_index,
-                                          const std::string& sdp,
-                                          SdpParseError* error);
+RTC_EXPORT IceCandidateInterface* CreateIceCandidate(const std::string& sdp_mid,
+                                                     int sdp_mline_index,
+                                                     const std::string& sdp,
+                                                     SdpParseError* error);
 
 // Creates an IceCandidateInterface based on a parsed candidate structure.
-std::unique_ptr<IceCandidateInterface> CreateIceCandidate(
+RTC_EXPORT std::unique_ptr<IceCandidateInterface> CreateIceCandidate(
     const std::string& sdp_mid,
     int sdp_mline_index,
     const cricket::Candidate& candidate);
@@ -121,7 +122,7 @@
 // and is therefore not expected to be thread safe.
 //
 // An instance can be created by CreateSessionDescription.
-class SessionDescriptionInterface {
+class RTC_EXPORT SessionDescriptionInterface {
  public:
   // String representations of the supported SDP types.
   static const char kOffer[];
@@ -181,21 +182,21 @@
 // |error| may be null.
 // TODO(steveanton): This function is deprecated. Please use the functions below
 // which take an SdpType enum instead. Remove this once it is no longer used.
-SessionDescriptionInterface* CreateSessionDescription(const std::string& type,
-                                                      const std::string& sdp,
-                                                      SdpParseError* error);
+RTC_EXPORT SessionDescriptionInterface* CreateSessionDescription(
+    const std::string& type,
+    const std::string& sdp,
+    SdpParseError* error);
 
 // Creates a SessionDescriptionInterface based on the SDP string and the type.
 // Returns null if the SDP string cannot be parsed.
 // If using the signature with |error_out|, details of the parsing error may be
 // written to |error_out| if it is not null.
-std::unique_ptr<SessionDescriptionInterface> CreateSessionDescription(
-    SdpType type,
-    const std::string& sdp);
-std::unique_ptr<SessionDescriptionInterface> CreateSessionDescription(
-    SdpType type,
-    const std::string& sdp,
-    SdpParseError* error_out);
+RTC_EXPORT std::unique_ptr<SessionDescriptionInterface>
+CreateSessionDescription(SdpType type, const std::string& sdp);
+RTC_EXPORT std::unique_ptr<SessionDescriptionInterface>
+CreateSessionDescription(SdpType type,
+                         const std::string& sdp,
+                         SdpParseError* error_out);
 
 // Creates a SessionDescriptionInterface based on a parsed SDP structure and the
 // given type, ID and version.
@@ -206,7 +207,8 @@
     std::unique_ptr<cricket::SessionDescription> description);
 
 // CreateOffer and CreateAnswer callback interface.
-class CreateSessionDescriptionObserver : public rtc::RefCountInterface {
+class RTC_EXPORT CreateSessionDescriptionObserver
+    : public rtc::RefCountInterface {
  public:
   // This callback transfers the ownership of the |desc|.
   // TODO(deadbeef): Make this take an std::unique_ptr<> to avoid confusion
@@ -227,7 +229,7 @@
 };
 
 // SetLocalDescription and SetRemoteDescription callback interface.
-class SetSessionDescriptionObserver : public rtc::RefCountInterface {
+class RTC_EXPORT SetSessionDescriptionObserver : public rtc::RefCountInterface {
  public:
   virtual void OnSuccess() = 0;
   // See description in CreateSessionDescriptionObserver for OnFailure.
diff --git a/api/jsepicecandidate.cc b/api/jsepicecandidate.cc
index b9ba2fe..ed2f792 100644
--- a/api/jsepicecandidate.cc
+++ b/api/jsepicecandidate.cc
@@ -10,6 +10,9 @@
 
 #include "api/jsepicecandidate.h"
 
+#include <algorithm>
+#include <utility>
+
 namespace webrtc {
 
 std::string JsepIceCandidate::sdp_mid() const {
diff --git a/api/jsepicecandidate.h b/api/jsepicecandidate.h
index a57f861..9cc7443 100644
--- a/api/jsepicecandidate.h
+++ b/api/jsepicecandidate.h
@@ -14,6 +14,7 @@
 #ifndef API_JSEPICECANDIDATE_H_
 #define API_JSEPICECANDIDATE_H_
 
+#include <stddef.h>
 #include <string>
 #include <vector>
 
diff --git a/api/media_transport_interface.cc b/api/media_transport_interface.cc
index fc97b0b..039a4a1 100644
--- a/api/media_transport_interface.cc
+++ b/api/media_transport_interface.cc
@@ -17,8 +17,18 @@
 
 #include "api/media_transport_interface.h"
 
+#include <cstdint>
+#include <utility>
+
 namespace webrtc {
 
+MediaTransportSettings::MediaTransportSettings() = default;
+MediaTransportSettings::MediaTransportSettings(const MediaTransportSettings&) =
+    default;
+MediaTransportSettings& MediaTransportSettings::operator=(
+    const MediaTransportSettings&) = default;
+MediaTransportSettings::~MediaTransportSettings() = default;
+
 MediaTransportEncodedAudioFrame::~MediaTransportEncodedAudioFrame() {}
 
 MediaTransportEncodedAudioFrame::MediaTransportEncodedAudioFrame(
@@ -73,4 +83,45 @@
 MediaTransportEncodedVideoFrame::MediaTransportEncodedVideoFrame(
     MediaTransportEncodedVideoFrame&&) = default;
 
+SendDataParams::SendDataParams() = default;
+
+RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
+MediaTransportFactory::CreateMediaTransport(
+    rtc::PacketTransportInternal* packet_transport,
+    rtc::Thread* network_thread,
+    bool is_caller) {
+  MediaTransportSettings settings;
+  settings.is_caller = is_caller;
+  return CreateMediaTransport(packet_transport, network_thread, settings);
+}
+
+RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
+MediaTransportFactory::CreateMediaTransport(
+    rtc::PacketTransportInternal* packet_transport,
+    rtc::Thread* network_thread,
+    const MediaTransportSettings& settings) {
+  return std::unique_ptr<MediaTransportInterface>(nullptr);
+}
+
+absl::optional<TargetTransferRate>
+MediaTransportInterface::GetLatestTargetTransferRate() {
+  return absl::nullopt;
+}
+
+void MediaTransportInterface::SetNetworkChangeCallback(
+    MediaTransportNetworkChangeCallback* callback) {}
+
+void MediaTransportInterface::RemoveTargetTransferRateObserver(
+    webrtc::TargetTransferRateObserver* observer) {}
+
+void MediaTransportInterface::SetTargetTransferRateObserver(
+    webrtc::TargetTransferRateObserver* observer) {}
+
+void MediaTransportInterface::AddTargetTransferRateObserver(
+    webrtc::TargetTransferRateObserver* observer) {}
+
+size_t MediaTransportInterface::GetAudioPacketOverhead() const {
+  return 0;
+}
+
 }  // namespace webrtc
diff --git a/api/media_transport_interface.h b/api/media_transport_interface.h
index 33fa2ad..7570160 100644
--- a/api/media_transport_interface.h
+++ b/api/media_transport_interface.h
@@ -17,13 +17,19 @@
 #ifndef API_MEDIA_TRANSPORT_INTERFACE_H_
 #define API_MEDIA_TRANSPORT_INTERFACE_H_
 
+#include <api/transport/network_control.h>
 #include <memory>
+#include <string>
 #include <utility>
 #include <vector>
 
+#include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "api/rtcerror.h"
 #include "api/video/encoded_image.h"
 #include "common_types.h"  // NOLINT(build/include)
+#include "rtc_base/copyonwritebuffer.h"
+#include "rtc_base/networkroute.h"
 
 namespace rtc {
 class PacketTransportInternal;
@@ -32,6 +38,23 @@
 
 namespace webrtc {
 
+// A collection of settings for creation of media transport.
+struct MediaTransportSettings final {
+  MediaTransportSettings();
+  MediaTransportSettings(const MediaTransportSettings&);
+  MediaTransportSettings& operator=(const MediaTransportSettings&);
+  ~MediaTransportSettings();
+
+  // Group calls are not currently supported, in 1:1 call one side must set
+  // is_caller = true and another is_caller = false.
+  bool is_caller;
+
+  // Must be set if a pre-shared key is used for the call.
+  // TODO(bugs.webrtc.org/9944): This should become zero buffer in the distant
+  // future.
+  absl::optional<std::string> pre_shared_key;
+};
+
 // Represents encoded audio frame in any encoding (type of encoding is opaque).
 // To avoid copying of encoded data use move semantics when passing by value.
 class MediaTransportEncodedAudioFrame final {
@@ -41,7 +64,10 @@
     kSpeech,
 
     // DTX frame (equivalent to webrtc::kAudioFrameCN).
-    kDiscountinuousTransmission,
+    // DTX frame (equivalent to webrtc::kAudioFrameCN).
+    kDiscontinuousTransmission,
+    // TODO(nisse): Mis-spelled version, update users, then delete.
+    kDiscountinuousTransmission = kDiscontinuousTransmission,
   };
 
   MediaTransportEncodedAudioFrame(
@@ -114,6 +140,16 @@
   std::vector<uint8_t> encoded_data_;
 };
 
+// Callback to notify about network route changes.
+class MediaTransportNetworkChangeCallback {
+ public:
+  virtual ~MediaTransportNetworkChangeCallback() = default;
+
+  // Called when the network route is changed, with the new network route.
+  virtual void OnNetworkRouteChanged(
+      const rtc::NetworkRoute& new_network_route) = 0;
+};
+
 // Interface for receiving encoded audio frames from MediaTransportInterface
 // implementations.
 class MediaTransportAudioSinkInterface {
@@ -187,6 +223,85 @@
   virtual void OnKeyFrameRequested(uint64_t channel_id) = 0;
 };
 
+// State of the media transport.  Media transport begins in the pending state.
+// It transitions to writable when it is ready to send media.  It may transition
+// back to pending if the connection is blocked.  It may transition to closed at
+// any time.  Closed is terminal: a transport will never re-open once closed.
+enum class MediaTransportState {
+  kPending,
+  kWritable,
+  kClosed,
+};
+
+// Callback invoked whenever the state of the media transport changes.
+class MediaTransportStateCallback {
+ public:
+  virtual ~MediaTransportStateCallback() = default;
+
+  // Invoked whenever the state of the media transport changes.
+  virtual void OnStateChanged(MediaTransportState state) = 0;
+};
+
+// Supported types of application data messages.
+enum class DataMessageType {
+  // Application data buffer with the binary bit unset.
+  kText,
+
+  // Application data buffer with the binary bit set.
+  kBinary,
+
+  // Transport-agnostic control messages, such as open or open-ack messages.
+  kControl,
+};
+
+// Parameters for sending data.  The parameters may change from message to
+// message, even within a single channel.  For example, control messages may be
+// sent reliably and in-order, even if the data channel is configured for
+// unreliable delivery.
+struct SendDataParams {
+  SendDataParams();
+
+  DataMessageType type = DataMessageType::kText;
+
+  // Whether to deliver the message in order with respect to other ordered
+  // messages with the same channel_id.
+  bool ordered = false;
+
+  // If set, the maximum number of times this message may be
+  // retransmitted by the transport before it is dropped.
+  // Setting this value to zero disables retransmission.
+  // Must be non-negative. |max_rtx_count| and |max_rtx_ms| may not be set
+  // simultaneously.
+  absl::optional<int> max_rtx_count;
+
+  // If set, the maximum number of milliseconds for which the transport
+  // may retransmit this message before it is dropped.
+  // Setting this value to zero disables retransmission.
+  // Must be non-negative. |max_rtx_count| and |max_rtx_ms| may not be set
+  // simultaneously.
+  absl::optional<int> max_rtx_ms;
+};
+
+// Sink for callbacks related to a data channel.
+class DataChannelSink {
+ public:
+  virtual ~DataChannelSink() = default;
+
+  // Callback issued when data is received by the transport.
+  virtual void OnDataReceived(int channel_id,
+                              DataMessageType type,
+                              const rtc::CopyOnWriteBuffer& buffer) = 0;
+
+  // Callback issued when a remote data channel begins the closing procedure.
+  // Messages sent after the closing procedure begins will not be transmitted.
+  virtual void OnChannelClosing(int channel_id) = 0;
+
+  // Callback issued when a (remote or local) data channel completes the closing
+  // procedure.  Closing channels become closed after all pending data has been
+  // transmitted.
+  virtual void OnChannelClosed(int channel_id) = 0;
+};
+
 // Media transport interface for sending / receiving encoded audio/video frames
 // and receiving bandwidth estimate update from congestion control.
 class MediaTransportInterface {
@@ -221,8 +336,71 @@
   // pass a nullptr.
   virtual void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) = 0;
 
+  // Sets a target bitrate observer. Before media transport is destructed
+  // the observer must be unregistered (set to nullptr).
+  // A newly registered observer will be called back with the latest recorded
+  // target rate, if available.
+  // TODO(psla): This method will be removed, in favor of
+  // AddTargetTransferRateObserver.
+  virtual void SetTargetTransferRateObserver(
+      TargetTransferRateObserver* observer);
+
+  // Adds a target bitrate observer. Before media transport is destructed
+  // the observer must be unregistered (by calling
+  // RemoveTargetTransferRateObserver).
+  // A newly registered observer will be called back with the latest recorded
+  // target rate, if available.
+  virtual void AddTargetTransferRateObserver(
+      webrtc::TargetTransferRateObserver* observer);
+
+  // Removes an existing |observer| from observers. If observer was never
+  // registered, an error is logged and method does nothing.
+  virtual void RemoveTargetTransferRateObserver(
+      webrtc::TargetTransferRateObserver* observer);
+
+  // Returns the last known target transfer rate as reported to the above
+  // observers.
+  virtual absl::optional<TargetTransferRate> GetLatestTargetTransferRate();
+
+  // Gets the audio packet overhead in bytes. Returned overhead does not include
+  // transport overhead (ipv4/6, turn channeldata, tcp/udp, etc.).
+  // If the transport is capable of fusing packets together, this overhead
+  // might not be a very accurate number.
+  virtual size_t GetAudioPacketOverhead() const;
+
+  // Sets an observer for network change events. If the network route is already
+  // established when the callback is set, |callback| will be called immediately
+  // with the current network route.
+  // Before media transport is destroyed, the callback must be unregistered by
+  // setting it to nullptr.
+  virtual void SetNetworkChangeCallback(
+      MediaTransportNetworkChangeCallback* callback);
+
+  // Sets a state observer callback. Before media transport is destroyed, the
+  // callback must be unregistered by setting it to nullptr.
+  // A newly registered callback will be called with the current state.
+  // Media transport does not invoke this callback concurrently.
+  virtual void SetMediaTransportStateCallback(
+      MediaTransportStateCallback* callback) = 0;
+
+  // Sends a data buffer to the remote endpoint using the given send parameters.
+  // |buffer| may not be larger than 256 KiB. Returns an error if the send
+  // fails.
+  virtual RTCError SendData(int channel_id,
+                            const SendDataParams& params,
+                            const rtc::CopyOnWriteBuffer& buffer) = 0;
+
+  // Closes |channel_id| gracefully.  Returns an error if |channel_id| is not
+  // open.  Data sent after the closing procedure begins will not be
+  // transmitted. The channel becomes closed after pending data is transmitted.
+  virtual RTCError CloseChannel(int channel_id) = 0;
+
+  // Sets a sink for data messages and channel state callbacks. Before media
+  // transport is destroyed, the sink must be unregistered by setting it to
+  // nullptr.
+  virtual void SetDataSink(DataChannelSink* sink) = 0;
+
   // TODO(sukhanov): RtcEventLogs.
-  // TODO(sukhanov): Bandwidth updates.
 };
 
 // If media transport factory is set in peer connection factory, it will be
@@ -240,10 +418,21 @@
   // - Does not take ownership of packet_transport or network_thread.
   // - Does not support group calls, in 1:1 call one side must set
   //   is_caller = true and another is_caller = false.
+  // TODO(bugs.webrtc.org/9938) This constructor will be removed and replaced
+  // with the one below.
   virtual RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
   CreateMediaTransport(rtc::PacketTransportInternal* packet_transport,
                        rtc::Thread* network_thread,
-                       bool is_caller) = 0;
+                       bool is_caller);
+
+  // Creates media transport.
+  // - Does not take ownership of packet_transport or network_thread.
+  // TODO(bugs.webrtc.org/9938): remove default implementation once all children
+  // override it.
+  virtual RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
+  CreateMediaTransport(rtc::PacketTransportInternal* packet_transport,
+                       rtc::Thread* network_thread,
+                       const MediaTransportSettings& settings);
 };
 
 }  // namespace webrtc
diff --git a/api/mediaconstraintsinterface.cc b/api/mediaconstraintsinterface.cc
index 5567786..b66ba05 100644
--- a/api/mediaconstraintsinterface.cc
+++ b/api/mediaconstraintsinterface.cc
@@ -10,7 +10,9 @@
 
 #include "api/mediaconstraintsinterface.h"
 
+#include "absl/types/optional.h"
 #include "api/peerconnectioninterface.h"
+#include "media/base/mediaconfig.h"
 #include "rtc_base/stringencode.h"
 
 namespace {
diff --git a/api/mediaconstraintsinterface.h b/api/mediaconstraintsinterface.h
index 560fa4a..c9a6e1b 100644
--- a/api/mediaconstraintsinterface.h
+++ b/api/mediaconstraintsinterface.h
@@ -21,9 +21,11 @@
 #ifndef API_MEDIACONSTRAINTSINTERFACE_H_
 #define API_MEDIACONSTRAINTSINTERFACE_H_
 
+#include <stddef.h>
 #include <string>
 #include <vector>
 
+#include "api/audio_options.h"
 #include "api/peerconnectioninterface.h"
 
 namespace webrtc {
diff --git a/api/mediastreaminterface.cc b/api/mediastreaminterface.cc
index 6f08a0c..e36d5cb 100644
--- a/api/mediastreaminterface.cc
+++ b/api/mediastreaminterface.cc
@@ -17,34 +17,6 @@
 const char MediaStreamTrackInterface::kVideoKind[] = "video";
 const char MediaStreamTrackInterface::kAudioKind[] = "audio";
 
-void AudioProcessorInterface::GetStats(AudioProcessorStats* /*stats*/) {
-  RTC_NOTREACHED() << "Old-style GetStats() is called but it has no "
-                   << "implementation.";
-  RTC_LOG(LS_ERROR) << "Old-style GetStats() is called but it has no "
-                    << "implementation.";
-}
-
-// TODO(ivoc): Remove this when the function becomes pure virtual.
-AudioProcessorInterface::AudioProcessorStatistics
-AudioProcessorInterface::GetStats(bool /*has_remote_tracks*/) {
-  AudioProcessorStats stats;
-  GetStats(&stats);
-  AudioProcessorStatistics new_stats;
-  new_stats.apm_statistics.divergent_filter_fraction =
-      stats.aec_divergent_filter_fraction;
-  new_stats.apm_statistics.delay_median_ms = stats.echo_delay_median_ms;
-  new_stats.apm_statistics.delay_standard_deviation_ms =
-      stats.echo_delay_std_ms;
-  new_stats.apm_statistics.echo_return_loss = stats.echo_return_loss;
-  new_stats.apm_statistics.echo_return_loss_enhancement =
-      stats.echo_return_loss_enhancement;
-  new_stats.apm_statistics.residual_echo_likelihood =
-      stats.residual_echo_likelihood;
-  new_stats.apm_statistics.residual_echo_likelihood_recent_max =
-      stats.residual_echo_likelihood_recent_max;
-  return new_stats;
-}
-
 VideoTrackInterface::ContentHint VideoTrackInterface::content_hint() const {
   return ContentHint::kNone;
 }
diff --git a/api/mediastreaminterface.h b/api/mediastreaminterface.h
index 2eb2f31..30f8f71 100644
--- a/api/mediastreaminterface.h
+++ b/api/mediastreaminterface.h
@@ -213,47 +213,17 @@
 // statistics.
 class AudioProcessorInterface : public rtc::RefCountInterface {
  public:
-  // Deprecated, use AudioProcessorStatistics instead.
-  // TODO(ivoc): Remove this when all implementations have switched to the new
-  //             GetStats function. See b/67926135.
-  struct AudioProcessorStats {
-    AudioProcessorStats()
-        : typing_noise_detected(false),
-          echo_return_loss(0),
-          echo_return_loss_enhancement(0),
-          echo_delay_median_ms(0),
-          echo_delay_std_ms(0),
-          residual_echo_likelihood(0.0f),
-          residual_echo_likelihood_recent_max(0.0f),
-          aec_divergent_filter_fraction(0.0) {}
-    ~AudioProcessorStats() {}
-
-    bool typing_noise_detected;
-    int echo_return_loss;
-    int echo_return_loss_enhancement;
-    int echo_delay_median_ms;
-    int echo_delay_std_ms;
-    float residual_echo_likelihood;
-    float residual_echo_likelihood_recent_max;
-    float aec_divergent_filter_fraction;
-  };
-  // This struct maintains the optionality of the stats, and will replace the
-  // regular stats struct when all users have been updated.
   struct AudioProcessorStatistics {
     bool typing_noise_detected = false;
     AudioProcessingStats apm_statistics;
   };
 
-  // Get audio processor statistics.
-  virtual void GetStats(AudioProcessorStats* stats);
-
   // Get audio processor statistics. The |has_remote_tracks| argument should be
   // set if there are active remote tracks (this would usually be true during
   // a call). If there are no remote tracks some of the stats will not be set by
   // the AudioProcessor, because they only make sense if there is at least one
   // remote track.
-  // TODO(ivoc): Make pure virtual when all implementions are updated.
-  virtual AudioProcessorStatistics GetStats(bool has_remote_tracks);
+  virtual AudioProcessorStatistics GetStats(bool has_remote_tracks) = 0;
 
  protected:
   ~AudioProcessorInterface() override = default;
diff --git a/api/peerconnectioninterface.cc b/api/peerconnectioninterface.cc
index b4148d7..f2953b5 100644
--- a/api/peerconnectioninterface.cc
+++ b/api/peerconnectioninterface.cc
@@ -159,6 +159,11 @@
   return SetBitrate(bitrate);
 }
 
+PeerConnectionInterface::PeerConnectionState
+PeerConnectionInterface::peer_connection_state() {
+  return PeerConnectionInterface::PeerConnectionState::kNew;
+}
+
 bool PeerConnectionInterface::StartRtcEventLog(rtc::PlatformFile file,
                                                int64_t max_size_bytes) {
   return false;
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index 3d8a9c1..80c3091 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -77,6 +77,7 @@
 #include "api/audio_codecs/audio_encoder_factory.h"
 #include "api/audio_options.h"
 #include "api/call/callfactoryinterface.h"
+#include "api/crypto/cryptooptions.h"
 #include "api/datachannelinterface.h"
 #include "api/fec_controller.h"
 #include "api/jsep.h"
@@ -112,6 +113,7 @@
 #include "rtc_base/socketaddress.h"
 #include "rtc_base/sslcertificate.h"
 #include "rtc_base/sslstreamadapter.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace rtc {
 class SSLIdentity;
@@ -158,7 +160,7 @@
 
 class PeerConnectionInterface : public rtc::RefCountInterface {
  public:
-  // See https://w3c.github.io/webrtc-pc/#state-definitions
+  // See https://w3c.github.io/webrtc-pc/#dom-rtcsignalingstate
   enum SignalingState {
     kStable,
     kHaveLocalOffer,
@@ -168,12 +170,24 @@
     kClosed,
   };
 
+  // See https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate
   enum IceGatheringState {
     kIceGatheringNew,
     kIceGatheringGathering,
     kIceGatheringComplete
   };
 
+  // See https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectionstate
+  enum class PeerConnectionState {
+    kNew,
+    kConnecting,
+    kConnected,
+    kDisconnected,
+    kFailed,
+    kClosed,
+  };
+
+  // See https://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate
   enum IceConnectionState {
     kIceConnectionNew,
     kIceConnectionChecking,
@@ -280,7 +294,7 @@
   // organization of the implementation, which isn't stable. So we
   // need getters and setters at least for fields which applications
   // are interested in.
-  struct RTCConfiguration {
+  struct RTC_EXPORT RTCConfiguration {
     // This struct is subject to reorganization, both for naming
     // consistency, and to group settings to match where they are used
     // in the implementation. To do that, we need getter and setter
@@ -392,6 +406,7 @@
     // Use new combined audio/video bandwidth estimation?
     absl::optional<bool> combined_audio_video_bwe;
 
+    // TODO(bugs.webrtc.org/9891) - Move to crypto_options
     // Can be used to disable DTLS-SRTP. This should never be done, but can be
     // useful for testing purposes, for example in setting up a loopback call
     // with a single PeerConnection.
@@ -554,6 +569,7 @@
     // For all other users, specify kUnifiedPlan.
     SdpSemantics sdp_semantics = SdpSemantics::kPlanB;
 
+    // TODO(bugs.webrtc.org/9891) - Move to crypto_options or remove.
     // Actively reset the SRTP parameters whenever the DTLS transports
     // underneath are reset for every offer/answer negotiation.
     // This is only intended to be a workaround for crbug.com/835958
@@ -567,6 +583,20 @@
     // provided.
     bool use_media_transport = false;
 
+    // If MediaTransportFactory is provided in PeerConnectionFactory, this flag
+    // informs PeerConnection that it should use the MediaTransportInterface for
+    // data channels.  It's invalid to set it to |true| if the
+    // MediaTransportFactory wasn't provided.  Data channels over media
+    // transport are not compatible with RTP or SCTP data channels.  Setting
+    // both |use_media_transport_for_data_channels| and
+    // |enable_rtp_data_channel| is invalid.
+    bool use_media_transport_for_data_channels = false;
+
+    // Defines advanced optional cryptographic settings related to SRTP and
+    // frame encryption for native WebRTC. Setting this will overwrite any
+    // settings set in PeerConnectionFactory (which is deprecated).
+    absl::optional<CryptoOptions> crypto_options;
+
     //
     // Don't forget to update operator== if adding something.
     //
@@ -976,11 +1006,13 @@
   virtual SignalingState signaling_state() = 0;
 
   // Returns the aggregate state of all ICE *and* DTLS transports.
-  // TODO(deadbeef): Implement "PeerConnectionState" according to the standard,
-  // to aggregate ICE+DTLS state, and change the scope of IceConnectionState to
-  // be just the ICE layer. See: crbug.com/webrtc/6145
+  // TODO(jonasolsson): Replace with standardized_ice_connection_state once it
+  // is ready, see crbug.com/webrtc/6145
   virtual IceConnectionState ice_connection_state() = 0;
 
+  // Returns the aggregated state of all ICE and DTLS transports.
+  virtual PeerConnectionState peer_connection_state();
+
   virtual IceGatheringState ice_gathering_state() = 0;
 
   // Starts RtcEventLog using existing file. Takes ownership of |file| and
@@ -1049,6 +1081,10 @@
   virtual void OnIceConnectionChange(
       PeerConnectionInterface::IceConnectionState new_state) = 0;
 
+  // Called any time the PeerConnectionState changes.
+  virtual void OnConnectionChange(
+      PeerConnectionInterface::PeerConnectionState new_state) {}
+
   // Called any time the IceGatheringState changes.
   virtual void OnIceGatheringChange(
       PeerConnectionInterface::IceGatheringState new_state) = 0;
@@ -1180,7 +1216,7 @@
  public:
   class Options {
    public:
-    Options() : crypto_options(rtc::CryptoOptions::NoGcm()) {}
+    Options() {}
 
     // If set to true, created PeerConnections won't enforce any SRTP
     // requirement, allowing unsecured media. Should only be used for
@@ -1209,7 +1245,7 @@
     rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
 
     // Sets crypto related options, e.g. enabled cipher suites.
-    rtc::CryptoOptions crypto_options;
+    CryptoOptions crypto_options = CryptoOptions::NoGcm();
   };
 
   // Set the options to be used for subsequently created PeerConnections.
@@ -1323,7 +1359,8 @@
 // rtc::Thread::Current()->Run(), or call
 // rtc::Thread::Current()->ProcessMessages() within the application's own
 // message loop.
-rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
     rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
     rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory);
 
@@ -1337,7 +1374,8 @@
 // returned factory.
 // TODO(deadbeef): Use rtc::scoped_refptr<> and std::unique_ptr<> to make this
 // ownership transfer and ref counting more obvious.
-rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
     rtc::Thread* network_thread,
     rtc::Thread* worker_thread,
     rtc::Thread* signaling_thread,
@@ -1353,7 +1391,8 @@
 // If |audio_mixer| is null, an internal audio mixer will be created and used.
 // If |audio_processing| is null, an internal audio processing module will be
 // created and used.
-rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
     rtc::Thread* network_thread,
     rtc::Thread* worker_thread,
     rtc::Thread* signaling_thread,
@@ -1375,7 +1414,8 @@
 // be created and used.
 // If |network_controller_factory| is provided, it will be used if enabled via
 // field trial.
-rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
     rtc::Thread* network_thread,
     rtc::Thread* worker_thread,
     rtc::Thread* signaling_thread,
@@ -1396,7 +1436,8 @@
 // extra internal video codecs will be added.
 // When building WebRTC with rtc_use_builtin_sw_codecs = false, this is the
 // only available CreatePeerConnectionFactory overload.
-rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
     rtc::Thread* network_thread,
     rtc::Thread* worker_thread,
     rtc::Thread* signaling_thread,
@@ -1413,7 +1454,7 @@
 // mixer.
 //
 // If |audio_mixer| is null, an internal audio mixer will be created and used.
-rtc::scoped_refptr<PeerConnectionFactoryInterface>
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
 CreatePeerConnectionFactoryWithAudioMixer(
     rtc::Thread* network_thread,
     rtc::Thread* worker_thread,
@@ -1427,7 +1468,7 @@
 
 // Create a new instance of PeerConnectionFactoryInterface.
 // Same thread is used as worker and network thread.
-inline rtc::scoped_refptr<PeerConnectionFactoryInterface>
+RTC_EXPORT inline rtc::scoped_refptr<PeerConnectionFactoryInterface>
 CreatePeerConnectionFactory(
     rtc::Thread* worker_and_network_thread,
     rtc::Thread* signaling_thread,
diff --git a/api/proxy.cc b/api/proxy.cc
index c86bddf..01e6be5 100644
--- a/api/proxy.cc
+++ b/api/proxy.cc
@@ -23,7 +23,7 @@
   if (t->IsCurrent()) {
     proxy_->OnMessage(nullptr);
   } else {
-    e_.reset(new rtc::Event(false, false));
+    e_ = absl::make_unique<rtc::Event>();
     t->Post(posted_from, this, 0);
     e_->Wait(rtc::Event::kForever);
   }
diff --git a/api/rtp_headers.h b/api/rtp_headers.h
index 799058d..eff6223 100644
--- a/api/rtp_headers.h
+++ b/api/rtp_headers.h
@@ -12,6 +12,7 @@
 #define API_RTP_HEADERS_H_
 
 #include <stddef.h>
+#include <stdint.h>
 #include <string.h>
 
 #include "api/array_view.h"
@@ -19,7 +20,6 @@
 #include "api/video/video_frame_marking.h"
 #include "api/video/video_rotation.h"
 #include "api/video/video_timing.h"
-
 #include "common_types.h"  // NOLINT(build/include)
 
 namespace webrtc {
diff --git a/api/rtpparameters.cc b/api/rtpparameters.cc
index e9f4d5d..063d106 100644
--- a/api/rtpparameters.cc
+++ b/api/rtpparameters.cc
@@ -12,6 +12,7 @@
 #include <algorithm>
 #include <string>
 
+#include "api/array_view.h"
 #include "rtc_base/strings/string_builder.h"
 
 namespace webrtc {
diff --git a/api/rtpparameters.h b/api/rtpparameters.h
index 678ac02..badda07 100644
--- a/api/rtpparameters.h
+++ b/api/rtpparameters.h
@@ -11,12 +11,14 @@
 #ifndef API_RTPPARAMETERS_H_
 #define API_RTPPARAMETERS_H_
 
+#include <stdint.h>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
 #include "absl/types/optional.h"
 #include "api/mediatypes.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
@@ -404,6 +406,14 @@
   // bitrate priority.
   double bitrate_priority = kDefaultBitratePriority;
 
+  // The relative DiffServ Code Point priority for this encoding, allowing
+  // packets to be marked relatively higher or lower without affecting
+  // bandwidth allocations. See https://w3c.github.io/webrtc-dscp-exp/ . NB
+  // we follow chromium's translation of the allowed string enum values for
+  // this field to 1.0, 0.5, et cetera, similar to bitrate_priority above.
+  // TODO(http://crbug.com/webrtc/8630): Implement this per encoding parameter.
+  double network_priority = kDefaultBitratePriority;
+
   // Indicates the preferred duration of media represented by a packet in
   // milliseconds for this encoding. If set, this will take precedence over the
   // ptime set in the RtpCodecParameters. This could happen if SDP negotiation
@@ -471,7 +481,8 @@
   bool operator==(const RtpEncodingParameters& o) const {
     return ssrc == o.ssrc && codec_payload_type == o.codec_payload_type &&
            fec == o.fec && rtx == o.rtx && dtx == o.dtx &&
-           bitrate_priority == o.bitrate_priority && ptime == o.ptime &&
+           bitrate_priority == o.bitrate_priority &&
+           network_priority == o.network_priority && ptime == o.ptime &&
            max_bitrate_bps == o.max_bitrate_bps &&
            min_bitrate_bps == o.min_bitrate_bps &&
            max_framerate == o.max_framerate &&
@@ -607,7 +618,7 @@
   bool operator!=(const RtcpParameters& o) const { return !(*this == o); }
 };
 
-struct RtpParameters {
+struct RTC_EXPORT RtpParameters {
   RtpParameters();
   RtpParameters(const RtpParameters&);
   ~RtpParameters();
diff --git a/api/rtptransceiverinterface.cc b/api/rtptransceiverinterface.cc
index d833339..e62b014 100644
--- a/api/rtptransceiverinterface.cc
+++ b/api/rtptransceiverinterface.cc
@@ -10,6 +10,8 @@
 
 #include "api/rtptransceiverinterface.h"
 
+#include "rtc_base/checks.h"
+
 namespace webrtc {
 
 RtpTransceiverInit::RtpTransceiverInit() = default;
diff --git a/api/rtptransceiverinterface.h b/api/rtptransceiverinterface.h
index 301a380..c01fdaf 100644
--- a/api/rtptransceiverinterface.h
+++ b/api/rtptransceiverinterface.h
@@ -16,9 +16,12 @@
 
 #include "absl/types/optional.h"
 #include "api/array_view.h"
+#include "api/mediatypes.h"
+#include "api/rtpparameters.h"
 #include "api/rtpreceiverinterface.h"
 #include "api/rtpsenderinterface.h"
 #include "rtc_base/refcount.h"
+#include "rtc_base/scoped_ref_ptr.h"
 
 namespace webrtc {
 
diff --git a/api/transport/network_types.cc b/api/transport/network_types.cc
index 48bdcab..80214de 100644
--- a/api/transport/network_types.cc
+++ b/api/transport/network_types.cc
@@ -38,7 +38,7 @@
     const {
   std::vector<PacketResult> res;
   for (const PacketResult& fb : packet_feedbacks) {
-    if (fb.receive_time.IsFinite() && fb.sent_packet.has_value()) {
+    if (fb.receive_time.IsFinite()) {
       res.push_back(fb);
     }
   }
@@ -48,7 +48,7 @@
 std::vector<PacketResult> TransportPacketsFeedback::LostWithSendInfo() const {
   std::vector<PacketResult> res;
   for (const PacketResult& fb : packet_feedbacks) {
-    if (fb.receive_time.IsPlusInfinity() && fb.sent_packet.has_value()) {
+    if (fb.receive_time.IsPlusInfinity()) {
       res.push_back(fb);
     }
   }
diff --git a/api/transport/network_types.h b/api/transport/network_types.h
index 3a00efe..0f1d7ab 100644
--- a/api/transport/network_types.h
+++ b/api/transport/network_types.h
@@ -126,7 +126,7 @@
   PacketResult(const PacketResult&);
   ~PacketResult();
 
-  absl::optional<SentPacket> sent_packet;
+  SentPacket sent_packet;
   Timestamp receive_time = Timestamp::PlusInfinity();
 };
 
@@ -140,6 +140,9 @@
   DataSize prior_in_flight = DataSize::Zero();
   std::vector<PacketResult> packet_feedbacks;
 
+  // Arrival times for messages without send time information.
+  std::vector<Timestamp> sendless_arrival_times;
+
   std::vector<PacketResult> ReceivedWithSendInfo() const;
   std::vector<PacketResult> LostWithSendInfo() const;
   std::vector<PacketResult> PacketsWithFeedback() const;
diff --git a/api/units/data_rate.h b/api/units/data_rate.h
index 4bb988b..28efcd3 100644
--- a/api/units/data_rate.h
+++ b/api/units/data_rate.h
@@ -20,12 +20,12 @@
 #include <cmath>
 #include <limits>
 #include <string>
-
-#include "rtc_base/checks.h"
-#include "rtc_base/numerics/safe_conversions.h"
+#include <type_traits>
 
 #include "api/units/data_size.h"
 #include "api/units/time_delta.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/numerics/safe_conversions.h"
 
 namespace webrtc {
 namespace data_rate_impl {
diff --git a/api/units/time_delta.h b/api/units/time_delta.h
index ec36417..74b5385 100644
--- a/api/units/time_delta.h
+++ b/api/units/time_delta.h
@@ -20,6 +20,7 @@
 #include <cstdlib>
 #include <limits>
 #include <string>
+#include <type_traits>
 
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/api/units/timestamp.h b/api/units/timestamp.h
index 0298f5d..80f1839 100644
--- a/api/units/timestamp.h
+++ b/api/units/timestamp.h
@@ -15,9 +15,11 @@
 #include <ostream>  // no-presubmit-check TODO(webrtc:8982)
 #endif              // UNIT_TEST
 
+#include <math.h>
 #include <stdint.h>
 #include <limits>
 #include <string>
+#include <type_traits>
 
 #include "api/units/time_delta.h"
 #include "rtc_base/checks.h"
diff --git a/api/video/builtin_video_bitrate_allocator_factory.cc b/api/video/builtin_video_bitrate_allocator_factory.cc
new file mode 100644
index 0000000..70f6ad0
--- /dev/null
+++ b/api/video/builtin_video_bitrate_allocator_factory.cc
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/builtin_video_bitrate_allocator_factory.h"
+
+#include "absl/memory/memory.h"
+#include "media/base/codec.h"
+#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
+#include "modules/video_coding/utility/default_video_bitrate_allocator.h"
+#include "modules/video_coding/utility/simulcast_rate_allocator.h"
+#include "rtc_base/system/fallthrough.h"
+
+namespace webrtc {
+
+namespace {
+
+class BuiltinVideoBitrateAllocatorFactory
+    : public VideoBitrateAllocatorFactory {
+ public:
+  BuiltinVideoBitrateAllocatorFactory() = default;
+  ~BuiltinVideoBitrateAllocatorFactory() override = default;
+
+  std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
+      const VideoCodec& codec) override {
+    std::unique_ptr<VideoBitrateAllocator> rate_allocator;
+    switch (codec.codecType) {
+      case kVideoCodecVP8:
+        RTC_FALLTHROUGH();
+      case kVideoCodecH264:
+        rate_allocator.reset(new SimulcastRateAllocator(codec));
+        break;
+      case kVideoCodecVP9:
+        rate_allocator.reset(new SvcRateAllocator(codec));
+        break;
+      default:
+        rate_allocator.reset(new DefaultVideoBitrateAllocator(codec));
+    }
+    return rate_allocator;
+  }
+};
+
+}  // namespace
+
+std::unique_ptr<VideoBitrateAllocatorFactory>
+CreateBuiltinVideoBitrateAllocatorFactory() {
+  return absl::make_unique<BuiltinVideoBitrateAllocatorFactory>();
+}
+
+}  // namespace webrtc
diff --git a/api/video/builtin_video_bitrate_allocator_factory.h b/api/video/builtin_video_bitrate_allocator_factory.h
new file mode 100644
index 0000000..ac880a0
--- /dev/null
+++ b/api/video/builtin_video_bitrate_allocator_factory.h
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_BUILTIN_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+#define API_VIDEO_BUILTIN_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+
+#include <memory>
+
+#include "api/video/video_bitrate_allocator_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoBitrateAllocatorFactory>
+CreateBuiltinVideoBitrateAllocatorFactory();
+
+}  // namespace webrtc
+
+#endif  // API_VIDEO_BUILTIN_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
diff --git a/api/video/encoded_image.cc b/api/video/encoded_image.cc
index 5658dfc..e7c6fad 100644
--- a/api/video/encoded_image.cc
+++ b/api/video/encoded_image.cc
@@ -12,11 +12,6 @@
 
 #include <string.h>
 
-#include <algorithm>  // swap
-
-#include "rtc_base/bind.h"
-#include "rtc_base/checks.h"
-
 namespace webrtc {
 
 // FFmpeg's decoder, used by H264DecoderImpl, requires up to 8 bytes padding due
diff --git a/api/video/encoded_image.h b/api/video/encoded_image.h
index ed58d96..5c4a82d 100644
--- a/api/video/encoded_image.h
+++ b/api/video/encoded_image.h
@@ -11,17 +11,22 @@
 #ifndef API_VIDEO_ENCODED_IMAGE_H_
 #define API_VIDEO_ENCODED_IMAGE_H_
 
+#include <stdint.h>
+
 #include "absl/types/optional.h"
+#include "api/video/video_bitrate_allocation.h"
 #include "api/video/video_content_type.h"
 #include "api/video/video_rotation.h"
 #include "api/video/video_timing.h"
 #include "common_types.h"  // NOLINT(build/include)
+#include "rtc_base/checks.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
 // TODO(bug.webrtc.org/9378): This is a legacy api class, which is slowly being
 // cleaned up. Direct use of its members is strongly discouraged.
-class EncodedImage {
+class RTC_EXPORT EncodedImage {
  public:
   static const size_t kBufferPaddingBytesH264;
 
diff --git a/api/video/hdr_metadata.cc b/api/video/hdr_metadata.cc
new file mode 100644
index 0000000..bfe54ce
--- /dev/null
+++ b/api/video/hdr_metadata.cc
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/hdr_metadata.h"
+
+namespace webrtc {
+
+HdrMasteringMetadata::Chromaticity::Chromaticity() = default;
+HdrMasteringMetadata::Chromaticity::Chromaticity(const Chromaticity& rhs) =
+    default;
+HdrMasteringMetadata::Chromaticity::Chromaticity(Chromaticity&& rhs) = default;
+HdrMasteringMetadata::Chromaticity& HdrMasteringMetadata::Chromaticity::
+operator=(const Chromaticity& rhs) = default;
+
+HdrMasteringMetadata::HdrMasteringMetadata() = default;
+HdrMasteringMetadata::HdrMasteringMetadata(const HdrMasteringMetadata& rhs) =
+    default;
+HdrMasteringMetadata::HdrMasteringMetadata(HdrMasteringMetadata&& rhs) =
+    default;
+HdrMasteringMetadata& HdrMasteringMetadata::operator=(
+    const HdrMasteringMetadata& rhs) = default;
+
+HdrMetadata::HdrMetadata() = default;
+HdrMetadata::HdrMetadata(const HdrMetadata& rhs) = default;
+HdrMetadata::HdrMetadata(HdrMetadata&& rhs) = default;
+HdrMetadata& HdrMetadata::operator=(const HdrMetadata& rhs) = default;
+
+}  // namespace webrtc
diff --git a/api/video/hdr_metadata.h b/api/video/hdr_metadata.h
new file mode 100644
index 0000000..be0c173
--- /dev/null
+++ b/api/video/hdr_metadata.h
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_HDR_METADATA_H_
+#define API_VIDEO_HDR_METADATA_H_
+
+#include <stdint.h>
+
+namespace webrtc {
+
+// SMPTE ST 2086 mastering metadata,
+// see https://ieeexplore.ieee.org/document/8353899.
+struct HdrMasteringMetadata {
+  struct Chromaticity {
+    // xy chromaticity coordinates must be calculated as specified in ISO
+    // 11664-3:2012 Section 7, and must be specified with four decimal places.
+    // The x coordinate must be in the range [0.0001, 0.7400] and the y
+    // coordinate must be in the range [0.0001, 0.8400].
+    float x = 0.0f;
+    float y = 0.0f;
+    bool operator==(const Chromaticity& rhs) const {
+      return x == rhs.x && y == rhs.y;
+    }
+
+    Chromaticity();
+    Chromaticity(const Chromaticity& rhs);
+    Chromaticity(Chromaticity&& rhs);
+    Chromaticity& operator=(const Chromaticity& rhs);
+  };
+
+  // The nominal primaries of the mastering display.
+  Chromaticity primary_r;
+  Chromaticity primary_g;
+  Chromaticity primary_b;
+
+  // The nominal chromaticity of the white point of the mastering display.
+  Chromaticity white_point;
+
+  // The nominal maximum display luminance of the mastering display. Specified
+  // in the unit candela/m2. The value must be in the range [5, 10000] with zero
+  // decimal places.
+  float luminance_max = 0.0f;
+
+  // The nominal minimum display luminance of the mastering display. Specified
+  // in the unit candela/m2. The value must be in the range [0.0001, 5.0000]
+  // with four decimal places.
+  float luminance_min = 0.0f;
+
+  HdrMasteringMetadata();
+  HdrMasteringMetadata(const HdrMasteringMetadata& rhs);
+  HdrMasteringMetadata(HdrMasteringMetadata&& rhs);
+  HdrMasteringMetadata& operator=(const HdrMasteringMetadata& rhs);
+
+  bool operator==(const HdrMasteringMetadata& rhs) const {
+    return ((primary_r == rhs.primary_r) && (primary_g == rhs.primary_g) &&
+            (primary_b == rhs.primary_b) && (white_point == rhs.white_point) &&
+            (luminance_max == rhs.luminance_max) &&
+            (luminance_min == rhs.luminance_min));
+  }
+};
+
+// High dynamic range (HDR) metadata common for HDR10 and WebM/VP9-based HDR
+// formats. This struct replicates the HDRMetadata struct defined in
+// https://cs.chromium.org/chromium/src/media/base/hdr_metadata.h
+struct HdrMetadata {
+  HdrMasteringMetadata mastering_metadata;
+  // Max content light level (CLL), i.e. maximum brightness level present in the
+  // stream, in nits. 1 nit = 1 candela/m2.
+  uint32_t max_content_light_level = 0;
+  // Max frame-average light level (FALL), i.e. maximum average brightness of
+  // the brightest frame in the stream, in nits.
+  uint32_t max_frame_average_light_level = 0;
+
+  HdrMetadata();
+  HdrMetadata(const HdrMetadata& rhs);
+  HdrMetadata(HdrMetadata&& rhs);
+  HdrMetadata& operator=(const HdrMetadata& rhs);
+
+  bool operator==(const HdrMetadata& rhs) const {
+    return (
+        (max_content_light_level == rhs.max_content_light_level) &&
+        (max_frame_average_light_level == rhs.max_frame_average_light_level) &&
+        (mastering_metadata == rhs.mastering_metadata));
+  }
+};
+
+}  // namespace webrtc
+
+#endif  // API_VIDEO_HDR_METADATA_H_
diff --git a/api/video/i420_buffer.h b/api/video/i420_buffer.h
index 282b242..631e394 100644
--- a/api/video/i420_buffer.h
+++ b/api/video/i420_buffer.h
@@ -11,16 +11,19 @@
 #ifndef API_VIDEO_I420_BUFFER_H_
 #define API_VIDEO_I420_BUFFER_H_
 
+#include <stdint.h>
 #include <memory>
 
 #include "api/video/video_frame_buffer.h"
 #include "api/video/video_rotation.h"
 #include "rtc_base/memory/aligned_malloc.h"
+#include "rtc_base/scoped_ref_ptr.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
 // Plain I420 buffer in standard memory.
-class I420Buffer : public I420BufferInterface {
+class RTC_EXPORT I420Buffer : public I420BufferInterface {
  public:
   static rtc::scoped_refptr<I420Buffer> Create(int width, int height);
   static rtc::scoped_refptr<I420Buffer> Create(int width,
diff --git a/api/video/video_bitrate_allocation.cc b/api/video/video_bitrate_allocation.cc
index 8922536..1b35690 100644
--- a/api/video/video_bitrate_allocation.cc
+++ b/api/video/video_bitrate_allocation.cc
@@ -10,6 +10,8 @@
 
 #include "api/video/video_bitrate_allocation.h"
 
+#include <cstdint>
+
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/strings/string_builder.h"
diff --git a/api/video/video_bitrate_allocation.h b/api/video/video_bitrate_allocation.h
index 9e2501d..d1771b4 100644
--- a/api/video/video_bitrate_allocation.h
+++ b/api/video/video_bitrate_allocation.h
@@ -11,6 +11,8 @@
 #ifndef API_VIDEO_VIDEO_BITRATE_ALLOCATION_H_
 #define API_VIDEO_VIDEO_BITRATE_ALLOCATION_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <limits>
 #include <string>
 #include <vector>
diff --git a/api/video/video_frame.cc b/api/video/video_frame.cc
index 5521ad8..12da43f 100644
--- a/api/video/video_frame.cc
+++ b/api/video/video_frame.cc
@@ -21,7 +21,7 @@
 
 VideoFrame VideoFrame::Builder::build() {
   return VideoFrame(video_frame_buffer_, timestamp_us_, timestamp_rtp_,
-                    ntp_time_ms_, rotation_, color_space_);
+                    ntp_time_ms_, rotation_, color_space_, hdr_metadata_);
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_video_frame_buffer(
@@ -64,6 +64,12 @@
   return *this;
 }
 
+VideoFrame::Builder& VideoFrame::Builder::set_hdr_metadata(
+    const HdrMetadata& hdr_metadata) {
+  hdr_metadata_ = hdr_metadata;
+  return *this;
+}
+
 VideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
                        webrtc::VideoRotation rotation,
                        int64_t timestamp_us)
@@ -90,13 +96,15 @@
                        uint32_t timestamp_rtp,
                        int64_t ntp_time_ms,
                        VideoRotation rotation,
-                       const absl::optional<ColorSpace>& color_space)
+                       const absl::optional<ColorSpace>& color_space,
+                       const absl::optional<HdrMetadata>& hdr_metadata)
     : video_frame_buffer_(buffer),
       timestamp_rtp_(timestamp_rtp),
       ntp_time_ms_(ntp_time_ms),
       timestamp_us_(timestamp_us),
       rotation_(rotation),
-      color_space_(color_space) {}
+      color_space_(color_space),
+      hdr_metadata_(hdr_metadata) {}
 
 VideoFrame::~VideoFrame() = default;
 
diff --git a/api/video/video_frame.h b/api/video/video_frame.h
index dcb533e..58362b0 100644
--- a/api/video/video_frame.h
+++ b/api/video/video_frame.h
@@ -15,12 +15,15 @@
 
 #include "absl/types/optional.h"
 #include "api/video/color_space.h"
+#include "api/video/hdr_metadata.h"
 #include "api/video/video_frame_buffer.h"
 #include "api/video/video_rotation.h"
+#include "rtc_base/scoped_ref_ptr.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
-class VideoFrame {
+class RTC_EXPORT VideoFrame {
  public:
   // Preferred way of building VideoFrame objects.
   class Builder {
@@ -37,6 +40,7 @@
     Builder& set_ntp_time_ms(int64_t ntp_time_ms);
     Builder& set_rotation(VideoRotation rotation);
     Builder& set_color_space(const ColorSpace& color_space);
+    Builder& set_hdr_metadata(const HdrMetadata& hdr_metadata);
 
    private:
     rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
@@ -45,6 +49,7 @@
     int64_t ntp_time_ms_ = 0;
     VideoRotation rotation_ = kVideoRotation_0;
     absl::optional<ColorSpace> color_space_;
+    absl::optional<HdrMetadata> hdr_metadata_;
   };
 
   // To be deprecated. Migrate all use to Builder.
@@ -110,9 +115,12 @@
   VideoRotation rotation() const { return rotation_; }
   void set_rotation(VideoRotation rotation) { rotation_ = rotation; }
 
-  // Set Color space when available.
+  // Get color space when available.
   absl::optional<ColorSpace> color_space() const { return color_space_; }
 
+  // Get HDR metadata when available.
+  absl::optional<HdrMetadata> hdr_metadata() const { return hdr_metadata_; }
+
   // Get render time in milliseconds.
   // TODO(nisse): Deprecated. Migrate all users to timestamp_us().
   int64_t render_time_ms() const;
@@ -133,7 +141,8 @@
              uint32_t timestamp_rtp,
              int64_t ntp_time_ms,
              VideoRotation rotation,
-             const absl::optional<ColorSpace>& color_space);
+             const absl::optional<ColorSpace>& color_space,
+             const absl::optional<HdrMetadata>& hdr_metadata);
 
   // An opaque reference counted handle that stores the pixel data.
   rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
@@ -142,6 +151,7 @@
   int64_t timestamp_us_;
   VideoRotation rotation_;
   absl::optional<ColorSpace> color_space_;
+  absl::optional<HdrMetadata> hdr_metadata_;
 };
 
 }  // namespace webrtc
diff --git a/api/video/video_source_interface.h b/api/video/video_source_interface.h
index 4ee4719..2bf7370 100644
--- a/api/video/video_source_interface.h
+++ b/api/video/video_source_interface.h
@@ -15,12 +15,13 @@
 
 #include "absl/types/optional.h"
 #include "api/video/video_sink_interface.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace rtc {
 
 // VideoSinkWants is used for notifying the source of properties a video frame
 // should have when it is delivered to a certain sink.
-struct VideoSinkWants {
+struct RTC_EXPORT VideoSinkWants {
   VideoSinkWants();
   VideoSinkWants(const VideoSinkWants&);
   ~VideoSinkWants();
diff --git a/api/video/video_stream_encoder_observer.h b/api/video/video_stream_encoder_observer.h
index b940efd..98b5cfc 100644
--- a/api/video/video_stream_encoder_observer.h
+++ b/api/video/video_stream_encoder_observer.h
@@ -11,6 +11,7 @@
 #ifndef API_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
 #define API_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
 
+#include <string>
 #include <vector>
 
 #include "absl/types/optional.h"
@@ -68,6 +69,9 @@
   virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
                                   const CodecSpecificInfo* codec_info) = 0;
 
+  virtual void OnEncoderImplementationChanged(
+      const std::string& implementation_name) = 0;
+
   virtual void OnFrameDropped(DropReason reason) = 0;
 
   // Used to indicate change in content type, which may require a change in
diff --git a/api/video/video_stream_encoder_settings.h b/api/video/video_stream_encoder_settings.h
index b67f33c..37c1de7 100644
--- a/api/video/video_stream_encoder_settings.h
+++ b/api/video/video_stream_encoder_settings.h
@@ -11,6 +11,7 @@
 #ifndef API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
 #define API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
 
+#include "api/video/video_bitrate_allocator_factory.h"
 #include "api/video_codecs/video_encoder_factory.h"
 
 namespace webrtc {
@@ -24,6 +25,9 @@
 
   // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
   VideoEncoderFactory* encoder_factory = nullptr;
+
+  // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
+  VideoBitrateAllocatorFactory* bitrate_allocator_factory = nullptr;
 };
 
 }  // namespace webrtc
diff --git a/audio/BUILD.gn b/audio/BUILD.gn
index 91cece9..4b2ec61 100644
--- a/audio/BUILD.gn
+++ b/audio/BUILD.gn
@@ -65,12 +65,14 @@
     "../common_audio:common_audio_c",
     "../logging:rtc_event_audio",
     "../logging:rtc_event_log_api",
+    "../logging:rtc_stream_config",
     "../modules/audio_coding",
+    "../modules/audio_coding:audio_encoder_cng",
     "../modules/audio_coding:audio_format_conversion",
     "../modules/audio_coding:audio_network_adaptor_config",
-    "../modules/audio_coding:cng",
     "../modules/audio_device",
     "../modules/audio_processing",
+    "../modules/audio_processing:api",
     "../modules/bitrate_controller:bitrate_controller",
     "../modules/pacing:pacing",
     "../modules/remote_bitrate_estimator:remote_bitrate_estimator",
@@ -128,22 +130,34 @@
       "mock_voe_channel_proxy.h",
       "remix_resample_unittest.cc",
       "test/audio_stats_test.cc",
+      "test/media_transport_test.cc",
       "time_interval_unittest.cc",
       "transport_feedback_packet_loss_tracker_unittest.cc",
     ]
     deps = [
       ":audio",
       ":audio_end_to_end_test",
+      "../api:loopback_media_transport",
       "../api:mock_audio_mixer",
+      "../api:mock_frame_decryptor",
+      "../api:mock_frame_encryptor",
       "../api/audio:audio_frame_api",
+      "../api/audio_codecs:audio_codecs_api",
+      "../api/audio_codecs/opus:audio_decoder_opus",
+      "../api/audio_codecs/opus:audio_encoder_opus",
       "../api/units:time_delta",
+      "../call:mock_bitrate_allocator",
       "../call:mock_call_interfaces",
       "../call:mock_rtp_interfaces",
       "../call:rtp_interfaces",
       "../call:rtp_receiver",
       "../common_audio",
       "../logging:mocks",
+      "../logging:rtc_event_log_api",
       "../modules/audio_device:mock_audio_device",
+
+      # For TestAudioDeviceModule
+      "../modules/audio_device:audio_device_impl",
       "../modules/audio_mixer:audio_mixer_impl",
       "../modules/audio_processing:audio_processing_statistics",
       "../modules/audio_processing:mocks",
@@ -151,6 +165,7 @@
       "../modules/pacing:pacing",
       "../modules/rtp_rtcp:mock_rtp_rtcp",
       "../modules/rtp_rtcp:rtp_rtcp_format",
+      "../modules/utility",
       "../rtc_base:checks",
       "../rtc_base:rtc_base_approved",
       "../rtc_base:rtc_base_tests_utils",
@@ -265,6 +280,7 @@
       "../test:single_threaded_task_queue",
       "../test:test_common",
       "../test:test_main",
+      "../test:test_support",
       "//testing/gtest",
       "//third_party/abseil-cpp/absl/memory",
     ]
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index 563e8a0..4f2e29c 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -13,14 +13,19 @@
 #include <string>
 #include <utility>
 
+#include "absl/memory/memory.h"
+#include "api/array_view.h"
+#include "api/audio_codecs/audio_format.h"
 #include "api/call/audio_sink.h"
+#include "api/rtpparameters.h"
 #include "audio/audio_send_stream.h"
 #include "audio/audio_state.h"
+#include "audio/channel_receive.h"
 #include "audio/channel_receive_proxy.h"
 #include "audio/conversion.h"
+#include "call/rtp_config.h"
 #include "call/rtp_stream_receiver_controller_interface.h"
-#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "common_types.h"  // NOLINT(build/include)
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/strings/string_builder.h"
@@ -53,6 +58,7 @@
   ss << "{rtp: " << rtp.ToString();
   ss << ", rtcp_send_transport: "
      << (rtcp_send_transport ? "(Transport)" : "null");
+  ss << ", media_transport: " << (media_transport ? "(Transport)" : "null");
   if (!sync_group.empty()) {
     ss << ", sync_group: " << sync_group;
   }
@@ -73,10 +79,10 @@
   return absl::make_unique<voe::ChannelReceiveProxy>(
       absl::make_unique<voe::ChannelReceive>(
           module_process_thread, internal_audio_state->audio_device_module(),
-          config.rtcp_send_transport, event_log, config.rtp.remote_ssrc,
-          config.jitter_buffer_max_packets,
+          config.media_transport, config.rtcp_send_transport, event_log,
+          config.rtp.remote_ssrc, config.jitter_buffer_max_packets,
           config.jitter_buffer_fast_accelerate, config.decoder_factory,
-          config.codec_pair_id, config.frame_decryptor));
+          config.codec_pair_id, config.frame_decryptor, config.crypto_options));
 }
 }  // namespace
 
@@ -106,8 +112,6 @@
     std::unique_ptr<voe::ChannelReceiveProxy> channel_proxy)
     : audio_state_(audio_state), channel_proxy_(std::move(channel_proxy)) {
   RTC_LOG(LS_INFO) << "AudioReceiveStream: " << config.rtp.remote_ssrc;
-  RTC_DCHECK(receiver_controller);
-  RTC_DCHECK(packet_router);
   RTC_DCHECK(config.decoder_factory);
   RTC_DCHECK(config.rtcp_send_transport);
   RTC_DCHECK(audio_state_);
@@ -115,13 +119,16 @@
 
   module_process_thread_checker_.DetachFromThread();
 
-  // Configure bandwidth estimation.
-  channel_proxy_->RegisterReceiverCongestionControlObjects(packet_router);
+  if (!config.media_transport) {
+    RTC_DCHECK(receiver_controller);
+    RTC_DCHECK(packet_router);
+    // Configure bandwidth estimation.
+    channel_proxy_->RegisterReceiverCongestionControlObjects(packet_router);
 
-  // Register with transport.
-  rtp_stream_receiver_ = receiver_controller->CreateReceiver(
-      config.rtp.remote_ssrc, channel_proxy_.get());
-
+    // Register with transport.
+    rtp_stream_receiver_ = receiver_controller->CreateReceiver(
+        config.rtp.remote_ssrc, channel_proxy_.get());
+  }
   ConfigureStream(this, config, true);
 }
 
@@ -130,7 +137,9 @@
   RTC_LOG(LS_INFO) << "~AudioReceiveStream: " << config_.rtp.remote_ssrc;
   Stop();
   channel_proxy_->DisassociateSendChannel();
-  channel_proxy_->ResetReceiverCongestionControlObjects();
+  if (!config_.media_transport) {
+    channel_proxy_->ResetReceiverCongestionControlObjects();
+  }
 }
 
 void AudioReceiveStream::Reconfigure(
diff --git a/audio/audio_receive_stream.h b/audio/audio_receive_stream.h
index e982b04..dde0da4 100644
--- a/audio/audio_receive_stream.h
+++ b/audio/audio_receive_stream.h
@@ -18,7 +18,6 @@
 #include "api/rtp_headers.h"
 #include "audio/audio_state.h"
 #include "call/audio_receive_stream.h"
-#include "call/rtp_packet_sink_interface.h"
 #include "call/syncable.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/thread_checker.h"
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index 97c42c4..a5c7e20 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "api/test/mock_audio_mixer.h"
+#include "api/test/mock_frame_decryptor.h"
 #include "audio/audio_receive_stream.h"
 #include "audio/conversion.h"
 #include "audio/mock_voe_channel_proxy.h"
@@ -216,7 +217,7 @@
       "{rtp: {remote_ssrc: 1234, local_ssrc: 5678, transport_cc: off, nack: "
       "{rtp_history_ms: 0}, extensions: [{uri: "
       "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 3}]}, "
-      "rtcp_send_transport: null}",
+      "rtcp_send_transport: null, media_transport: null}",
       config.ToString());
 }
 
@@ -373,5 +374,25 @@
 
   recv_stream->Reconfigure(new_config);
 }
+
+TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
+  ConfigHelper helper;
+  auto recv_stream = helper.CreateAudioReceiveStream();
+
+  auto new_config_0 = helper.config();
+  rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_0(
+      new rtc::RefCountedObject<MockFrameDecryptor>());
+  new_config_0.frame_decryptor = mock_frame_decryptor_0;
+
+  recv_stream->Reconfigure(new_config_0);
+
+  auto new_config_1 = helper.config();
+  rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_1(
+      new rtc::RefCountedObject<MockFrameDecryptor>());
+  new_config_1.frame_decryptor = mock_frame_decryptor_1;
+  new_config_1.crypto_options.sframe.require_frame_encryption = true;
+  recv_stream->Reconfigure(new_config_1);
+}
+
 }  // namespace test
 }  // namespace webrtc
diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc
index 49d933c..37f89c5 100644
--- a/audio/audio_send_stream.cc
+++ b/audio/audio_send_stream.cc
@@ -15,12 +15,24 @@
 #include <vector>
 
 #include "absl/memory/memory.h"
-
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/call/transport.h"
+#include "api/crypto/frameencryptorinterface.h"
 #include "audio/audio_state.h"
+#include "audio/channel_send.h"
 #include "audio/channel_send_proxy.h"
 #include "audio/conversion.h"
+#include "call/rtp_config.h"
 #include "call/rtp_transport_controller_send_interface.h"
+#include "common_audio/vad/include/vad.h"
+#include "common_types.h"  // NOLINT(build/include)
+#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
+#include "logging/rtc_event_log/rtc_event_log.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
 #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
+#include "modules/audio_processing/include/audio_processing.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/event.h"
 #include "rtc_base/function_view.h"
@@ -49,14 +61,50 @@
 std::unique_ptr<voe::ChannelSendProxy> CreateChannelAndProxy(
     rtc::TaskQueue* worker_queue,
     ProcessThread* module_process_thread,
+    MediaTransportInterface* media_transport,
     RtcpRttStats* rtcp_rtt_stats,
     RtcEventLog* event_log,
-    FrameEncryptorInterface* frame_encryptor) {
+    FrameEncryptorInterface* frame_encryptor,
+    const webrtc::CryptoOptions& crypto_options,
+    bool extmap_allow_mixed) {
   return absl::make_unique<voe::ChannelSendProxy>(
-      absl::make_unique<voe::ChannelSend>(worker_queue, module_process_thread,
-                                          rtcp_rtt_stats, event_log,
-                                          frame_encryptor));
+      absl::make_unique<voe::ChannelSend>(
+          worker_queue, module_process_thread, media_transport, rtcp_rtt_stats,
+          event_log, frame_encryptor, crypto_options, extmap_allow_mixed));
 }
+
+void UpdateEventLogStreamConfig(RtcEventLog* event_log,
+                                const AudioSendStream::Config& config,
+                                const AudioSendStream::Config* old_config) {
+  using SendCodecSpec = AudioSendStream::Config::SendCodecSpec;
+  // Only update if any of the things we log have changed.
+  auto payload_types_equal = [](const absl::optional<SendCodecSpec>& a,
+                                const absl::optional<SendCodecSpec>& b) {
+    if (a.has_value() && b.has_value()) {
+      return a->format.name == b->format.name &&
+             a->payload_type == b->payload_type;
+    }
+    return !a.has_value() && !b.has_value();
+  };
+
+  if (old_config && config.rtp.ssrc == old_config->rtp.ssrc &&
+      config.rtp.extensions == old_config->rtp.extensions &&
+      payload_types_equal(config.send_codec_spec,
+                          old_config->send_codec_spec)) {
+    return;
+  }
+
+  auto rtclog_config = absl::make_unique<rtclog::StreamConfig>();
+  rtclog_config->local_ssrc = config.rtp.ssrc;
+  rtclog_config->rtp_extensions = config.rtp.extensions;
+  if (config.send_codec_spec) {
+    rtclog_config->codecs.emplace_back(config.send_codec_spec->format.name,
+                                       config.send_codec_spec->payload_type, 0);
+  }
+  event_log->Log(absl::make_unique<RtcEventAudioSendStreamConfig>(
+      std::move(rtclog_config)));
+}
+
 }  // namespace
 
 // Helper class to track the actively sending lifetime of this stream.
@@ -87,8 +135,8 @@
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
     rtc::TaskQueue* worker_queue,
     ProcessThread* module_process_thread,
-    RtpTransportControllerSendInterface* transport,
-    BitrateAllocator* bitrate_allocator,
+    RtpTransportControllerSendInterface* rtp_transport,
+    BitrateAllocatorInterface* bitrate_allocator,
     RtcEventLog* event_log,
     RtcpRttStats* rtcp_rtt_stats,
     const absl::optional<RtpState>& suspended_rtp_state,
@@ -96,7 +144,7 @@
     : AudioSendStream(config,
                       audio_state,
                       worker_queue,
-                      transport,
+                      rtp_transport,
                       bitrate_allocator,
                       event_log,
                       rtcp_rtt_stats,
@@ -104,28 +152,32 @@
                       overall_call_lifetime,
                       CreateChannelAndProxy(worker_queue,
                                             module_process_thread,
+                                            config.media_transport,
                                             rtcp_rtt_stats,
                                             event_log,
-                                            config.frame_encryptor)) {}
+                                            config.frame_encryptor,
+                                            config.crypto_options,
+                                            config.rtp.extmap_allow_mixed)) {}
 
 AudioSendStream::AudioSendStream(
     const webrtc::AudioSendStream::Config& config,
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
     rtc::TaskQueue* worker_queue,
-    RtpTransportControllerSendInterface* transport,
-    BitrateAllocator* bitrate_allocator,
+    RtpTransportControllerSendInterface* rtp_transport,
+    BitrateAllocatorInterface* bitrate_allocator,
     RtcEventLog* event_log,
     RtcpRttStats* rtcp_rtt_stats,
     const absl::optional<RtpState>& suspended_rtp_state,
     TimeInterval* overall_call_lifetime,
     std::unique_ptr<voe::ChannelSendProxy> channel_proxy)
     : worker_queue_(worker_queue),
-      config_(Config(nullptr)),
+      config_(Config(/*send_transport=*/nullptr,
+                     /*media_transport=*/nullptr)),
       audio_state_(audio_state),
       channel_proxy_(std::move(channel_proxy)),
       event_log_(event_log),
       bitrate_allocator_(bitrate_allocator),
-      transport_(transport),
+      rtp_transport_(rtp_transport),
       packet_loss_tracker_(kPacketLossTrackerMaxWindowSizeMs,
                            kPacketLossRateMinNumAckedPackets,
                            kRecoverablePacketLossRateMinNumAckedPairs),
@@ -137,7 +189,11 @@
   RTC_DCHECK(audio_state_);
   RTC_DCHECK(channel_proxy_);
   RTC_DCHECK(bitrate_allocator_);
-  RTC_DCHECK(transport);
+  // TODO(nisse): Eventually, we should have only media_transport. But for the
+  // time being, we can have either. When media transport is injected, there
+  // should be no rtp_transport, and below check should be strengthened to XOR
+  // (either rtp_transport or media_transport but not both).
+  RTC_DCHECK(rtp_transport || config.media_transport);
   RTC_DCHECK(overall_call_lifetime_);
 
   channel_proxy_->SetRTCPStatus(true);
@@ -147,17 +203,22 @@
   ConfigureStream(this, config, true);
 
   pacer_thread_checker_.DetachFromThread();
-  // Signal congestion controller this object is ready for OnPacket* callbacks.
-  transport_->RegisterPacketFeedbackObserver(this);
+  if (rtp_transport_) {
+    // Signal congestion controller this object is ready for OnPacket*
+    // callbacks.
+    rtp_transport_->RegisterPacketFeedbackObserver(this);
+  }
 }
 
 AudioSendStream::~AudioSendStream() {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   RTC_LOG(LS_INFO) << "~AudioSendStream: " << config_.rtp.ssrc;
   RTC_DCHECK(!sending_);
-  transport_->DeRegisterPacketFeedbackObserver(this);
-  channel_proxy_->RegisterTransport(nullptr);
-  channel_proxy_->ResetSenderCongestionControlObjects();
+  if (rtp_transport_) {
+    rtp_transport_->DeRegisterPacketFeedbackObserver(this);
+    channel_proxy_->RegisterTransport(nullptr);
+    channel_proxy_->ResetSenderCongestionControlObjects();
+  }
   // Lifetime can only be updated after deregistering
   // |timed_send_transport_adapter_| in the underlying channel object to avoid
   // data races in |active_lifetime_|.
@@ -196,6 +257,9 @@
     bool first_time) {
   RTC_LOG(LS_INFO) << "AudioSendStream::ConfigureStream: "
                    << new_config.ToString();
+  UpdateEventLogStreamConfig(stream->event_log_, new_config,
+                             first_time ? nullptr : &stream->config_);
+
   const auto& channel_proxy = stream->channel_proxy_;
   const auto& old_config = stream->config_;
 
@@ -235,6 +299,11 @@
     channel_proxy->SetFrameEncryptor(new_config.frame_encryptor);
   }
 
+  if (first_time ||
+      new_config.rtp.extmap_allow_mixed != old_config.rtp.extmap_allow_mixed) {
+    channel_proxy->SetExtmapAllowMixed(new_config.rtp.extmap_allow_mixed);
+  }
+
   const ExtensionIds old_ids = FindExtensionIds(old_config.rtp.extensions);
   const ExtensionIds new_ids = FindExtensionIds(new_config.rtp.extensions);
   // Audio level indication
@@ -261,14 +330,16 @@
       // Probing in application limited region is only used in combination with
       // send side congestion control, wich depends on feedback packets which
       // requires transport sequence numbers to be enabled.
-      stream->transport_->EnablePeriodicAlrProbing(true);
-      bandwidth_observer = stream->transport_->GetBandwidthObserver();
+      if (stream->rtp_transport_) {
+        stream->rtp_transport_->EnablePeriodicAlrProbing(true);
+        bandwidth_observer = stream->rtp_transport_->GetBandwidthObserver();
+      }
     }
-
-    channel_proxy->RegisterSenderCongestionControlObjects(stream->transport_,
-                                                          bandwidth_observer);
+    if (stream->rtp_transport_) {
+      channel_proxy->RegisterSenderCongestionControlObjects(
+          stream->rtp_transport_, bandwidth_observer);
+    }
   }
-
   // MID RTP header extension.
   if ((first_time || new_ids.mid != old_ids.mid ||
        new_config.rtp.mid != old_config.rtp.mid) &&
@@ -296,11 +367,12 @@
       FindExtensionIds(config_.rtp.extensions).transport_sequence_number != 0 &&
       !webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC");
   if (config_.min_bitrate_bps != -1 && config_.max_bitrate_bps != -1 &&
+      !config_.has_dscp &&
       (has_transport_sequence_number ||
        !webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe") ||
        webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC"))) {
     // Audio BWE is enabled.
-    transport_->packet_sender()->SetAccountForAudioPackets(true);
+    rtp_transport_->packet_sender()->SetAccountForAudioPackets(true);
     rtp_rtcp_module_->SetAsPartOfAllocation(true);
     ConfigureBitrateObserver(config_.min_bitrate_bps, config_.max_bitrate_bps,
                              config_.bitrate_priority,
@@ -355,6 +427,7 @@
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   webrtc::AudioSendStream::Stats stats;
   stats.local_ssrc = config_.rtp.ssrc;
+  stats.target_bitrate_bps = channel_proxy_->GetBitrate();
 
   webrtc::CallSendStatistics call_stats = channel_proxy_->GetRTCPStatistics();
   stats.bytes_sent = call_stats.bytesSent;
@@ -412,24 +485,22 @@
   return channel_proxy_->ReceivedRTCPPacket(packet, length);
 }
 
-uint32_t AudioSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
-                                           uint8_t fraction_loss,
-                                           int64_t rtt,
-                                           int64_t bwe_period_ms) {
+uint32_t AudioSendStream::OnBitrateUpdated(BitrateAllocationUpdate update) {
   // A send stream may be allocated a bitrate of zero if the allocator decides
   // to disable it. For now we ignore this decision and keep sending on min
   // bitrate.
-  if (bitrate_bps == 0) {
-    bitrate_bps = config_.min_bitrate_bps;
+  if (update.bitrate_bps == 0) {
+    update.bitrate_bps = config_.min_bitrate_bps;
   }
-  RTC_DCHECK_GE(bitrate_bps, static_cast<uint32_t>(config_.min_bitrate_bps));
+  RTC_DCHECK_GE(update.bitrate_bps,
+                static_cast<uint32_t>(config_.min_bitrate_bps));
   // The bitrate allocator might allocate an higher than max configured bitrate
   // if there is room, to allow for, as example, extra FEC. Ignore that for now.
   const uint32_t max_bitrate_bps = config_.max_bitrate_bps;
-  if (bitrate_bps > max_bitrate_bps)
-    bitrate_bps = max_bitrate_bps;
+  if (update.bitrate_bps > max_bitrate_bps)
+    update.bitrate_bps = max_bitrate_bps;
 
-  channel_proxy_->SetBitrate(bitrate_bps, bwe_period_ms);
+  channel_proxy_->SetBitrate(update.bitrate_bps, update.bwe_period_ms);
 
   // The amount of audio protection is not exposed by the encoder, hence
   // always returning 0.
@@ -552,12 +623,12 @@
 
   // Wrap the encoder in a an AudioEncoderCNG, if VAD is enabled.
   if (spec.cng_payload_type) {
-    AudioEncoderCng::Config cng_config;
+    AudioEncoderCngConfig cng_config;
     cng_config.num_channels = encoder->NumChannels();
     cng_config.payload_type = *spec.cng_payload_type;
     cng_config.speech_encoder = std::move(encoder);
     cng_config.vad_mode = Vad::kVadNormal;
-    encoder.reset(new AudioEncoderCng(std::move(cng_config)));
+    encoder = CreateComfortNoiseEncoder(std::move(cng_config));
 
     stream->RegisterCngPayloadType(
         *spec.cng_payload_type,
@@ -679,12 +750,12 @@
           old_encoder = std::move(tmp);
         }
         if (new_config.send_codec_spec->cng_payload_type) {
-          AudioEncoderCng::Config config;
+          AudioEncoderCngConfig config;
           config.speech_encoder = std::move(old_encoder);
           config.num_channels = config.speech_encoder->NumChannels();
           config.payload_type = *new_config.send_codec_spec->cng_payload_type;
           config.vad_mode = Vad::kVadNormal;
-          encoder_ptr->reset(new AudioEncoderCng(std::move(config)));
+          *encoder_ptr = CreateComfortNoiseEncoder(std::move(config));
         } else {
           *encoder_ptr = std::move(old_encoder);
         }
@@ -711,13 +782,16 @@
 
   bool has_transport_sequence_number = new_transport_seq_num_id != 0;
   if (new_config.min_bitrate_bps != -1 && new_config.max_bitrate_bps != -1 &&
+      !new_config.has_dscp &&
       (has_transport_sequence_number ||
        !webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe"))) {
+    stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(true);
     stream->ConfigureBitrateObserver(
         new_config.min_bitrate_bps, new_config.max_bitrate_bps,
         new_config.bitrate_priority, has_transport_sequence_number);
     stream->rtp_rtcp_module_->SetAsPartOfAllocation(true);
   } else {
+    stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(false);
     stream->RemoveBitrateObserver();
     stream->rtp_rtcp_module_->SetAsPartOfAllocation(false);
   }
@@ -729,7 +803,7 @@
                                                bool has_packet_feedback) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   RTC_DCHECK_GE(max_bitrate_bps, min_bitrate_bps);
-  rtc::Event thread_sync_event(false /* manual_reset */, false);
+  rtc::Event thread_sync_event;
   worker_queue_->PostTask([&] {
     // We may get a callback immediately as the observer is registered, so make
     // sure the bitrate limits in config_ are up-to-date.
@@ -749,7 +823,7 @@
 
 void AudioSendStream::RemoveBitrateObserver() {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  rtc::Event thread_sync_event(false /* manual_reset */, false);
+  rtc::Event thread_sync_event;
   worker_queue_->PostTask([this, &thread_sync_event] {
     bitrate_allocator_->RemoveObserver(this);
     thread_sync_event.Set();
diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h
index 1ea676b..c86a9dc 100644
--- a/audio/audio_send_stream.h
+++ b/audio/audio_send_stream.h
@@ -45,8 +45,8 @@
                   const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
                   rtc::TaskQueue* worker_queue,
                   ProcessThread* module_process_thread,
-                  RtpTransportControllerSendInterface* transport,
-                  BitrateAllocator* bitrate_allocator,
+                  RtpTransportControllerSendInterface* rtp_transport,
+                  BitrateAllocatorInterface* bitrate_allocator,
                   RtcEventLog* event_log,
                   RtcpRttStats* rtcp_rtt_stats,
                   const absl::optional<RtpState>& suspended_rtp_state,
@@ -55,8 +55,8 @@
   AudioSendStream(const webrtc::AudioSendStream::Config& config,
                   const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
                   rtc::TaskQueue* worker_queue,
-                  RtpTransportControllerSendInterface* transport,
-                  BitrateAllocator* bitrate_allocator,
+                  RtpTransportControllerSendInterface* rtp_transport,
+                  BitrateAllocatorInterface* bitrate_allocator,
                   RtcEventLog* event_log,
                   RtcpRttStats* rtcp_rtt_stats,
                   const absl::optional<RtpState>& suspended_rtp_state,
@@ -83,10 +83,7 @@
   bool DeliverRtcp(const uint8_t* packet, size_t length);
 
   // Implements BitrateAllocatorObserver.
-  uint32_t OnBitrateUpdated(uint32_t bitrate_bps,
-                            uint8_t fraction_loss,
-                            int64_t rtt,
-                            int64_t bwe_period_ms) override;
+  uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) override;
 
   // From PacketFeedbackObserver.
   void OnPacketAdded(uint32_t ssrc, uint16_t seq_num) override;
@@ -140,8 +137,8 @@
   size_t encoder_num_channels_ = 0;
   bool sending_ = false;
 
-  BitrateAllocator* const bitrate_allocator_;
-  RtpTransportControllerSendInterface* const transport_;
+  BitrateAllocatorInterface* const bitrate_allocator_;
+  RtpTransportControllerSendInterface* const rtp_transport_;
 
   rtc::CriticalSection packet_loss_tracker_cs_;
   TransportFeedbackPacketLossTracker packet_loss_tracker_
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index 0a954f8..6a92329 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "absl/memory/memory.h"
+#include "api/test/mock_frame_encryptor.h"
 #include "api/units/time_delta.h"
 #include "audio/audio_send_stream.h"
 #include "audio/audio_state.h"
@@ -128,7 +129,7 @@
 
 struct ConfigHelper {
   ConfigHelper(bool audio_bwe_enabled, bool expect_set_encoder_call)
-      : stream_config_(nullptr),
+      : stream_config_(/*send_transport=*/nullptr, /*media_transport=*/nullptr),
         audio_processing_(new rtc::RefCountedObject<MockAudioProcessing>()),
         bitrate_allocator_(&limit_observer_),
         worker_queue_("ConfigHelper_worker_queue"),
@@ -196,7 +197,8 @@
     EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1);
     EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1);
     EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 10)).Times(1);
-    EXPECT_CALL(*channel_proxy_, SetFrameEncryptor(nullptr)).Times(1);
+    EXPECT_CALL(*channel_proxy_, SetFrameEncryptor(_)).Times(1);
+    EXPECT_CALL(*channel_proxy_, SetExtmapAllowMixed(false)).Times(1);
     EXPECT_CALL(*channel_proxy_,
                 SetSendAudioLevelIndicationStatus(true, kAudioLevelId))
         .Times(1);
@@ -278,6 +280,7 @@
         .WillRepeatedly(Return(report_blocks));
     EXPECT_CALL(*channel_proxy_, GetANAStatistics())
         .WillRepeatedly(Return(ANAStats()));
+    EXPECT_CALL(*channel_proxy_, GetBitrate()).WillRepeatedly(Return(0));
 
     audio_processing_stats_.echo_return_loss = kEchoReturnLoss;
     audio_processing_stats_.echo_return_loss_enhancement =
@@ -316,7 +319,8 @@
 }  // namespace
 
 TEST(AudioSendStreamTest, ConfigToString) {
-  AudioSendStream::Config config(nullptr);
+  AudioSendStream::Config config(/*send_transport=*/nullptr,
+                                 /*media_transport=*/nullptr);
   config.rtp.ssrc = kSsrc;
   config.rtp.c_name = kCName;
   config.min_bitrate_bps = 12000;
@@ -327,12 +331,14 @@
   config.send_codec_spec->transport_cc_enabled = false;
   config.send_codec_spec->cng_payload_type = 42;
   config.encoder_factory = MockAudioEncoderFactory::CreateUnusedFactory();
+  config.rtp.extmap_allow_mixed = true;
   config.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
   EXPECT_EQ(
-      "{rtp: {ssrc: 1234, extensions: [{uri: "
+      "{rtp: {ssrc: 1234, extmap-allow-mixed: true, extensions: [{uri: "
       "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 2}], nack: "
       "{rtp_history_ms: 0}, c_name: foo_name}, send_transport: null, "
+      "media_transport: null, "
       "min_bitrate_bps: 12000, max_bitrate_bps: 34000, "
       "send_codec_spec: {nack_enabled: true, transport_cc_enabled: false, "
       "cng_payload_type: 42, payload_type: 103, "
@@ -470,15 +476,24 @@
   auto send_stream = helper.CreateAudioSendStream();
   EXPECT_CALL(*helper.channel_proxy(),
               SetBitrate(helper.config().max_bitrate_bps, _));
-  send_stream->OnBitrateUpdated(helper.config().max_bitrate_bps + 5000, 0.0, 50,
-                                6000);
+  BitrateAllocationUpdate update;
+  update.bitrate_bps = helper.config().max_bitrate_bps + 5000;
+  update.fraction_loss = 0;
+  update.rtt = 50;
+  update.bwe_period_ms = 6000;
+  send_stream->OnBitrateUpdated(update);
 }
 
 TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
   ConfigHelper helper(false, true);
   auto send_stream = helper.CreateAudioSendStream();
   EXPECT_CALL(*helper.channel_proxy(), SetBitrate(_, 5000));
-  send_stream->OnBitrateUpdated(50000, 0.0, 50, 5000);
+  BitrateAllocationUpdate update;
+  update.bitrate_bps = helper.config().max_bitrate_bps + 5000;
+  update.fraction_loss = 0;
+  update.rtt = 50;
+  update.bwe_period_ms = 5000;
+  send_stream->OnBitrateUpdated(update);
 }
 
 // Test that AudioSendStream doesn't recreate the encoder unnecessarily.
@@ -518,6 +533,32 @@
   send_stream->Reconfigure(new_config);
 }
 
+// Validates that reconfiguring the AudioSendStream with a Frame encryptor
+// correctly reconfigures on the object without crashing.
+TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) {
+  ConfigHelper helper(false, true);
+  auto send_stream = helper.CreateAudioSendStream();
+  auto new_config = helper.config();
+
+  rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
+      new rtc::RefCountedObject<MockFrameEncryptor>());
+  new_config.frame_encryptor = mock_frame_encryptor_0;
+  EXPECT_CALL(*helper.channel_proxy(), SetFrameEncryptor(Ne(nullptr))).Times(1);
+  send_stream->Reconfigure(new_config);
+
+  // Not updating the frame encryptor shouldn't force it to reconfigure.
+  EXPECT_CALL(*helper.channel_proxy(), SetFrameEncryptor(_)).Times(0);
+  send_stream->Reconfigure(new_config);
+
+  // Updating frame encryptor to a new object should force a call to the proxy.
+  rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
+      new rtc::RefCountedObject<MockFrameEncryptor>());
+  new_config.frame_encryptor = mock_frame_encryptor_1;
+  new_config.crypto_options.sframe.require_frame_encryption = true;
+  EXPECT_CALL(*helper.channel_proxy(), SetFrameEncryptor(Ne(nullptr))).Times(1);
+  send_stream->Reconfigure(new_config);
+}
+
 // Checks that AudioSendStream logs the times at which RTP packets are sent
 // through its interface.
 TEST(AudioSendStreamTest, UpdateLifetime) {
diff --git a/audio/audio_transport_impl.cc b/audio/audio_transport_impl.cc
index 94ef6cb..539456e 100644
--- a/audio/audio_transport_impl.cc
+++ b/audio/audio_transport_impl.cc
@@ -17,7 +17,7 @@
 #include "audio/remix_resample.h"
 #include "audio/utility/audio_frame_operations.h"
 #include "call/audio_send_stream.h"
-#include "rtc_base/logging.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc
index e9f7503..704ba79 100644
--- a/audio/channel_receive.cc
+++ b/audio/channel_receive.cc
@@ -26,6 +26,7 @@
 #include "modules/audio_device/include/audio_device.h"
 #include "modules/pacing/packet_router.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
+#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 #include "modules/utility/include/process_thread.h"
 #include "rtc_base/checks.h"
@@ -50,12 +51,47 @@
 constexpr int kVoiceEngineMinMinPlayoutDelayMs = 0;
 constexpr int kVoiceEngineMaxMinPlayoutDelayMs = 10000;
 
+webrtc::FrameType WebrtcFrameTypeForMediaTransportFrameType(
+    MediaTransportEncodedAudioFrame::FrameType frame_type) {
+  switch (frame_type) {
+    case MediaTransportEncodedAudioFrame::FrameType::kSpeech:
+      return kAudioFrameSpeech;
+      break;
+
+    case MediaTransportEncodedAudioFrame::FrameType::
+        kDiscountinuousTransmission:
+      return kAudioFrameCN;
+      break;
+  }
+}
+
+WebRtcRTPHeader CreateWebrtcRTPHeaderForMediaTransportFrame(
+    const MediaTransportEncodedAudioFrame& frame,
+    uint64_t channel_id) {
+  webrtc::WebRtcRTPHeader webrtc_header = {};
+  webrtc_header.header.payloadType = frame.payload_type();
+  webrtc_header.header.payload_type_frequency = frame.sampling_rate_hz();
+  webrtc_header.header.timestamp = frame.starting_sample_index();
+  webrtc_header.header.sequenceNumber = frame.sequence_number();
+
+  webrtc_header.frameType =
+      WebrtcFrameTypeForMediaTransportFrameType(frame.frame_type());
+
+  webrtc_header.header.ssrc = static_cast<uint32_t>(channel_id);
+
+  // The rest are initialized by the RTPHeader constructor.
+  return webrtc_header;
+}
+
 }  // namespace
 
 int32_t ChannelReceive::OnReceivedPayloadData(
     const uint8_t* payloadData,
     size_t payloadSize,
     const WebRtcRTPHeader* rtpHeader) {
+  // We should not be receiving any RTP packets if media_transport is set.
+  RTC_CHECK(!media_transport_);
+
   if (!channel_state_.Get().playing) {
     // Avoid inserting into NetEQ when we are not playing. Count the
     // packet as discarded.
@@ -82,6 +118,27 @@
   return 0;
 }
 
+// MediaTransportAudioSinkInterface override.
+void ChannelReceive::OnData(uint64_t channel_id,
+                            MediaTransportEncodedAudioFrame frame) {
+  RTC_CHECK(media_transport_);
+
+  if (!channel_state_.Get().playing) {
+    // Avoid inserting into NetEQ when we are not playing. Count the
+    // packet as discarded.
+    return;
+  }
+
+  // Send encoded audio frame to Decoder / NetEq.
+  if (audio_coding_->IncomingPacket(
+          frame.encoded_data().data(), frame.encoded_data().size(),
+          CreateWebrtcRTPHeaderForMediaTransportFrame(frame, channel_id)) !=
+      0) {
+    RTC_DLOG(LS_ERROR) << "ChannelReceive::OnData: unable to "
+                          "push data to the ACM";
+  }
+}
+
 AudioMixer::Source::AudioFrameInfo ChannelReceive::GetAudioFrameWithInfo(
     int sample_rate_hz,
     AudioFrame* audio_frame) {
@@ -199,6 +256,7 @@
 ChannelReceive::ChannelReceive(
     ProcessThread* module_process_thread,
     AudioDeviceModule* audio_device_module,
+    MediaTransportInterface* media_transport,
     Transport* rtcp_send_transport,
     RtcEventLog* rtc_event_log,
     uint32_t remote_ssrc,
@@ -206,7 +264,8 @@
     bool jitter_buffer_fast_playout,
     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
     absl::optional<AudioCodecPairId> codec_pair_id,
-    FrameDecryptorInterface* frame_decryptor)
+    rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
+    const webrtc::CryptoOptions& crypto_options)
     : event_log_(rtc_event_log),
       rtp_receive_statistics_(
           ReceiveStatistics::Create(Clock::GetRealTimeClock())),
@@ -222,7 +281,9 @@
       _audioDeviceModulePtr(audio_device_module),
       _outputGain(1.0f),
       associated_send_channel_(nullptr),
-      frame_decryptor_(frame_decryptor) {
+      media_transport_(media_transport),
+      frame_decryptor_(frame_decryptor),
+      crypto_options_(crypto_options) {
   RTC_DCHECK(module_process_thread);
   RTC_DCHECK(audio_device_module);
   AudioCodingModule::Config acm_config;
@@ -238,9 +299,7 @@
   rtp_receive_statistics_->EnableRetransmitDetection(remote_ssrc_, true);
   RtpRtcp::Configuration configuration;
   configuration.audio = true;
-  // TODO(nisse): Also set receiver_only = true, but that seems to break RTT
-  // estimation, resulting in test failures for
-  // PeerConnectionIntegrationTest.GetCaptureStartNtpTimeWithOldStatsApi
+  configuration.receiver_only = true;
   configuration.outgoing_transport = rtcp_send_transport;
   configuration.receive_statistics = rtp_receive_statistics_.get();
 
@@ -276,10 +335,19 @@
   // be transmitted since the Transport object will then be invalid.
   // RTCP is enabled by default.
   _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound);
+
+  if (media_transport_) {
+    media_transport_->SetReceiveAudioSink(this);
+  }
 }
 
 void ChannelReceive::Terminate() {
   RTC_DCHECK(construction_thread_.CalledOnValidThread());
+
+  if (media_transport_) {
+    media_transport_->SetReceiveAudioSink(nullptr);
+  }
+
   // Must be called on the same thread as Init().
   rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
 
@@ -369,7 +437,9 @@
     if (has_audio_level)
       last_received_rtp_audio_level_ = audio_level;
     std::vector<uint32_t> csrcs = packet.Csrcs();
-    contributing_sources_.Update(now_ms, csrcs);
+    contributing_sources_.Update(
+        now_ms, csrcs,
+        has_audio_level ? absl::optional<uint8_t>(audio_level) : absl::nullopt);
   }
 
   // Store playout timestamp for the received RTP packet
@@ -429,6 +499,10 @@
     // Update the final payload.
     payload = decrypted_audio_payload.data();
     payload_data_length = decrypted_audio_payload.size();
+  } else if (crypto_options_.sframe.require_frame_encryption) {
+    RTC_DLOG(LS_ERROR)
+        << "FrameDecryptor required but not set, dropping packet";
+    payload_data_length = 0;
   }
 
   if (payload_data_length == 0) {
@@ -705,6 +779,8 @@
   int64_t avg_rtt = 0;
   int64_t max_rtt = 0;
   int64_t min_rtt = 0;
+  // TODO(nisse): This method computes RTT based on sender reports, even though
+  // a receive stream is not supposed to do that.
   if (_rtpRtcpModule->RTT(remote_ssrc_, &rtt, &avg_rtt, &min_rtt, &max_rtt) !=
       0) {
     return 0;
diff --git a/audio/channel_receive.h b/audio/channel_receive.h
index 82eb4df..0c50962 100644
--- a/audio/channel_receive.h
+++ b/audio/channel_receive.h
@@ -19,6 +19,8 @@
 #include "api/audio/audio_mixer.h"
 #include "api/call/audio_sink.h"
 #include "api/call/transport.h"
+#include "api/crypto/cryptooptions.h"
+#include "api/media_transport_interface.h"
 #include "api/rtpreceiverinterface.h"
 #include "audio/audio_level.h"
 #include "call/syncable.h"
@@ -102,11 +104,12 @@
   State state_;
 };
 
-class ChannelReceive : public RtpData {
+class ChannelReceive : public RtpData, public MediaTransportAudioSinkInterface {
  public:
   // Used for receive streams.
   ChannelReceive(ProcessThread* module_process_thread,
                  AudioDeviceModule* audio_device_module,
+                 MediaTransportInterface* media_transport,
                  Transport* rtcp_send_transport,
                  RtcEventLog* rtc_event_log,
                  uint32_t remote_ssrc,
@@ -114,7 +117,8 @@
                  bool jitter_buffer_fast_playout,
                  rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
                  absl::optional<AudioCodecPairId> codec_pair_id,
-                 FrameDecryptorInterface* frame_decryptor);
+                 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
+                 const webrtc::CryptoOptions& crypto_options);
   virtual ~ChannelReceive();
 
   void SetSink(AudioSinkInterface* sink);
@@ -163,6 +167,10 @@
   int GetRTPStatistics(CallReceiveStatistics& stats);  // NOLINT
   void SetNACKStatus(bool enable, int maxNumberOfPackets);
 
+  // MediaTransportAudioSinkInterface override;
+  void OnData(uint64_t channel_id,
+              MediaTransportEncodedAudioFrame frame) override;
+
   // From RtpData in the RTP/RTCP module
   int32_t OnReceivedPayloadData(const uint8_t* payloadData,
                                 size_t payloadSize,
@@ -257,8 +265,11 @@
 
   rtc::ThreadChecker construction_thread_;
 
+  MediaTransportInterface* const media_transport_;
+
   // E2EE Audio Frame Decryption
-  FrameDecryptorInterface* frame_decryptor_ = nullptr;
+  rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
+  webrtc::CryptoOptions crypto_options_;
 };
 
 }  // namespace voe
diff --git a/audio/channel_receive_proxy.cc b/audio/channel_receive_proxy.cc
index b1c1c45..1dee640 100644
--- a/audio/channel_receive_proxy.cc
+++ b/audio/channel_receive_proxy.cc
@@ -14,7 +14,6 @@
 
 #include "api/call/audio_sink.h"
 #include "audio/channel_send_proxy.h"
-#include "call/rtp_transport_controller_send_interface.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_minmax.h"
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
index 8639fbd..c0de939 100644
--- a/audio/channel_send.cc
+++ b/audio/channel_send.cc
@@ -48,6 +48,24 @@
 constexpr int64_t kMaxRetransmissionWindowMs = 1000;
 constexpr int64_t kMinRetransmissionWindowMs = 30;
 
+MediaTransportEncodedAudioFrame::FrameType
+MediaTransportFrameTypeForWebrtcFrameType(webrtc::FrameType frame_type) {
+  switch (frame_type) {
+    case kAudioFrameSpeech:
+      return MediaTransportEncodedAudioFrame::FrameType::kSpeech;
+      break;
+
+    case kAudioFrameCN:
+      return MediaTransportEncodedAudioFrame::FrameType::
+          kDiscontinuousTransmission;
+      break;
+
+    default:
+      RTC_CHECK(false) << "Unexpected frame type=" << frame_type;
+      break;
+  }
+}
+
 }  // namespace
 
 const int kTelephoneEventAttenuationdB = 10;
@@ -255,6 +273,23 @@
                               size_t payloadSize,
                               const RTPFragmentationHeader* fragmentation) {
   RTC_DCHECK_RUN_ON(encoder_queue_);
+  rtc::ArrayView<const uint8_t> payload(payloadData, payloadSize);
+
+  if (media_transport() != nullptr) {
+    return SendMediaTransportAudio(frameType, payloadType, timeStamp, payload,
+                                   fragmentation);
+  } else {
+    return SendRtpAudio(frameType, payloadType, timeStamp, payload,
+                        fragmentation);
+  }
+}
+
+int32_t ChannelSend::SendRtpAudio(FrameType frameType,
+                                  uint8_t payloadType,
+                                  uint32_t timeStamp,
+                                  rtc::ArrayView<const uint8_t> payload,
+                                  const RTPFragmentationHeader* fragmentation) {
+  RTC_DCHECK_RUN_ON(encoder_queue_);
   if (_includeAudioLevelIndication) {
     // Store current audio level in the RTP/RTCP module.
     // The level will be used in combination with voice-activity state
@@ -269,16 +304,15 @@
     // TODO(benwright@webrtc.org) - Allocate enough to always encrypt inline.
     // Allocate a buffer to hold the maximum possible encrypted payload.
     size_t max_ciphertext_size = frame_encryptor_->GetMaxCiphertextByteSize(
-        cricket::MEDIA_TYPE_AUDIO, payloadSize);
+        cricket::MEDIA_TYPE_AUDIO, payload.size());
     encrypted_audio_payload.SetSize(max_ciphertext_size);
 
     // Encrypt the audio payload into the buffer.
     size_t bytes_written = 0;
     int encrypt_status = frame_encryptor_->Encrypt(
         cricket::MEDIA_TYPE_AUDIO, _rtpRtcpModule->SSRC(),
-        /*additional_data=*/nullptr,
-        rtc::ArrayView<const uint8_t>(payloadData, payloadSize),
-        encrypted_audio_payload, &bytes_written);
+        /*additional_data=*/nullptr, payload, encrypted_audio_payload,
+        &bytes_written);
     if (encrypt_status != 0) {
       RTC_DLOG(LS_ERROR) << "Channel::SendData() failed encrypt audio payload: "
                          << encrypt_status;
@@ -287,19 +321,23 @@
     // Resize the buffer to the exact number of bytes actually used.
     encrypted_audio_payload.SetSize(bytes_written);
     // Rewrite the payloadData and size to the new encrypted payload.
-    payloadData = encrypted_audio_payload.data();
-    payloadSize = encrypted_audio_payload.size();
+    payload = encrypted_audio_payload;
+  } else if (crypto_options_.sframe.require_frame_encryption) {
+    RTC_DLOG(LS_ERROR) << "Channel::SendData() failed sending audio payload: "
+                       << "A frame encryptor is required but one is not set.";
+    return -1;
   }
 
   // Push data from ACM to RTP/RTCP-module to deliver audio frame for
   // packetization.
   // This call will trigger Transport::SendPacket() from the RTP/RTCP module.
-  if (!_rtpRtcpModule->SendOutgoingData(
-          (FrameType&)frameType, payloadType, timeStamp,
-          // Leaving the time when this frame was
-          // received from the capture device as
-          // undefined for voice for now.
-          -1, payloadData, payloadSize, fragmentation, nullptr, nullptr)) {
+  if (!_rtpRtcpModule->SendOutgoingData((FrameType&)frameType, payloadType,
+                                        timeStamp,
+                                        // Leaving the time when this frame was
+                                        // received from the capture device as
+                                        // undefined for voice for now.
+                                        -1, payload.data(), payload.size(),
+                                        fragmentation, nullptr, nullptr)) {
     RTC_DLOG(LS_ERROR)
         << "ChannelSend::SendData() failed to send data to RTP/RTCP module";
     return -1;
@@ -308,9 +346,68 @@
   return 0;
 }
 
+int32_t ChannelSend::SendMediaTransportAudio(
+    FrameType frameType,
+    uint8_t payloadType,
+    uint32_t timeStamp,
+    rtc::ArrayView<const uint8_t> payload,
+    const RTPFragmentationHeader* fragmentation) {
+  RTC_DCHECK_RUN_ON(encoder_queue_);
+  // TODO(nisse): Use null _transportPtr for MediaTransport.
+  // RTC_DCHECK(_transportPtr == nullptr);
+  uint64_t channel_id;
+  int sampling_rate_hz;
+  {
+    rtc::CritScope cs(&media_transport_lock_);
+    if (media_transport_payload_type_ != payloadType) {
+      // Payload type is being changed, media_transport_sampling_frequency_,
+      // no longer current.
+      return -1;
+    }
+    sampling_rate_hz = media_transport_sampling_frequency_;
+    channel_id = media_transport_channel_id_;
+  }
+  const MediaTransportEncodedAudioFrame frame(
+      /*sampling_rate_hz=*/sampling_rate_hz,
+
+      // TODO(nisse): Timestamp and sample index are the same for all supported
+      // audio codecs except G722. Refactor audio coding module to only use
+      // sample index, and leave translation to RTP time, when needed, for
+      // RTP-specific code.
+      /*starting_sample_index=*/timeStamp,
+
+      // Sample count isn't conveniently available from the AudioCodingModule,
+      // and needs some refactoring to wire up in a good way. For now, left as
+      // zero.
+      /*sample_count=*/0,
+
+      /*sequence_number=*/media_transport_sequence_number_,
+      MediaTransportFrameTypeForWebrtcFrameType(frameType), payloadType,
+      std::vector<uint8_t>(payload.begin(), payload.end()));
+
+  // TODO(nisse): Introduce a MediaTransportSender object bound to a specific
+  // channel id.
+  RTCError rtc_error =
+      media_transport()->SendAudioFrame(channel_id, std::move(frame));
+
+  if (!rtc_error.ok()) {
+    RTC_LOG(LS_ERROR) << "Failed to send frame, rtc_error="
+                      << ToString(rtc_error.type()) << ", "
+                      << rtc_error.message();
+    return -1;
+  }
+
+  ++media_transport_sequence_number_;
+
+  return 0;
+}
+
 bool ChannelSend::SendRtp(const uint8_t* data,
                           size_t len,
                           const PacketOptions& options) {
+  // We should not be sending RTP packets if media transport is available.
+  RTC_CHECK(!media_transport());
+
   rtc::CritScope cs(&_callbackCritSect);
 
   if (_transportPtr == NULL) {
@@ -352,9 +449,12 @@
 
 ChannelSend::ChannelSend(rtc::TaskQueue* encoder_queue,
                          ProcessThread* module_process_thread,
+                         MediaTransportInterface* media_transport,
                          RtcpRttStats* rtcp_rtt_stats,
                          RtcEventLog* rtc_event_log,
-                         FrameEncryptorInterface* frame_encryptor)
+                         FrameEncryptorInterface* frame_encryptor,
+                         const webrtc::CryptoOptions& crypto_options,
+                         bool extmap_allow_mixed)
     : event_log_(rtc_event_log),
       _timeStamp(0),  // This is just an offset, RTP module will add it's own
                       // random offset
@@ -375,7 +475,9 @@
       use_twcc_plr_for_ana_(
           webrtc::field_trial::FindFullName("UseTwccPlrForAna") == "Enabled"),
       encoder_queue_(encoder_queue),
-      frame_encryptor_(frame_encryptor) {
+      media_transport_(media_transport),
+      frame_encryptor_(frame_encryptor),
+      crypto_options_(crypto_options) {
   RTC_DCHECK(module_process_thread);
   RTC_DCHECK(encoder_queue);
   audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config()));
@@ -395,6 +497,7 @@
   configuration.rtt_stats = rtcp_rtt_stats;
   configuration.retransmission_rate_limiter =
       retransmission_rate_limiter_.get();
+  configuration.extmap_allow_mixed = extmap_allow_mixed;
 
   _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
   _rtpRtcpModule->SetSendingMediaStatus(false);
@@ -492,7 +595,7 @@
   // to acccess and invalid channel object.
   RTC_DCHECK(encoder_queue_);
 
-  rtc::Event flush(false, false);
+  rtc::Event flush;
   {
     // Clear |encoder_queue_is_active_| under lock to prevent any other tasks
     // than this final "flush task" to be posted on the queue.
@@ -550,6 +653,13 @@
     }
   }
 
+  if (media_transport_) {
+    rtc::CritScope cs(&media_transport_lock_);
+    media_transport_payload_type_ = payload_type;
+    // TODO(nisse): Currently broken for G722, since timestamps passed through
+    // encoder use RTP clock rather than sample count, and they differ for G722.
+    media_transport_sampling_frequency_ = encoder->RtpTimestampRateHz();
+  }
   audio_coding_->SetEncoder(std::move(encoder));
   return true;
 }
@@ -566,6 +676,11 @@
     }
   });
   retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
+  configured_bitrate_bps_ = bitrate_bps;
+}
+
+int ChannelSend::GetBitRate() const {
+  return configured_bitrate_bps_;
 }
 
 void ChannelSend::OnTwccBasedUplinkPacketLossRate(float packet_loss_rate) {
@@ -709,6 +824,10 @@
     RTC_DLOG(LS_ERROR) << "SetLocalSSRC() already sending";
     return -1;
   }
+  if (media_transport_) {
+    rtc::CritScope cs(&media_transport_lock_);
+    media_transport_channel_id_ = ssrc;
+  }
   _rtpRtcpModule->SetSSRC(ssrc);
   return 0;
 }
@@ -719,6 +838,10 @@
   _rtpRtcpModule->SetMid(mid);
 }
 
+void ChannelSend::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+  _rtpRtcpModule->SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
 int ChannelSend::SetSendAudioLevelIndicationStatus(bool enable,
                                                    unsigned char id) {
   _includeAudioLevelIndication = enable;
@@ -982,14 +1105,15 @@
   return rtt;
 }
 
-void ChannelSend::SetFrameEncryptor(FrameEncryptorInterface* frame_encryptor) {
+void ChannelSend::SetFrameEncryptor(
+    rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
   rtc::CritScope cs(&encoder_queue_lock_);
   if (encoder_queue_is_active_) {
     encoder_queue_->PostTask([this, frame_encryptor]() {
-      this->frame_encryptor_ = frame_encryptor;
+      this->frame_encryptor_ = std::move(frame_encryptor);
     });
   } else {
-    frame_encryptor_ = frame_encryptor;
+    frame_encryptor_ = std::move(frame_encryptor);
   }
 }
 
diff --git a/audio/channel_send.h b/audio/channel_send.h
index ef92f8e..407303f 100644
--- a/audio/channel_send.h
+++ b/audio/channel_send.h
@@ -19,6 +19,8 @@
 #include "api/audio/audio_frame.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/call/transport.h"
+#include "api/crypto/cryptooptions.h"
+#include "api/media_transport_interface.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_processing/rms_level.h"
@@ -118,9 +120,12 @@
 
   ChannelSend(rtc::TaskQueue* encoder_queue,
               ProcessThread* module_process_thread,
+              MediaTransportInterface* media_transport,
               RtcpRttStats* rtcp_rtt_stats,
               RtcEventLog* rtc_event_log,
-              FrameEncryptorInterface* frame_encryptor);
+              FrameEncryptorInterface* frame_encryptor,
+              const webrtc::CryptoOptions& crypto_options,
+              bool extmap_allow_mixed);
 
   virtual ~ChannelSend();
 
@@ -137,6 +142,7 @@
 
   // Codecs
   void SetBitRate(int bitrate_bps, int64_t probing_interval_ms);
+  int GetBitRate() const;
   bool EnableAudioNetworkAdaptor(const std::string& config_string);
   void DisableAudioNetworkAdaptor();
 
@@ -166,6 +172,7 @@
   int SetLocalSSRC(unsigned int ssrc);
 
   void SetMid(const std::string& mid, int extension_id);
+  void SetExtmapAllowMixed(bool extmap_allow_mixed);
   int SetSendAudioLevelIndicationStatus(bool enable, unsigned char id);
   void EnableSendTransportSequenceNumber(int id);
 
@@ -225,7 +232,8 @@
   int64_t GetRTT() const;
 
   // E2EE Custom Audio Frame Encryption
-  void SetFrameEncryptor(FrameEncryptorInterface* frame_encryptor);
+  void SetFrameEncryptor(
+      rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor);
 
  private:
   class ProcessAndEncodeAudioTask;
@@ -247,6 +255,21 @@
 
   int GetRtpTimestampRateHz() const;
 
+  int32_t SendRtpAudio(FrameType frameType,
+                       uint8_t payloadType,
+                       uint32_t timeStamp,
+                       rtc::ArrayView<const uint8_t> payload,
+                       const RTPFragmentationHeader* fragmentation);
+
+  int32_t SendMediaTransportAudio(FrameType frameType,
+                                  uint8_t payloadType,
+                                  uint32_t timeStamp,
+                                  rtc::ArrayView<const uint8_t> payload,
+                                  const RTPFragmentationHeader* fragmentation);
+
+  // Return media transport or nullptr if using RTP.
+  MediaTransportInterface* media_transport() { return media_transport_; }
+
   // Called on the encoder task queue when a new input audio frame is ready
   // for encoding.
   void ProcessAndEncodeAudioOnTaskQueue(AudioFrame* audio_input);
@@ -296,8 +319,25 @@
   bool encoder_queue_is_active_ RTC_GUARDED_BY(encoder_queue_lock_) = false;
   rtc::TaskQueue* encoder_queue_ = nullptr;
 
+  MediaTransportInterface* const media_transport_;
+  int media_transport_sequence_number_ RTC_GUARDED_BY(encoder_queue_) = 0;
+
+  rtc::CriticalSection media_transport_lock_;
+  // Currently set by SetLocalSSRC.
+  uint64_t media_transport_channel_id_ RTC_GUARDED_BY(&media_transport_lock_) =
+      0;
+  // Cache payload type and sampling frequency from most recent call to
+  // SetEncoder. Needed to set MediaTransportEncodedAudioFrame metadata, and
+  // invalidate on encoder change.
+  int media_transport_payload_type_ RTC_GUARDED_BY(&media_transport_lock_);
+  int media_transport_sampling_frequency_
+      RTC_GUARDED_BY(&media_transport_lock_);
+
   // E2EE Audio Frame Encryption
-  FrameEncryptorInterface* frame_encryptor_ = nullptr;
+  rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_;
+  // E2EE Frame Encryption Options
+  webrtc::CryptoOptions crypto_options_;
+  int configured_bitrate_bps_ = 0;
 };
 
 }  // namespace voe
diff --git a/audio/channel_send_proxy.cc b/audio/channel_send_proxy.cc
index 8091bdc..2d0bdd3 100644
--- a/audio/channel_send_proxy.cc
+++ b/audio/channel_send_proxy.cc
@@ -12,11 +12,9 @@
 
 #include <utility>
 
-#include "api/call/audio_sink.h"
+#include "api/crypto/frameencryptorinterface.h"
 #include "call/rtp_transport_controller_send_interface.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_minmax.h"
 
 namespace webrtc {
 namespace voe {
@@ -90,6 +88,11 @@
   RTC_DCHECK_EQ(0, error);
 }
 
+void ChannelSendProxy::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+  channel_->SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
 void ChannelSendProxy::SetSendAudioLevelIndicationStatus(bool enable, int id) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   int error = channel_->SetSendAudioLevelIndicationStatus(enable, id);
@@ -150,6 +153,10 @@
   channel_->SetBitRate(bitrate_bps, probing_interval_ms);
 }
 
+int ChannelSendProxy::GetBitrate() const {
+  return channel_->GetBitRate();
+}
+
 void ChannelSendProxy::SetInputMute(bool muted) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   channel_->SetInputMute(muted);
@@ -198,7 +205,7 @@
 }
 
 void ChannelSendProxy::SetFrameEncryptor(
-    FrameEncryptorInterface* frame_encryptor) {
+    rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   channel_->SetFrameEncryptor(frame_encryptor);
 }
diff --git a/audio/channel_send_proxy.h b/audio/channel_send_proxy.h
index 1b8b4a0..3146830 100644
--- a/audio/channel_send_proxy.h
+++ b/audio/channel_send_proxy.h
@@ -58,6 +58,7 @@
   virtual void SetRTCPStatus(bool enable);
   virtual void SetMid(const std::string& mid, int extension_id);
   virtual void SetRTCP_CNAME(const std::string& c_name);
+  virtual void SetExtmapAllowMixed(bool extmap_allow_mixed);
   virtual void SetSendAudioLevelIndicationStatus(bool enable, int id);
   virtual void EnableSendTransportSequenceNumber(int id);
   virtual void RegisterSenderCongestionControlObjects(
@@ -70,6 +71,7 @@
                                                 int payload_frequency);
   virtual bool SendTelephoneEventOutband(int event, int duration_ms);
   virtual void SetBitrate(int bitrate_bps, int64_t probing_interval_ms);
+  virtual int GetBitrate() const;
   virtual void SetInputMute(bool muted);
 
   virtual void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame);
@@ -86,7 +88,8 @@
   virtual ChannelSend* GetChannel() const;
 
   // E2EE Custom Audio Frame Encryption (Optional)
-  virtual void SetFrameEncryptor(FrameEncryptorInterface* frame_encryptor);
+  virtual void SetFrameEncryptor(
+      rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor);
 
  private:
   // Thread checkers document and lock usage of some methods on voe::Channel to
diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h
index 910858f..962152f 100644
--- a/audio/mock_voe_channel_proxy.h
+++ b/audio/mock_voe_channel_proxy.h
@@ -16,6 +16,7 @@
 #include <string>
 #include <vector>
 
+#include "api/test/mock_frame_encryptor.h"
 #include "audio/channel_receive_proxy.h"
 #include "audio/channel_send_proxy.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
@@ -75,6 +76,7 @@
   MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc));
   MOCK_METHOD1(SetRTCP_CNAME, void(const std::string& c_name));
   MOCK_METHOD2(SetNACKStatus, void(bool enable, int max_packets));
+  MOCK_METHOD1(SetExtmapAllowMixed, void(bool extmap_allow_mixed));
   MOCK_METHOD2(SetSendAudioLevelIndicationStatus, void(bool enable, int id));
   MOCK_METHOD1(EnableSendTransportSequenceNumber, void(int id));
   MOCK_METHOD2(RegisterSenderCongestionControlObjects,
@@ -99,13 +101,15 @@
                void(std::unique_ptr<AudioFrame>* audio_frame));
   MOCK_METHOD1(SetTransportOverhead, void(int transport_overhead_per_packet));
   MOCK_CONST_METHOD0(GetRtpRtcp, RtpRtcp*());
+  MOCK_CONST_METHOD0(GetBitrate, int());
   MOCK_METHOD1(OnTwccBasedUplinkPacketLossRate, void(float packet_loss_rate));
   MOCK_METHOD1(OnRecoverableUplinkPacketLossRate,
                void(float recoverable_packet_loss_rate));
   MOCK_METHOD0(StartSend, void());
   MOCK_METHOD0(StopSend, void());
-  MOCK_METHOD1(SetFrameEncryptor,
-               void(FrameEncryptorInterface* frame_encryptor));
+  MOCK_METHOD1(
+      SetFrameEncryptor,
+      void(rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor));
 };
 }  // namespace test
 }  // namespace webrtc
diff --git a/audio/null_audio_poller.cc b/audio/null_audio_poller.cc
index bd5317b..d2b1199 100644
--- a/audio/null_audio_poller.cc
+++ b/audio/null_audio_poller.cc
@@ -9,9 +9,13 @@
  */
 
 #include "audio/null_audio_poller.h"
-#include "rtc_base/logging.h"
+
+#include <stddef.h>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/location.h"
 #include "rtc_base/thread.h"
-#include "rtc_base/timeutils.h"  // for TimeMillis
+#include "rtc_base/timeutils.h"
 
 namespace webrtc {
 namespace internal {
diff --git a/audio/null_audio_poller.h b/audio/null_audio_poller.h
index afb6edb..f91eb7d 100644
--- a/audio/null_audio_poller.h
+++ b/audio/null_audio_poller.h
@@ -11,8 +11,11 @@
 #ifndef AUDIO_NULL_AUDIO_POLLER_H_
 #define AUDIO_NULL_AUDIO_POLLER_H_
 
+#include <stdint.h>
+
 #include "modules/audio_device/include/audio_device_defines.h"
 #include "rtc_base/messagehandler.h"
+#include "rtc_base/messagequeue.h"
 #include "rtc_base/thread_checker.h"
 
 namespace webrtc {
diff --git a/audio/remix_resample.cc b/audio/remix_resample.cc
index eda70c7..cc59e2a 100644
--- a/audio/remix_resample.cc
+++ b/audio/remix_resample.cc
@@ -13,10 +13,7 @@
 #include "api/audio/audio_frame.h"
 #include "audio/utility/audio_frame_operations.h"
 #include "common_audio/resampler/include/push_resampler.h"
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "common_types.h"  // NOLINT(build/include)
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 
 namespace webrtc {
 namespace voe {
diff --git a/audio/transport_feedback_packet_loss_tracker.cc b/audio/transport_feedback_packet_loss_tracker.cc
index c7acd76..f41439b 100644
--- a/audio/transport_feedback_packet_loss_tracker.cc
+++ b/audio/transport_feedback_packet_loss_tracker.cc
@@ -10,11 +10,11 @@
 
 #include "audio/transport_feedback_packet_loss_tracker.h"
 
+#include <iterator>
 #include <limits>
 #include <utility>
 
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/mod_ops.h"
 
diff --git a/audio/utility/audio_frame_operations.cc b/audio/utility/audio_frame_operations.cc
index fb1f3b0..1a8232b 100644
--- a/audio/utility/audio_frame_operations.cc
+++ b/audio/utility/audio_frame_operations.cc
@@ -12,6 +12,7 @@
 
 #include <string.h>
 #include <algorithm>
+#include <cstdint>
 
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/audio/utility/audio_frame_operations.h b/audio/utility/audio_frame_operations.h
index 5993523..c1445b6 100644
--- a/audio/utility/audio_frame_operations.h
+++ b/audio/utility/audio_frame_operations.h
@@ -12,6 +12,7 @@
 #define AUDIO_UTILITY_AUDIO_FRAME_OPERATIONS_H_
 
 #include <stddef.h>
+#include <stdint.h>
 
 #include "api/audio/audio_frame.h"
 
diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn
index abcfe9a..911c050 100644
--- a/common_audio/BUILD.gn
+++ b/common_audio/BUILD.gn
@@ -51,6 +51,7 @@
     "../rtc_base:checks",
     "../rtc_base:gtest_prod",
     "../rtc_base:rtc_base_approved",
+    "../rtc_base:sanitizer",
     "../rtc_base/memory:aligned_array",
     "../rtc_base/memory:aligned_malloc",
     "../rtc_base/system:arch",
@@ -389,6 +390,7 @@
       "../system_wrappers:cpu_features_api",
       "../test:fileutils",
       "../test:test_main",
+      "../test:test_support",
       "//testing/gtest",
     ]
 
diff --git a/common_audio/audio_converter.h b/common_audio/audio_converter.h
index 769d724..24a5e72 100644
--- a/common_audio/audio_converter.h
+++ b/common_audio/audio_converter.h
@@ -11,6 +11,7 @@
 #ifndef COMMON_AUDIO_AUDIO_CONVERTER_H_
 #define COMMON_AUDIO_AUDIO_CONVERTER_H_
 
+#include <stddef.h>
 #include <memory>
 
 #include "rtc_base/constructormagic.h"
diff --git a/common_audio/channel_buffer.cc b/common_audio/channel_buffer.cc
index 38d231e..b9b8c25 100644
--- a/common_audio/channel_buffer.cc
+++ b/common_audio/channel_buffer.cc
@@ -10,6 +10,9 @@
 
 #include "common_audio/channel_buffer.h"
 
+#include <cstdint>
+
+#include "common_audio/include/audio_util.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/common_audio/fir_filter_c.cc b/common_audio/fir_filter_c.cc
index 3418434..b6ec27a 100644
--- a/common_audio/fir_filter_c.cc
+++ b/common_audio/fir_filter_c.cc
@@ -11,11 +11,8 @@
 #include "common_audio/fir_filter_c.h"
 
 #include <string.h>
-
 #include <memory>
 
-#include "common_audio/fir_filter_neon.h"
-#include "common_audio/fir_filter_sse.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/common_audio/fir_filter_factory.cc b/common_audio/fir_filter_factory.cc
index 3243b27..19528e3 100644
--- a/common_audio/fir_filter_factory.cc
+++ b/common_audio/fir_filter_factory.cc
@@ -13,12 +13,12 @@
 #include "common_audio/fir_filter_c.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/system/arch.h"
-#include "system_wrappers/include/cpu_features_wrapper.h"
 
 #if defined(WEBRTC_HAS_NEON)
 #include "common_audio/fir_filter_neon.h"
 #elif defined(WEBRTC_ARCH_X86_FAMILY)
 #include "common_audio/fir_filter_sse.h"
+#include "system_wrappers/include/cpu_features_wrapper.h"  // kSSE2, WebRtc_G...
 #endif
 
 namespace webrtc {
diff --git a/common_audio/fir_filter_sse.h b/common_audio/fir_filter_sse.h
index 7707f93..b768a37 100644
--- a/common_audio/fir_filter_sse.h
+++ b/common_audio/fir_filter_sse.h
@@ -11,6 +11,7 @@
 #ifndef COMMON_AUDIO_FIR_FILTER_SSE_H_
 #define COMMON_AUDIO_FIR_FILTER_SSE_H_
 
+#include <stddef.h>
 #include <memory>
 
 #include "common_audio/fir_filter.h"
diff --git a/common_audio/include/audio_util.h b/common_audio/include/audio_util.h
index de242a4..bca5718 100644
--- a/common_audio/include/audio_util.h
+++ b/common_audio/include/audio_util.h
@@ -11,6 +11,7 @@
 #ifndef COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_
 #define COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_
 
+#include <stdint.h>
 #include <algorithm>
 #include <cmath>
 #include <cstring>
diff --git a/common_audio/real_fourier.h b/common_audio/real_fourier.h
index a3e4dd1..4d0d8bf 100644
--- a/common_audio/real_fourier.h
+++ b/common_audio/real_fourier.h
@@ -11,6 +11,7 @@
 #ifndef COMMON_AUDIO_REAL_FOURIER_H_
 #define COMMON_AUDIO_REAL_FOURIER_H_
 
+#include <stddef.h>
 #include <complex>
 #include <memory>
 
diff --git a/common_audio/real_fourier_ooura.h b/common_audio/real_fourier_ooura.h
index bb8eef9..b36c84f 100644
--- a/common_audio/real_fourier_ooura.h
+++ b/common_audio/real_fourier_ooura.h
@@ -11,6 +11,7 @@
 #ifndef COMMON_AUDIO_REAL_FOURIER_OOURA_H_
 #define COMMON_AUDIO_REAL_FOURIER_OOURA_H_
 
+#include <stddef.h>
 #include <complex>
 #include <memory>
 
diff --git a/common_audio/resampler/push_resampler.cc b/common_audio/resampler/push_resampler.cc
index 318d97b..9b89867 100644
--- a/common_audio/resampler/push_resampler.cc
+++ b/common_audio/resampler/push_resampler.cc
@@ -10,12 +10,12 @@
 
 #include "common_audio/resampler/include/push_resampler.h"
 
+#include <stdint.h>
 #include <string.h>
 
 #include "absl/container/inlined_vector.h"
 #include "absl/memory/memory.h"
 #include "common_audio/include/audio_util.h"
-#include "common_audio/resampler/include/resampler.h"
 #include "common_audio/resampler/push_sinc_resampler.h"
 #include "rtc_base/checks.h"
 
diff --git a/common_audio/resampler/push_sinc_resampler.h b/common_audio/resampler/push_sinc_resampler.h
index 1ffe73f..db9cdc1 100644
--- a/common_audio/resampler/push_sinc_resampler.h
+++ b/common_audio/resampler/push_sinc_resampler.h
@@ -11,6 +11,8 @@
 #ifndef COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
 #define COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 
 #include "common_audio/resampler/sinc_resampler.h"
diff --git a/common_audio/resampler/resampler.cc b/common_audio/resampler/resampler.cc
index aa3a4ba..e4d2aa2 100644
--- a/common_audio/resampler/resampler.cc
+++ b/common_audio/resampler/resampler.cc
@@ -12,6 +12,7 @@
  * A wrapper for resampling a numerous amount of sampling combinations.
  */
 
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/common_audio/resampler/sinc_resampler.cc b/common_audio/resampler/sinc_resampler.cc
index 5aa2061..4601514 100644
--- a/common_audio/resampler/sinc_resampler.cc
+++ b/common_audio/resampler/sinc_resampler.cc
@@ -88,13 +88,13 @@
 #include "common_audio/resampler/sinc_resampler.h"
 
 #include <math.h>
+#include <stdint.h>
 #include <string.h>
-
 #include <limits>
 
 #include "rtc_base/checks.h"
 #include "rtc_base/system/arch.h"
-#include "system_wrappers/include/cpu_features_wrapper.h"
+#include "system_wrappers/include/cpu_features_wrapper.h"  // kSSE2, WebRtc_G...
 
 namespace webrtc {
 
diff --git a/common_audio/resampler/sinc_resampler.h b/common_audio/resampler/sinc_resampler.h
index 8a833ce..0be4318 100644
--- a/common_audio/resampler/sinc_resampler.h
+++ b/common_audio/resampler/sinc_resampler.h
@@ -14,6 +14,7 @@
 #ifndef COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
 #define COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
 
+#include <stddef.h>
 #include <memory>
 
 #include "rtc_base/constructormagic.h"
diff --git a/common_audio/resampler/sinc_resampler_sse.cc b/common_audio/resampler/sinc_resampler_sse.cc
index 3906a79..f6a24d0 100644
--- a/common_audio/resampler/sinc_resampler_sse.cc
+++ b/common_audio/resampler/sinc_resampler_sse.cc
@@ -11,10 +11,12 @@
 // Modified from the Chromium original:
 // src/media/base/simd/sinc_resampler_sse.cc
 
-#include "common_audio/resampler/sinc_resampler.h"
-
+#include <stddef.h>
+#include <stdint.h>
 #include <xmmintrin.h>
 
+#include "common_audio/resampler/sinc_resampler.h"
+
 namespace webrtc {
 
 float SincResampler::Convolve_SSE(const float* input_ptr,
diff --git a/common_audio/smoothing_filter.cc b/common_audio/smoothing_filter.cc
index d426bda..0d5aaa4 100644
--- a/common_audio/smoothing_filter.cc
+++ b/common_audio/smoothing_filter.cc
@@ -12,6 +12,7 @@
 
 #include <cmath>
 
+#include "rtc_base/checks.h"
 #include "rtc_base/timeutils.h"
 
 namespace webrtc {
diff --git a/common_audio/smoothing_filter.h b/common_audio/smoothing_filter.h
index cff7469..c467d85 100644
--- a/common_audio/smoothing_filter.h
+++ b/common_audio/smoothing_filter.h
@@ -11,9 +11,10 @@
 #ifndef COMMON_AUDIO_SMOOTHING_FILTER_H_
 #define COMMON_AUDIO_SMOOTHING_FILTER_H_
 
+#include <stdint.h>
+
 #include "absl/types/optional.h"
 #include "rtc_base/constructormagic.h"
-#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 
diff --git a/common_audio/vad/vad.cc b/common_audio/vad/vad.cc
index 1cb332a..987ed52 100644
--- a/common_audio/vad/vad.cc
+++ b/common_audio/vad/vad.cc
@@ -12,6 +12,7 @@
 
 #include <memory>
 
+#include "common_audio/vad/include/webrtc_vad.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/common_audio/wav_file.cc b/common_audio/wav_file.cc
index 008891f..1b8bcbd 100644
--- a/common_audio/wav_file.cc
+++ b/common_audio/wav_file.cc
@@ -10,35 +10,45 @@
 
 #include "common_audio/wav_file.h"
 
+#include <errno.h>
 #include <algorithm>
 #include <cstdio>
-#include <limits>
+#include <type_traits>
 
 #include "common_audio/include/audio_util.h"
 #include "common_audio/wav_header.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/system/arch.h"
 
 namespace webrtc {
+namespace {
 
 // We write 16-bit PCM WAV files.
-static const WavFormat kWavFormat = kWavFormatPcm;
-static const size_t kBytesPerSample = 2;
+constexpr WavFormat kWavFormat = kWavFormatPcm;
+static_assert(std::is_trivially_destructible<WavFormat>::value, "");
+constexpr size_t kBytesPerSample = 2;
 
 // Doesn't take ownership of the file handle and won't close it.
 class ReadableWavFile : public ReadableWav {
  public:
   explicit ReadableWavFile(FILE* file) : file_(file) {}
+  ReadableWavFile(const ReadableWavFile&) = delete;
+  ReadableWavFile& operator=(const ReadableWavFile&) = delete;
   size_t Read(void* buf, size_t num_bytes) override {
     return fread(buf, 1, num_bytes, file_);
   }
+  bool Eof() const override { return feof(file_) != 0; }
+  bool SeekForward(uint32_t num_bytes) override {
+    return fseek(file_, num_bytes, SEEK_CUR) == 0;
+  }
 
  private:
   FILE* file_;
 };
 
+}  // namespace
+
 WavReader::WavReader(const std::string& filename)
     : WavReader(rtc::OpenPlatformFileReadOnly(filename)) {}
 
diff --git a/common_audio/wav_header.cc b/common_audio/wav_header.cc
index 8fc5fef..e49b748 100644
--- a/common_audio/wav_header.cc
+++ b/common_audio/wav_header.cc
@@ -14,13 +14,13 @@
 
 #include "common_audio/wav_header.h"
 
-#include <algorithm>
 #include <cstring>
 #include <limits>
 #include <string>
 
-#include "common_audio/include/audio_util.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/sanitizer.h"
 #include "rtc_base/system/arch.h"
 
 namespace webrtc {
@@ -32,6 +32,11 @@
 };
 static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
 
+struct RiffHeader {
+  ChunkHeader header;
+  uint32_t Format;
+};
+
 // We can't nest this definition in WavHeader, because VS2013 gives an error
 // on sizeof(WavHeader::fmt): "error C2070: 'unknown': illegal sizeof operand".
 struct FmtSubchunk {
@@ -46,11 +51,12 @@
 static_assert(sizeof(FmtSubchunk) == 24, "FmtSubchunk size");
 const uint32_t kFmtSubchunkSize = sizeof(FmtSubchunk) - sizeof(ChunkHeader);
 
+// Simple wav header. It does not include chunks that are not essential to read
+// audio samples.
 struct WavHeader {
-  struct {
-    ChunkHeader header;
-    uint32_t Format;
-  } riff;
+  WavHeader(const WavHeader&) = default;
+  WavHeader& operator=(const WavHeader&) = default;
+  RiffHeader riff;
   FmtSubchunk fmt;
   struct {
     ChunkHeader header;
@@ -58,6 +64,87 @@
 };
 static_assert(sizeof(WavHeader) == kWavHeaderSize, "no padding in header");
 
+#ifdef WEBRTC_ARCH_LITTLE_ENDIAN
+static inline void WriteLE16(uint16_t* f, uint16_t x) {
+  *f = x;
+}
+static inline void WriteLE32(uint32_t* f, uint32_t x) {
+  *f = x;
+}
+static inline void WriteFourCC(uint32_t* f, char a, char b, char c, char d) {
+  *f = static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
+       static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
+}
+
+static inline uint16_t ReadLE16(uint16_t x) {
+  return x;
+}
+static inline uint32_t ReadLE32(uint32_t x) {
+  return x;
+}
+static inline std::string ReadFourCC(uint32_t x) {
+  return std::string(reinterpret_cast<char*>(&x), 4);
+}
+#else
+#error "Write be-to-le conversion functions"
+#endif
+
+static inline uint32_t RiffChunkSize(size_t bytes_in_payload) {
+  return static_cast<uint32_t>(bytes_in_payload + kWavHeaderSize -
+                               sizeof(ChunkHeader));
+}
+
+static inline uint32_t ByteRate(size_t num_channels,
+                                int sample_rate,
+                                size_t bytes_per_sample) {
+  return static_cast<uint32_t>(num_channels * sample_rate * bytes_per_sample);
+}
+
+static inline uint16_t BlockAlign(size_t num_channels,
+                                  size_t bytes_per_sample) {
+  return static_cast<uint16_t>(num_channels * bytes_per_sample);
+}
+
+// Finds a chunk having the sought ID. If found, then |readable| points to the
+// first byte of the sought chunk data. If not found, the end of the file is
+// reached.
+void FindWaveChunk(ChunkHeader* chunk_header,
+                   ReadableWav* readable,
+                   const std::string sought_chunk_id) {
+  RTC_DCHECK_EQ(sought_chunk_id.size(), 4);
+  while (!readable->Eof()) {
+    if (readable->Read(chunk_header, sizeof(*chunk_header)) !=
+        sizeof(*chunk_header))
+      return;  // EOF.
+    if (ReadFourCC(chunk_header->ID) == sought_chunk_id)
+      return;  // Sought chunk found.
+    // Ignore current chunk by skipping its payload.
+    if (!readable->SeekForward(chunk_header->Size))
+      return;  // EOF or error.
+  }
+  return;  // EOF.
+}
+
+bool ReadFmtChunkData(FmtSubchunk* fmt_subchunk, ReadableWav* readable) {
+  // Reads "fmt " chunk payload.
+  if (readable->Read(&(fmt_subchunk->AudioFormat), kFmtSubchunkSize) !=
+      kFmtSubchunkSize)
+    return false;
+  const uint32_t fmt_size = ReadLE32(fmt_subchunk->header.Size);
+  if (fmt_size != kFmtSubchunkSize) {
+    // There is an optional two-byte extension field permitted to be present
+    // with PCM, but which must be zero.
+    int16_t ext_size;
+    if (kFmtSubchunkSize + sizeof(ext_size) != fmt_size)
+      return false;
+    if (readable->Read(&ext_size, sizeof(ext_size)) != sizeof(ext_size))
+      return false;
+    if (ext_size != 0)
+      return false;
+  }
+  return true;
+}
+
 }  // namespace
 
 bool CheckWavParameters(size_t num_channels,
@@ -112,47 +199,6 @@
   return true;
 }
 
-#ifdef WEBRTC_ARCH_LITTLE_ENDIAN
-static inline void WriteLE16(uint16_t* f, uint16_t x) {
-  *f = x;
-}
-static inline void WriteLE32(uint32_t* f, uint32_t x) {
-  *f = x;
-}
-static inline void WriteFourCC(uint32_t* f, char a, char b, char c, char d) {
-  *f = static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
-       static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
-}
-
-static inline uint16_t ReadLE16(uint16_t x) {
-  return x;
-}
-static inline uint32_t ReadLE32(uint32_t x) {
-  return x;
-}
-static inline std::string ReadFourCC(uint32_t x) {
-  return std::string(reinterpret_cast<char*>(&x), 4);
-}
-#else
-#error "Write be-to-le conversion functions"
-#endif
-
-static inline uint32_t RiffChunkSize(size_t bytes_in_payload) {
-  return static_cast<uint32_t>(bytes_in_payload + kWavHeaderSize -
-                               sizeof(ChunkHeader));
-}
-
-static inline uint32_t ByteRate(size_t num_channels,
-                                int sample_rate,
-                                size_t bytes_per_sample) {
-  return static_cast<uint32_t>(num_channels * sample_rate * bytes_per_sample);
-}
-
-static inline uint16_t BlockAlign(size_t num_channels,
-                                  size_t bytes_per_sample) {
-  return static_cast<uint16_t>(num_channels * bytes_per_sample);
-}
-
 void WriteWavHeader(uint8_t* buf,
                     size_t num_channels,
                     int sample_rate,
@@ -162,7 +208,7 @@
   RTC_CHECK(CheckWavParameters(num_channels, sample_rate, format,
                                bytes_per_sample, num_samples));
 
-  WavHeader header;
+  auto header = rtc::MsanUninitialized<WavHeader>({});
   const size_t bytes_in_payload = bytes_per_sample * num_samples;
 
   WriteFourCC(&header.riff.header.ID, 'R', 'I', 'F', 'F');
@@ -194,25 +240,38 @@
                    WavFormat* format,
                    size_t* bytes_per_sample,
                    size_t* num_samples) {
-  WavHeader header;
-  if (readable->Read(&header, kWavHeaderSize - sizeof(header.data)) !=
-      kWavHeaderSize - sizeof(header.data))
+  auto header = rtc::MsanUninitialized<WavHeader>({});
+
+  // Read RIFF chunk.
+  if (readable->Read(&header.riff, sizeof(header.riff)) != sizeof(header.riff))
+    return false;
+  if (ReadFourCC(header.riff.header.ID) != "RIFF")
+    return false;
+  if (ReadFourCC(header.riff.Format) != "WAVE")
     return false;
 
-  const uint32_t fmt_size = ReadLE32(header.fmt.header.Size);
-  if (fmt_size != kFmtSubchunkSize) {
-    // There is an optional two-byte extension field permitted to be present
-    // with PCM, but which must be zero.
-    int16_t ext_size;
-    if (kFmtSubchunkSize + sizeof(ext_size) != fmt_size)
-      return false;
-    if (readable->Read(&ext_size, sizeof(ext_size)) != sizeof(ext_size))
-      return false;
-    if (ext_size != 0)
-      return false;
-  }
-  if (readable->Read(&header.data, sizeof(header.data)) != sizeof(header.data))
+  // Find "fmt " and "data" chunks. While the official Wave file specification
+  // does not put requirements on the chunks order, it is uncommon to find the
+  // "data" chunk before the "fmt " one. The code below fails if this is not the
+  // case.
+  FindWaveChunk(&header.fmt.header, readable, "fmt ");
+  if (ReadFourCC(header.fmt.header.ID) != "fmt ") {
+    RTC_LOG(LS_ERROR) << "Cannot find 'fmt ' chunk.";
     return false;
+  }
+  if (!ReadFmtChunkData(&header.fmt, readable)) {
+    RTC_LOG(LS_ERROR) << "Cannot read 'fmt ' chunk.";
+    return false;
+  }
+  if (readable->Eof()) {
+    RTC_LOG(LS_ERROR) << "'fmt ' chunk placed after 'data' chunk.";
+    return false;
+  }
+  FindWaveChunk(&header.data.header, readable, "data");
+  if (ReadFourCC(header.data.header.ID) != "data") {
+    RTC_LOG(LS_ERROR) << "Cannot find 'data' chunk.";
+    return false;
+  }
 
   // Parse needed fields.
   *format = static_cast<WavFormat>(ReadLE16(header.fmt.AudioFormat));
@@ -224,16 +283,6 @@
     return false;
   *num_samples = bytes_in_payload / *bytes_per_sample;
 
-  // Sanity check remaining fields.
-  if (ReadFourCC(header.riff.header.ID) != "RIFF")
-    return false;
-  if (ReadFourCC(header.riff.Format) != "WAVE")
-    return false;
-  if (ReadFourCC(header.fmt.header.ID) != "fmt ")
-    return false;
-  if (ReadFourCC(header.data.header.ID) != "data")
-    return false;
-
   if (ReadLE32(header.riff.header.Size) < RiffChunkSize(bytes_in_payload))
     return false;
   if (ReadLE32(header.fmt.ByteRate) !=
diff --git a/common_audio/wav_header.h b/common_audio/wav_header.h
index 872d3ab..a519ba5 100644
--- a/common_audio/wav_header.h
+++ b/common_audio/wav_header.h
@@ -21,8 +21,11 @@
 class ReadableWav {
  public:
   // Returns the number of bytes read.
-  size_t virtual Read(void* buf, size_t num_bytes) = 0;
-  virtual ~ReadableWav() {}
+  virtual size_t Read(void* buf, size_t num_bytes) = 0;
+  // Returns true if the end-of-file has been reached.
+  virtual bool Eof() const = 0;
+  virtual bool SeekForward(uint32_t num_bytes) = 0;
+  virtual ~ReadableWav() = default;
 };
 
 enum WavFormat {
diff --git a/common_audio/wav_header_unittest.cc b/common_audio/wav_header_unittest.cc
index b7169b5..2e2eda5 100644
--- a/common_audio/wav_header_unittest.cc
+++ b/common_audio/wav_header_unittest.cc
@@ -19,12 +19,6 @@
 // Doesn't take ownership of the buffer.
 class ReadableWavBuffer : public ReadableWav {
  public:
-  ReadableWavBuffer(const uint8_t* buf, size_t size)
-      : buf_(buf),
-        size_(size),
-        pos_(0),
-        buf_exhausted_(false),
-        check_read_size_(true) {}
   ReadableWavBuffer(const uint8_t* buf, size_t size, bool check_read_size)
       : buf_(buf),
         size_(size),
@@ -57,6 +51,27 @@
     return num_bytes;
   }
 
+  bool Eof() const override { return pos_ == size_; }
+
+  bool SeekForward(uint32_t num_bytes) override {
+    // Verify we don't try to read outside of a properly sized header.
+    if (size_ >= kWavHeaderSize)
+      EXPECT_GE(size_, pos_ + num_bytes);
+    EXPECT_FALSE(buf_exhausted_);
+
+    const size_t bytes_remaining = size_ - pos_;
+    if (num_bytes > bytes_remaining) {
+      // Error: cannot seek beyond EOF.
+      return false;
+    }
+    if (num_bytes == bytes_remaining) {
+      // There should not be another read attempt after this point.
+      buf_exhausted_ = true;
+    }
+    pos_ += num_bytes;
+    return true;
+  }
+
  private:
   const uint8_t* buf_;
   const size_t size_;
@@ -103,7 +118,7 @@
   // invalid field is indicated in the array name, and in the comments with
   // *BAD*.
   {
-    static const uint8_t kBadRiffID[] = {
+    constexpr uint8_t kBadRiffID[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'i', 'f', 'f',  // *BAD*
@@ -121,12 +136,13 @@
       0x99, 0xd0, 0x5b, 0x07,  // size of payload: 123457689
         // clang-format on
     };
-    ReadableWavBuffer r(kBadRiffID, sizeof(kBadRiffID));
+    ReadableWavBuffer r(kBadRiffID, sizeof(kBadRiffID),
+                        /*check_read_size=*/false);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
   {
-    static const uint8_t kBadBitsPerSample[] = {
+    constexpr uint8_t kBadBitsPerSample[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'I', 'F', 'F',
@@ -144,12 +160,13 @@
       0x99, 0xd0, 0x5b, 0x07,  // size of payload: 123457689
         // clang-format on
     };
-    ReadableWavBuffer r(kBadBitsPerSample, sizeof(kBadBitsPerSample));
+    ReadableWavBuffer r(kBadBitsPerSample, sizeof(kBadBitsPerSample),
+                        /*check_read_size=*/true);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
   {
-    static const uint8_t kBadByteRate[] = {
+    constexpr uint8_t kBadByteRate[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'I', 'F', 'F',
@@ -167,12 +184,13 @@
       0x99, 0xd0, 0x5b, 0x07,  // size of payload: 123457689
         // clang-format on
     };
-    ReadableWavBuffer r(kBadByteRate, sizeof(kBadByteRate));
+    ReadableWavBuffer r(kBadByteRate, sizeof(kBadByteRate),
+                        /*check_read_size=*/true);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
   {
-    static const uint8_t kBadFmtHeaderSize[] = {
+    constexpr uint8_t kBadFmtHeaderSize[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'I', 'F', 'F',
@@ -191,12 +209,13 @@
       0x99, 0xd0, 0x5b, 0x07,  // size of payload: 123457689
         // clang-format on
     };
-    ReadableWavBuffer r(kBadFmtHeaderSize, sizeof(kBadFmtHeaderSize), false);
+    ReadableWavBuffer r(kBadFmtHeaderSize, sizeof(kBadFmtHeaderSize),
+                        /*check_read_size=*/false);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
   {
-    static const uint8_t kNonZeroExtensionField[] = {
+    constexpr uint8_t kNonZeroExtensionField[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'I', 'F', 'F',
@@ -216,12 +235,12 @@
         // clang-format on
     };
     ReadableWavBuffer r(kNonZeroExtensionField, sizeof(kNonZeroExtensionField),
-                        false);
+                        /*check_read_size=*/false);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
   {
-    static const uint8_t kMissingDataChunk[] = {
+    constexpr uint8_t kMissingDataChunk[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'I', 'F', 'F',
@@ -237,12 +256,13 @@
       8, 0,  // bits per sample: 1 * 8
         // clang-format on
     };
-    ReadableWavBuffer r(kMissingDataChunk, sizeof(kMissingDataChunk));
+    ReadableWavBuffer r(kMissingDataChunk, sizeof(kMissingDataChunk),
+                        /*check_read_size=*/true);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
   {
-    static const uint8_t kMissingFmtAndDataChunks[] = {
+    constexpr uint8_t kMissingFmtAndDataChunks[] = {
         // clang-format off
         // clang formatting doesn't respect inline comments.
       'R', 'I', 'F', 'F',
@@ -251,7 +271,8 @@
         // clang-format on
     };
     ReadableWavBuffer r(kMissingFmtAndDataChunks,
-                        sizeof(kMissingFmtAndDataChunks));
+                        sizeof(kMissingFmtAndDataChunks),
+                        /*check_read_size=*/true);
     EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                                &bytes_per_sample, &num_samples));
   }
@@ -259,11 +280,11 @@
 
 // Try writing and reading a valid WAV header and make sure it looks OK.
 TEST(WavHeaderTest, WriteAndReadWavHeader) {
-  static const int kSize = 4 + kWavHeaderSize + 4;
+  constexpr int kSize = 4 + kWavHeaderSize + 4;
   uint8_t buf[kSize];
   memset(buf, 0xa4, sizeof(buf));
   WriteWavHeader(buf + 4, 17, 12345, kWavFormatALaw, 1, 123457689);
-  static const uint8_t kExpectedBuf[] = {
+  constexpr uint8_t kExpectedBuf[] = {
       // clang-format off
       // clang formatting doesn't respect inline comments.
     0xa4, 0xa4, 0xa4, 0xa4,  // untouched bytes before header
@@ -291,7 +312,8 @@
   WavFormat format = kWavFormatPcm;
   size_t bytes_per_sample = 0;
   size_t num_samples = 0;
-  ReadableWavBuffer r(buf + 4, sizeof(buf) - 8);
+  ReadableWavBuffer r(buf + 4, sizeof(buf) - 8,
+                      /*check_read_size=*/true);
   EXPECT_TRUE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                             &bytes_per_sample, &num_samples));
   EXPECT_EQ(17u, num_channels);
@@ -303,24 +325,25 @@
 
 // Try reading an atypical but valid WAV header and make sure it's parsed OK.
 TEST(WavHeaderTest, ReadAtypicalWavHeader) {
-  static const uint8_t kBuf[] = {
+  constexpr uint8_t kBuf[] = {
       // clang-format off
       // clang formatting doesn't respect inline comments.
     'R', 'I', 'F', 'F',
-    0x3d, 0xd1, 0x5b, 0x07,  // size of whole file - 8 + an extra 128 bytes of
-                             // "metadata": 123457689 + 44 - 8 + 128. (atypical)
+    0xbf, 0xd0, 0x5b, 0x07,  // Size of whole file - 8 + extra 2 bytes of zero
+                             // extension: 123457689 + 44 - 8 + 2 (atypical).
     'W', 'A', 'V', 'E',
     'f', 'm', 't', ' ',
-    18, 0, 0, 0,  // size of fmt block (with an atypical extension size field)
-    6, 0,  // format: A-law (6)
-    17, 0,  // channels: 17
-    0x39, 0x30, 0, 0,  // sample rate: 12345
-    0xc9, 0x33, 0x03, 0,  // byte rate: 1 * 17 * 12345
-    17, 0,  // block align: NumChannels * BytesPerSample
-    8, 0,  // bits per sample: 1 * 8
-    0, 0,  // zero extension size field (atypical)
+    18, 0, 0, 0,             // Size of fmt block (with an atypical extension
+                             // size field).
+    6, 0,                    // Format: A-law (6).
+    17, 0,                   // Channels: 17.
+    0x39, 0x30, 0, 0,        // Sample rate: 12345.
+    0xc9, 0x33, 0x03, 0,     // Byte rate: 1 * 17 * 12345.
+    17, 0,                   // Block align: NumChannels * BytesPerSample.
+    8, 0,                    // Bits per sample: 1 * 8.
+    0, 0,                    // Zero extension size field (atypical).
     'd', 'a', 't', 'a',
-    0x99, 0xd0, 0x5b, 0x07,  // size of payload: 123457689
+    0x99, 0xd0, 0x5b, 0x07,  // Size of payload: 123457689.
       // clang-format on
   };
 
@@ -329,7 +352,7 @@
   WavFormat format = kWavFormatPcm;
   size_t bytes_per_sample = 0;
   size_t num_samples = 0;
-  ReadableWavBuffer r(kBuf, sizeof(kBuf));
+  ReadableWavBuffer r(kBuf, sizeof(kBuf), /*check_read_size=*/true);
   EXPECT_TRUE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
                             &bytes_per_sample, &num_samples));
   EXPECT_EQ(17u, num_channels);
@@ -339,4 +362,79 @@
   EXPECT_EQ(123457689u, num_samples);
 }
 
+// Try reading a valid WAV header which contains an optional chunk and make sure
+// it's parsed OK.
+TEST(WavHeaderTest, ReadWavHeaderWithOptionalChunk) {
+  constexpr uint8_t kBuf[] = {
+      // clang-format off
+      // clang formatting doesn't respect inline comments.
+    'R', 'I', 'F', 'F',
+    0xcd, 0xd0, 0x5b, 0x07,  // Size of whole file - 8 + an extra 16 bytes of
+                             // "metadata" (8 bytes header, 16 bytes payload):
+                             // 123457689 + 44 - 8 + 16.
+    'W', 'A', 'V', 'E',
+    'f', 'm', 't', ' ',
+    16, 0, 0, 0,             // Size of fmt block.
+    6, 0,                    // Format: A-law (6).
+    17, 0,                   // Channels: 17.
+    0x39, 0x30, 0, 0,        // Sample rate: 12345.
+    0xc9, 0x33, 0x03, 0,     // Byte rate: 1 * 17 * 12345.
+    17, 0,                   // Block align: NumChannels * BytesPerSample.
+    8, 0,                    // Bits per sample: 1 * 8.
+    'L', 'I', 'S', 'T',      // Metadata chunk ID.
+    16, 0, 0, 0,             // Metadata chunk payload size.
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // Metadata (16 bytes).
+    'd', 'a', 't', 'a',
+    0x99, 0xd0, 0x5b, 0x07,  // Size of payload: 123457689.
+      // clang-format on
+  };
+
+  size_t num_channels = 0;
+  int sample_rate = 0;
+  WavFormat format = kWavFormatPcm;
+  size_t bytes_per_sample = 0;
+  size_t num_samples = 0;
+  ReadableWavBuffer r(kBuf, sizeof(kBuf), /*check_read_size=*/true);
+  EXPECT_TRUE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
+                            &bytes_per_sample, &num_samples));
+  EXPECT_EQ(17u, num_channels);
+  EXPECT_EQ(12345, sample_rate);
+  EXPECT_EQ(kWavFormatALaw, format);
+  EXPECT_EQ(1u, bytes_per_sample);
+  EXPECT_EQ(123457689u, num_samples);
+}
+
+// Try reading an invalid WAV header which has the the data chunk before the
+// format one and make sure it's not parsed.
+TEST(WavHeaderTest, ReadWavHeaderWithDataBeforeFormat) {
+  constexpr uint8_t kBuf[] = {
+      // clang-format off
+      // clang formatting doesn't respect inline comments.
+    'R', 'I', 'F', 'F',
+    52,  0,   0,   0,    // Size of whole file - 8: 16 + 44 - 8.
+    'W', 'A', 'V', 'E',
+    'd', 'a', 't', 'a',
+    16, 0, 0, 0,         // Data chunk payload size.
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // Data 16 bytes.
+    'f', 'm', 't', ' ',
+    16,  0,   0,   0,    // Size of fmt block.
+    6,   0,              // Format: A-law (6).
+    1,   0,              // Channels: 1.
+    60,  0,   0,   0,    // Sample rate: 60.
+    60,  0,   0,   0,    // Byte rate: 1 * 1 * 60.
+    1,   0,              // Block align: NumChannels * BytesPerSample.
+    8,   0,              // Bits per sample: 1 * 8.
+      // clang-format on
+  };
+
+  size_t num_channels = 0;
+  int sample_rate = 0;
+  WavFormat format = kWavFormatPcm;
+  size_t bytes_per_sample = 0;
+  size_t num_samples = 0;
+  ReadableWavBuffer r(kBuf, sizeof(kBuf), /*check_read_size=*/false);
+  EXPECT_FALSE(ReadWavHeader(&r, &num_channels, &sample_rate, &format,
+                             &bytes_per_sample, &num_samples));
+}
+
 }  // namespace webrtc
diff --git a/common_types.h b/common_types.h
index 99c4064..b2fcf17 100644
--- a/common_types.h
+++ b/common_types.h
@@ -11,12 +11,10 @@
 #ifndef COMMON_TYPES_H_
 #define COMMON_TYPES_H_
 
-#include <stddef.h>
-#include <string.h>
-#include <string>
-#include <vector>
+#include <stddef.h>  // For size_t
+#include <cstdint>
 
-#include "api/array_view.h"
+#include "absl/strings/match.h"
 // TODO(sprang): Remove this include when all usage includes it directly.
 #include "api/video/video_bitrate_allocation.h"
 #include "rtc_base/checks.h"
@@ -30,16 +28,6 @@
 
 #define RTP_PAYLOAD_NAME_SIZE 32u
 
-#if defined(WEBRTC_WIN) || defined(WIN32)
-// Compares two strings without regard to case.
-#define STR_CASE_CMP(s1, s2) ::_stricmp(s1, s2)
-// Compares characters of two strings without regard to case.
-#define STR_NCASE_CMP(s1, s2, n) ::_strnicmp(s1, s2, n)
-#else
-#define STR_CASE_CMP(s1, s2) ::strcasecmp(s1, s2)
-#define STR_NCASE_CMP(s1, s2, n) ::strncasecmp(s1, s2, n)
-#endif
-
 namespace webrtc {
 
 enum FrameType {
@@ -207,7 +195,7 @@
 
   bool operator==(const CodecInst& other) const {
     return pltype == other.pltype &&
-           (STR_CASE_CMP(plname, other.plname) == 0) &&
+           absl::EqualsIgnoreCase(plname, other.plname) &&
            plfreq == other.plfreq && pacsize == other.pacsize &&
            channels == other.channels && rate == other.rate;
   }
@@ -361,9 +349,6 @@
 // settings such as resolution.
 typedef SpatialLayer SimulcastStream;
 
-// TODO(sprang): Remove this when downstream projects have been updated.
-using BitrateAllocation = VideoBitrateAllocation;
-
 // Bandwidth over-use detector options.  These are used to drive
 // experimentation with bandwidth estimation parameters.
 // See modules/remote_bitrate_estimator/overuse_detector.h
diff --git a/cras-config/aec_config.cc b/cras-config/aec_config.cc
index 68696c6..adbd453 100644
--- a/cras-config/aec_config.cc
+++ b/cras-config/aec_config.cc
@@ -24,6 +24,14 @@
 	if (ini == NULL)
 		return;
 
+	config->buffering.use_new_render_buffering =
+		AEC_GET_INT(ini, BUFFERING, USE_NEW_RENDER_BUFFERING);
+	config->buffering.excess_render_detection_interval_blocks =
+		AEC_GET_INT(ini, BUFFERING,
+			EXCESS_RENDER_DETECTION_INTERVAL_BLOCKS);
+	config->buffering.max_allowed_excess_render_blocks =
+		AEC_GET_INT(ini, BUFFERING, MAX_ALLOWED_EXCESS_RENDER_BLOCKS);
+
 	config->delay.default_delay =
 		AEC_GET_INT(ini, DELAY, DEFAULT_DELAY);
 	config->delay.down_sampling_factor =
@@ -44,6 +52,14 @@
 		AEC_GET_INT(ini, DELAY, SKEW_HYSTERESIS_BLOCKS);
 	config->delay.fixed_capture_delay_samples =
 		AEC_GET_INT(ini, DELAY, FIXED_CAPTURE_DELAY_SAMPLES);
+	config->delay.delay_estimate_smoothing =
+		AEC_GET_FLOAT(ini, DELAY, DELAY_ESTIMATE_SMOOTHING);
+	config->delay.delay_candidate_detection_threshold =
+		AEC_GET_FLOAT(ini, DELAY, DELAY_CANDIDATE_DETECTION_THRESHOLD);
+	config->delay.delay_selection_thresholds.initial =
+		AEC_GET_INT(ini, DELAY, DELAY_SELECTION_THRESHOLD_INITIAL);
+	config->delay.delay_selection_thresholds.converged =
+		AEC_GET_INT(ini, DELAY, DELAY_SELECTION_THRESHOLD_CONVERGED);
 
 	config->filter.main.length_blocks =
 		AEC_GET_INT(ini, FILTER_MAIN, LENGTH_BLOCKS);
@@ -53,6 +69,8 @@
 		AEC_GET_FLOAT(ini, FILTER_MAIN, LEAKAGE_DIVERGED);
 	config->filter.main.error_floor =
 		AEC_GET_FLOAT(ini, FILTER_MAIN, ERROR_FLOOR);
+	config->filter.main.error_ceil =
+		AEC_GET_FLOAT(ini, FILTER_MAIN, ERROR_CEIL);
 	config->filter.main.noise_gate =
 		AEC_GET_FLOAT(ini, FILTER_MAIN, NOISE_GATE);
 
@@ -71,6 +89,8 @@
 		AEC_GET_FLOAT(ini, FILTER_MAIN_INIT, LEAKAGE_DIVERGED);
 	config->filter.main_initial.error_floor =
 		AEC_GET_FLOAT(ini, FILTER_MAIN_INIT, ERROR_FLOOR);
+	config->filter.main_initial.error_ceil =
+		AEC_GET_FLOAT(ini, FILTER_MAIN_INIT, ERROR_CEIL);
 	config->filter.main_initial.noise_gate =
 		AEC_GET_FLOAT(ini, FILTER_MAIN_INIT, NOISE_GATE);
 
@@ -114,35 +134,6 @@
 	config->ep_strength.echo_can_saturate =
 		AEC_GET_INT(ini, EP_STRENGTH, ECHO_CAN_SATURATE);
 
-	config->gain_mask.m0 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M0);
-	config->gain_mask.m1 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M1);
-	config->gain_mask.m2 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M2);
-	config->gain_mask.m3 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M3);
-	config->gain_mask.m5 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M5);
-	config->gain_mask.m6 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M6);
-	config->gain_mask.m7 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M7);
-	config->gain_mask.m8 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M8);
-	config->gain_mask.m9 =
-		AEC_GET_FLOAT(ini, GAIN_MASK, M9);
-	config->gain_mask.gain_curve_offset =
-		AEC_GET_FLOAT(ini, GAIN_MASK, GAIN_CURVE_OFFSET);
-	config->gain_mask.gain_curve_slope =
-		AEC_GET_FLOAT(ini, GAIN_MASK, GAIN_CURVE_SLOPE);
-	config->gain_mask.temporal_masking_lf =
-		AEC_GET_FLOAT(ini, GAIN_MASK, TEMPORAL_MASKING_LF);
-	config->gain_mask.temporal_masking_hf =
-		AEC_GET_FLOAT(ini, GAIN_MASK, TEMPORAL_MASKING_HF);
-	config->gain_mask.temporal_masking_lf_bands =
-		AEC_GET_INT(ini, GAIN_MASK, TEMPORAL_MASKING_LF_BANDS);
-
 	config->echo_audibility.low_render_limit =
 		AEC_GET_FLOAT(ini, ECHO_AUDIBILITY, LOW_RENDER_LIMIT);
 	config->echo_audibility.normal_render_limit =
@@ -157,6 +148,9 @@
 		AEC_GET_FLOAT(ini, ECHO_AUDIBILITY, AUDIBILITY_THRESHOLD_HF);
 	config->echo_audibility.use_stationary_properties =
 		AEC_GET_INT(ini, ECHO_AUDIBILITY, USE_STATIONARY_PROPERTIES);
+	config->echo_audibility.use_stationarity_properties_at_init =
+		AEC_GET_INT(ini, ECHO_AUDIBILITY,
+			    USE_STATIONARITY_PROPERTIES_AT_INIT);
 
 	config->render_levels.active_render_limit =
 		AEC_GET_FLOAT(ini, RENDER_LEVELS, ACTIVE_RENDER_LIMIT);
@@ -253,6 +247,9 @@
 	config->suppressor.dominant_nearend_detection.enr_threshold =
 		AEC_GET_FLOAT(ini, SUPPRESSOR_DOMINANT_NEAREND_DETECTION,
 			ENR_THRESHOLD);
+	config->suppressor.dominant_nearend_detection.enr_exit_threshold =
+		AEC_GET_FLOAT(ini, SUPPRESSOR_DOMINANT_NEAREND_DETECTION,
+			ENR_EXIT_THRESHOLD);
 	config->suppressor.dominant_nearend_detection.snr_threshold =
 		AEC_GET_FLOAT(ini, SUPPRESSOR_DOMINANT_NEAREND_DETECTION,
 			SNR_THRESHOLD);
@@ -262,6 +259,9 @@
 	config->suppressor.dominant_nearend_detection.trigger_threshold =
 		AEC_GET_INT(ini, SUPPRESSOR_DOMINANT_NEAREND_DETECTION,
 			TRIGGER_THRESHOLD);
+	config->suppressor.dominant_nearend_detection.use_during_initial_phase =
+		AEC_GET_INT(ini, SUPPRESSOR_DOMINANT_NEAREND_DETECTION,
+			USE_DURING_INITIAL_PHASE);
 
 	config->suppressor.high_bands_suppression.enr_threshold =
 		AEC_GET_FLOAT(ini, SUPPRESSOR_HIGH_BANDS_SUPPRESSION,
@@ -285,6 +285,14 @@
 	aec_config_get(ini, &config);
 
 	syslog(LOG_ERR, "---- aec config dump ----");
+	syslog(LOG_ERR, "Buffering:");
+	syslog(LOG_ERR, "    use_new_render_buffering %d",
+			config.buffering.use_new_render_buffering);
+	syslog(LOG_ERR, "    excess_render_detection_interval_blocks %zu",
+			config.buffering.excess_render_detection_interval_blocks);
+	syslog(LOG_ERR, "    max_allowed_excess_render_blocks %zu",
+			config.buffering.max_allowed_excess_render_blocks);
+
 	syslog(LOG_ERR, "Delay:");
 	syslog(LOG_ERR, "    default_delay %zu sampling_factor %zu num_filters %zu",
 			config.delay.default_delay,
@@ -301,14 +309,23 @@
 			config.delay.skew_hysteresis_blocks);
 	syslog(LOG_ERR, "    fixed_capture_delay_samples %zu",
 			config.delay.fixed_capture_delay_samples);
+	syslog(LOG_ERR, "    delay_estimate_smoothing %f",
+			config.delay.delay_estimate_smoothing);
+	syslog(LOG_ERR, "    delay_candidate_detection_threshold %f",
+			config.delay.delay_candidate_detection_threshold);
+	syslog(LOG_ERR, "    delay_selection_thresholds.initial %d",
+			config.delay.delay_selection_thresholds.initial);
+	syslog(LOG_ERR, "    delay_selection_thresholds.converged %d",
+			config.delay.delay_selection_thresholds.converged);
 
 	syslog(LOG_ERR, "Filter main configuration:");
 	syslog(LOG_ERR, "    length_blocks %zu, leakage_converged %f, leakage_diverged %f",
 			config.filter.main.length_blocks,
 			config.filter.main.leakage_converged,
 			config.filter.main.leakage_diverged);
-	syslog(LOG_ERR, "    error_floor %f, noise_gate %f",
+	syslog(LOG_ERR, "    error_floor %f, error_ceil %f, noise_gate %f",
 			config.filter.main.error_floor,
+			config.filter.main.error_ceil,
 			config.filter.main.noise_gate);
 	syslog(LOG_ERR, "Filter shadow configuration:");
 	syslog(LOG_ERR, "    length_blocks %zu, rate %f, noise_gate %f",
@@ -316,12 +333,13 @@
 			config.filter.shadow.rate,
 			config.filter.shadow.noise_gate);
 	syslog(LOG_ERR, "Filter main initial configuration:");
-	syslog(LOG_ERR, "    length_blocks %zu, leakage_converged %f",
+	syslog(LOG_ERR, "    length_blocks %zu, leakage_converged %f leakage_diverged %f",
 			config.filter.main_initial.length_blocks,
-			config.filter.main_initial.leakage_converged);
-	syslog(LOG_ERR, "    leakage_diverged %f, error_floor %f, noise_gate %f",
-			config.filter.main_initial.leakage_diverged,
+			config.filter.main_initial.leakage_converged,
+			config.filter.main_initial.leakage_diverged);
+	syslog(LOG_ERR, "    error_floor %f, error_ceil %f, noise_gate %f",
 			config.filter.main_initial.error_floor,
+			config.filter.main_initial.error_ceil,
 			config.filter.main_initial.noise_gate);
 	syslog(LOG_ERR, "Filter shadow initial configuration:");
 	syslog(LOG_ERR, "    length_blocks %zu, rate %f, noise_gate %f",
@@ -349,25 +367,6 @@
 			config.ep_strength.echo_can_saturate,
 			config.ep_strength.bounded_erl,
 			config.ep_strength.reverb_based_on_render);
-	syslog(LOG_ERR, "Gain mask: m0 %f m1 %f m2 %f m3 %f m5 %f",
-			config.gain_mask.m0,
-			config.gain_mask.m1,
-			config.gain_mask.m2,
-			config.gain_mask.m3,
-			config.gain_mask.m5);
-	syslog(LOG_ERR, "    m6 %f m7 %f m8 %f m9 %f",
-			config.gain_mask.m6,
-			config.gain_mask.m7,
-			config.gain_mask.m8,
-			config.gain_mask.m9);
-	syslog(LOG_ERR, "    gain_curve offset %f, gain_curve_slope %f",
-			config.gain_mask.gain_curve_offset,
-			config.gain_mask.gain_curve_slope);
-	syslog(LOG_ERR, "    temporal_masking_lf %f, temporal_masking_hf %f",
-			config.gain_mask.temporal_masking_lf,
-			config.gain_mask.temporal_masking_hf);
-	syslog(LOG_ERR, "    temporal_masking_lf_bands %zu",
-			config.gain_mask.temporal_masking_lf_bands);
 	syslog(LOG_ERR, "Echo audibility:");
 	syslog(LOG_ERR, "    low_render_limit %f, normal_render_limit %f",
 			config.echo_audibility.low_render_limit,
@@ -381,6 +380,9 @@
 			config.echo_audibility.audibility_threshold_hf);
 	syslog(LOG_ERR, "    use_stationary_properties %d",
 			config.echo_audibility.use_stationary_properties);
+	syslog(LOG_ERR, "    use_stationarity_properties_at_init %d",
+			config.echo_audibility.use_stationarity_properties_at_init);
+
 	syslog(LOG_ERR, "Render levels:");
 	syslog(LOG_ERR, "    active_render_limit %f",
 			config.render_levels.active_render_limit);
@@ -447,12 +449,16 @@
 	syslog(LOG_ERR, "    Dominant nearend detection:");
 	syslog(LOG_ERR, "        enr_threshold %f",
 			config.suppressor.dominant_nearend_detection.enr_threshold);
+	syslog(LOG_ERR, "        enr_exit_threshold %f",
+			config.suppressor.dominant_nearend_detection.enr_exit_threshold);
 	syslog(LOG_ERR, "        snr_threshold %f",
 			config.suppressor.dominant_nearend_detection.snr_threshold);
 	syslog(LOG_ERR, "        hold_duration %d",
 			config.suppressor.dominant_nearend_detection.hold_duration);
 	syslog(LOG_ERR, "        trigger_threshold %d",
 			config.suppressor.dominant_nearend_detection.trigger_threshold);
+	syslog(LOG_ERR, "        use_during_initial_phase %d",
+			config.suppressor.dominant_nearend_detection.use_during_initial_phase);
 	syslog(LOG_ERR, "    High bands suppression:");
 	syslog(LOG_ERR, "        enr_threshold %f max_gain_during_echo %f",
 			config.suppressor.high_bands_suppression.enr_threshold,
diff --git a/cras-config/aec_config.h b/cras-config/aec_config.h
index 8255ce5..5318ac9 100644
--- a/cras-config/aec_config.h
+++ b/cras-config/aec_config.h
@@ -10,12 +10,21 @@
 
 #include "api/audio/echo_canceller3_config.h"
 
+#define AEC_BUFFERING_USE_NEW_RENDER_BUFFERING "buffering:use_new_render_buffering"
+#define AEC_BUFFERING_USE_NEW_RENDER_BUFFERING_VALUE 1
+#define AEC_BUFFERING_EXCESS_RENDER_DETECTION_INTERVAL_BLOCKS \
+	"buffering:excess_render_detection_interval_blocks"
+#define AEC_BUFFERING_EXCESS_RENDER_DETECTION_INTERVAL_BLOCKS_VALUE 250
+#define AEC_BUFFERING_MAX_ALLOWED_EXCESS_RENDER_BLOCKS \
+	"buffering:max_allowed_excess_render_blocks"
+#define AEC_BUFFERING_MAX_ALLOWED_EXCESS_RENDER_BLOCKS_VALUE 8
+
 #define AEC_DELAY_DEFAULT_DELAY "delay:default_delay"
 #define AEC_DELAY_DEFAULT_DELAY_VALUE 5
 #define AEC_DELAY_DOWN_SAMPLING_FACTOR "delay:down_sampling_factor"
 #define AEC_DELAY_DOWN_SAMPLING_FACTOR_VALUE 4
 #define AEC_DELAY_NUM_FILTERS "delay:num_filters"
-#define AEC_DELAY_NUM_FILTERS_VALUE 6
+#define AEC_DELAY_NUM_FILTERS_VALUE 5
 #define AEC_DELAY_API_CALL_JITTER_BLOCKS "delay:api_call_jitter_blocks"
 #define AEC_DELAY_API_CALL_JITTER_BLOCKS_VALUE 26
 #define AEC_DELAY_MIN_ECHO_PATH_DELAY_BLOCKS "delay:min_echo_path_delay_blocks"
@@ -31,6 +40,17 @@
 #define AEC_DELAY_FIXED_CAPTURE_DELAY_SAMPLES \
 	"delay:fixed_capture_delay_samples"
 #define AEC_DELAY_FIXED_CAPTURE_DELAY_SAMPLES_VALUE 0
+#define AEC_DELAY_DELAY_ESTIMATE_SMOOTHING "delay:delay_estimate_smoothing"
+#define AEC_DELAY_DELAY_ESTIMATE_SMOOTHING_VALUE 0.7f
+#define AEC_DELAY_DELAY_CANDIDATE_DETECTION_THRESHOLD \
+	"delay:delay_candidate_detection_threshold"
+#define AEC_DELAY_DELAY_CANDIDATE_DETECTION_THRESHOLD_VALUE 0.2f
+#define AEC_DELAY_DELAY_SELECTION_THRESHOLD_INITIAL \
+	"delay:delay_selection_thresholds_initial"
+#define AEC_DELAY_DELAY_SELECTION_THRESHOLD_INITIAL_VALUE 5
+#define AEC_DELAY_DELAY_SELECTION_THRESHOLD_CONVERGED \
+	"delay:delay_selection_thresholds_converged"
+#define AEC_DELAY_DELAY_SELECTION_THRESHOLD_CONVERGED_VALUE 20
 
 // Filter Main configuration
 #define AEC_FILTER_MAIN_LENGTH_BLOCKS "filter.main:length_blocks"
@@ -38,9 +58,11 @@
 #define AEC_FILTER_MAIN_LEAKAGE_CONVERGED "filter.main:leakage_converged"
 #define AEC_FILTER_MAIN_LEAKAGE_CONVERGED_VALUE 0.00005f
 #define AEC_FILTER_MAIN_LEAKAGE_DIVERGED "filter.main:leakage_diverged"
-#define AEC_FILTER_MAIN_LEAKAGE_DIVERGED_VALUE 0.01f
+#define AEC_FILTER_MAIN_LEAKAGE_DIVERGED_VALUE 0.05f
 #define AEC_FILTER_MAIN_ERROR_FLOOR "filter.main:error_floor"
-#define AEC_FILTER_MAIN_ERROR_FLOOR_VALUE 0.1f
+#define AEC_FILTER_MAIN_ERROR_FLOOR_VALUE 0.001f
+#define AEC_FILTER_MAIN_ERROR_CEIL "filter.main:error_ceil"
+#define AEC_FILTER_MAIN_ERROR_CEIL_VALUE 2.f
 #define AEC_FILTER_MAIN_NOISE_GATE "filter.main:noise_gate"
 #define AEC_FILTER_MAIN_NOISE_GATE_VALUE 20075344.f
 
@@ -63,6 +85,8 @@
 #define AEC_FILTER_MAIN_INIT_LEAKAGE_DIVERGED_VALUE 0.5f
 #define AEC_FILTER_MAIN_INIT_ERROR_FLOOR "filter.main_initial:error_floor"
 #define AEC_FILTER_MAIN_INIT_ERROR_FLOOR_VALUE 0.001f
+#define AEC_FILTER_MAIN_INIT_ERROR_CEIL "filter.main_initial:error_ceil"
+#define AEC_FILTER_MAIN_INIT_ERROR_CEIL_VALUE 2.f
 #define AEC_FILTER_MAIN_INIT_NOISE_GATE "filter.main_initial:noise_gate"
 #define AEC_FILTER_MAIN_INIT_NOISE_GATE_VALUE 20075344.f
 
@@ -105,7 +129,7 @@
 #define AEC_EP_STRENGTH_HF "ep_strength:hf"
 #define AEC_EP_STRENGTH_HF_VALUE 1.f
 #define AEC_EP_STRENGTH_DEFAULT_LEN "ep_strength:default_len"
-#define AEC_EP_STRENGTH_DEFAULT_LEN_VALUE 0.88f
+#define AEC_EP_STRENGTH_DEFAULT_LEN_VALUE 0.83f
 #define AEC_EP_STRENGTH_REVERB_BASED_ON_RENDER \
 	"ep_strength:reverb_based_on_render"
 #define AEC_EP_STRENGTH_REVERB_BASED_ON_RENDER_VALUE 1
@@ -114,39 +138,6 @@
 #define AEC_EP_STRENGTH_BOUNDED_ERL "ep_strength:bounded_erl"
 #define AEC_EP_STRENGTH_BOUNDED_ERL_VALUE 0
 
-// Gain mask
-#define AEC_GAIN_MASK_M0 "gain_mask:m0"
-#define AEC_GAIN_MASK_M0_VALUE 0.1f
-#define AEC_GAIN_MASK_M1 "gain_mask:m1"
-#define AEC_GAIN_MASK_M1_VALUE 0.01f
-#define AEC_GAIN_MASK_M2 "gain_mask:m2"
-#define AEC_GAIN_MASK_M2_VALUE 0.0001f
-#define AEC_GAIN_MASK_M3 "gain_mask:m3"
-#define AEC_GAIN_MASK_M3_VALUE 0.01f
-// m4 was removed intentionally.
-// https://webrtc-review.googlesource.com/c/src/+/70421
-#define AEC_GAIN_MASK_M5 "gain_mask:m5"
-#define AEC_GAIN_MASK_M5_VALUE 0.01f
-#define AEC_GAIN_MASK_M6 "gain_mask:m6"
-#define AEC_GAIN_MASK_M6_VALUE 0.0001f
-#define AEC_GAIN_MASK_M7 "gain_mask:m7"
-#define AEC_GAIN_MASK_M7_VALUE 0.01f
-#define AEC_GAIN_MASK_M8 "gain_mask:m8"
-#define AEC_GAIN_MASK_M8_VALUE 0.0001f
-#define AEC_GAIN_MASK_M9 "gain_mask:m9"
-#define AEC_GAIN_MASK_M9_VALUE 0.1f
-#define AEC_GAIN_MASK_GAIN_CURVE_OFFSET "gain_mask:gain_curve_offset"
-#define AEC_GAIN_MASK_GAIN_CURVE_OFFSET_VALUE 1.45f
-#define AEC_GAIN_MASK_GAIN_CURVE_SLOPE "gain_mask:gain_curve_slope"
-#define AEC_GAIN_MASK_GAIN_CURVE_SLOPE_VALUE 5.f
-#define AEC_GAIN_MASK_TEMPORAL_MASKING_LF "gain_mask:temporal_masking_lf"
-#define AEC_GAIN_MASK_TEMPORAL_MASKING_LF_VALUE 0.9f
-#define AEC_GAIN_MASK_TEMPORAL_MASKING_HF "gain_mask:temporal_masking_hf"
-#define AEC_GAIN_MASK_TEMPORAL_MASKING_HF_VALUE 0.6f
-#define AEC_GAIN_MASK_TEMPORAL_MASKING_LF_BANDS \
-	"gain_mask:temporal_masking_lf_bands"
-#define AEC_GAIN_MASK_TEMPORAL_MASKING_LF_BANDS_VALUE 3
-
 #define AEC_ECHO_AUDIBILITY_LOW_RENDER_LIMIT "echo_audibility:low_render_limit"
 #define AEC_ECHO_AUDIBILITY_LOW_RENDER_LIMIT_VALUE 4 * 64.f
 #define AEC_ECHO_AUDIBILITY_NORMAL_RENDER_LIMIT \
@@ -166,6 +157,9 @@
 #define AEC_ECHO_AUDIBILITY_USE_STATIONARY_PROPERTIES \
 	"echo_audibility:use_stationary_properties"
 #define AEC_ECHO_AUDIBILITY_USE_STATIONARY_PROPERTIES_VALUE 1
+#define AEC_ECHO_AUDIBILITY_USE_STATIONARITY_PROPERTIES_AT_INIT \
+	 "echo_audibility:use_stationarity_properties_at_init"
+#define AEC_ECHO_AUDIBILITY_USE_STATIONARITY_PROPERTIES_AT_INIT_VALUE 1
 
 // Rendering levels
 #define AEC_RENDER_LEVELS_ACTIVE_RENDER_LIMIT \
@@ -231,10 +225,10 @@
 
 #define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_ENR_TRANSPARENT \
 	"suppressor.normal_tuning:mask_lf_enr_transparent"
-#define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_ENR_TRANSPARENT_VALUE .2f
+#define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_ENR_TRANSPARENT_VALUE .3f
 #define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_ENR_SUPPRESS \
 	"suppressor.normal_tuning:mask_lf_enr_suppress"
-#define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_ENR_SUPPRESS_VALUE .3f
+#define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_ENR_SUPPRESS_VALUE .4f
 #define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_EMR_TRANSPARENT \
 	"suppressor.normal_tuning:mask_lf_emr_transparent"
 #define AEC_SUPPRESSOR_NORMAL_TUNING_MASK_LF_EMR_TRANSPARENT_VALUE .3f
@@ -258,20 +252,20 @@
 
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_ENR_TRANSPARENT \
 	"suppressor.nearend_tuning:mask_lf_enr_transparent"
-#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_ENR_TRANSPARENT_VALUE .2f
+#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_ENR_TRANSPARENT_VALUE 1.09f
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_ENR_SUPPRESS \
 	"suppressor.nearend_tuning:mask_lf_enr_suppress"
-#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_ENR_SUPPRESS_VALUE .3f
+#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_ENR_SUPPRESS_VALUE 1.1f
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_EMR_TRANSPARENT \
 	"suppressor.nearend_tuning:mask_lf_emr_transparent"
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_LF_EMR_TRANSPARENT_VALUE .3f
 
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_ENR_TRANSPARENT \
 	"suppressor.nearend_tuning:mask_hf_enr_transparent"
-#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_ENR_TRANSPARENT_VALUE .07f
+#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_ENR_TRANSPARENT_VALUE .1f
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_ENR_SUPPRESS \
 	"suppressor.nearend_tuning:mask_hf_enr_suppress"
-#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_ENR_SUPPRESS_VALUE .1f
+#define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_ENR_SUPPRESS_VALUE .3f
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_EMR_TRANSPARENT \
 	"suppressor.nearend_tuning:mask_hf_emr_transparent"
 #define AEC_SUPPRESSOR_NEAREND_TUNING_MASK_HF_EMR_TRANSPARENT_VALUE .3f
@@ -285,16 +279,22 @@
 
 #define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_ENR_THRESHOLD \
 	"suppressor.dominant_nearend_detection:enr_threshold"
-#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_ENR_THRESHOLD_VALUE 10.f
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_ENR_THRESHOLD_VALUE 4.f
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_ENR_EXIT_THRESHOLD \
+	"suppressor.dominant_nearend_detection:enr_exit_threshold"
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_ENR_EXIT_THRESHOLD_VALUE .1f
 #define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_SNR_THRESHOLD \
 	"suppressor.dominant_nearend_detection:snr_threshold"
-#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_SNR_THRESHOLD_VALUE 10.f
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_SNR_THRESHOLD_VALUE 30.f
 #define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_HOLD_DURATION \
 	"suppressor.dominant_nearend_detection:hold_duration"
-#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_HOLD_DURATION_VALUE 25
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_HOLD_DURATION_VALUE 50
 #define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_TRIGGER_THRESHOLD \
 	"suppressor.dominant_nearend_detection:trigger_threshold"
-#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_TRIGGER_THRESHOLD_VALUE 15
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_TRIGGER_THRESHOLD_VALUE 12
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_USE_DURING_INITIAL_PHASE \
+	"suppressor.dominant_nearend_detection:use_during_initial_phase"
+#define AEC_SUPPRESSOR_DOMINANT_NEAREND_DETECTION_USE_DURING_INITIAL_PHASE_VALUE 1
 
 #define AEC_SUPPRESSOR_HIGH_BANDS_SUPPRESSION_ENR_THRESHOLD \
 	"suppressor.high_bands_suppression:enr_threshold"
diff --git a/cras-config/apm_config.cc b/cras-config/apm_config.cc
index bcf1c96..b03f8d5 100644
--- a/cras-config/apm_config.cc
+++ b/cras-config/apm_config.cc
@@ -37,10 +37,12 @@
 			APM_GET_FLOAT(ini, APM_PRE_AMPLIFIER_FIXED_GAIN_FACTOR);
 	config.gain_controller2.enabled =
 			APM_GET_INT(ini, APM_GAIN_CONTROLLER2_ENABLED);
-	config.gain_controller2.fixed_gain_db =
-			APM_GET_FLOAT(ini, APM_GAIN_CONTROLLER2_FIXED_GAIN_DB);
 	config.gain_controller2.adaptive_digital_mode =
-			APM_GET_INT(ini, APM_GAIN_CONTROLLER2_ADAPTIVE_DIGITAL_MODE);
+		APM_GET_INT(ini, APM_GAIN_CONTROLLER2_ADAPTIVE_DIGITAL_MODE);
+	config.gain_controller2.extra_saturation_margin_db =
+		APM_GET_FLOAT(ini, APM_GAIN_CONTROLLER2_EXTRA_SATURATION_MARGIN_DB);
+	config.gain_controller2.fixed_gain_db =
+		APM_GET_FLOAT(ini, APM_GAIN_CONTROLLER2_FIXED_GAIN_DB);
 	apm->ApplyConfig(config);
 
 	apm->gain_control()->set_compression_gain_db(
@@ -71,10 +73,12 @@
 		APM_GET_FLOAT(ini, APM_PRE_AMPLIFIER_FIXED_GAIN_FACTOR));
 	syslog(LOG_ERR, "gain_controller2_enabled %u",
 		APM_GET_INT(ini, APM_GAIN_CONTROLLER2_ENABLED));
-	syslog(LOG_ERR, "gain_controller2_fixed_gain_db %f",
-		APM_GET_FLOAT(ini, APM_GAIN_CONTROLLER2_FIXED_GAIN_DB));
 	syslog(LOG_ERR, "gain_controller2_adaptive_digital_mode %d",
 		APM_GET_INT(ini, APM_GAIN_CONTROLLER2_ADAPTIVE_DIGITAL_MODE));
+	syslog(LOG_ERR, "gain_controller2_extra_saturation_margin_db %f",
+		APM_GET_FLOAT(ini, APM_GAIN_CONTROLLER2_EXTRA_SATURATION_MARGIN_DB));
+	syslog(LOG_ERR, "gain_controller2_fixed_gain_db %f",
+		APM_GET_FLOAT(ini, APM_GAIN_CONTROLLER2_FIXED_GAIN_DB));
 	syslog(LOG_ERR, "gain_control_compression_gain_db %u",
 		APM_GET_INT(ini, APM_GAIN_CONTROL_COMPRESSION_GAIN_DB));
 	syslog(LOG_ERR, "gain_control_mode %u",
diff --git a/cras-config/apm_config.h b/cras-config/apm_config.h
index 30d2b04..a223877 100644
--- a/cras-config/apm_config.h
+++ b/cras-config/apm_config.h
@@ -24,6 +24,9 @@
 #define APM_GAIN_CONTROLLER2_FIXED_GAIN_DB_VALUE 0.f
 #define APM_GAIN_CONTROLLER2_ADAPTIVE_DIGITAL_MODE "apm:gain_controller2_adaptive_digital_mode"
 #define APM_GAIN_CONTROLLER2_ADAPTIVE_DIGITAL_MODE_VALUE 1
+#define APM_GAIN_CONTROLLER2_EXTRA_SATURATION_MARGIN_DB \
+	"apm:gain_controller2_extra_saturation_margin_db"
+#define APM_GAIN_CONTROLLER2_EXTRA_SATURATION_MARGIN_DB_VALUE 2.f
 #define APM_GAIN_CONTROL_COMPRESSION_GAIN_DB "apm:gain_control_compression_gain_db"
 #define APM_GAIN_CONTROL_COMPRESSION_GAIN_DB_VALUE 9
 /* 0: adaptive analog, 1: adaptive digital, 2: fixed digital */
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 5889018..ec81697 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -15,7 +15,6 @@
 visibility = [ ":*" ]
 
 audio_codec_deps = [
-  ":cng",
   ":g711",
   ":pcm16b",
 ]
@@ -53,6 +52,7 @@
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
     "../../rtc_base:sanitizer",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
@@ -74,6 +74,7 @@
   deps = [
            "../../rtc_base:checks",
            "../../api:array_view",
+           "//third_party/abseil-cpp/absl/strings",
            "//third_party/abseil-cpp/absl/types:optional",
            "../../api/audio_codecs:audio_codecs_api",
            "../..:webrtc_common",
@@ -83,6 +84,7 @@
            ":audio_coding_module_typedefs",
            ":isac_common",
            ":isac_fix_c",
+           ":audio_encoder_cng",
            ":neteq_decoder_enum",
          ] + audio_codec_deps
 
@@ -126,6 +128,7 @@
            "../../system_wrappers:metrics",
            "../../api/audio:audio_frame_api",
            "..:module_api",
+           "..:module_api_public",
            "../../common_audio:common_audio_c",
            "../../rtc_base:deprecation",
            "../../rtc_base:checks",
@@ -133,9 +136,11 @@
            "../../api/audio_codecs:audio_codecs_api",
            ":audio_coding_module_typedefs",
            ":neteq",
+           ":neteq_decoder_enum",
            ":rent_a_codec",
            "../../rtc_base:audio_format_to_string",
            "../../rtc_base:rtc_base_approved",
+           "//third_party/abseil-cpp/absl/strings",
            "//third_party/abseil-cpp/absl/types:optional",
            "../../logging:rtc_event_log_api",
          ]
@@ -150,26 +155,41 @@
   deps = [
     "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
+    "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
+    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
-rtc_static_library("cng") {
-  visibility += [ "*" ]
+rtc_static_library("webrtc_cng") {
+  visibility += webrtc_default_visibility
   sources = [
-    "codecs/cng/audio_encoder_cng.cc",
-    "codecs/cng/audio_encoder_cng.h",
     "codecs/cng/webrtc_cng.cc",
     "codecs/cng/webrtc_cng.h",
   ]
 
   deps = [
-    "../..:webrtc_common",
     "../../api:array_view",
+    "../../common_audio:common_audio_c",
+    "../../rtc_base:checks",
+    "../../rtc_base:rtc_base_approved",
+    "../../rtc_base:safe_conversions",
+  ]
+}
+
+rtc_static_library("audio_encoder_cng") {
+  visibility += [ "*" ]
+  sources = [
+    "codecs/cng/audio_encoder_cng.cc",
+    "codecs/cng/audio_encoder_cng.h",
+  ]
+
+  deps = [
+    ":webrtc_cng",
     "../../api/audio_codecs:audio_codecs_api",
     "../../common_audio",
-    "../../common_audio:common_audio_c",
-    "../../rtc_base:rtc_base_approved",
+    "../../rtc_base:checks",
+    "//third_party/abseil-cpp/absl/memory",
   ]
 }
 
@@ -181,10 +201,12 @@
   ]
 
   deps = [
+    "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
     "../../common_audio",
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
+    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -201,6 +223,7 @@
   deps = [
     ":legacy_encoded_audio_frame",
     "../..:webrtc_common",
+    "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
@@ -235,6 +258,7 @@
   deps = [
     ":legacy_encoded_audio_frame",
     "../..:webrtc_common",
+    "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
     "../../api/audio_codecs/g722:audio_encoder_g722_config",
     "../../rtc_base:checks",
@@ -270,6 +294,7 @@
   deps = [
     ":legacy_encoded_audio_frame",
     "../..:webrtc_common",
+    "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
     "../../api/audio_codecs/ilbc:audio_encoder_ilbc_config",
     "../../common_audio",
@@ -786,6 +811,7 @@
     ":g711",
     ":legacy_encoded_audio_frame",
     "../..:webrtc_common",
+    "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
@@ -820,6 +846,7 @@
   deps = [
     ":audio_network_adaptor",
     "../..:webrtc_common",
+    "../../api:array_view",
     "../../api/audio_codecs:audio_codecs_api",
     "../../api/audio_codecs/opus:audio_encoder_opus_config",
     "../../common_audio",
@@ -829,6 +856,7 @@
     "../../rtc_base:safe_minmax",
     "../../system_wrappers:field_trial",
     "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps = [
@@ -882,6 +910,7 @@
     proto_out_dir = "modules/audio_coding/audio_network_adaptor"
   }
   proto_library("ana_config_proto") {
+    visibility += webrtc_default_visibility
     sources = [
       "audio_network_adaptor/config.proto",
     ]
@@ -1048,9 +1077,10 @@
 
   deps = [
     ":audio_coding_module_typedefs",
-    ":cng",
     ":neteq_decoder_enum",
+    ":webrtc_cng",
     "..:module_api",
+    "..:module_api_public",
     "../..:webrtc_common",
     "../../api:array_view",
     "../../api:libjingle_peerconnection_api",
@@ -1067,6 +1097,7 @@
     "../../rtc_base/system:fallthrough",
     "../../system_wrappers:field_trial",
     "../../system_wrappers:metrics",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
@@ -1105,6 +1136,7 @@
     "../rtp_rtcp",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
+  defines = audio_codec_defines
 }
 
 rtc_source_set("neteq_test_tools") {
@@ -1145,6 +1177,7 @@
     "../../test:rtp_test_utils",
     "../rtp_rtcp",
     "../rtp_rtcp:rtp_rtcp_format",
+    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   public_deps = [
@@ -1238,6 +1271,7 @@
       "../../rtc_base:rtc_base_approved",
       "../rtp_rtcp",
       "../rtp_rtcp:rtp_rtcp_format",
+      "//third_party/abseil-cpp/absl/types:optional",
     ]
     public_deps = [
       "../../logging:rtc_event_log_proto",
@@ -1330,8 +1364,8 @@
     deps = [
       ":audio_coding",
       ":audio_coding_module_typedefs",
+      ":audio_encoder_cng",
       ":audio_format_conversion",
-      ":cng",
       ":pcm16b_c",
       ":red",
       "..:module_api",
@@ -1359,6 +1393,7 @@
       "../../system_wrappers",
       "../../test:fileutils",
       "../../test:test_support",
+      "//third_party/abseil-cpp/absl/strings",
       "//third_party/abseil-cpp/absl/types:optional",
     ]
     defines = audio_coding_defines
@@ -1414,6 +1449,7 @@
              ":neteq_tools",
              "../../rtc_base:rtc_base_approved",
              "../../test:test_support",
+             "//third_party/abseil-cpp/absl/strings",
              "//testing/gtest",
            ]
   }
@@ -1477,6 +1513,7 @@
              "../../rtc_base/system:arch",
              "../../test:test_main",
              "//testing/gtest",
+             "../../test:test_support",
            ] + audio_coding_deps
 
     data = audio_decoder_unittests_resources
@@ -1501,7 +1538,7 @@
     rtc_source_set("neteq_test_factory") {
       testonly = true
       visibility += webrtc_default_visibility
-      defines = []
+      defines = audio_codec_defines
       deps = [
         "../../rtc_base:checks",
         "../../test:fileutils",
@@ -1594,6 +1631,7 @@
       "../../api:libjingle_peerconnection_api",
       "../../rtc_base:rtc_base_approved",
       "../../test:test_main",
+      "../../test:test_support",
       "../audio_processing",
       "//testing/gtest",
     ]
@@ -1661,6 +1699,7 @@
     deps = audio_coding_deps + [
              "//third_party/abseil-cpp/absl/memory",
              ":audio_coding",
+             ":audio_encoder_cng",
              ":neteq_input_audio_tools",
              "../../api/audio:audio_frame_api",
              "../../api/audio_codecs/g711:audio_encoder_g711",
@@ -1955,6 +1994,7 @@
       "../../rtc_base:rtc_base_approved",
       "../../test:fileutils",
       "../../test:test_main",
+      "../../test:test_support",
       "//testing/gtest",
     ]
   }
@@ -2047,9 +2087,9 @@
       ":acm_send_test",
       ":audio_coding",
       ":audio_coding_module_typedefs",
+      ":audio_encoder_cng",
       ":audio_format_conversion",
       ":audio_network_adaptor",
-      ":cng",
       ":g711",
       ":ilbc",
       ":isac",
@@ -2063,6 +2103,7 @@
       ":pcm16b",
       ":red",
       ":rent_a_codec",
+      ":webrtc_cng",
       ":webrtc_opus",
       "..:module_api",
       "../..:webrtc_common",
@@ -2097,6 +2138,7 @@
       "codecs/opus/test:test_unittest",
       "//testing/gtest",
       "//third_party/abseil-cpp/absl/memory",
+      "//third_party/abseil-cpp/absl/types:optional",
     ]
 
     defines = audio_coding_defines
diff --git a/modules/audio_coding/OWNERS b/modules/audio_coding/OWNERS
index c1adc56..46f9958 100644
--- a/modules/audio_coding/OWNERS
+++ b/modules/audio_coding/OWNERS
@@ -4,6 +4,7 @@
 minyue@webrtc.org
 jan.skoglund@webrtc.org
 ossu@webrtc.org
+ivoc@webrtc.org
 
 # These are for the common case of adding or renaming files. If you're doing
 # structural changes, please get a review from a reviewer in this file.
diff --git a/modules/audio_coding/acm2/acm_codec_database.cc b/modules/audio_coding/acm2/acm_codec_database.cc
index 311af2d..879082c 100644
--- a/modules/audio_coding/acm2/acm_codec_database.cc
+++ b/modules/audio_coding/acm2/acm_codec_database.cc
@@ -17,7 +17,9 @@
 // references, where appropriate.
 #include "modules/audio_coding/acm2/acm_codec_database.h"
 
-#include "rtc_base/checks.h"
+#include "absl/strings/match.h"
+#include "api/array_view.h"
+#include "modules/audio_coding/acm2/rent_a_codec.h"
 
 #if ((defined WEBRTC_CODEC_ISAC) && (defined WEBRTC_CODEC_ISACFX))
 #error iSAC and iSACFX codecs cannot be enabled at the same time
@@ -239,12 +241,12 @@
   }
 
   // Comfort Noise is special case, packet-size & rate is not checked.
-  if (STR_CASE_CMP(database_[codec_id].plname, "CN") == 0) {
+  if (absl::EqualsIgnoreCase(database_[codec_id].plname, "CN")) {
     return codec_id;
   }
 
   // RED is special case, packet-size & rate is not checked.
-  if (STR_CASE_CMP(database_[codec_id].plname, "red") == 0) {
+  if (absl::EqualsIgnoreCase(database_[codec_id].plname, "red")) {
     return codec_id;
   }
 
@@ -272,12 +274,12 @@
 
   // Check the validity of rate. Codecs with multiple rates have their own
   // function for this.
-  if (STR_CASE_CMP("isac", codec_inst.plname) == 0) {
+  if (absl::EqualsIgnoreCase("isac", codec_inst.plname)) {
     return IsISACRateValid(codec_inst.rate) ? codec_id : kInvalidRate;
-  } else if (STR_CASE_CMP("ilbc", codec_inst.plname) == 0) {
+  } else if (absl::EqualsIgnoreCase("ilbc", codec_inst.plname)) {
     return IsILBCRateValid(codec_inst.rate, codec_inst.pacsize) ? codec_id
                                                                 : kInvalidRate;
-  } else if (STR_CASE_CMP("opus", codec_inst.plname) == 0) {
+  } else if (absl::EqualsIgnoreCase("opus", codec_inst.plname)) {
     return IsOpusRateValid(codec_inst.rate) ? codec_id : kInvalidRate;
   }
 
@@ -304,10 +306,10 @@
     // Payload name, sampling frequency and number of channels need to match.
     // NOTE! If |frequency| is -1, the frequency is not applicable, and is
     // always treated as true, like for RED.
-    name_match = (STR_CASE_CMP(ci.plname, payload_name) == 0);
+    name_match = absl::EqualsIgnoreCase(ci.plname, payload_name);
     frequency_match = (frequency == ci.plfreq) || (frequency == -1);
     // The number of channels must match for all codecs but Opus.
-    if (STR_CASE_CMP(payload_name, "opus") != 0) {
+    if (!absl::EqualsIgnoreCase(payload_name, "opus")) {
       channels_match = (channels == ci.channels);
     } else {
       // For opus we just check that number of channels is valid.
diff --git a/modules/audio_coding/acm2/acm_receive_test.cc b/modules/audio_coding/acm2/acm_receive_test.cc
index 2d7f296..c149ec1 100644
--- a/modules/audio_coding/acm2/acm_receive_test.cc
+++ b/modules/audio_coding/acm2/acm_receive_test.cc
@@ -14,6 +14,7 @@
 
 #include <memory>
 
+#include "absl/strings/match.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
 #include "modules/audio_coding/codecs/audio_format_conversion.h"
 #include "modules/audio_coding/include/audio_coding_module.h"
@@ -30,11 +31,11 @@
 // Returns true if the codec should be registered, otherwise false. Changes
 // the number of channels for the Opus codec to always be 1.
 bool ModifyAndUseThisCodec(CodecInst* codec_param) {
-  if (STR_CASE_CMP(codec_param->plname, "CN") == 0 &&
+  if (absl::EqualsIgnoreCase(codec_param->plname, "CN") &&
       codec_param->plfreq == 48000)
     return false;  // Skip 48 kHz comfort noise.
 
-  if (STR_CASE_CMP(codec_param->plname, "telephone-event") == 0)
+  if (absl::EqualsIgnoreCase(codec_param->plname, "telephone-event"))
     return false;  // Skip DTFM.
 
   return true;
@@ -65,39 +66,43 @@
     return false;  // Don't use non-mono codecs.
 
   // Re-map pltypes to those used in the NetEq test files.
-  if (STR_CASE_CMP(plname, "PCMU") == 0 && plfreq == 8000) {
+  if (absl::EqualsIgnoreCase(plname, "PCMU") && plfreq == 8000) {
     *pltype = 0;
-  } else if (STR_CASE_CMP(plname, "PCMA") == 0 && plfreq == 8000) {
+  } else if (absl::EqualsIgnoreCase(plname, "PCMA") && plfreq == 8000) {
     *pltype = 8;
-  } else if (STR_CASE_CMP(plname, "CN") == 0 && plfreq == 8000) {
+  } else if (absl::EqualsIgnoreCase(plname, "CN") && plfreq == 8000) {
     *pltype = 13;
-  } else if (STR_CASE_CMP(plname, "CN") == 0 && plfreq == 16000) {
+  } else if (absl::EqualsIgnoreCase(plname, "CN") && plfreq == 16000) {
     *pltype = 98;
-  } else if (STR_CASE_CMP(plname, "CN") == 0 && plfreq == 32000) {
+  } else if (absl::EqualsIgnoreCase(plname, "CN") && plfreq == 32000) {
     *pltype = 99;
-  } else if (STR_CASE_CMP(plname, "ILBC") == 0) {
+  } else if (absl::EqualsIgnoreCase(plname, "ILBC")) {
     *pltype = 102;
-  } else if (STR_CASE_CMP(plname, "ISAC") == 0 && plfreq == 16000) {
+  } else if (absl::EqualsIgnoreCase(plname, "ISAC") && plfreq == 16000) {
     *pltype = 103;
-  } else if (STR_CASE_CMP(plname, "ISAC") == 0 && plfreq == 32000) {
+  } else if (absl::EqualsIgnoreCase(plname, "ISAC") && plfreq == 32000) {
     *pltype = 104;
-  } else if (STR_CASE_CMP(plname, "telephone-event") == 0 && plfreq == 8000) {
+  } else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
+             plfreq == 8000) {
     *pltype = 106;
-  } else if (STR_CASE_CMP(plname, "telephone-event") == 0 && plfreq == 16000) {
+  } else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
+             plfreq == 16000) {
     *pltype = 114;
-  } else if (STR_CASE_CMP(plname, "telephone-event") == 0 && plfreq == 32000) {
+  } else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
+             plfreq == 32000) {
     *pltype = 115;
-  } else if (STR_CASE_CMP(plname, "telephone-event") == 0 && plfreq == 48000) {
+  } else if (absl::EqualsIgnoreCase(plname, "telephone-event") &&
+             plfreq == 48000) {
     *pltype = 116;
-  } else if (STR_CASE_CMP(plname, "red") == 0) {
+  } else if (absl::EqualsIgnoreCase(plname, "red")) {
     *pltype = 117;
-  } else if (STR_CASE_CMP(plname, "L16") == 0 && plfreq == 8000) {
+  } else if (absl::EqualsIgnoreCase(plname, "L16") && plfreq == 8000) {
     *pltype = 93;
-  } else if (STR_CASE_CMP(plname, "L16") == 0 && plfreq == 16000) {
+  } else if (absl::EqualsIgnoreCase(plname, "L16") && plfreq == 16000) {
     *pltype = 94;
-  } else if (STR_CASE_CMP(plname, "L16") == 0 && plfreq == 32000) {
+  } else if (absl::EqualsIgnoreCase(plname, "L16") && plfreq == 32000) {
     *pltype = 95;
-  } else if (STR_CASE_CMP(plname, "G722") == 0) {
+  } else if (absl::EqualsIgnoreCase(plname, "G722")) {
     *pltype = 9;
   } else {
     // Don't use any other codecs.
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index f631746..3411d90 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -10,21 +10,22 @@
 
 #include "modules/audio_coding/acm2/acm_receiver.h"
 
-#include <stdlib.h>  // malloc
-
-#include <algorithm>  // sort
+#include <stdlib.h>
+#include <string.h>
+#include <cstdint>
 #include <vector>
 
+#include "absl/strings/match.h"
+#include "api/audio/audio_frame.h"
 #include "api/audio_codecs/audio_decoder.h"
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "common_types.h"  // NOLINT(build/include)
+#include "common_types.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/acm2/call_statistics.h"
 #include "modules/audio_coding/acm2/rent_a_codec.h"
 #include "modules/audio_coding/neteq/include/neteq.h"
+#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
 #include "modules/include/module_common_types.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/format_macros.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/strings/audio_format_to_string.h"
@@ -92,7 +93,7 @@
     }
     receive_timestamp = NowInTimestamp(ci->plfreq);
 
-    if (STR_CASE_CMP(ci->plname, "cn") == 0) {
+    if (absl::EqualsIgnoreCase(ci->plname, "cn")) {
       if (last_audio_decoder_ && last_audio_decoder_->channels > 1) {
         // This is a CNG and the audio codec is not mono, so skip pushing in
         // packets into NetEq.
@@ -391,7 +392,7 @@
     uint8_t first_payload_byte) const {
   const absl::optional<CodecInst> ci =
       neteq_->GetDecoder(rtp_header.payloadType);
-  if (ci && STR_CASE_CMP(ci->plname, "red") == 0) {
+  if (ci && absl::EqualsIgnoreCase(ci->plname, "red")) {
     // This is a RED packet. Get the payload of the audio codec.
     return neteq_->GetDecoder(first_payload_byte & 0x7f);
   } else {
diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h
index a2ae723..8e7d839 100644
--- a/modules/audio_coding/acm2/acm_receiver.h
+++ b/modules/audio_coding/acm2/acm_receiver.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_
 #define MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_
 
+#include <stdint.h>
 #include <map>
 #include <memory>
 #include <string>
@@ -18,19 +19,21 @@
 
 #include "absl/types/optional.h"
 #include "api/array_view.h"
-#include "api/audio/audio_frame.h"
-#include "common_audio/vad/include/webrtc_vad.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.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/neteq/include/neteq.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
+class Clock;
 struct CodecInst;
 class NetEq;
+struct RTPHeader;
+struct WebRtcRTPHeader;
 
 namespace acm2 {
 
diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc
index 29f2a45..46384fe 100644
--- a/modules/audio_coding/acm2/acm_receiver_unittest.cc
+++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc
@@ -73,12 +73,12 @@
     // If we have a compatible CN specification, stack a CNG on top.
     auto it = cng_payload_types.find(info.sample_rate_hz);
     if (it != cng_payload_types.end()) {
-      AudioEncoderCng::Config config;
+      AudioEncoderCngConfig config;
       config.speech_encoder = std::move(enc);
       config.num_channels = 1;
       config.payload_type = it->second;
       config.vad_mode = Vad::kVadNormal;
-      enc = absl::make_unique<AudioEncoderCng>(std::move(config));
+      enc = CreateComfortNoiseEncoder(std::move(config));
     }
 
     // Actually start using the new encoder.
diff --git a/modules/audio_coding/acm2/acm_resampler.cc b/modules/audio_coding/acm2/acm_resampler.cc
index c0b2064..ca3583e 100644
--- a/modules/audio_coding/acm2/acm_resampler.cc
+++ b/modules/audio_coding/acm2/acm_resampler.cc
@@ -13,7 +13,6 @@
 #include <assert.h>
 #include <string.h>
 
-#include "common_audio/resampler/include/resampler.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/acm2/acm_resampler.h b/modules/audio_coding/acm2/acm_resampler.h
index 904ea52..96ba93a 100644
--- a/modules/audio_coding/acm2/acm_resampler.h
+++ b/modules/audio_coding/acm2/acm_resampler.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_ACM2_ACM_RESAMPLER_H_
 #define MODULES_AUDIO_CODING_ACM2_ACM_RESAMPLER_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "common_audio/resampler/include/push_resampler.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/acm2/audio_coding_module.cc b/modules/audio_coding/acm2/audio_coding_module.cc
index 60afeb6..334c0e0 100644
--- a/modules/audio_coding/acm2/audio_coding_module.cc
+++ b/modules/audio_coding/acm2/audio_coding_module.cc
@@ -10,16 +10,24 @@
 
 #include "modules/audio_coding/include/audio_coding_module.h"
 
+#include <assert.h>
 #include <algorithm>
+#include <cstdint>
 
+#include "absl/strings/match.h"
+#include "api/array_view.h"
 #include "modules/audio_coding/acm2/acm_receiver.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/acm2/codec_manager.h"
 #include "modules/audio_coding/acm2/rent_a_codec.h"
 #include "modules/include/module_common_types.h"
+#include "modules/include/module_common_types_public.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/criticalsection.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/thread_annotations.h"
 #include "system_wrappers/include/metrics.h"
 
 namespace webrtc {
@@ -990,7 +998,7 @@
   }
 
   AudioDecoder* isac_decoder = nullptr;
-  if (STR_CASE_CMP(codec.plname, "isac") == 0) {
+  if (absl::EqualsIgnoreCase(codec.plname, "isac")) {
     std::unique_ptr<AudioDecoder>& saved_isac_decoder =
         codec.plfreq == 16000 ? isac_decoder_16k_ : isac_decoder_32k_;
     if (!saved_isac_decoder) {
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index 5ac6102..b227cfb 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -35,6 +35,7 @@
 #include "modules/audio_coding/neteq/tools/packet.h"
 #include "modules/audio_coding/neteq/tools/rtp_file_source.h"
 #include "rtc_base/criticalsection.h"
+#include "rtc_base/event.h"
 #include "rtc_base/messagedigest.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/platform_thread.h"
@@ -42,7 +43,6 @@
 #include "rtc_base/system/arch.h"
 #include "rtc_base/thread_annotations.h"
 #include "system_wrappers/include/clock.h"
-#include "system_wrappers/include/event_wrapper.h"
 #include "system_wrappers/include/sleep.h"
 #include "test/gtest.h"
 #include "test/mock_audio_decoder.h"
@@ -408,12 +408,12 @@
               acm_->RegisterReceiveCodec(
                   rtp_payload_type, SdpAudioFormat("cn", kSampleRateHz, 1)));
     acm_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* enc) {
-      AudioEncoderCng::Config config;
+      AudioEncoderCngConfig config;
       config.speech_encoder = std::move(*enc);
       config.num_channels = 1;
       config.payload_type = rtp_payload_type;
       config.vad_mode = Vad::kVadNormal;
-      *enc = absl::make_unique<AudioEncoderCng>(std::move(config));
+      *enc = CreateComfortNoiseEncoder(std::move(config));
     });
   }
 
@@ -481,7 +481,6 @@
         send_thread_(CbSendThread, this, "send"),
         insert_packet_thread_(CbInsertPacketThread, this, "insert_packet"),
         pull_audio_thread_(CbPullAudioThread, this, "pull_audio"),
-        test_complete_(EventWrapper::Create()),
         send_count_(0),
         insert_packet_count_(0),
         pull_audio_count_(0),
@@ -512,8 +511,8 @@
     insert_packet_thread_.Stop();
   }
 
-  EventTypeWrapper RunTest() {
-    return test_complete_->Wait(10 * 60 * 1000);  // 10 minutes' timeout.
+  bool RunTest() {
+    return test_complete_.Wait(10 * 60 * 1000);  // 10 minutes' timeout.
   }
 
   virtual bool TestDone() {
@@ -538,12 +537,12 @@
     SleepMs(1);
     if (HasFatalFailure()) {
       // End the test early if a fatal failure (ASSERT_*) has occurred.
-      test_complete_->Set();
+      test_complete_.Set();
     }
     ++send_count_;
     InsertAudioAndVerifyEncoding();
     if (TestDone()) {
-      test_complete_->Set();
+      test_complete_.Set();
     }
     return true;
   }
@@ -592,7 +591,7 @@
   rtc::PlatformThread send_thread_;
   rtc::PlatformThread insert_packet_thread_;
   rtc::PlatformThread pull_audio_thread_;
-  const std::unique_ptr<EventWrapper> test_complete_;
+  rtc::Event test_complete_;
   int send_count_;
   int insert_packet_count_;
   int pull_audio_count_ RTC_GUARDED_BY(crit_sect_);
@@ -607,7 +606,7 @@
 #define MAYBE_DoTest DoTest
 #endif
 TEST_F(AudioCodingModuleMtTestOldApi, MAYBE_DoTest) {
-  EXPECT_EQ(kEventSignaled, RunTest());
+  EXPECT_TRUE(RunTest());
 }
 
 // This is a multi-threaded ACM test using iSAC. The test encodes audio
@@ -717,7 +716,7 @@
 #endif
 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
 TEST_F(AcmIsacMtTestOldApi, MAYBE_DoTest) {
-  EXPECT_EQ(kEventSignaled, RunTest());
+  EXPECT_TRUE(RunTest());
 }
 #endif
 
@@ -734,7 +733,6 @@
         codec_registration_thread_(CbCodecRegistrationThread,
                                    this,
                                    "codec_registration"),
-        test_complete_(EventWrapper::Create()),
         codec_registered_(false),
         receive_packet_count_(0),
         next_insert_packet_time_ms_(0),
@@ -781,8 +779,8 @@
     codec_registration_thread_.Stop();
   }
 
-  EventTypeWrapper RunTest() {
-    return test_complete_->Wait(10 * 60 * 1000);  // 10 minutes' timeout.
+  bool RunTest() {
+    return test_complete_.Wait(10 * 60 * 1000);  // 10 minutes' timeout.
   }
 
   static bool CbReceiveThread(void* context) {
@@ -845,7 +843,7 @@
     SleepMs(1);
     if (HasFatalFailure()) {
       // End the test early if a fatal failure (ASSERT_*) has occurred.
-      test_complete_->Set();
+      test_complete_.Set();
     }
     rtc::CritScope lock(&crit_sect_);
     if (!codec_registered_ &&
@@ -856,14 +854,14 @@
       codec_registered_ = true;
     }
     if (codec_registered_ && receive_packet_count_ > kNumPackets) {
-      test_complete_->Set();
+      test_complete_.Set();
     }
     return true;
   }
 
   rtc::PlatformThread receive_thread_;
   rtc::PlatformThread codec_registration_thread_;
-  const std::unique_ptr<EventWrapper> test_complete_;
+  rtc::Event test_complete_;
   rtc::CriticalSection crit_sect_;
   bool codec_registered_ RTC_GUARDED_BY(crit_sect_);
   int receive_packet_count_ RTC_GUARDED_BY(crit_sect_);
@@ -880,7 +878,7 @@
 #endif
 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
 TEST_F(AcmReRegisterIsacMtTestOldApi, MAYBE_DoTest) {
-  EXPECT_EQ(kEventSignaled, RunTest());
+  EXPECT_TRUE(RunTest());
 }
 #endif
 
diff --git a/modules/audio_coding/acm2/codec_manager.cc b/modules/audio_coding/acm2/codec_manager.cc
index f29e0f1..eda6555 100644
--- a/modules/audio_coding/acm2/codec_manager.cc
+++ b/modules/audio_coding/acm2/codec_manager.cc
@@ -10,9 +10,16 @@
 
 #include "modules/audio_coding/acm2/codec_manager.h"
 
-#include "rtc_base/checks.h"
-//#include "rtc_base/format_macros.h"
+#include <string.h>
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "absl/strings/match.h"
+#include "api/array_view.h"
+#include "api/audio_codecs/audio_encoder.h"
 #include "modules/audio_coding/acm2/rent_a_codec.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
@@ -35,7 +42,7 @@
   }
 
   // Telephone-event cannot be a send codec.
-  if (!STR_CASE_CMP(send_codec.plname, "telephone-event")) {
+  if (absl::EqualsIgnoreCase(send_codec.plname, "telephone-event")) {
     RTC_LOG(LS_ERROR) << "telephone-event cannot be a send codec";
     return -1;
   }
@@ -53,7 +60,7 @@
 bool IsOpus(const CodecInst& codec) {
   return
 #ifdef WEBRTC_CODEC_OPUS
-      !STR_CASE_CMP(codec.plname, "opus") ||
+      absl::EqualsIgnoreCase(codec.plname, "opus") ||
 #endif
       false;
 }
diff --git a/modules/audio_coding/acm2/codec_manager.h b/modules/audio_coding/acm2/codec_manager.h
index ffbad96..22dbf4e 100644
--- a/modules/audio_coding/acm2/codec_manager.h
+++ b/modules/audio_coding/acm2/codec_manager.h
@@ -11,8 +11,6 @@
 #ifndef MODULES_AUDIO_CODING_ACM2_CODEC_MANAGER_H_
 #define MODULES_AUDIO_CODING_ACM2_CODEC_MANAGER_H_
 
-#include <map>
-
 #include "absl/types/optional.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/audio_coding/acm2/rent_a_codec.h"
@@ -23,7 +21,6 @@
 
 namespace webrtc {
 
-class AudioDecoder;
 class AudioEncoder;
 
 namespace acm2 {
diff --git a/modules/audio_coding/acm2/rent_a_codec.cc b/modules/audio_coding/acm2/rent_a_codec.cc
index 0a9ce11..7601519 100644
--- a/modules/audio_coding/acm2/rent_a_codec.cc
+++ b/modules/audio_coding/acm2/rent_a_codec.cc
@@ -13,10 +13,11 @@
 #include <memory>
 #include <utility>
 
+#include "absl/strings/match.h"
 #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
 #include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
-#include "rtc_base/logging.h"
 #include "modules/audio_coding/codecs/g722/audio_encoder_g722.h"
+#include "rtc_base/logging.h"
 #ifdef WEBRTC_CODEC_ILBC
 #include "modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"  // nogncheck
 #endif
@@ -109,7 +110,7 @@
 RentACodec::RegistrationResult RentACodec::RegisterCngPayloadType(
     std::map<int, int>* pt_map,
     const CodecInst& codec_inst) {
-  if (STR_CASE_CMP(codec_inst.plname, "CN") != 0)
+  if (!absl::EqualsIgnoreCase(codec_inst.plname, "CN"))
     return RegistrationResult::kSkip;
   switch (codec_inst.plfreq) {
     case 8000:
@@ -126,7 +127,7 @@
 RentACodec::RegistrationResult RentACodec::RegisterRedPayloadType(
     std::map<int, int>* pt_map,
     const CodecInst& codec_inst) {
-  if (STR_CASE_CMP(codec_inst.plname, "RED") != 0)
+  if (!absl::EqualsIgnoreCase(codec_inst.plname, "RED"))
     return RegistrationResult::kSkip;
   switch (codec_inst.plfreq) {
     case 8000:
@@ -145,30 +146,30 @@
     const CodecInst& speech_inst,
     const rtc::scoped_refptr<LockedIsacBandwidthInfo>& bwinfo) {
 #if defined(WEBRTC_CODEC_ISACFX)
-  if (STR_CASE_CMP(speech_inst.plname, "isac") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "isac"))
     return std::unique_ptr<AudioEncoder>(
         new AudioEncoderIsacFixImpl(speech_inst, bwinfo));
 #endif
 #if defined(WEBRTC_CODEC_ISAC)
-  if (STR_CASE_CMP(speech_inst.plname, "isac") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "isac"))
     return std::unique_ptr<AudioEncoder>(
         new AudioEncoderIsacFloatImpl(speech_inst, bwinfo));
 #endif
 #ifdef WEBRTC_CODEC_OPUS
-  if (STR_CASE_CMP(speech_inst.plname, "opus") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "opus"))
     return std::unique_ptr<AudioEncoder>(new AudioEncoderOpusImpl(speech_inst));
 #endif
-  if (STR_CASE_CMP(speech_inst.plname, "pcmu") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "pcmu"))
     return std::unique_ptr<AudioEncoder>(new AudioEncoderPcmU(speech_inst));
-  if (STR_CASE_CMP(speech_inst.plname, "pcma") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "pcma"))
     return std::unique_ptr<AudioEncoder>(new AudioEncoderPcmA(speech_inst));
-  if (STR_CASE_CMP(speech_inst.plname, "l16") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "l16"))
     return std::unique_ptr<AudioEncoder>(new AudioEncoderPcm16B(speech_inst));
 #ifdef WEBRTC_CODEC_ILBC
-  if (STR_CASE_CMP(speech_inst.plname, "ilbc") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "ilbc"))
     return std::unique_ptr<AudioEncoder>(new AudioEncoderIlbcImpl(speech_inst));
 #endif
-  if (STR_CASE_CMP(speech_inst.plname, "g722") == 0)
+  if (absl::EqualsIgnoreCase(speech_inst.plname, "g722"))
     return std::unique_ptr<AudioEncoder>(new AudioEncoderG722Impl(speech_inst));
   RTC_LOG_F(LS_ERROR) << "Could not create encoder of type "
                       << speech_inst.plname;
@@ -193,7 +194,7 @@
     std::unique_ptr<AudioEncoder> encoder,
     int payload_type,
     ACMVADMode vad_mode) {
-  AudioEncoderCng::Config config;
+  AudioEncoderCngConfig config;
   config.num_channels = encoder->NumChannels();
   config.payload_type = payload_type;
   config.speech_encoder = std::move(encoder);
@@ -213,7 +214,7 @@
     default:
       FATAL();
   }
-  return std::unique_ptr<AudioEncoder>(new AudioEncoderCng(std::move(config)));
+  return CreateComfortNoiseEncoder(std::move(config));
 }
 
 std::unique_ptr<AudioDecoder> CreateIsacDecoder(
diff --git a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
index c4832a3..85084c8 100644
--- a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
+++ b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
@@ -10,9 +10,14 @@
 
 #include "modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
 
+#include <stdint.h>
 #include <utility>
+#include <vector>
 
-#include "rtc_base/logging.h"
+#include "modules/audio_coding/audio_network_adaptor/controller_manager.h"
+#include "modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
+#include "modules/audio_coding/audio_network_adaptor/event_log_writer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/timeutils.h"
 #include "system_wrappers/include/field_trial.h"
 
diff --git a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
index e208ed2..d3ecce0 100644
--- a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
+++ b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
@@ -11,17 +11,21 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_AUDIO_NETWORK_ADAPTOR_IMPL_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_AUDIO_NETWORK_ADAPTOR_IMPL_H_
 
+#include <stdio.h>
 #include <memory>
 
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_encoder.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
-#include "modules/audio_coding/audio_network_adaptor/controller_manager.h"
 #include "modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
-#include "modules/audio_coding/audio_network_adaptor/event_log_writer.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
+class ControllerManager;
+class EventLogWriter;
 class RtcEventLog;
 
 class AudioNetworkAdaptorImpl final : public AudioNetworkAdaptor {
diff --git a/modules/audio_coding/audio_network_adaptor/bitrate_controller.h b/modules/audio_coding/audio_network_adaptor/bitrate_controller.h
index 282f599..6b6330b 100644
--- a/modules/audio_coding/audio_network_adaptor/bitrate_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/bitrate_controller.h
@@ -11,7 +11,11 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_BITRATE_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_BITRATE_CONTROLLER_H_
 
+#include <stddef.h>
+
+#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/audio_network_adaptor/channel_controller.h b/modules/audio_coding/audio_network_adaptor/channel_controller.h
index 23cbef6..0d775b1 100644
--- a/modules/audio_coding/audio_network_adaptor/channel_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/channel_controller.h
@@ -11,7 +11,11 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CHANNEL_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CHANNEL_CONTROLLER_H_
 
+#include <stddef.h>
+
+#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc b/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
index 818362e..8e04e8e 100644
--- a/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
+++ b/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
@@ -10,10 +10,12 @@
 
 #include "modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
 
+#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/ignore_wundef.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/protobuf_utils.h"
+#include "rtc_base/system/file_wrapper.h"
 
 #if WEBRTC_ENABLE_PROTOBUF
 RTC_PUSH_IGNORING_WUNDEF()
diff --git a/modules/audio_coding/audio_network_adaptor/dtx_controller.h b/modules/audio_coding/audio_network_adaptor/dtx_controller.h
index fb40db2..d3334ec 100644
--- a/modules/audio_coding/audio_network_adaptor/dtx_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/dtx_controller.h
@@ -11,7 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_
 
+#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/audio_network_adaptor/event_log_writer.cc b/modules/audio_coding/audio_network_adaptor/event_log_writer.cc
index 4a92343..7925b89 100644
--- a/modules/audio_coding/audio_network_adaptor/event_log_writer.cc
+++ b/modules/audio_coding/audio_network_adaptor/event_log_writer.cc
@@ -9,13 +9,17 @@
  */
 
 #include <math.h>
-
 #include <algorithm>
+#include <cstdlib>
+#include <utility>
 
 #include "absl/memory/memory.h"
+#include "absl/types/optional.h"
+#include "logging/rtc_event_log/events/rtc_event.h"
 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
 #include "logging/rtc_event_log/rtc_event_log.h"
 #include "modules/audio_coding/audio_network_adaptor/event_log_writer.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/audio_network_adaptor/event_log_writer.h b/modules/audio_coding/audio_network_adaptor/event_log_writer.h
index fca8e53..72b5245 100644
--- a/modules/audio_coding/audio_network_adaptor/event_log_writer.h
+++ b/modules/audio_coding/audio_network_adaptor/event_log_writer.h
@@ -11,7 +11,7 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_EVENT_LOG_WRITER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_EVENT_LOG_WRITER_H_
 
-#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc
index 7ab72c9..936e224 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.cc
@@ -10,7 +10,7 @@
 
 #include "modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
 
-#include <limits>
+#include <string>
 #include <utility>
 
 #include "rtc_base/checks.h"
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h
index b66883e..b7d3d56 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h
@@ -13,8 +13,10 @@
 
 #include <memory>
 
+#include "absl/types/optional.h"
 #include "common_audio/smoothing_filter.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "modules/audio_coding/audio_network_adaptor/util/threshold_curve.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.cc b/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.cc
index c8cfd31..6c30b8f 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.cc
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.cc
@@ -10,9 +10,6 @@
 
 #include "modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h"
 
-#include <limits>
-#include <utility>
-
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h b/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h
index 9a3c37c..421cb70 100644
--- a/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h
+++ b/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FEC_CONTROLLER_RPLR_BASED_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FEC_CONTROLLER_RPLR_BASED_H_
 
-#include <memory>
-
+#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "modules/audio_coding/audio_network_adaptor/util/threshold_curve.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc b/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc
index 40e97cb..b123c7c 100644
--- a/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc
+++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller.cc
@@ -11,10 +11,10 @@
 #include "modules/audio_coding/audio_network_adaptor/frame_length_controller.h"
 
 #include <algorithm>
+#include <iterator>
 #include <utility>
 
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/audio_network_adaptor/frame_length_controller.h b/modules/audio_coding/audio_network_adaptor/frame_length_controller.h
index f084fd0..f0a5aab 100644
--- a/modules/audio_coding/audio_network_adaptor/frame_length_controller.h
+++ b/modules/audio_coding/audio_network_adaptor/frame_length_controller.h
@@ -11,10 +11,13 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_H_
 
+#include <stddef.h>
 #include <map>
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "modules/audio_coding/audio_network_adaptor/controller.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h
index 257a79a..94e8ed9 100644
--- a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h
+++ b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_INCLUDE_AUDIO_NETWORK_ADAPTOR_CONFIG_H_
 #define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_INCLUDE_AUDIO_NETWORK_ADAPTOR_CONFIG_H_
 
+#include <stddef.h>
+
 #include "absl/types/optional.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/codecs/audio_format_conversion.cc b/modules/audio_coding/codecs/audio_format_conversion.cc
index e38aa33..f068301 100644
--- a/modules/audio_coding/codecs/audio_format_conversion.cc
+++ b/modules/audio_coding/codecs/audio_format_conversion.cc
@@ -11,11 +11,12 @@
 #include "modules/audio_coding/codecs/audio_format_conversion.h"
 
 #include <string.h>
+#include <string>
+#include <utility>
 
-#include "absl/types/optional.h"
+#include "absl/strings/match.h"
 #include "api/array_view.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/sanitizer.h"
 
 namespace webrtc {
@@ -41,11 +42,11 @@
 }  // namespace
 
 SdpAudioFormat CodecInstToSdp(const CodecInst& ci) {
-  if (STR_CASE_CMP(ci.plname, "g722") == 0) {
+  if (absl::EqualsIgnoreCase(ci.plname, "g722")) {
     RTC_CHECK_EQ(16000, ci.plfreq);
     RTC_CHECK(ci.channels == 1 || ci.channels == 2);
     return {"g722", 8000, ci.channels};
-  } else if (STR_CASE_CMP(ci.plname, "opus") == 0) {
+  } else if (absl::EqualsIgnoreCase(ci.plname, "opus")) {
     RTC_CHECK_EQ(48000, ci.plfreq);
     RTC_CHECK(ci.channels == 1 || ci.channels == 2);
     return ci.channels == 1
@@ -57,12 +58,12 @@
 }
 
 CodecInst SdpToCodecInst(int payload_type, const SdpAudioFormat& audio_format) {
-  if (STR_CASE_CMP(audio_format.name.c_str(), "g722") == 0) {
+  if (absl::EqualsIgnoreCase(audio_format.name, "g722")) {
     RTC_CHECK_EQ(8000, audio_format.clockrate_hz);
     RTC_CHECK(audio_format.num_channels == 1 || audio_format.num_channels == 2);
     return MakeCodecInst(payload_type, "g722", 16000,
                          audio_format.num_channels);
-  } else if (STR_CASE_CMP(audio_format.name.c_str(), "opus") == 0) {
+  } else if (absl::EqualsIgnoreCase(audio_format.name, "opus")) {
     RTC_CHECK_EQ(48000, audio_format.clockrate_hz);
     RTC_CHECK_EQ(2, audio_format.num_channels);
     const int num_channels = [&] {
diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
index 4cda340..9a29261 100644
--- a/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
+++ b/modules/audio_coding/codecs/cng/audio_encoder_cng.cc
@@ -10,40 +10,72 @@
 
 #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
 
-#include <algorithm>
-#include <limits>
+#include <cstdint>
 #include <memory>
 #include <utility>
 
+#include "absl/memory/memory.h"
+#include "modules/audio_coding/codecs/cng/webrtc_cng.h"
+#include "rtc_base/checks.h"
+
 namespace webrtc {
 
 namespace {
 
 const int kMaxFrameSizeMs = 60;
 
-}  // namespace
+class AudioEncoderCng final : public AudioEncoder {
+ public:
+  explicit AudioEncoderCng(AudioEncoderCngConfig&& config);
+  ~AudioEncoderCng() override;
 
-AudioEncoderCng::Config::Config() = default;
-AudioEncoderCng::Config::Config(Config&&) = default;
-AudioEncoderCng::Config::~Config() = default;
+  // Not copyable or moveable.
+  AudioEncoderCng(const AudioEncoderCng&) = delete;
+  AudioEncoderCng(AudioEncoderCng&&) = delete;
+  AudioEncoderCng& operator=(const AudioEncoderCng&) = delete;
+  AudioEncoderCng& operator=(AudioEncoderCng&&) = delete;
 
-bool AudioEncoderCng::Config::IsOk() const {
-  if (num_channels != 1)
-    return false;
-  if (!speech_encoder)
-    return false;
-  if (num_channels != speech_encoder->NumChannels())
-    return false;
-  if (sid_frame_interval_ms <
-      static_cast<int>(speech_encoder->Max10MsFramesInAPacket() * 10))
-    return false;
-  if (num_cng_coefficients > WEBRTC_CNG_MAX_LPC_ORDER ||
-      num_cng_coefficients <= 0)
-    return false;
-  return true;
-}
+  int SampleRateHz() const override;
+  size_t NumChannels() const override;
+  int RtpTimestampRateHz() const override;
+  size_t Num10MsFramesInNextPacket() const override;
+  size_t Max10MsFramesInAPacket() const override;
+  int GetTargetBitrate() const override;
+  EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
+                         rtc::ArrayView<const int16_t> audio,
+                         rtc::Buffer* encoded) override;
+  void Reset() override;
+  bool SetFec(bool enable) override;
+  bool SetDtx(bool enable) override;
+  bool SetApplication(Application application) override;
+  void SetMaxPlaybackRate(int frequency_hz) override;
+  rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
+      override;
+  void OnReceivedUplinkPacketLossFraction(
+      float uplink_packet_loss_fraction) override;
+  void OnReceivedUplinkRecoverablePacketLossFraction(
+      float uplink_recoverable_packet_loss_fraction) override;
+  void OnReceivedUplinkBandwidth(
+      int target_audio_bitrate_bps,
+      absl::optional<int64_t> bwe_period_ms) override;
 
-AudioEncoderCng::AudioEncoderCng(Config&& config)
+ private:
+  EncodedInfo EncodePassive(size_t frames_to_encode, rtc::Buffer* encoded);
+  EncodedInfo EncodeActive(size_t frames_to_encode, rtc::Buffer* encoded);
+  size_t SamplesPer10msFrame() const;
+
+  std::unique_ptr<AudioEncoder> speech_encoder_;
+  const int cng_payload_type_;
+  const int num_cng_coefficients_;
+  const int sid_frame_interval_ms_;
+  std::vector<int16_t> speech_buffer_;
+  std::vector<uint32_t> rtp_timestamps_;
+  bool last_frame_active_;
+  std::unique_ptr<Vad> vad_;
+  std::unique_ptr<ComfortNoiseEncoder> cng_encoder_;
+};
+
+AudioEncoderCng::AudioEncoderCng(AudioEncoderCngConfig&& config)
     : speech_encoder_((static_cast<void>([&] {
                          RTC_CHECK(config.IsOk()) << "Invalid configuration.";
                        }()),
@@ -261,4 +293,31 @@
   return rtc::CheckedDivExact(10 * SampleRateHz(), 1000);
 }
 
+}  // namespace
+
+AudioEncoderCngConfig::AudioEncoderCngConfig() = default;
+AudioEncoderCngConfig::AudioEncoderCngConfig(AudioEncoderCngConfig&&) = default;
+AudioEncoderCngConfig::~AudioEncoderCngConfig() = default;
+
+bool AudioEncoderCngConfig::IsOk() const {
+  if (num_channels != 1)
+    return false;
+  if (!speech_encoder)
+    return false;
+  if (num_channels != speech_encoder->NumChannels())
+    return false;
+  if (sid_frame_interval_ms <
+      static_cast<int>(speech_encoder->Max10MsFramesInAPacket() * 10))
+    return false;
+  if (num_cng_coefficients > WEBRTC_CNG_MAX_LPC_ORDER ||
+      num_cng_coefficients <= 0)
+    return false;
+  return true;
+}
+
+std::unique_ptr<AudioEncoder> CreateComfortNoiseEncoder(
+    AudioEncoderCngConfig&& config) {
+  return absl::make_unique<AudioEncoderCng>(std::move(config));
+}
+
 }  // namespace webrtc
diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng.h b/modules/audio_coding/codecs/cng/audio_encoder_cng.h
index e4c6507..2ef3236 100644
--- a/modules/audio_coding/codecs/cng/audio_encoder_cng.h
+++ b/modules/audio_coding/codecs/cng/audio_encoder_cng.h
@@ -11,86 +11,38 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_CNG_AUDIO_ENCODER_CNG_H_
 #define MODULES_AUDIO_CODING_CODECS_CNG_AUDIO_ENCODER_CNG_H_
 
+#include <stddef.h>
 #include <memory>
-#include <vector>
 
 #include "api/audio_codecs/audio_encoder.h"
 #include "common_audio/vad/include/vad.h"
-#include "modules/audio_coding/codecs/cng/webrtc_cng.h"
-#include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
-class Vad;
+struct AudioEncoderCngConfig {
+  // Moveable, not copyable.
+  AudioEncoderCngConfig();
+  AudioEncoderCngConfig(AudioEncoderCngConfig&&);
+  ~AudioEncoderCngConfig();
 
-class AudioEncoderCng final : public AudioEncoder {
- public:
-  struct Config {
-    Config();
-    Config(Config&&);
-    ~Config();
-    bool IsOk() const;
+  bool IsOk() const;
 
-    size_t num_channels = 1;
-    int payload_type = 13;
-    std::unique_ptr<AudioEncoder> speech_encoder;
-    Vad::Aggressiveness vad_mode = Vad::kVadNormal;
-    int sid_frame_interval_ms = 100;
-    int num_cng_coefficients = 8;
-    // The Vad pointer is mainly for testing. If a NULL pointer is passed, the
-    // AudioEncoderCng creates (and destroys) a Vad object internally. If an
-    // object is passed, the AudioEncoderCng assumes ownership of the Vad
-    // object.
-    Vad* vad = nullptr;
-  };
-
-  explicit AudioEncoderCng(Config&& config);
-  ~AudioEncoderCng() override;
-
-  int SampleRateHz() const override;
-  size_t NumChannels() const override;
-  int RtpTimestampRateHz() const override;
-  size_t Num10MsFramesInNextPacket() const override;
-  size_t Max10MsFramesInAPacket() const override;
-  int GetTargetBitrate() const override;
-  EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
-                         rtc::ArrayView<const int16_t> audio,
-                         rtc::Buffer* encoded) override;
-  void Reset() override;
-  bool SetFec(bool enable) override;
-  bool SetDtx(bool enable) override;
-  bool SetApplication(Application application) override;
-  void SetMaxPlaybackRate(int frequency_hz) override;
-  rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
-      override;
-  void OnReceivedUplinkPacketLossFraction(
-      float uplink_packet_loss_fraction) override;
-  void OnReceivedUplinkRecoverablePacketLossFraction(
-      float uplink_recoverable_packet_loss_fraction) override;
-  void OnReceivedUplinkBandwidth(
-      int target_audio_bitrate_bps,
-      absl::optional<int64_t> bwe_period_ms) override;
-
- private:
-  EncodedInfo EncodePassive(size_t frames_to_encode,
-                            rtc::Buffer* encoded);
-  EncodedInfo EncodeActive(size_t frames_to_encode,
-                           rtc::Buffer* encoded);
-  size_t SamplesPer10msFrame() const;
-
-  std::unique_ptr<AudioEncoder> speech_encoder_;
-  const int cng_payload_type_;
-  const int num_cng_coefficients_;
-  const int sid_frame_interval_ms_;
-  std::vector<int16_t> speech_buffer_;
-  std::vector<uint32_t> rtp_timestamps_;
-  bool last_frame_active_;
-  std::unique_ptr<Vad> vad_;
-  std::unique_ptr<ComfortNoiseEncoder> cng_encoder_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderCng);
+  size_t num_channels = 1;
+  int payload_type = 13;
+  std::unique_ptr<AudioEncoder> speech_encoder;
+  Vad::Aggressiveness vad_mode = Vad::kVadNormal;
+  int sid_frame_interval_ms = 100;
+  int num_cng_coefficients = 8;
+  // The Vad pointer is mainly for testing. If a NULL pointer is passed, the
+  // AudioEncoderCng creates (and destroys) a Vad object internally. If an
+  // object is passed, the AudioEncoderCng assumes ownership of the Vad
+  // object.
+  Vad* vad = nullptr;
 };
 
+std::unique_ptr<AudioEncoder> CreateComfortNoiseEncoder(
+    AudioEncoderCngConfig&& config);
+
 }  // namespace webrtc
 
 #endif  // MODULES_AUDIO_CODING_CODECS_CNG_AUDIO_ENCODER_CNG_H_
diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
index a76dcbd..e3655b4 100644
--- a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
+++ b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc
@@ -50,8 +50,8 @@
     cng_.reset();
   }
 
-  AudioEncoderCng::Config MakeCngConfig() {
-    AudioEncoderCng::Config config;
+  AudioEncoderCngConfig MakeCngConfig() {
+    AudioEncoderCngConfig config;
     config.speech_encoder = std::move(mock_encoder_owner_);
     EXPECT_TRUE(config.speech_encoder);
 
@@ -63,7 +63,7 @@
     return config;
   }
 
-  void CreateCng(AudioEncoderCng::Config&& config) {
+  void CreateCng(AudioEncoderCngConfig&& config) {
     num_audio_samples_10ms_ = static_cast<size_t>(10 * sample_rate_hz_ / 1000);
     ASSERT_LE(num_audio_samples_10ms_, kMaxNumSamples);
     if (config.speech_encoder) {
@@ -75,7 +75,7 @@
       EXPECT_CALL(*mock_encoder_, Max10MsFramesInAPacket())
           .WillOnce(Return(1u));
     }
-    cng_.reset(new AudioEncoderCng(std::move(config)));
+    cng_ = CreateComfortNoiseEncoder(std::move(config));
   }
 
   void Encode() {
@@ -193,7 +193,7 @@
     return encoded_info_.payload_type != kCngPayloadType;
   }
 
-  std::unique_ptr<AudioEncoderCng> cng_;
+  std::unique_ptr<AudioEncoder> cng_;
   std::unique_ptr<MockAudioEncoder> mock_encoder_owner_;
   MockAudioEncoder* mock_encoder_;
   MockVad* mock_vad_;  // Ownership is transferred to |cng_|.
@@ -432,7 +432,7 @@
   // deleted.
   void TearDown() override { cng_.reset(); }
 
-  AudioEncoderCng::Config MakeCngConfig() {
+  AudioEncoderCngConfig MakeCngConfig() {
     // Don't provide a Vad mock object, since it would leak when the test dies.
     auto config = AudioEncoderCngTest::MakeCngConfig();
     config.vad = nullptr;
diff --git a/modules/audio_coding/codecs/cng/webrtc_cng.cc b/modules/audio_coding/codecs/cng/webrtc_cng.cc
index a07b093..f18fb28 100644
--- a/modules/audio_coding/codecs/cng/webrtc_cng.cc
+++ b/modules/audio_coding/codecs/cng/webrtc_cng.cc
@@ -13,6 +13,7 @@
 #include <algorithm>
 
 #include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/codecs/cng/webrtc_cng.h b/modules/audio_coding/codecs/cng/webrtc_cng.h
index 3f8fadc..6ff7529 100644
--- a/modules/audio_coding/codecs/cng/webrtc_cng.h
+++ b/modules/audio_coding/codecs/cng/webrtc_cng.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_
 #define MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_
 
+#include <stdint.h>
 #include <cstddef>
 
 #include "api/array_view.h"
diff --git a/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc b/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc
index 25f495f..d580a05 100644
--- a/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc
+++ b/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc
@@ -10,6 +10,8 @@
 
 #include "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
 
+#include <utility>
+
 #include "modules/audio_coding/codecs/g711/g711_interface.h"
 #include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
 
diff --git a/modules/audio_coding/codecs/g711/audio_decoder_pcm.h b/modules/audio_coding/codecs/g711/audio_decoder_pcm.h
index 29e4fa6..9a01b8a 100644
--- a/modules/audio_coding/codecs/g711/audio_decoder_pcm.h
+++ b/modules/audio_coding/codecs/g711/audio_decoder_pcm.h
@@ -11,7 +11,12 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
 #define MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
 
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
 #include "api/audio_codecs/audio_decoder.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc b/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
index c14287e..dce1635 100644
--- a/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
+++ b/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
@@ -10,10 +10,9 @@
 
 #include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
 
-#include <algorithm>
-#include <limits>
+#include <cstdint>
 
-#include "common_types.h"  // NOLINT(build/include)
+#include "common_types.h"
 #include "modules/audio_coding/codecs/g711/g711_interface.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_coding/codecs/g722/audio_decoder_g722.cc b/modules/audio_coding/codecs/g722/audio_decoder_g722.cc
index ea4a721..4de55a0 100644
--- a/modules/audio_coding/codecs/g722/audio_decoder_g722.cc
+++ b/modules/audio_coding/codecs/g722/audio_decoder_g722.cc
@@ -11,6 +11,7 @@
 #include "modules/audio_coding/codecs/g722/audio_decoder_g722.h"
 
 #include <string.h>
+#include <utility>
 
 #include "modules/audio_coding/codecs/g722/g722_interface.h"
 #include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
diff --git a/modules/audio_coding/codecs/g722/audio_encoder_g722.cc b/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
index cb96c3c..e63d590 100644
--- a/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
+++ b/modules/audio_coding/codecs/g722/audio_encoder_g722.cc
@@ -10,10 +10,9 @@
 
 #include "modules/audio_coding/codecs/g722/audio_encoder_g722.h"
 
-#include <algorithm>
+#include <cstdint>
 
-#include <limits>
-#include "common_types.h"  // NOLINT(build/include)
+#include "common_types.h"
 #include "modules/audio_coding/codecs/g722/g722_interface.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc b/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc
index 9e58ce0..57b5abb 100644
--- a/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc
+++ b/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
 
+#include <memory>
 #include <utility>
 
 #include "modules/audio_coding/codecs/ilbc/ilbc.h"
diff --git a/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h b/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h
index edb65d0..fcb2074 100644
--- a/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h
+++ b/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h
@@ -11,7 +11,12 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_
 #define MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_
 
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
 #include "api/audio_codecs/audio_decoder.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 
 typedef struct iLBC_decinst_t_ IlbcDecoderInstance;
diff --git a/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc b/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
index 84695e3..8801fd5 100644
--- a/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
+++ b/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc
@@ -11,8 +11,9 @@
 #include "modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
 
 #include <algorithm>
-#include <limits>
-#include "common_types.h"  // NOLINT(build/include)
+#include <cstdint>
+
+#include "common_types.h"
 #include "modules/audio_coding/codecs/ilbc/ilbc.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc b/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc
index 0bf3b19..d9efc21 100644
--- a/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc
+++ b/modules/audio_coding/codecs/legacy_encoded_audio_frame.cc
@@ -14,6 +14,8 @@
 #include <memory>
 #include <utility>
 
+#include "rtc_base/checks.h"
+
 namespace webrtc {
 
 LegacyEncodedAudioFrame::LegacyEncodedAudioFrame(AudioDecoder* decoder,
diff --git a/modules/audio_coding/codecs/legacy_encoded_audio_frame.h b/modules/audio_coding/codecs/legacy_encoded_audio_frame.h
index 05d4fe4..41b08f7 100644
--- a/modules/audio_coding/codecs/legacy_encoded_audio_frame.h
+++ b/modules/audio_coding/codecs/legacy_encoded_audio_frame.h
@@ -11,10 +11,14 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_LEGACY_ENCODED_AUDIO_FRAME_H_
 #define MODULES_AUDIO_CODING_CODECS_LEGACY_ENCODED_AUDIO_FRAME_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio_codecs/audio_decoder.h"
+#include "rtc_base/buffer.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
index 302b714..357cb1a 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
+++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc
@@ -10,8 +10,11 @@
 
 #include "modules/audio_coding/codecs/opus/audio_decoder_opus.h"
 
+#include <memory>
 #include <utility>
 
+#include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.h b/modules/audio_coding/codecs/opus/audio_decoder_opus.h
index 70aa40b..8043425 100644
--- a/modules/audio_coding/codecs/opus/audio_decoder_opus.h
+++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.h
@@ -11,8 +11,13 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_
 #define MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_
 
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
 #include "api/audio_codecs/audio_decoder.h"
 #include "modules/audio_coding/codecs/opus/opus_interface.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
index c07abbe..adc6656 100644
--- a/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
+++ b/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
@@ -15,7 +15,8 @@
 #include <utility>
 
 #include "absl/memory/memory.h"
-#include "common_types.h"  // NOLINT(build/include)
+#include "absl/strings/match.h"
+#include "common_types.h"
 #include "modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
 #include "modules/audio_coding/audio_network_adaptor/controller_manager.h"
 #include "modules/audio_coding/codecs/opus/opus_interface.h"
@@ -316,7 +317,7 @@
 
 absl::optional<AudioCodecInfo> AudioEncoderOpusImpl::QueryAudioEncoder(
     const SdpAudioFormat& format) {
-  if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 &&
+  if (absl::EqualsIgnoreCase(format.name, GetPayloadName()) &&
       format.clockrate_hz == 48000 && format.num_channels == 2) {
     const size_t num_channels = GetChannelCount(format);
     const int bitrate =
@@ -348,7 +349,7 @@
 
 absl::optional<AudioEncoderOpusConfig> AudioEncoderOpusImpl::SdpToConfig(
     const SdpAudioFormat& format) {
-  if (STR_CASE_CMP(format.name.c_str(), "opus") != 0 ||
+  if (!absl::EqualsIgnoreCase(format.name, "opus") ||
       format.clockrate_hz != 48000 || format.num_channels != 2) {
     return absl::nullopt;
   }
diff --git a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
index b07624d..1dd2ff2 100644
--- a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
+++ b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
@@ -10,6 +10,8 @@
 
 #include "modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
 
+#include <utility>
+
 #include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
 #include "rtc_base/checks.h"
diff --git a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h
index 7d23422..9b478d8 100644
--- a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h
+++ b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h
@@ -11,7 +11,12 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_DECODER_PCM16B_H_
 #define MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_DECODER_PCM16B_H_
 
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
 #include "api/audio_codecs/audio_decoder.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc b/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc
index 831daed..106ab16 100644
--- a/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc
+++ b/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc
@@ -10,12 +10,9 @@
 
 #include "modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
 
-#include <algorithm>
-
-#include "common_types.h"  // NOLINT(build/include)
+#include "common_types.h"
 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/numerics/safe_conversions.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/codecs/pcm16b/pcm16b_common.cc b/modules/audio_coding/codecs/pcm16b/pcm16b_common.cc
index 6d0fc2d..8f8bba5 100644
--- a/modules/audio_coding/codecs/pcm16b/pcm16b_common.cc
+++ b/modules/audio_coding/codecs/pcm16b/pcm16b_common.cc
@@ -10,6 +10,9 @@
 
 #include "modules/audio_coding/codecs/pcm16b/pcm16b_common.h"
 
+#include <stdint.h>
+#include <initializer_list>
+
 namespace webrtc {
 
 void Pcm16BAppendSupportedCodecSpecs(std::vector<AudioCodecSpec>* specs) {
diff --git a/modules/audio_coding/codecs/pcm16b/pcm16b_common.h b/modules/audio_coding/codecs/pcm16b/pcm16b_common.h
index 980a996..3fae717 100644
--- a/modules/audio_coding/codecs/pcm16b/pcm16b_common.h
+++ b/modules/audio_coding/codecs/pcm16b/pcm16b_common.h
@@ -13,7 +13,7 @@
 
 #include <vector>
 
-#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/audio_codecs/audio_format.h"
 
 namespace webrtc {
 void Pcm16BAppendSupportedCodecSpecs(std::vector<AudioCodecSpec>* specs);
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
index 2601f26..124e811 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
@@ -11,8 +11,8 @@
 #include "modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
 
 #include <string.h>
-
 #include <utility>
+#include <vector>
 
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red.h b/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
index 492ee3a..5a68876 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red.h
@@ -11,9 +11,12 @@
 #ifndef MODULES_AUDIO_CODING_CODECS_RED_AUDIO_ENCODER_COPY_RED_H_
 #define MODULES_AUDIO_CODING_CODECS_RED_AUDIO_ENCODER_COPY_RED_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
-#include <vector>
 
+#include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
diff --git a/modules/audio_coding/neteq/accelerate.cc b/modules/audio_coding/neteq/accelerate.cc
index 18350b0..6161a8f 100644
--- a/modules/audio_coding/neteq/accelerate.cc
+++ b/modules/audio_coding/neteq/accelerate.cc
@@ -10,7 +10,10 @@
 
 #include "modules/audio_coding/neteq/accelerate.h"
 
-#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include <assert.h>
+
+#include "api/array_view.h"
+#include "modules/audio_coding/neteq/audio_multi_vector.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/neteq/accelerate.h b/modules/audio_coding/neteq/accelerate.h
index 5609568..1a3af42 100644
--- a/modules/audio_coding/neteq/accelerate.h
+++ b/modules/audio_coding/neteq/accelerate.h
@@ -11,13 +11,15 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_ACCELERATE_H_
 #define MODULES_AUDIO_CODING_NETEQ_ACCELERATE_H_
 
-#include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/audio_coding/neteq/time_stretch.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
-// Forward declarations.
+class AudioMultiVector;
 class BackgroundNoise;
 
 // This class implements the Accelerate operation. Most of the work is done
diff --git a/modules/audio_coding/neteq/audio_multi_vector.h b/modules/audio_coding/neteq/audio_multi_vector.h
index 86f8282..a2dd3c3 100644
--- a/modules/audio_coding/neteq/audio_multi_vector.h
+++ b/modules/audio_coding/neteq/audio_multi_vector.h
@@ -11,8 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_AUDIO_MULTI_VECTOR_H_
 #define MODULES_AUDIO_CODING_NETEQ_AUDIO_MULTI_VECTOR_H_
 
-#include <string.h>  // Access to size_t.
-
+#include <stdint.h>
+#include <string.h>
 #include <vector>
 
 #include "api/array_view.h"
diff --git a/modules/audio_coding/neteq/audio_vector.h b/modules/audio_coding/neteq/audio_vector.h
index 825a3bc..d0db332 100644
--- a/modules/audio_coding/neteq/audio_vector.h
+++ b/modules/audio_coding/neteq/audio_vector.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_AUDIO_VECTOR_H_
 #define MODULES_AUDIO_CODING_NETEQ_AUDIO_VECTOR_H_
 
-#include <string.h>  // Access to size_t.
+#include <string.h>
+#include <cstdint>
 #include <memory>
 
 #include "rtc_base/checks.h"
diff --git a/modules/audio_coding/neteq/background_noise.h b/modules/audio_coding/neteq/background_noise.h
index 58eecaa..84d7eb9 100644
--- a/modules/audio_coding/neteq/background_noise.h
+++ b/modules/audio_coding/neteq/background_noise.h
@@ -14,13 +14,12 @@
 #include <string.h>  // size_t
 #include <memory>
 
-#include "modules/audio_coding/neteq/audio_multi_vector.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
 // Forward declarations.
+class AudioMultiVector;
 class PostDecodeVad;
 
 // This class handles estimation of background noise parameters.
diff --git a/modules/audio_coding/neteq/buffer_level_filter.cc b/modules/audio_coding/neteq/buffer_level_filter.cc
index 6e8da0a..2f96618 100644
--- a/modules/audio_coding/neteq/buffer_level_filter.cc
+++ b/modules/audio_coding/neteq/buffer_level_filter.cc
@@ -10,7 +10,8 @@
 
 #include "modules/audio_coding/neteq/buffer_level_filter.h"
 
-#include <algorithm>  // Provide access to std::max.
+#include <stdint.h>
+#include <algorithm>
 
 #include "rtc_base/numerics/safe_conversions.h"
 
diff --git a/modules/audio_coding/neteq/comfort_noise.cc b/modules/audio_coding/neteq/comfort_noise.cc
index b341acd..cb2b74d 100644
--- a/modules/audio_coding/neteq/comfort_noise.cc
+++ b/modules/audio_coding/neteq/comfort_noise.cc
@@ -11,11 +11,18 @@
 #include "modules/audio_coding/neteq/comfort_noise.h"
 
 #include <assert.h>
+#include <cstdint>
+#include <memory>
 
-#include "api/audio_codecs/audio_decoder.h"
+#include "api/array_view.h"
+#include "modules/audio_coding/codecs/cng/webrtc_cng.h"
+#include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include "modules/audio_coding/neteq/audio_vector.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
 #include "modules/audio_coding/neteq/dsp_helper.h"
 #include "modules/audio_coding/neteq/sync_buffer.h"
+#include "rtc_base/buffer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/comfort_noise.h b/modules/audio_coding/neteq/comfort_noise.h
index 5169124..3a9bfde 100644
--- a/modules/audio_coding/neteq/comfort_noise.h
+++ b/modules/audio_coding/neteq/comfort_noise.h
@@ -11,12 +11,14 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_COMFORT_NOISE_H_
 #define MODULES_AUDIO_CODING_NETEQ_COMFORT_NOISE_H_
 
-#include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include <stddef.h>
+
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
 // Forward declarations.
+class AudioMultiVector;
 class DecoderDatabase;
 class SyncBuffer;
 struct Packet;
diff --git a/modules/audio_coding/neteq/cross_correlation.h b/modules/audio_coding/neteq/cross_correlation.h
index a747772..9ce8be8 100644
--- a/modules/audio_coding/neteq/cross_correlation.h
+++ b/modules/audio_coding/neteq/cross_correlation.h
@@ -11,7 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_CROSS_CORRELATION_H_
 #define MODULES_AUDIO_CODING_NETEQ_CROSS_CORRELATION_H_
 
-#include "common_types.h"  // NOLINT(build/include)
+#include <stddef.h>
+#include <stdint.h>
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc
index 349fdab..83c2b3b 100644
--- a/modules/audio_coding/neteq/decision_logic.cc
+++ b/modules/audio_coding/neteq/decision_logic.cc
@@ -11,8 +11,8 @@
 #include "modules/audio_coding/neteq/decision_logic.h"
 
 #include <assert.h>
-#include <algorithm>
-#include <limits>
+#include <stdio.h>
+#include <string>
 
 #include "modules/audio_coding/neteq/buffer_level_filter.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
@@ -20,8 +20,9 @@
 #include "modules/audio_coding/neteq/expand.h"
 #include "modules/audio_coding/neteq/packet_buffer.h"
 #include "modules/audio_coding/neteq/sync_buffer.h"
-#include "modules/include/module_common_types.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/numerics/safe_conversions.h"
 #include "system_wrappers/include/field_trial.h"
 
 namespace {
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index 39761da..2a53359 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -12,7 +12,6 @@
 #define MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
 
 #include "modules/audio_coding/neteq/defines.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "modules/audio_coding/neteq/tick_timer.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/neteq/decoder_database.cc b/modules/audio_coding/neteq/decoder_database.cc
index 1fd8c03..0890beb 100644
--- a/modules/audio_coding/neteq/decoder_database.cc
+++ b/modules/audio_coding/neteq/decoder_database.cc
@@ -10,9 +10,15 @@
 
 #include "modules/audio_coding/neteq/decoder_database.h"
 
-#include <utility>  // pair
+#include <stddef.h>
+#include <cstdint>
+#include <list>
+#include <type_traits>
+#include <utility>
 
+#include "absl/strings/match.h"
 #include "api/audio_codecs/audio_decoder.h"
+#include "common_types.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/strings/audio_format_to_string.h"
@@ -101,7 +107,7 @@
 }
 
 bool DecoderDatabase::DecoderInfo::IsType(const char* name) const {
-  return STR_CASE_CMP(audio_format_.name.c_str(), name) == 0;
+  return absl::EqualsIgnoreCase(audio_format_.name, name);
 }
 
 bool DecoderDatabase::DecoderInfo::IsType(const std::string& name) const {
@@ -110,7 +116,7 @@
 
 absl::optional<DecoderDatabase::DecoderInfo::CngDecoder>
 DecoderDatabase::DecoderInfo::CngDecoder::Create(const SdpAudioFormat& format) {
-  if (STR_CASE_CMP(format.name.c_str(), "CN") == 0) {
+  if (absl::EqualsIgnoreCase(format.name, "CN")) {
     // CN has a 1:1 RTP clock rate to sample rate ratio.
     const int sample_rate_hz = format.clockrate_hz;
     RTC_DCHECK(sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
@@ -123,11 +129,11 @@
 
 DecoderDatabase::DecoderInfo::Subtype
 DecoderDatabase::DecoderInfo::SubtypeFromFormat(const SdpAudioFormat& format) {
-  if (STR_CASE_CMP(format.name.c_str(), "CN") == 0) {
+  if (absl::EqualsIgnoreCase(format.name, "CN")) {
     return Subtype::kComfortNoise;
-  } else if (STR_CASE_CMP(format.name.c_str(), "telephone-event") == 0) {
+  } else if (absl::EqualsIgnoreCase(format.name, "telephone-event")) {
     return Subtype::kDtmf;
-  } else if (STR_CASE_CMP(format.name.c_str(), "red") == 0) {
+  } else if (absl::EqualsIgnoreCase(format.name, "red")) {
     return Subtype::kRed;
   }
 
diff --git a/modules/audio_coding/neteq/delay_manager.cc b/modules/audio_coding/neteq/delay_manager.cc
index e5eb592..628812a 100644
--- a/modules/audio_coding/neteq/delay_manager.cc
+++ b/modules/audio_coding/neteq/delay_manager.cc
@@ -11,14 +11,15 @@
 #include "modules/audio_coding/neteq/delay_manager.h"
 
 #include <assert.h>
-#include <math.h>
-
-#include <algorithm>  // max, min
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
 #include <numeric>
+#include <string>
 
-#include "common_audio/signal_processing/include/signal_processing_library.h"
 #include "modules/audio_coding/neteq/delay_peak_detector.h"
-#include "modules/include/module_common_types.h"
+#include "modules/include/module_common_types_public.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "system_wrappers/include/field_trial.h"
diff --git a/modules/audio_coding/neteq/delay_peak_detector.cc b/modules/audio_coding/neteq/delay_peak_detector.cc
index eb9f6d5..893ce3e 100644
--- a/modules/audio_coding/neteq/delay_peak_detector.cc
+++ b/modules/audio_coding/neteq/delay_peak_detector.cc
@@ -10,10 +10,9 @@
 
 #include "modules/audio_coding/neteq/delay_peak_detector.h"
 
-#include <algorithm>  // max
+#include <algorithm>
 
 #include "rtc_base/checks.h"
-#include "rtc_base/numerics/safe_conversions.h"
 #include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/delay_peak_detector.h b/modules/audio_coding/neteq/delay_peak_detector.h
index 9defca5..272d50e 100644
--- a/modules/audio_coding/neteq/delay_peak_detector.h
+++ b/modules/audio_coding/neteq/delay_peak_detector.h
@@ -11,8 +11,8 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_DELAY_PEAK_DETECTOR_H_
 #define MODULES_AUDIO_CODING_NETEQ_DELAY_PEAK_DETECTOR_H_
 
-#include <string.h>  // size_t
-
+#include <stdint.h>
+#include <string.h>
 #include <list>
 #include <memory>
 
diff --git a/modules/audio_coding/neteq/dsp_helper.h b/modules/audio_coding/neteq/dsp_helper.h
index efa2f9c..8379461 100644
--- a/modules/audio_coding/neteq/dsp_helper.h
+++ b/modules/audio_coding/neteq/dsp_helper.h
@@ -11,9 +11,11 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_DSP_HELPER_H_
 #define MODULES_AUDIO_CODING_NETEQ_DSP_HELPER_H_
 
-#include <string.h>  // Access to size_t.
+#include <stdint.h>
+#include <string.h>
 
 #include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include "modules/audio_coding/neteq/audio_vector.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/dtmf_buffer.h b/modules/audio_coding/neteq/dtmf_buffer.h
index 6de5127..24b14ec 100644
--- a/modules/audio_coding/neteq/dtmf_buffer.h
+++ b/modules/audio_coding/neteq/dtmf_buffer.h
@@ -11,8 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_DTMF_BUFFER_H_
 #define MODULES_AUDIO_CODING_NETEQ_DTMF_BUFFER_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <list>
-#include <string>  // size_t
 
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/neteq/dtmf_tone_generator.cc b/modules/audio_coding/neteq/dtmf_tone_generator.cc
index 6fdb95a..6c412e3 100644
--- a/modules/audio_coding/neteq/dtmf_tone_generator.cc
+++ b/modules/audio_coding/neteq/dtmf_tone_generator.cc
@@ -30,6 +30,7 @@
 
 #include "modules/audio_coding/neteq/dtmf_tone_generator.h"
 
+#include "modules/audio_coding/neteq/audio_vector.h"
 #include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_coding/neteq/dtmf_tone_generator.h b/modules/audio_coding/neteq/dtmf_tone_generator.h
index a773ff3..22e166e 100644
--- a/modules/audio_coding/neteq/dtmf_tone_generator.h
+++ b/modules/audio_coding/neteq/dtmf_tone_generator.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_DTMF_TONE_GENERATOR_H_
 #define MODULES_AUDIO_CODING_NETEQ_DTMF_TONE_GENERATOR_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/audio_coding/neteq/audio_multi_vector.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/neteq/expand.cc b/modules/audio_coding/neteq/expand.cc
index 5f671ad..97ce529 100644
--- a/modules/audio_coding/neteq/expand.cc
+++ b/modules/audio_coding/neteq/expand.cc
@@ -17,6 +17,7 @@
 #include <limits>     // numeric_limits<T>
 
 #include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "modules/audio_coding/neteq/audio_multi_vector.h"
 #include "modules/audio_coding/neteq/background_noise.h"
 #include "modules/audio_coding/neteq/cross_correlation.h"
 #include "modules/audio_coding/neteq/dsp_helper.h"
diff --git a/modules/audio_coding/neteq/expand.h b/modules/audio_coding/neteq/expand.h
index 4cfe7b9..30c34a2 100644
--- a/modules/audio_coding/neteq/expand.h
+++ b/modules/audio_coding/neteq/expand.h
@@ -14,12 +14,13 @@
 #include <assert.h>
 #include <memory>
 
-#include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include "modules/audio_coding/neteq/audio_vector.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
 // Forward declarations.
+class AudioMultiVector;
 class BackgroundNoise;
 class RandomVector;
 class StatisticsCalculator;
diff --git a/modules/audio_coding/neteq/expand_uma_logger.h b/modules/audio_coding/neteq/expand_uma_logger.h
index 00907d4..bd079c6 100644
--- a/modules/audio_coding/neteq/expand_uma_logger.h
+++ b/modules/audio_coding/neteq/expand_uma_logger.h
@@ -10,6 +10,7 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_EXPAND_UMA_LOGGER_H_
 #define MODULES_AUDIO_CODING_NETEQ_EXPAND_UMA_LOGGER_H_
 
+#include <stdint.h>
 #include <memory>
 #include <string>
 
diff --git a/modules/audio_coding/neteq/nack_tracker.cc b/modules/audio_coding/neteq/nack_tracker.cc
index c62cdf8..e3ecfea 100644
--- a/modules/audio_coding/neteq/nack_tracker.cc
+++ b/modules/audio_coding/neteq/nack_tracker.cc
@@ -10,9 +10,9 @@
 
 #include "modules/audio_coding/neteq/nack_tracker.h"
 
-#include <assert.h>  // For assert.
-
-#include <algorithm>  // For std::max.
+#include <assert.h>
+#include <cstdint>
+#include <utility>
 
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_coding/neteq/nack_tracker.h b/modules/audio_coding/neteq/nack_tracker.h
index 1936a94..d7c6b08 100644
--- a/modules/audio_coding/neteq/nack_tracker.h
+++ b/modules/audio_coding/neteq/nack_tracker.h
@@ -11,11 +11,12 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_
 #define MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <map>
 #include <vector>
 
-#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
-#include "modules/include/module_common_types.h"
+#include "modules/include/module_common_types_public.h"
 #include "rtc_base/gtest_prod_util.h"
 
 //
diff --git a/modules/audio_coding/neteq/neteq.cc b/modules/audio_coding/neteq/neteq.cc
index cf1c6aa..0e6147e 100644
--- a/modules/audio_coding/neteq/neteq.cc
+++ b/modules/audio_coding/neteq/neteq.cc
@@ -10,8 +10,6 @@
 
 #include "modules/audio_coding/neteq/include/neteq.h"
 
-#include <memory>
-
 #include "modules/audio_coding/neteq/neteq_impl.h"
 #include "rtc_base/strings/string_builder.h"
 
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index f428be1..6a2cbae 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -11,13 +11,16 @@
 #include "modules/audio_coding/neteq/neteq_impl.h"
 
 #include <assert.h>
-
 #include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <list>
 #include <utility>
 #include <vector>
 
 #include "api/audio_codecs/audio_decoder.h"
 #include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "modules/audio_coding/codecs/cng/webrtc_cng.h"
 #include "modules/audio_coding/neteq/accelerate.h"
 #include "modules/audio_coding/neteq/background_noise.h"
 #include "modules/audio_coding/neteq/buffer_level_filter.h"
@@ -40,15 +43,14 @@
 #include "modules/audio_coding/neteq/red_payload_splitter.h"
 #include "modules/audio_coding/neteq/sync_buffer.h"
 #include "modules/audio_coding/neteq/tick_timer.h"
+#include "modules/audio_coding/neteq/time_stretch.h"
 #include "modules/audio_coding/neteq/timestamp_scaler.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/sanitizer.h"
 #include "rtc_base/strings/audio_format_to_string.h"
-#include "rtc_base/system/fallthrough.h"
 #include "rtc_base/trace_event.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h
index 8ef97ce..36990fb 100644
--- a/modules/audio_coding/neteq/neteq_impl.h
+++ b/modules/audio_coding/neteq/neteq_impl.h
@@ -17,10 +17,10 @@
 #include "absl/types/optional.h"
 #include "api/audio/audio_frame.h"
 #include "modules/audio_coding/neteq/audio_multi_vector.h"
-#include "modules/audio_coding/neteq/defines.h"
+#include "modules/audio_coding/neteq/defines.h"  // Modes, Operations
 #include "modules/audio_coding/neteq/expand_uma_logger.h"
 #include "modules/audio_coding/neteq/include/neteq.h"
-#include "modules/audio_coding/neteq/packet.h"  // Declare PacketList.
+#include "modules/audio_coding/neteq/packet.h"
 #include "modules/audio_coding/neteq/random_vector.h"
 #include "modules/audio_coding/neteq/rtcp.h"
 #include "modules/audio_coding/neteq/statistics_calculator.h"
diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc
index 3ee0b5b..1c9b9e7 100644
--- a/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_unittest.cc
@@ -52,7 +52,7 @@
 RTC_POP_IGNORING_WUNDEF()
 #endif
 
-DEFINE_bool(gen_ref, false, "Generate reference files.");
+WEBRTC_DEFINE_bool(gen_ref, false, "Generate reference files.");
 
 namespace webrtc {
 
@@ -1740,7 +1740,7 @@
       {8, kRtpExtensionVideoTiming}};
   std::unique_ptr<NetEqInput> input(new NetEqRtpDumpInput(
       webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"),
-      rtp_ext_map));
+      rtp_ext_map, absl::nullopt /*No SSRC filter*/));
   std::unique_ptr<TimeLimitedNetEqInput> input_time_limit(
       new TimeLimitedNetEqInput(std::move(input), 20000));
   std::unique_ptr<AudioSink> output(new VoidAudioSink);
diff --git a/modules/audio_coding/neteq/normal.h b/modules/audio_coding/neteq/normal.h
index b13f16e..80451b5 100644
--- a/modules/audio_coding/neteq/normal.h
+++ b/modules/audio_coding/neteq/normal.h
@@ -11,11 +11,9 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_NORMAL_H_
 #define MODULES_AUDIO_CODING_NETEQ_NORMAL_H_
 
+#include <stdint.h>
 #include <string.h>  // Access to size_t.
 
-#include <vector>
-
-#include "modules/audio_coding/neteq/audio_multi_vector.h"
 #include "modules/audio_coding/neteq/defines.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
@@ -24,6 +22,7 @@
 namespace webrtc {
 
 // Forward declarations.
+class AudioMultiVector;
 class BackgroundNoise;
 class DecoderDatabase;
 class Expand;
diff --git a/modules/audio_coding/neteq/packet.h b/modules/audio_coding/neteq/packet.h
index 45c56e1..358d8fa 100644
--- a/modules/audio_coding/neteq/packet.h
+++ b/modules/audio_coding/neteq/packet.h
@@ -11,12 +11,14 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_PACKET_H_
 #define MODULES_AUDIO_CODING_NETEQ_PACKET_H_
 
+#include <stdint.h>
 #include <list>
 #include <memory>
 
 #include "api/audio_codecs/audio_decoder.h"
 #include "modules/audio_coding/neteq/tick_timer.h"
 #include "rtc_base/buffer.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/neteq/packet_buffer.cc b/modules/audio_coding/neteq/packet_buffer.cc
index eba4d3e..7b70dee 100644
--- a/modules/audio_coding/neteq/packet_buffer.cc
+++ b/modules/audio_coding/neteq/packet_buffer.cc
@@ -14,12 +14,17 @@
 
 #include "modules/audio_coding/neteq/packet_buffer.h"
 
-#include <algorithm>  // find_if()
+#include <algorithm>
+#include <list>
+#include <memory>
+#include <type_traits>
+#include <utility>
 
 #include "api/audio_codecs/audio_decoder.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
 #include "modules/audio_coding/neteq/statistics_calculator.h"
 #include "modules/audio_coding/neteq/tick_timer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/packet_buffer.h b/modules/audio_coding/neteq/packet_buffer.h
index 7e34c1e..269b957 100644
--- a/modules/audio_coding/neteq/packet_buffer.h
+++ b/modules/audio_coding/neteq/packet_buffer.h
@@ -14,7 +14,7 @@
 #include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
 #include "modules/audio_coding/neteq/packet.h"
-#include "modules/include/module_common_types.h"
+#include "modules/include/module_common_types_public.h"  // IsNewerTimestamp
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/post_decode_vad.h b/modules/audio_coding/neteq/post_decode_vad.h
index ad4f082..27d69a6 100644
--- a/modules/audio_coding/neteq/post_decode_vad.h
+++ b/modules/audio_coding/neteq/post_decode_vad.h
@@ -11,13 +11,11 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_
 #define MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_
 
-#include <string>  // size_t
+#include <stddef.h>
+#include <stdint.h>
 
 #include "api/audio_codecs/audio_decoder.h"
 #include "common_audio/vad/include/webrtc_vad.h"
-#include "common_types.h"  // NOLINT(build/include)  // NULL
-#include "modules/audio_coding/neteq/defines.h"
-#include "modules/audio_coding/neteq/packet.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/preemptive_expand.cc b/modules/audio_coding/neteq/preemptive_expand.cc
index 6159a9c..cad8d6a 100644
--- a/modules/audio_coding/neteq/preemptive_expand.cc
+++ b/modules/audio_coding/neteq/preemptive_expand.cc
@@ -10,9 +10,11 @@
 
 #include "modules/audio_coding/neteq/preemptive_expand.h"
 
-#include <algorithm>  // min, max
+#include <algorithm>
 
-#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "api/array_view.h"
+#include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include "modules/audio_coding/neteq/time_stretch.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/neteq/preemptive_expand.h b/modules/audio_coding/neteq/preemptive_expand.h
index ace648f..0f7b3bc 100644
--- a/modules/audio_coding/neteq/preemptive_expand.h
+++ b/modules/audio_coding/neteq/preemptive_expand.h
@@ -11,13 +11,15 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_PREEMPTIVE_EXPAND_H_
 #define MODULES_AUDIO_CODING_NETEQ_PREEMPTIVE_EXPAND_H_
 
-#include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/audio_coding/neteq/time_stretch.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
-// Forward declarations.
+class AudioMultiVector;
 class BackgroundNoise;
 
 // This class implements the PreemptiveExpand operation. Most of the work is
diff --git a/modules/audio_coding/neteq/red_payload_splitter.cc b/modules/audio_coding/neteq/red_payload_splitter.cc
index f5435e8..2dfe838 100644
--- a/modules/audio_coding/neteq/red_payload_splitter.cc
+++ b/modules/audio_coding/neteq/red_payload_splitter.cc
@@ -11,10 +11,15 @@
 #include "modules/audio_coding/neteq/red_payload_splitter.h"
 
 #include <assert.h>
+#include <stddef.h>
+#include <cstdint>
+#include <list>
+#include <utility>
 #include <vector>
 
 #include "modules/audio_coding/neteq/decoder_database.h"
-#include "rtc_base/checks.h"
+#include "modules/audio_coding/neteq/packet.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
 
diff --git a/modules/audio_coding/neteq/red_payload_splitter.h b/modules/audio_coding/neteq/red_payload_splitter.h
index 5e239dd..55063e7 100644
--- a/modules/audio_coding/neteq/red_payload_splitter.h
+++ b/modules/audio_coding/neteq/red_payload_splitter.h
@@ -16,7 +16,6 @@
 
 namespace webrtc {
 
-// Forward declarations.
 class DecoderDatabase;
 
 // This class handles splitting of RED payloads into smaller parts.
diff --git a/modules/audio_coding/neteq/rtcp.cc b/modules/audio_coding/neteq/rtcp.cc
index 551eb5f..6519337 100644
--- a/modules/audio_coding/neteq/rtcp.cc
+++ b/modules/audio_coding/neteq/rtcp.cc
@@ -10,10 +10,12 @@
 
 #include "modules/audio_coding/neteq/rtcp.h"
 
-#include <stdlib.h>
-#include <string.h>
-
 #include <algorithm>
+#include <cstdlib>
+
+#include "api/rtp_headers.h"
+#include "common_types.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_coding/neteq/rtcp.h b/modules/audio_coding/neteq/rtcp.h
index b1de7eb..60c2673 100644
--- a/modules/audio_coding/neteq/rtcp.h
+++ b/modules/audio_coding/neteq/rtcp.h
@@ -11,12 +11,13 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_RTCP_H_
 #define MODULES_AUDIO_CODING_NETEQ_RTCP_H_
 
-#include "modules/audio_coding/neteq/include/neteq.h"
+#include <stdint.h>
+
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
-// Forward declaration.
+struct RtcpStatistics;
 struct RTPHeader;
 
 class Rtcp {
diff --git a/modules/audio_coding/neteq/sync_buffer.h b/modules/audio_coding/neteq/sync_buffer.h
index 72e320c..d645e91 100644
--- a/modules/audio_coding/neteq/sync_buffer.h
+++ b/modules/audio_coding/neteq/sync_buffer.h
@@ -11,8 +11,13 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_SYNC_BUFFER_H_
 #define MODULES_AUDIO_CODING_NETEQ_SYNC_BUFFER_H_
 
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
 #include "api/audio/audio_frame.h"
 #include "modules/audio_coding/neteq/audio_multi_vector.h"
+#include "modules/audio_coding/neteq/audio_vector.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_coding/neteq/tick_timer.h b/modules/audio_coding/neteq/tick_timer.h
index 520099e..02f083e 100644
--- a/modules/audio_coding/neteq/tick_timer.h
+++ b/modules/audio_coding/neteq/tick_timer.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_TICK_TIMER_H_
 #define MODULES_AUDIO_CODING_NETEQ_TICK_TIMER_H_
 
+#include <stdint.h>
 #include <memory>
 
 #include "rtc_base/checks.h"
diff --git a/modules/audio_coding/neteq/timestamp_scaler.cc b/modules/audio_coding/neteq/timestamp_scaler.cc
index 07d945e..b0461bb 100644
--- a/modules/audio_coding/neteq/timestamp_scaler.cc
+++ b/modules/audio_coding/neteq/timestamp_scaler.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_coding/neteq/timestamp_scaler.h"
 
+#include "api/audio_codecs/audio_format.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_coding/neteq/tools/neteq_event_log_input.cc b/modules/audio_coding/neteq/tools/neteq_event_log_input.cc
index 21c5f9e..9107e5e 100644
--- a/modules/audio_coding/neteq/tools/neteq_event_log_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_event_log_input.cc
@@ -19,11 +19,8 @@
 namespace test {
 
 NetEqEventLogInput::NetEqEventLogInput(const std::string& file_name,
-                                       const RtpHeaderExtensionMap& hdr_ext_map)
-    : source_(RtcEventLogSource::Create(file_name)) {
-  for (const auto& ext_pair : hdr_ext_map) {
-    source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first);
-  }
+                                       absl::optional<uint32_t> ssrc_filter)
+    : source_(RtcEventLogSource::Create(file_name, ssrc_filter)) {
   LoadNextPacket();
   AdvanceOutputEvent();
 }
diff --git a/modules/audio_coding/neteq/tools/neteq_event_log_input.h b/modules/audio_coding/neteq/tools/neteq_event_log_input.h
index 86cf9f2..e04df16 100644
--- a/modules/audio_coding/neteq/tools/neteq_event_log_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_event_log_input.h
@@ -28,7 +28,7 @@
 class NetEqEventLogInput final : public NetEqPacketSourceInput {
  public:
   NetEqEventLogInput(const std::string& file_name,
-                     const RtpHeaderExtensionMap& hdr_ext_map);
+                     absl::optional<uint32_t> ssrc_filter);
 
   absl::optional<int64_t> NextOutputEventTime() const override;
   void AdvanceOutputEvent() override;
diff --git a/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc b/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc
index a86cf6a..ee02288 100644
--- a/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc
@@ -58,15 +58,10 @@
   return packet_data;
 }
 
-void NetEqPacketSourceInput::SelectSsrc(uint32_t ssrc) {
-  source()->SelectSsrc(ssrc);
-  if (packet_ && packet_->header().ssrc != ssrc)
-    LoadNextPacket();
-}
-
 NetEqRtpDumpInput::NetEqRtpDumpInput(const std::string& file_name,
-                                     const RtpHeaderExtensionMap& hdr_ext_map)
-    : source_(RtpFileSource::Create(file_name)) {
+                                     const RtpHeaderExtensionMap& hdr_ext_map,
+                                     absl::optional<uint32_t> ssrc_filter)
+    : source_(RtpFileSource::Create(file_name, ssrc_filter)) {
   for (const auto& ext_pair : hdr_ext_map) {
     source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first);
   }
diff --git a/modules/audio_coding/neteq/tools/neteq_packet_source_input.h b/modules/audio_coding/neteq/tools/neteq_packet_source_input.h
index b32c534..8633d1f 100644
--- a/modules/audio_coding/neteq/tools/neteq_packet_source_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_packet_source_input.h
@@ -12,8 +12,10 @@
 #define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PACKET_SOURCE_INPUT_H_
 
 #include <map>
+#include <memory>
 #include <string>
 
+#include "absl/types/optional.h"
 #include "modules/audio_coding/neteq/tools/neteq_input.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 
@@ -32,7 +34,6 @@
   std::unique_ptr<PacketData> PopPacket() override;
   absl::optional<RTPHeader> NextHeader() const override;
   bool ended() const override { return !next_output_event_ms_; }
-  void SelectSsrc(uint32_t);
 
  protected:
   virtual PacketSource* source() = 0;
@@ -48,7 +49,8 @@
 class NetEqRtpDumpInput final : public NetEqPacketSourceInput {
  public:
   NetEqRtpDumpInput(const std::string& file_name,
-                    const RtpHeaderExtensionMap& hdr_ext_map);
+                    const RtpHeaderExtensionMap& hdr_ext_map,
+                    absl::optional<uint32_t> ssrc_filter);
 
   absl::optional<int64_t> NextOutputEventTime() const override;
   void AdvanceOutputEvent() override;
diff --git a/modules/audio_coding/neteq/tools/neteq_quality_test.cc b/modules/audio_coding/neteq/tools/neteq_quality_test.cc
index faca895..2ee6779 100644
--- a/modules/audio_coding/neteq/tools/neteq_quality_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_quality_test.cc
@@ -47,42 +47,47 @@
   return true;
 }
 
-DEFINE_string(
+WEBRTC_DEFINE_string(
     in_filename,
     DefaultInFilename().c_str(),
     "Filename for input audio (specify sample rate with --input_sample_rate, "
     "and channels with --channels).");
 
-DEFINE_int(input_sample_rate, 16000, "Sample rate of input file in Hz.");
+WEBRTC_DEFINE_int(input_sample_rate, 16000, "Sample rate of input file in Hz.");
 
-DEFINE_int(channels, 1, "Number of channels in input audio.");
+WEBRTC_DEFINE_int(channels, 1, "Number of channels in input audio.");
 
-DEFINE_string(out_filename,
-              DefaultOutFilename().c_str(),
-              "Name of output audio file.");
+WEBRTC_DEFINE_string(out_filename,
+                     DefaultOutFilename().c_str(),
+                     "Name of output audio file.");
 
-DEFINE_int(runtime_ms, 10000, "Simulated runtime (milliseconds).");
+WEBRTC_DEFINE_int(runtime_ms, 10000, "Simulated runtime (milliseconds).");
 
-DEFINE_int(packet_loss_rate, 10, "Percentile of packet loss.");
+WEBRTC_DEFINE_int(packet_loss_rate, 10, "Percentile of packet loss.");
 
-DEFINE_int(random_loss_mode,
-           kUniformLoss,
-           "Random loss mode: 0--no loss, 1--uniform loss, 2--Gilbert Elliot "
-           "loss, 3--fixed loss.");
+WEBRTC_DEFINE_int(
+    random_loss_mode,
+    kUniformLoss,
+    "Random loss mode: 0--no loss, 1--uniform loss, 2--Gilbert Elliot "
+    "loss, 3--fixed loss.");
 
-DEFINE_int(burst_length,
-           30,
-           "Burst length in milliseconds, only valid for Gilbert Elliot loss.");
+WEBRTC_DEFINE_int(
+    burst_length,
+    30,
+    "Burst length in milliseconds, only valid for Gilbert Elliot loss.");
 
-DEFINE_float(drift_factor, 0.0, "Time drift factor.");
+WEBRTC_DEFINE_float(drift_factor, 0.0, "Time drift factor.");
 
-DEFINE_int(preload_packets, 0, "Preload the buffer with this many packets.");
+WEBRTC_DEFINE_int(preload_packets,
+                  0,
+                  "Preload the buffer with this many packets.");
 
-DEFINE_string(loss_events,
-              "",
-              "List of loss events time and duration separated by comma: "
-              "<first_event_time> <first_event_duration>, <second_event_time> "
-              "<second_event_duration>, ...");
+WEBRTC_DEFINE_string(
+    loss_events,
+    "",
+    "List of loss events time and duration separated by comma: "
+    "<first_event_time> <first_event_duration>, <second_event_time> "
+    "<second_event_duration>, ...");
 
 // ProbTrans00Solver() is to calculate the transition probability from no-loss
 // state to itself in a modified Gilbert Elliot packet loss model. The result is
diff --git a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
index 25e8cd8..c2726eb 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
+++ b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -17,17 +17,17 @@
 #include "system_wrappers/include/field_trial.h"
 #include "test/field_trial.h"
 
-DEFINE_bool(codec_map,
-            false,
-            "Prints the mapping between RTP payload type and "
-            "codec");
-DEFINE_string(
+WEBRTC_DEFINE_bool(codec_map,
+                   false,
+                   "Prints the mapping between RTP payload type and "
+                   "codec");
+WEBRTC_DEFINE_string(
     force_fieldtrials,
     "",
     "Field trials control experimental feature code which can be forced. "
     "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
     " will assign the group Enable to field trial WebRTC-FooFeature.");
-DEFINE_bool(help, false, "Prints this message");
+WEBRTC_DEFINE_bool(help, false, "Prints this message");
 
 int main(int argc, char* argv[]) {
   webrtc::test::NetEqTestFactory factory;
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.cc b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
index 51077bc..aa956ce 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
@@ -91,47 +91,60 @@
 }
 
 // Define command line flags.
-DEFINE_int(pcmu, 0, "RTP payload type for PCM-u");
-DEFINE_int(pcma, 8, "RTP payload type for PCM-a");
-DEFINE_int(ilbc, 102, "RTP payload type for iLBC");
-DEFINE_int(isac, 103, "RTP payload type for iSAC");
-DEFINE_int(isac_swb, 104, "RTP payload type for iSAC-swb (32 kHz)");
-DEFINE_int(opus, 111, "RTP payload type for Opus");
-DEFINE_int(pcm16b, 93, "RTP payload type for PCM16b-nb (8 kHz)");
-DEFINE_int(pcm16b_wb, 94, "RTP payload type for PCM16b-wb (16 kHz)");
-DEFINE_int(pcm16b_swb32, 95, "RTP payload type for PCM16b-swb32 (32 kHz)");
-DEFINE_int(pcm16b_swb48, 96, "RTP payload type for PCM16b-swb48 (48 kHz)");
-DEFINE_int(g722, 9, "RTP payload type for G.722");
-DEFINE_int(avt, 106, "RTP payload type for AVT/DTMF (8 kHz)");
-DEFINE_int(avt_16, 114, "RTP payload type for AVT/DTMF (16 kHz)");
-DEFINE_int(avt_32, 115, "RTP payload type for AVT/DTMF (32 kHz)");
-DEFINE_int(avt_48, 116, "RTP payload type for AVT/DTMF (48 kHz)");
-DEFINE_int(red, 117, "RTP payload type for redundant audio (RED)");
-DEFINE_int(cn_nb, 13, "RTP payload type for comfort noise (8 kHz)");
-DEFINE_int(cn_wb, 98, "RTP payload type for comfort noise (16 kHz)");
-DEFINE_int(cn_swb32, 99, "RTP payload type for comfort noise (32 kHz)");
-DEFINE_int(cn_swb48, 100, "RTP payload type for comfort noise (48 kHz)");
-DEFINE_string(replacement_audio_file,
-              "",
-              "A PCM file that will be used to populate "
-              "dummy"
-              " RTP packets");
-DEFINE_string(ssrc,
-              "",
-              "Only use packets with this SSRC (decimal or hex, the latter "
-              "starting with 0x)");
-DEFINE_int(audio_level, 1, "Extension ID for audio level (RFC 6464)");
-DEFINE_int(abs_send_time, 3, "Extension ID for absolute sender time");
-DEFINE_int(transport_seq_no, 5, "Extension ID for transport sequence number");
-DEFINE_int(video_content_type, 7, "Extension ID for video content type");
-DEFINE_int(video_timing, 8, "Extension ID for video timing");
-DEFINE_bool(matlabplot,
-            false,
-            "Generates a matlab script for plotting the delay profile");
-DEFINE_bool(pythonplot,
-            false,
-            "Generates a python script for plotting the delay profile");
-DEFINE_bool(concealment_events, false, "Prints concealment events");
+WEBRTC_DEFINE_int(pcmu, 0, "RTP payload type for PCM-u");
+WEBRTC_DEFINE_int(pcma, 8, "RTP payload type for PCM-a");
+WEBRTC_DEFINE_int(ilbc, 102, "RTP payload type for iLBC");
+WEBRTC_DEFINE_int(isac, 103, "RTP payload type for iSAC");
+WEBRTC_DEFINE_int(isac_swb, 104, "RTP payload type for iSAC-swb (32 kHz)");
+WEBRTC_DEFINE_int(opus, 111, "RTP payload type for Opus");
+WEBRTC_DEFINE_int(pcm16b, 93, "RTP payload type for PCM16b-nb (8 kHz)");
+WEBRTC_DEFINE_int(pcm16b_wb, 94, "RTP payload type for PCM16b-wb (16 kHz)");
+WEBRTC_DEFINE_int(pcm16b_swb32,
+                  95,
+                  "RTP payload type for PCM16b-swb32 (32 kHz)");
+WEBRTC_DEFINE_int(pcm16b_swb48,
+                  96,
+                  "RTP payload type for PCM16b-swb48 (48 kHz)");
+WEBRTC_DEFINE_int(g722, 9, "RTP payload type for G.722");
+WEBRTC_DEFINE_int(avt, 106, "RTP payload type for AVT/DTMF (8 kHz)");
+WEBRTC_DEFINE_int(avt_16, 114, "RTP payload type for AVT/DTMF (16 kHz)");
+WEBRTC_DEFINE_int(avt_32, 115, "RTP payload type for AVT/DTMF (32 kHz)");
+WEBRTC_DEFINE_int(avt_48, 116, "RTP payload type for AVT/DTMF (48 kHz)");
+WEBRTC_DEFINE_int(red, 117, "RTP payload type for redundant audio (RED)");
+WEBRTC_DEFINE_int(cn_nb, 13, "RTP payload type for comfort noise (8 kHz)");
+WEBRTC_DEFINE_int(cn_wb, 98, "RTP payload type for comfort noise (16 kHz)");
+WEBRTC_DEFINE_int(cn_swb32, 99, "RTP payload type for comfort noise (32 kHz)");
+WEBRTC_DEFINE_int(cn_swb48, 100, "RTP payload type for comfort noise (48 kHz)");
+WEBRTC_DEFINE_string(replacement_audio_file,
+                     "",
+                     "A PCM file that will be used to populate "
+                     "dummy"
+                     " RTP packets");
+WEBRTC_DEFINE_string(
+    ssrc,
+    "",
+    "Only use packets with this SSRC (decimal or hex, the latter "
+    "starting with 0x)");
+WEBRTC_DEFINE_int(audio_level, 1, "Extension ID for audio level (RFC 6464)");
+WEBRTC_DEFINE_int(abs_send_time, 3, "Extension ID for absolute sender time");
+WEBRTC_DEFINE_int(transport_seq_no,
+                  5,
+                  "Extension ID for transport sequence number");
+WEBRTC_DEFINE_int(video_content_type, 7, "Extension ID for video content type");
+WEBRTC_DEFINE_int(video_timing, 8, "Extension ID for video timing");
+WEBRTC_DEFINE_bool(matlabplot,
+                   false,
+                   "Generates a matlab script for plotting the delay profile");
+WEBRTC_DEFINE_bool(pythonplot,
+                   false,
+                   "Generates a python script for plotting the delay profile");
+WEBRTC_DEFINE_bool(concealment_events, false, "Prints concealment events");
+WEBRTC_DEFINE_int(max_nr_packets_in_buffer,
+                  50,
+                  "Maximum allowed number of packets in the buffer");
+WEBRTC_DEFINE_bool(enable_fast_accelerate,
+                   false,
+                   "Enables jitter buffer fast accelerate");
 
 // Maps a codec type to a printable name string.
 std::string CodecName(NetEqDecoder codec) {
@@ -309,25 +322,27 @@
       {FLAG_video_content_type, kRtpExtensionVideoContentType},
       {FLAG_video_timing, kRtpExtensionVideoTiming}};
 
+  absl::optional<uint32_t> ssrc_filter;
+  // Check if an SSRC value was provided.
+  if (strlen(FLAG_ssrc) > 0) {
+    uint32_t ssrc;
+    RTC_CHECK(ParseSsrc(FLAG_ssrc, &ssrc)) << "Flag verification has failed.";
+    ssrc_filter = ssrc;
+  }
+
   std::unique_ptr<NetEqInput> input;
   if (RtpFileSource::ValidRtpDump(input_file_name) ||
       RtpFileSource::ValidPcap(input_file_name)) {
-    input.reset(new NetEqRtpDumpInput(input_file_name, rtp_ext_map));
+    input.reset(
+        new NetEqRtpDumpInput(input_file_name, rtp_ext_map, ssrc_filter));
   } else {
-    input.reset(new NetEqEventLogInput(input_file_name, rtp_ext_map));
+    input.reset(new NetEqEventLogInput(input_file_name, ssrc_filter));
   }
 
   std::cout << "Input file: " << input_file_name << std::endl;
   RTC_CHECK(input) << "Cannot open input file";
   RTC_CHECK(!input->ended()) << "Input file is empty";
 
-  // Check if an SSRC value was provided.
-  if (strlen(FLAG_ssrc) > 0) {
-    uint32_t ssrc;
-    RTC_CHECK(ParseSsrc(FLAG_ssrc, &ssrc)) << "Flag verification has failed.";
-    static_cast<NetEqPacketSourceInput*>(input.get())->SelectSsrc(ssrc);
-  }
-
   // Check the sample rate.
   absl::optional<int> sample_rate_hz;
   std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc;
@@ -457,6 +472,8 @@
   callbacks.simulation_ended_callback = stats_plotter_.get();
   NetEq::Config config;
   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;
   return absl::make_unique<NetEqTest>(config, codecs, ext_codecs_,
                                       std::move(input), std::move(output),
                                       callbacks);
diff --git a/modules/audio_coding/neteq/tools/packet.cc b/modules/audio_coding/neteq/tools/packet.cc
index b1a9b64..0e7951b 100644
--- a/modules/audio_coding/neteq/tools/packet.cc
+++ b/modules/audio_coding/neteq/tools/packet.cc
@@ -49,6 +49,20 @@
   valid_header_ = ParseHeader(parser);
 }
 
+Packet::Packet(const RTPHeader& header,
+               size_t virtual_packet_length_bytes,
+               size_t virtual_payload_length_bytes,
+               double time_ms)
+    : header_(header),
+      payload_memory_(),
+      payload_(NULL),
+      packet_length_bytes_(0),
+      payload_length_bytes_(0),
+      virtual_packet_length_bytes_(virtual_packet_length_bytes),
+      virtual_payload_length_bytes_(virtual_payload_length_bytes),
+      time_ms_(time_ms),
+      valid_header_(true) {}
+
 Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
     : payload_memory_(packet_memory),
       payload_(NULL),
diff --git a/modules/audio_coding/neteq/tools/packet.h b/modules/audio_coding/neteq/tools/packet.h
index 623c5cb..39137aa 100644
--- a/modules/audio_coding/neteq/tools/packet.h
+++ b/modules/audio_coding/neteq/tools/packet.h
@@ -50,7 +50,17 @@
          double time_ms,
          const RtpHeaderParser& parser);
 
-  // The following two constructors are the same as above, but without a
+  // Same as above, but creates the packet from an already parsed RTPHeader.
+  // This is typically used when reading RTP dump files that only contain the
+  // RTP headers, and no payload. The |virtual_packet_length_bytes| tells what
+  // size the packet had on wire, including the now discarded payload,
+  // The |virtual_payload_length_bytes| tells the size of the payload.
+  Packet(const RTPHeader& header,
+         size_t virtual_packet_length_bytes,
+         size_t virtual_payload_length_bytes,
+         double time_ms);
+
+  // The following constructors are the same as the first two, but without a
   // parser. Note that when the object is constructed using any of these
   // methods, the header will be parsed using a default RtpHeaderParser object.
   // In particular, RTP header extensions won't be parsed.
diff --git a/modules/audio_coding/neteq/tools/packet_source.cc b/modules/audio_coding/neteq/tools/packet_source.cc
index 30bf431..598ae6e 100644
--- a/modules/audio_coding/neteq/tools/packet_source.cc
+++ b/modules/audio_coding/neteq/tools/packet_source.cc
@@ -13,7 +13,7 @@
 namespace webrtc {
 namespace test {
 
-PacketSource::PacketSource() : use_ssrc_filter_(false), ssrc_(0) {}
+PacketSource::PacketSource() = default;
 
 PacketSource::~PacketSource() = default;
 
@@ -21,10 +21,5 @@
   filter_.set(payload_type, true);
 }
 
-void PacketSource::SelectSsrc(uint32_t ssrc) {
-  use_ssrc_filter_ = true;
-  ssrc_ = ssrc;
-}
-
 }  // namespace test
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/tools/packet_source.h b/modules/audio_coding/neteq/tools/packet_source.h
index fb689e3..cb86a98 100644
--- a/modules/audio_coding/neteq/tools/packet_source.h
+++ b/modules/audio_coding/neteq/tools/packet_source.h
@@ -32,13 +32,8 @@
 
   virtual void FilterOutPayloadType(uint8_t payload_type);
 
-  virtual void SelectSsrc(uint32_t ssrc);
-
  protected:
   std::bitset<128> filter_;  // Payload type is 7 bits in the RFC.
-  // If SSRC filtering discards all packet that do not match the SSRC.
-  bool use_ssrc_filter_;  // True when SSRC filtering is active.
-  uint32_t ssrc_;  // The selected SSRC. All other SSRCs will be discarded.
 
  private:
   RTC_DISALLOW_COPY_AND_ASSIGN(PacketSource);
diff --git a/modules/audio_coding/neteq/tools/rtc_event_log_source.cc b/modules/audio_coding/neteq/tools/rtc_event_log_source.cc
index 9e435c7..582c2f2 100644
--- a/modules/audio_coding/neteq/tools/rtc_event_log_source.cc
+++ b/modules/audio_coding/neteq/tools/rtc_event_log_source.cc
@@ -13,94 +13,115 @@
 #include <string.h>
 #include <iostream>
 #include <limits>
+#include <utility>
 
+#include "logging/rtc_event_log/rtc_event_processor.h"
 #include "modules/audio_coding/neteq/tools/packet.h"
-#include "modules/rtp_rtcp/include/rtp_header_parser.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
 namespace test {
 
-RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) {
+namespace {
+bool ShouldSkipStream(ParsedRtcEventLogNew::MediaType media_type,
+                      uint32_t ssrc,
+                      absl::optional<uint32_t> ssrc_filter) {
+  if (media_type != ParsedRtcEventLogNew::MediaType::AUDIO)
+    return true;
+  if (ssrc_filter.has_value() && ssrc != *ssrc_filter)
+    return true;
+  return false;
+}
+}  // namespace
+
+RtcEventLogSource* RtcEventLogSource::Create(
+    const std::string& file_name,
+    absl::optional<uint32_t> ssrc_filter) {
   RtcEventLogSource* source = new RtcEventLogSource();
-  RTC_CHECK(source->OpenFile(file_name));
+  RTC_CHECK(source->OpenFile(file_name, ssrc_filter));
   return source;
 }
 
 RtcEventLogSource::~RtcEventLogSource() {}
 
-bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type,
-                                                   uint8_t id) {
-  RTC_CHECK(parser_.get());
-  return parser_->RegisterRtpHeaderExtension(type, id);
-}
-
 std::unique_ptr<Packet> RtcEventLogSource::NextPacket() {
-  for (; rtp_packet_index_ < parsed_stream_.GetNumberOfEvents();
-       rtp_packet_index_++) {
-    if (parsed_stream_.GetEventType(rtp_packet_index_) ==
-        ParsedRtcEventLogNew::EventType::RTP_EVENT) {
-      PacketDirection direction;
-      size_t header_length;
-      size_t packet_length;
-      uint64_t timestamp_us = parsed_stream_.GetTimestamp(rtp_packet_index_);
-      parsed_stream_.GetRtpHeader(rtp_packet_index_, &direction, nullptr,
-                                  &header_length, &packet_length, nullptr);
+  if (rtp_packet_index_ >= rtp_packets_.size())
+    return nullptr;
 
-      if (direction != kIncomingPacket) {
-        continue;
-      }
-
-      uint8_t* packet_header = new uint8_t[header_length];
-      parsed_stream_.GetRtpHeader(rtp_packet_index_, nullptr, packet_header,
-                                  nullptr, nullptr, nullptr);
-      std::unique_ptr<Packet> packet(
-          new Packet(packet_header, header_length, packet_length,
-                     static_cast<double>(timestamp_us) / 1000, *parser_.get()));
-
-      if (!packet->valid_header()) {
-        std::cout << "Warning: Packet with index " << rtp_packet_index_
-                  << " has an invalid header and will be ignored." << std::endl;
-        continue;
-      }
-
-      if (parsed_stream_.GetMediaType(packet->header().ssrc, direction) !=
-          ParsedRtcEventLogNew::MediaType::AUDIO) {
-        continue;
-      }
-
-      // Check if the packet should not be filtered out.
-      if (!filter_.test(packet->header().payloadType) &&
-          !(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) {
-        ++rtp_packet_index_;
-        return packet;
-      }
-    }
-  }
-  return nullptr;
+  std::unique_ptr<Packet> packet = std::move(rtp_packets_[rtp_packet_index_++]);
+  return packet;
 }
 
 int64_t RtcEventLogSource::NextAudioOutputEventMs() {
-  while (audio_output_index_ < parsed_stream_.GetNumberOfEvents()) {
-    if (parsed_stream_.GetEventType(audio_output_index_) ==
-        ParsedRtcEventLogNew::EventType::AUDIO_PLAYOUT_EVENT) {
-      LoggedAudioPlayoutEvent playout_event =
-          parsed_stream_.GetAudioPlayout(audio_output_index_);
-      if (!(use_ssrc_filter_ && playout_event.ssrc != ssrc_)) {
-        audio_output_index_++;
-        return playout_event.timestamp_us / 1000;
-      }
-    }
-    audio_output_index_++;
-  }
-  return std::numeric_limits<int64_t>::max();
+  if (audio_output_index_ >= audio_outputs_.size())
+    return std::numeric_limits<int64_t>::max();
+
+  int64_t output_time_ms = audio_outputs_[audio_output_index_++];
+  return output_time_ms;
 }
 
-RtcEventLogSource::RtcEventLogSource()
-    : PacketSource(), parser_(RtpHeaderParser::Create()) {}
+RtcEventLogSource::RtcEventLogSource() : PacketSource() {}
 
-bool RtcEventLogSource::OpenFile(const std::string& file_name) {
-  return parsed_stream_.ParseFile(file_name);
+bool RtcEventLogSource::OpenFile(const std::string& file_name,
+                                 absl::optional<uint32_t> ssrc_filter) {
+  ParsedRtcEventLogNew parsed_log;
+  if (!parsed_log.ParseFile(file_name))
+    return false;
+
+  const auto first_log_end_time_us =
+      parsed_log.stop_log_events().empty()
+          ? std::numeric_limits<int64_t>::max()
+          : parsed_log.stop_log_events().front().log_time_us();
+
+  auto handle_rtp_packet =
+      [this,
+       first_log_end_time_us](const webrtc::LoggedRtpPacketIncoming& incoming) {
+        if (!filter_.test(incoming.rtp.header.payloadType) &&
+            incoming.log_time_us() < first_log_end_time_us) {
+          rtp_packets_.emplace_back(absl::make_unique<Packet>(
+              incoming.rtp.header, incoming.rtp.total_length,
+              incoming.rtp.total_length - incoming.rtp.header_length,
+              static_cast<double>(incoming.log_time_ms())));
+        }
+      };
+
+  auto handle_audio_playout =
+      [this, first_log_end_time_us](
+          const webrtc::LoggedAudioPlayoutEvent& audio_playout) {
+        if (audio_playout.log_time_us() < first_log_end_time_us) {
+          audio_outputs_.emplace_back(audio_playout.log_time_ms());
+        }
+      };
+
+  // This wouldn't be needed if we knew that there was at most one audio stream.
+  webrtc::RtcEventProcessor event_processor;
+  for (const auto& rtp_packets : parsed_log.incoming_rtp_packets_by_ssrc()) {
+    ParsedRtcEventLogNew::MediaType media_type =
+        parsed_log.GetMediaType(rtp_packets.ssrc, webrtc::kIncomingPacket);
+    if (ShouldSkipStream(media_type, rtp_packets.ssrc, ssrc_filter)) {
+      continue;
+    }
+    auto rtp_view = absl::make_unique<
+        webrtc::ProcessableEventList<webrtc::LoggedRtpPacketIncoming>>(
+        rtp_packets.incoming_packets.begin(),
+        rtp_packets.incoming_packets.end(), handle_rtp_packet);
+    event_processor.AddEvents(std::move(rtp_view));
+  }
+
+  for (const auto& audio_playouts : parsed_log.audio_playout_events()) {
+    if (ssrc_filter.has_value() && audio_playouts.first != *ssrc_filter)
+      continue;
+    auto audio_view = absl::make_unique<
+        webrtc::ProcessableEventList<webrtc::LoggedAudioPlayoutEvent>>(
+        audio_playouts.second.begin(), audio_playouts.second.end(),
+        handle_audio_playout);
+    event_processor.AddEvents(std::move(audio_view));
+  }
+
+  // Fills in rtp_packets_ and audio_outputs_.
+  event_processor.ProcessEventsInOrder();
+
+  return true;
 }
 
 }  // namespace test
diff --git a/modules/audio_coding/neteq/tools/rtc_event_log_source.h b/modules/audio_coding/neteq/tools/rtc_event_log_source.h
index db4eb19..6b761f7 100644
--- a/modules/audio_coding/neteq/tools/rtc_event_log_source.h
+++ b/modules/audio_coding/neteq/tools/rtc_event_log_source.h
@@ -13,7 +13,9 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
+#include "absl/types/optional.h"
 #include "logging/rtc_event_log/rtc_event_log_parser_new.h"
 #include "modules/audio_coding/neteq/tools/packet_source.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -31,13 +33,11 @@
  public:
   // Creates an RtcEventLogSource reading from |file_name|. If the file cannot
   // be opened, or has the wrong format, NULL will be returned.
-  static RtcEventLogSource* Create(const std::string& file_name);
+  static RtcEventLogSource* Create(const std::string& file_name,
+                                   absl::optional<uint32_t> ssrc_filter);
 
   virtual ~RtcEventLogSource();
 
-  // Registers an RTP header extension and binds it to |id|.
-  virtual bool RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
-
   std::unique_ptr<Packet> NextPacket() override;
 
   // Returns the timestamp of the next audio output event, in milliseconds. The
@@ -48,14 +48,14 @@
  private:
   RtcEventLogSource();
 
-  bool OpenFile(const std::string& file_name);
+  bool OpenFile(const std::string& file_name,
+                absl::optional<uint32_t> ssrc_filter);
 
+  std::vector<std::unique_ptr<Packet>> rtp_packets_;
   size_t rtp_packet_index_ = 0;
+  std::vector<int64_t> audio_outputs_;
   size_t audio_output_index_ = 0;
 
-  ParsedRtcEventLogNew parsed_stream_;
-  std::unique_ptr<RtpHeaderParser> parser_;
-
   RTC_DISALLOW_COPY_AND_ASSIGN(RtcEventLogSource);
 };
 
diff --git a/modules/audio_coding/neteq/tools/rtp_analyze.cc b/modules/audio_coding/neteq/tools/rtp_analyze.cc
index f939038..9d3041e 100644
--- a/modules/audio_coding/neteq/tools/rtp_analyze.cc
+++ b/modules/audio_coding/neteq/tools/rtp_analyze.cc
@@ -19,16 +19,16 @@
 #include "rtc_base/flags.h"
 
 // Define command line flags.
-DEFINE_int(red, 117, "RTP payload type for RED");
-DEFINE_int(audio_level,
-           -1,
-           "Extension ID for audio level (RFC 6464); "
-           "-1 not to print audio level");
-DEFINE_int(abs_send_time,
-           -1,
-           "Extension ID for absolute sender time; "
-           "-1 not to print absolute send time");
-DEFINE_bool(help, false, "Print this message");
+WEBRTC_DEFINE_int(red, 117, "RTP payload type for RED");
+WEBRTC_DEFINE_int(audio_level,
+                  -1,
+                  "Extension ID for audio level (RFC 6464); "
+                  "-1 not to print audio level");
+WEBRTC_DEFINE_int(abs_send_time,
+                  -1,
+                  "Extension ID for absolute sender time; "
+                  "-1 not to print absolute send time");
+WEBRTC_DEFINE_bool(help, false, "Print this message");
 
 int main(int argc, char* argv[]) {
   std::string program_name = argv[0];
diff --git a/modules/audio_coding/neteq/tools/rtp_encode.cc b/modules/audio_coding/neteq/tools/rtp_encode.cc
index 5065ca1..14c6e58 100644
--- a/modules/audio_coding/neteq/tools/rtp_encode.cc
+++ b/modules/audio_coding/neteq/tools/rtp_encode.cc
@@ -40,20 +40,24 @@
 namespace {
 
 // Define command line flags.
-DEFINE_bool(list_codecs, false, "Enumerate all codecs");
-DEFINE_string(codec, "opus", "Codec to use");
-DEFINE_int(frame_len, 0, "Frame length in ms; 0 indicates codec default value");
-DEFINE_int(bitrate, 0, "Bitrate in kbps; 0 indicates codec default value");
-DEFINE_int(payload_type,
-           -1,
-           "RTP payload type; -1 indicates codec default value");
-DEFINE_int(cng_payload_type,
-           -1,
-           "RTP payload type for CNG; -1 indicates default value");
-DEFINE_int(ssrc, 0, "SSRC to write to the RTP header");
-DEFINE_bool(dtx, false, "Use DTX/CNG");
-DEFINE_int(sample_rate, 48000, "Sample rate of the input file");
-DEFINE_bool(help, false, "Print this message");
+WEBRTC_DEFINE_bool(list_codecs, false, "Enumerate all codecs");
+WEBRTC_DEFINE_string(codec, "opus", "Codec to use");
+WEBRTC_DEFINE_int(frame_len,
+                  0,
+                  "Frame length in ms; 0 indicates codec default value");
+WEBRTC_DEFINE_int(bitrate,
+                  0,
+                  "Bitrate in kbps; 0 indicates codec default value");
+WEBRTC_DEFINE_int(payload_type,
+                  -1,
+                  "RTP payload type; -1 indicates codec default value");
+WEBRTC_DEFINE_int(cng_payload_type,
+                  -1,
+                  "RTP payload type for CNG; -1 indicates default value");
+WEBRTC_DEFINE_int(ssrc, 0, "SSRC to write to the RTP header");
+WEBRTC_DEFINE_bool(dtx, false, "Use DTX/CNG");
+WEBRTC_DEFINE_int(sample_rate, 48000, "Sample rate of the input file");
+WEBRTC_DEFINE_bool(help, false, "Print this message");
 
 // Add new codecs here, and to the map below.
 enum class CodecType {
@@ -242,8 +246,8 @@
   return nullptr;
 }
 
-AudioEncoderCng::Config GetCngConfig(int sample_rate_hz) {
-  AudioEncoderCng::Config cng_config;
+AudioEncoderCngConfig GetCngConfig(int sample_rate_hz) {
+  AudioEncoderCngConfig cng_config;
   const auto default_payload_type = [&] {
     switch (sample_rate_hz) {
       case 8000:
@@ -309,10 +313,10 @@
 
   // Create an external VAD/CNG encoder if needed.
   if (FLAG_dtx && !codec_it->second.internal_dtx) {
-    AudioEncoderCng::Config cng_config = GetCngConfig(codec->SampleRateHz());
+    AudioEncoderCngConfig cng_config = GetCngConfig(codec->SampleRateHz());
     RTC_DCHECK(codec);
     cng_config.speech_encoder = std::move(codec);
-    codec = absl::make_unique<AudioEncoderCng>(std::move(cng_config));
+    codec = CreateComfortNoiseEncoder(std::move(cng_config));
   }
   RTC_DCHECK(codec);
 
diff --git a/modules/audio_coding/neteq/tools/rtp_file_source.cc b/modules/audio_coding/neteq/tools/rtp_file_source.cc
index 806bba7..eda2b3e 100644
--- a/modules/audio_coding/neteq/tools/rtp_file_source.cc
+++ b/modules/audio_coding/neteq/tools/rtp_file_source.cc
@@ -26,8 +26,9 @@
 namespace webrtc {
 namespace test {
 
-RtpFileSource* RtpFileSource::Create(const std::string& file_name) {
-  RtpFileSource* source = new RtpFileSource();
+RtpFileSource* RtpFileSource::Create(const std::string& file_name,
+                                     absl::optional<uint32_t> ssrc_filter) {
+  RtpFileSource* source = new RtpFileSource(ssrc_filter);
   RTC_CHECK(source->OpenFile(file_name));
   return source;
 }
@@ -72,7 +73,7 @@
       continue;
     }
     if (filter_.test(packet->header().payloadType) ||
-        (use_ssrc_filter_ && packet->header().ssrc != ssrc_)) {
+        (ssrc_filter_ && packet->header().ssrc != *ssrc_filter_)) {
       // This payload type should be filtered out. Continue to the next packet.
       continue;
     }
@@ -80,8 +81,10 @@
   }
 }
 
-RtpFileSource::RtpFileSource()
-    : PacketSource(), parser_(RtpHeaderParser::Create()) {}
+RtpFileSource::RtpFileSource(absl::optional<uint32_t> ssrc_filter)
+    : PacketSource(),
+      parser_(RtpHeaderParser::Create()),
+      ssrc_filter_(ssrc_filter) {}
 
 bool RtpFileSource::OpenFile(const std::string& file_name) {
   rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kRtpDump, file_name));
diff --git a/modules/audio_coding/neteq/tools/rtp_file_source.h b/modules/audio_coding/neteq/tools/rtp_file_source.h
index 013333b..02ab897 100644
--- a/modules/audio_coding/neteq/tools/rtp_file_source.h
+++ b/modules/audio_coding/neteq/tools/rtp_file_source.h
@@ -16,6 +16,7 @@
 #include <memory>
 #include <string>
 
+#include "absl/types/optional.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/audio_coding/neteq/tools/packet_source.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -33,7 +34,9 @@
  public:
   // Creates an RtpFileSource reading from |file_name|. If the file cannot be
   // opened, or has the wrong format, NULL will be returned.
-  static RtpFileSource* Create(const std::string& file_name);
+  static RtpFileSource* Create(
+      const std::string& file_name,
+      absl::optional<uint32_t> ssrc_filter = absl::nullopt);
 
   // Checks whether a files is a valid RTP dump or PCAP (Wireshark) file.
   static bool ValidRtpDump(const std::string& file_name);
@@ -51,12 +54,13 @@
   static const int kRtpFileHeaderSize = 4 + 4 + 4 + 2 + 2;
   static const size_t kPacketHeaderSize = 8;
 
-  RtpFileSource();
+  explicit RtpFileSource(absl::optional<uint32_t> ssrc_filter);
 
   bool OpenFile(const std::string& file_name);
 
   std::unique_ptr<RtpFileReader> rtp_reader_;
   std::unique_ptr<RtpHeaderParser> parser_;
+  const absl::optional<uint32_t> ssrc_filter_;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(RtpFileSource);
 };
diff --git a/modules/audio_coding/neteq/tools/rtp_jitter.cc b/modules/audio_coding/neteq/tools/rtp_jitter.cc
index 3c49443..92a7a8d 100644
--- a/modules/audio_coding/neteq/tools/rtp_jitter.cc
+++ b/modules/audio_coding/neteq/tools/rtp_jitter.cc
@@ -23,7 +23,7 @@
 namespace test {
 namespace {
 
-DEFINE_bool(help, false, "Print help message");
+WEBRTC_DEFINE_bool(help, false, "Print help message");
 
 constexpr size_t kRtpDumpHeaderLength = 8;
 
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index dd1569e..a244c84 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -26,6 +26,41 @@
   }
 }
 
+rtc_static_library("config") {
+  visibility = [ ":*" ]
+  sources = [
+    "include/config.cc",
+    "include/config.h",
+  ]
+  deps = [
+    "../../rtc_base:macromagic",
+    "../../rtc_base/system:rtc_export",
+  ]
+}
+
+rtc_source_set("api") {
+  visibility = [ "*" ]
+  sources = [
+    "include/audio_processing.cc",
+    "include/audio_processing.h",
+  ]
+  deps = [
+    ":audio_frame_view",
+    ":audio_generator_interface",
+    ":audio_processing_statistics",
+    ":config",
+    ":gain_control_interface",
+    "../../api/audio:aec3_config",
+    "../../api/audio:echo_control",
+    "../../rtc_base:deprecation",
+    "../../rtc_base:macromagic",
+    "../../rtc_base:ptr_util",
+    "../../rtc_base:rtc_base_approved",
+    "../../rtc_base/system:rtc_export",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
 rtc_static_library("audio_processing") {
   visibility = [ "*" ]
   configs += [ ":apm_debug_dump" ]
@@ -55,10 +90,6 @@
     "gain_controller2.h",
     "include/aec_dump.cc",
     "include/aec_dump.h",
-    "include/audio_processing.cc",
-    "include/audio_processing.h",
-    "include/config.cc",
-    "include/config.h",
     "level_estimator_impl.cc",
     "level_estimator_impl.h",
     "low_cut_filter.cc",
@@ -95,11 +126,13 @@
 
   defines = []
   deps = [
+    ":api",
     ":apm_logging",
     ":audio_frame_view",
     ":audio_generator_interface",
     ":audio_processing_c",
     ":audio_processing_statistics",
+    ":config",
     ":gain_control_interface",
     "../..:webrtc_common",
     "../../api:array_view",
@@ -309,6 +342,7 @@
       "include/mock_audio_processing.h",
     ]
     deps = [
+      ":api",
       ":audio_processing",
       ":audio_processing_statistics",
       "../../test:test_support",
@@ -360,10 +394,12 @@
 
     deps = [
       ":analog_mic_simulation",
+      ":api",
       ":apm_logging",
       ":audio_frame_view",
       ":audio_processing",
       ":audioproc_test_utils",
+      ":config",
       ":file_audio_generator_unittests",
       ":mocks",
       "../..:webrtc_common",
@@ -393,6 +429,7 @@
       "agc2:biquad_filter_unittests",
       "agc2:fixed_digital_unittests",
       "agc2:noise_estimator_unittests",
+      "agc2:test_utils",
       "agc2/rnn_vad:unittests",
       "test/conversational_speech:unittest",
       "utility:block_mean_calculator_unittest",
@@ -484,6 +521,7 @@
     ]
 
     deps = [
+      ":api",
       ":audio_generator_factory",
       ":audio_processing",
       ":file_audio_generator",
@@ -514,6 +552,7 @@
   if (rtc_enable_protobuf) {
     rtc_source_set("audioproc_f_impl") {
       testonly = true
+      configs += [ ":apm_debug_dump" ]
       sources = [
         "test/aec_dump_based_simulator.cc",
         "test/aec_dump_based_simulator.h",
@@ -527,6 +566,8 @@
 
       deps = [
         ":analog_mic_simulation",
+        ":api",
+        ":apm_logging",
         ":audio_processing",
         ":audioproc_debug_proto",
         ":audioproc_protobuf_utils",
@@ -556,6 +597,7 @@
         "test/audioproc_float_main.cc",
       ]
       deps = [
+        ":api",
         ":audio_processing",
         "../../api:audioproc_f_api",
         "../../rtc_base:rtc_base_approved",
@@ -581,6 +623,7 @@
     ]
 
     deps = [
+      ":api",
       ":audio_processing",
       "../../api:array_view",
       "../../api/audio:audio_frame_api",
@@ -665,6 +708,7 @@
       ]
 
       deps = [
+        ":api",
         ":audio_processing",
         ":audioproc_debug_proto",
         ":audioproc_protobuf_utils",
diff --git a/modules/audio_processing/aec/aec_core.cc b/modules/audio_processing/aec/aec_core.cc
index 5a8cf8f..62b8ad0 100644
--- a/modules/audio_processing/aec/aec_core.cc
+++ b/modules/audio_processing/aec/aec_core.cc
@@ -21,6 +21,7 @@
 #include <algorithm>
 
 #include "rtc_base/checks.h"
+
 extern "C" {
 #include "common_audio/ring_buffer.h"
 }
@@ -29,7 +30,6 @@
 #include "modules/audio_processing/aec/aec_core_optimized_methods.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "modules/audio_processing/utility/delay_estimator_wrapper.h"
-#include "rtc_base/checks.h"
 #include "rtc_base/system/arch.h"
 #include "system_wrappers/include/cpu_features_wrapper.h"
 #include "system_wrappers/include/metrics.h"
diff --git a/modules/audio_processing/aec/aec_resampler.cc b/modules/audio_processing/aec/aec_resampler.cc
index 2851c0b..210c2be 100644
--- a/modules/audio_processing/aec/aec_resampler.cc
+++ b/modules/audio_processing/aec/aec_resampler.cc
@@ -14,7 +14,6 @@
 
 #include "modules/audio_processing/aec/aec_resampler.h"
 
-#include <math.h>
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/modules/audio_processing/aec/aec_resampler.h b/modules/audio_processing/aec/aec_resampler.h
index 130f7ec..a112c43 100644
--- a/modules/audio_processing/aec/aec_resampler.h
+++ b/modules/audio_processing/aec/aec_resampler.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC_AEC_RESAMPLER_H_
 #define MODULES_AUDIO_PROCESSING_AEC_AEC_RESAMPLER_H_
 
+#include <stddef.h>
+
 #include "modules/audio_processing/aec/aec_core.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn
index d1f4595..c3f6dd5 100644
--- a/modules/audio_processing/aec3/BUILD.gn
+++ b/modules/audio_processing/aec3/BUILD.gn
@@ -83,6 +83,8 @@
     "render_delay_controller2.cc",
     "render_delay_controller_metrics.cc",
     "render_delay_controller_metrics.h",
+    "render_reverb_model.cc",
+    "render_reverb_model.h",
     "render_signal_analyzer.cc",
     "render_signal_analyzer.h",
     "residual_echo_estimator.cc",
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter.cc b/modules/audio_processing/aec3/adaptive_fir_filter.cc
index abe68f8..3ab1ebc 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter.cc
+++ b/modules/audio_processing/aec3/adaptive_fir_filter.cc
@@ -24,7 +24,6 @@
 
 #include "modules/audio_processing/aec3/fft_data.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 #include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter.h b/modules/audio_processing/aec3/adaptive_fir_filter.h
index f9d3f1a..7c832a6 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter.h
+++ b/modules/audio_processing/aec3/adaptive_fir_filter.h
@@ -11,8 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ADAPTIVE_FIR_FILTER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ADAPTIVE_FIR_FILTER_H_
 
+#include <stddef.h>
 #include <array>
-#include <memory>
 #include <vector>
 
 #include "api/array_view.h"
diff --git a/modules/audio_processing/aec3/aec3_common.cc b/modules/audio_processing/aec3/aec3_common.cc
index c374a35..aeb848a 100644
--- a/modules/audio_processing/aec3/aec3_common.cc
+++ b/modules/audio_processing/aec3/aec3_common.cc
@@ -10,10 +10,11 @@
 
 #include "modules/audio_processing/aec3/aec3_common.h"
 
-#include "system_wrappers/include/cpu_features_wrapper.h"
+#include <stdint.h>
 
 #include "rtc_base/checks.h"
 #include "rtc_base/system/arch.h"
+#include "system_wrappers/include/cpu_features_wrapper.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/aec3_fft.cc b/modules/audio_processing/aec3/aec3_fft.cc
index e29434d..1832101 100644
--- a/modules/audio_processing/aec3/aec3_fft.cc
+++ b/modules/audio_processing/aec3/aec3_fft.cc
@@ -12,6 +12,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <iterator>
 
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/aec3/aec3_fft.h b/modules/audio_processing/aec3/aec3_fft.h
index b700222..6cd649a 100644
--- a/modules/audio_processing/aec3/aec3_fft.h
+++ b/modules/audio_processing/aec3/aec3_fft.h
@@ -17,6 +17,7 @@
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/utility/ooura_fft.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc
index b9cd5ea..0eeb7eb 100644
--- a/modules/audio_processing/aec3/aec_state.cc
+++ b/modules/audio_processing/aec3/aec_state.cc
@@ -11,7 +11,7 @@
 #include "modules/audio_processing/aec3/aec_state.h"
 
 #include <math.h>
-
+#include <algorithm>
 #include <numeric>
 #include <vector>
 
@@ -41,6 +41,10 @@
 bool UseSuppressionGainLimiter() {
   return field_trial::IsEnabled("WebRTC-Aec3GainLimiterDeactivationKillSwitch");
 }
+bool EnableErleUpdatesDuringReverb() {
+  return !field_trial::IsEnabled(
+      "WebRTC-Aec3EnableErleUpdatesDuringReverbKillSwitch");
+}
 
 constexpr size_t kBlocksSinceConvergencedFilterInit = 10000;
 constexpr size_t kBlocksSinceConsistentEstimateInit = 10000;
@@ -64,19 +68,6 @@
 }
 
 absl::optional<float> AecState::ErleUncertainty() const {
-  bool filter_has_had_time_to_converge;
-  if (config_.filter.conservative_initial_phase) {
-    filter_has_had_time_to_converge =
-        strong_not_saturated_render_blocks_ >= 1.5f * kNumBlocksPerSecond;
-  } else {
-    filter_has_had_time_to_converge =
-        strong_not_saturated_render_blocks_ >= 0.8f * kNumBlocksPerSecond;
-  }
-
-  if (!filter_has_had_time_to_converge) {
-    return 1.f;
-  }
-
   if (SaturatedEcho() && use_legacy_saturation_behavior_) {
     return 1.f;
   }
@@ -90,6 +81,7 @@
       config_(config),
       use_legacy_saturation_behavior_(EnableLegacySaturationBehavior()),
       enable_erle_resets_at_gain_changes_(EnableErleResetsAtGainChanges()),
+      enable_erle_updates_during_reverb_(EnableErleUpdatesDuringReverb()),
       use_legacy_filter_quality_(UseLegacyFilterQualityState()),
       use_suppressor_gain_limiter_(UseSuppressionGainLimiter()),
       initial_state_(config_),
@@ -195,22 +187,33 @@
     }
   }
 
+  std::array<float, kFftLengthBy2Plus1> X2_reverb;
+  render_reverb_.Apply(
+      render_buffer.GetSpectrumBuffer(), delay_state_.DirectPathFilterDelay(),
+      config_.ep_strength.reverb_based_on_render ? ReverbDecay() : 0.f,
+      X2_reverb);
+
   if (config_.echo_audibility.use_stationary_properties) {
     // Update the echo audibility evaluator.
-    echo_audibility_.Update(
-        render_buffer, delay_state_.DirectPathFilterDelay(),
-        delay_state_.ExternalDelayReported(),
-        config_.ep_strength.reverb_based_on_render ? ReverbDecay() : 0.f);
+    echo_audibility_.Update(render_buffer,
+                            render_reverb_.GetReverbContributionPowerSpectrum(),
+                            delay_state_.DirectPathFilterDelay(),
+                            delay_state_.ExternalDelayReported());
   }
 
   // Update the ERL and ERLE measures.
   if (initial_state_.TransitionTriggered()) {
     erle_estimator_.Reset(false);
   }
+
   const auto& X2 = render_buffer.Spectrum(delay_state_.DirectPathFilterDelay());
-  erle_estimator_.Update(X2, Y2, E2_main,
+  const auto& X2_input_erle =
+      enable_erle_updates_during_reverb_ ? X2_reverb : X2;
+
+  erle_estimator_.Update(X2_input_erle, Y2, E2_main,
                          subtractor_output_analyzer_.ConvergedFilter(),
                          config_.erle.onset_detection);
+
   erl_estimator_.Update(subtractor_output_analyzer_.ConvergedFilter(), X2, Y2);
 
   // Detect and flag echo saturation.
diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h
index 9bb8624..c9d9cf3 100644
--- a/modules/audio_processing/aec3/aec_state.h
+++ b/modules/audio_processing/aec3/aec_state.h
@@ -11,9 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_AEC_STATE_H_
 
-#include <math.h>
-
-#include <algorithm>
+#include <stddef.h>
+#include <array>
 #include <memory>
 #include <vector>
 
@@ -28,6 +27,7 @@
 #include "modules/audio_processing/aec3/erle_estimator.h"
 #include "modules/audio_processing/aec3/filter_analyzer.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
+#include "modules/audio_processing/aec3/render_reverb_model.h"
 #include "modules/audio_processing/aec3/reverb_model_estimator.h"
 #include "modules/audio_processing/aec3/subtractor_output.h"
 #include "modules/audio_processing/aec3/subtractor_output_analyzer.h"
@@ -172,6 +172,7 @@
   const EchoCanceller3Config config_;
   const bool use_legacy_saturation_behavior_;
   const bool enable_erle_resets_at_gain_changes_;
+  const bool enable_erle_updates_during_reverb_;
   const bool use_legacy_filter_quality_;
   const bool use_suppressor_gain_limiter_;
 
@@ -383,6 +384,7 @@
   absl::optional<DelayEstimate> external_delay_;
   EchoAudibility echo_audibility_;
   ReverbModelEstimator reverb_model_estimator_;
+  RenderReverbModel render_reverb_;
   SubtractorOutputAnalyzer subtractor_output_analyzer_;
 };
 
diff --git a/modules/audio_processing/aec3/block_delay_buffer.h b/modules/audio_processing/aec3/block_delay_buffer.h
index 6e5fd5c..624e913 100644
--- a/modules/audio_processing/aec3/block_delay_buffer.h
+++ b/modules/audio_processing/aec3/block_delay_buffer.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_BLOCK_DELAY_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_BLOCK_DELAY_BUFFER_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "modules/audio_processing/audio_buffer.h"
diff --git a/modules/audio_processing/aec3/block_framer.cc b/modules/audio_processing/aec3/block_framer.cc
index 3160624..ca7667c 100644
--- a/modules/audio_processing/aec3/block_framer.cc
+++ b/modules/audio_processing/aec3/block_framer.cc
@@ -12,6 +12,7 @@
 
 #include <algorithm>
 
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/block_processor.cc b/modules/audio_processing/aec3/block_processor.cc
index 4f4020e..590380f 100644
--- a/modules/audio_processing/aec3/block_processor.cc
+++ b/modules/audio_processing/aec3/block_processor.cc
@@ -9,12 +9,16 @@
  */
 #include "modules/audio_processing/aec3/block_processor.h"
 
+#include <utility>
+
 #include "absl/types/optional.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/block_processor_metrics.h"
+#include "modules/audio_processing/aec3/delay_estimate.h"
 #include "modules/audio_processing/aec3/echo_path_variability.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/logging.h"
 
diff --git a/modules/audio_processing/aec3/block_processor.h b/modules/audio_processing/aec3/block_processor.h
index 8793a03..5f7ec7c 100644
--- a/modules/audio_processing/aec3/block_processor.h
+++ b/modules/audio_processing/aec3/block_processor.h
@@ -11,9 +11,12 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_BLOCK_PROCESSOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_BLOCK_PROCESSOR_H_
 
+#include <stddef.h>
 #include <memory>
 #include <vector>
 
+#include "api/audio/echo_canceller3_config.h"
+#include "api/audio/echo_control.h"
 #include "modules/audio_processing/aec3/echo_remover.h"
 #include "modules/audio_processing/aec3/render_delay_buffer.h"
 #include "modules/audio_processing/aec3/render_delay_controller.h"
diff --git a/modules/audio_processing/aec3/block_processor_metrics.cc b/modules/audio_processing/aec3/block_processor_metrics.cc
index c8bdda7..deac1fc 100644
--- a/modules/audio_processing/aec3/block_processor_metrics.cc
+++ b/modules/audio_processing/aec3/block_processor_metrics.cc
@@ -11,6 +11,7 @@
 #include "modules/audio_processing/aec3/block_processor_metrics.h"
 
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "rtc_base/checks.h"
 #include "system_wrappers/include/metrics.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/cascaded_biquad_filter.cc b/modules/audio_processing/aec3/cascaded_biquad_filter.cc
index 333d226..5dfd7c5 100644
--- a/modules/audio_processing/aec3/cascaded_biquad_filter.cc
+++ b/modules/audio_processing/aec3/cascaded_biquad_filter.cc
@@ -9,6 +9,8 @@
  */
 #include "modules/audio_processing/aec3/cascaded_biquad_filter.h"
 
+#include <algorithm>
+
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/cascaded_biquad_filter.h b/modules/audio_processing/aec3/cascaded_biquad_filter.h
index 1e09fa6..2a3b6d6 100644
--- a/modules/audio_processing/aec3/cascaded_biquad_filter.h
+++ b/modules/audio_processing/aec3/cascaded_biquad_filter.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_CASCADED_BIQUAD_FILTER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_CASCADED_BIQUAD_FILTER_H_
 
+#include <stddef.h>
 #include <complex>
 #include <vector>
 
diff --git a/modules/audio_processing/aec3/comfort_noise_generator.cc b/modules/audio_processing/aec3/comfort_noise_generator.cc
index a37c67a..766e658 100644
--- a/modules/audio_processing/aec3/comfort_noise_generator.cc
+++ b/modules/audio_processing/aec3/comfort_noise_generator.cc
@@ -16,9 +16,10 @@
 #if defined(WEBRTC_ARCH_X86_FAMILY)
 #include <emmintrin.h>
 #endif
-#include <math.h>
 #include <algorithm>
 #include <array>
+#include <cmath>
+#include <cstdint>
 #include <functional>
 #include <numeric>
 
diff --git a/modules/audio_processing/aec3/comfort_noise_generator.h b/modules/audio_processing/aec3/comfort_noise_generator.h
index 6a47989..3be386b 100644
--- a/modules/audio_processing/aec3/comfort_noise_generator.h
+++ b/modules/audio_processing/aec3/comfort_noise_generator.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_COMFORT_NOISE_GENERATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_COMFORT_NOISE_GENERATOR_H_
 
+#include <stdint.h>
 #include <array>
 #include <memory>
 
diff --git a/modules/audio_processing/aec3/decimator.cc b/modules/audio_processing/aec3/decimator.cc
index d9faa62..bd03237 100644
--- a/modules/audio_processing/aec3/decimator.cc
+++ b/modules/audio_processing/aec3/decimator.cc
@@ -9,6 +9,10 @@
  */
 #include "modules/audio_processing/aec3/decimator.h"
 
+#include <array>
+#include <vector>
+
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/downsampled_render_buffer.cc b/modules/audio_processing/aec3/downsampled_render_buffer.cc
index df0af6e..c105911 100644
--- a/modules/audio_processing/aec3/downsampled_render_buffer.cc
+++ b/modules/audio_processing/aec3/downsampled_render_buffer.cc
@@ -10,6 +10,8 @@
 
 #include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 
+#include <algorithm>
+
 namespace webrtc {
 
 DownsampledRenderBuffer::DownsampledRenderBuffer(size_t downsampled_buffer_size)
diff --git a/modules/audio_processing/aec3/downsampled_render_buffer.h b/modules/audio_processing/aec3/downsampled_render_buffer.h
index 9439496..c91ea3b 100644
--- a/modules/audio_processing/aec3/downsampled_render_buffer.h
+++ b/modules/audio_processing/aec3/downsampled_render_buffer.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_DOWNSAMPLED_RENDER_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_DOWNSAMPLED_RENDER_BUFFER_H_
 
+#include <stddef.h>
 #include <vector>
 
-#include "modules/audio_processing/aec3/aec3_common.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/echo_audibility.cc b/modules/audio_processing/aec3/echo_audibility.cc
index fa123de..e857a7e 100644
--- a/modules/audio_processing/aec3/echo_audibility.cc
+++ b/modules/audio_processing/aec3/echo_audibility.cc
@@ -12,8 +12,10 @@
 
 #include <algorithm>
 #include <cmath>
+#include <utility>
+#include <vector>
 
-#include "modules/audio_processing/aec3/aec3_common.h"
+#include "api/array_view.h"
 #include "modules/audio_processing/aec3/matrix_buffer.h"
 #include "modules/audio_processing/aec3/stationarity_estimator.h"
 #include "modules/audio_processing/aec3/vector_buffer.h"
@@ -27,16 +29,18 @@
 
 EchoAudibility::~EchoAudibility() = default;
 
-void EchoAudibility::Update(const RenderBuffer& render_buffer,
-                            int delay_blocks,
-                            bool external_delay_seen,
-                            float reverb_decay) {
+void EchoAudibility::Update(
+    const RenderBuffer& render_buffer,
+    rtc::ArrayView<const float> render_reverb_contribution_spectrum,
+    int delay_blocks,
+    bool external_delay_seen) {
   UpdateRenderNoiseEstimator(render_buffer.GetSpectrumBuffer(),
                              render_buffer.GetBlockBuffer(),
                              external_delay_seen);
 
   if (external_delay_seen || use_render_stationarity_at_init_) {
-    UpdateRenderStationarityFlags(render_buffer, delay_blocks, reverb_decay);
+    UpdateRenderStationarityFlags(
+        render_buffer, render_reverb_contribution_spectrum, delay_blocks);
   }
 }
 
@@ -48,8 +52,8 @@
 
 void EchoAudibility::UpdateRenderStationarityFlags(
     const RenderBuffer& render_buffer,
-    int delay_blocks,
-    float reverb_decay) {
+    rtc::ArrayView<const float> render_reverb_contribution_spectrum,
+    int delay_blocks) {
   const VectorBuffer& spectrum_buffer = render_buffer.GetSpectrumBuffer();
   int idx_at_delay =
       spectrum_buffer.OffsetIndex(spectrum_buffer.read, delay_blocks);
@@ -57,8 +61,9 @@
   int num_lookahead = render_buffer.Headroom() - delay_blocks + 1;
   num_lookahead = std::max(0, num_lookahead);
 
-  render_stationarity_.UpdateStationarityFlags(spectrum_buffer, idx_at_delay,
-                                               num_lookahead, reverb_decay);
+  render_stationarity_.UpdateStationarityFlags(
+      spectrum_buffer, render_reverb_contribution_spectrum, idx_at_delay,
+      num_lookahead);
 }
 
 void EchoAudibility::UpdateRenderNoiseEstimator(
diff --git a/modules/audio_processing/aec3/echo_audibility.h b/modules/audio_processing/aec3/echo_audibility.h
index 3b252f3..b903ca0 100644
--- a/modules/audio_processing/aec3/echo_audibility.h
+++ b/modules/audio_processing/aec3/echo_audibility.h
@@ -11,11 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_AUDIBILITY_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ECHO_AUDIBILITY_H_
 
-#include <algorithm>
-#include <array>
-#include <limits>
-#include <memory>
-#include <vector>
+#include <stddef.h>
 
 #include "absl/types/optional.h"
 #include "api/array_view.h"
@@ -27,8 +23,6 @@
 
 namespace webrtc {
 
-class ApmDataDumper;
-
 class EchoAudibility {
  public:
   explicit EchoAudibility(bool use_render_stationarity_at_init);
@@ -36,9 +30,9 @@
 
   // Feed new render data to the echo audibility estimator.
   void Update(const RenderBuffer& render_buffer,
+              rtc::ArrayView<const float> render_reverb_contribution_spectrum,
               int delay_blocks,
-              bool external_delay_seen,
-              float reverb_decay);
+              bool external_delay_seen);
   // Get the residual echo scaling.
   void GetResidualEchoScaling(bool filter_has_had_time_to_converge,
                               rtc::ArrayView<float> residual_scaling) const {
@@ -62,9 +56,10 @@
   void Reset();
 
   // Updates the render stationarity flags for the current frame.
-  void UpdateRenderStationarityFlags(const RenderBuffer& render_buffer,
-                                     int delay_blocks,
-                                     float reverb_decay);
+  void UpdateRenderStationarityFlags(
+      const RenderBuffer& render_buffer,
+      rtc::ArrayView<const float> render_reverb_contribution_spectrum,
+      int delay_blocks);
 
   // Updates the noise estimator with the new render data since the previous
   // call to this method.
diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc
index 857587a..5debcda 100644
--- a/modules/audio_processing/aec3/echo_canceller3.cc
+++ b/modules/audio_processing/aec3/echo_canceller3.cc
@@ -9,9 +9,12 @@
  */
 #include "modules/audio_processing/aec3/echo_canceller3.h"
 
+#include <algorithm>
+#include <utility>
+
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
-#include "rtc_base/logging.h"
 #include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
@@ -41,19 +44,6 @@
   return !field_trial::IsEnabled("WebRTC-Aec3ReverbModellingKillSwitch");
 }
 
-bool EnableSuppressorNearendAveraging() {
-  return !field_trial::IsEnabled(
-      "WebRTC-Aec3SuppressorNearendAveragingKillSwitch");
-}
-
-bool EnableSlowFilterAdaptation() {
-  return !field_trial::IsEnabled("WebRTC-Aec3SlowFilterAdaptationKillSwitch");
-}
-
-bool EnableShadowFilterJumpstart() {
-  return !field_trial::IsEnabled("WebRTC-Aec3ShadowFilterJumpstartKillSwitch");
-}
-
 bool EnableUnityInitialRampupGain() {
   return field_trial::IsEnabled("WebRTC-Aec3EnableUnityInitialRampupGain");
 }
@@ -78,22 +68,24 @@
   return field_trial::IsEnabled("WebRTC-Aec3UseLegacyNormalSuppressorTuning");
 }
 
-bool ActivateStationarityProperties() {
-  return field_trial::IsEnabled("WebRTC-Aec3UseStationarityProperties");
+bool DeactivateStationarityProperties() {
+  return field_trial::IsEnabled(
+      "WebRTC-Aec3UseStationarityPropertiesKillSwitch");
 }
 
-bool ActivateStationarityPropertiesAtInit() {
-  return field_trial::IsEnabled("WebRTC-Aec3UseStationarityPropertiesAtInit");
-}
-
-bool UseEarlyDelayDetection() {
-  return !field_trial::IsEnabled("WebRTC-Aec3EarlyDelayDetectionKillSwitch");
+bool DeactivateStationarityPropertiesAtInit() {
+  return field_trial::IsEnabled(
+      "WebRTC-Aec3UseStationarityPropertiesAtInitKillSwitch");
 }
 
 bool EnableNewRenderBuffering() {
   return !field_trial::IsEnabled("WebRTC-Aec3NewRenderBufferingKillSwitch");
 }
 
+bool UseEarlyDelayDetection() {
+  return !field_trial::IsEnabled("WebRTC-Aec3EarlyDelayDetectionKillSwitch");
+}
+
 // Method for adjusting config parameter dependencies..
 EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
   EchoCanceller3Config adjusted_cfg = config;
@@ -119,30 +111,6 @@
     adjusted_cfg.ep_strength.reverb_based_on_render = false;
   }
 
-  if (!EnableSuppressorNearendAveraging()) {
-    adjusted_cfg.suppressor.nearend_average_blocks = 1;
-  }
-
-  if (!EnableSlowFilterAdaptation()) {
-    if (!EnableShadowFilterJumpstart()) {
-      adjusted_cfg.filter.main.leakage_converged = 0.005f;
-      adjusted_cfg.filter.main.leakage_diverged = 0.1f;
-    }
-    adjusted_cfg.filter.main_initial.leakage_converged = 0.05f;
-    adjusted_cfg.filter.main_initial.leakage_diverged = 5.f;
-  }
-
-  if (!EnableShadowFilterJumpstart()) {
-    if (EnableSlowFilterAdaptation()) {
-      adjusted_cfg.filter.main.leakage_converged = 0.0005f;
-      adjusted_cfg.filter.main.leakage_diverged = 0.01f;
-    } else {
-      adjusted_cfg.filter.main.leakage_converged = 0.005f;
-      adjusted_cfg.filter.main.leakage_diverged = 0.1f;
-    }
-    adjusted_cfg.filter.main.error_floor = 0.001f;
-  }
-
   if (!EnableNewFilterParams()) {
     adjusted_cfg.filter.main.leakage_diverged = 0.01f;
     adjusted_cfg.filter.main.error_floor = 0.1f;
@@ -186,12 +154,15 @@
     adjusted_cfg.suppressor.dominant_nearend_detection.hold_duration = 25;
   }
 
-  if (ActivateStationarityProperties()) {
-    adjusted_cfg.echo_audibility.use_stationary_properties = true;
+  // TODO(peah): Clean this up once upstream dependencies that forces this to
+  // zero are resolved.
+  adjusted_cfg.echo_audibility.use_stationary_properties = true;
+  if (DeactivateStationarityProperties()) {
+    adjusted_cfg.echo_audibility.use_stationary_properties = false;
   }
 
-  if (ActivateStationarityPropertiesAtInit()) {
-    adjusted_cfg.echo_audibility.use_stationarity_properties_at_init = true;
+  if (DeactivateStationarityPropertiesAtInit()) {
+    adjusted_cfg.echo_audibility.use_stationarity_properties_at_init = false;
   }
 
   if (!UseEarlyDelayDetection()) {
diff --git a/modules/audio_processing/aec3/echo_canceller3.h b/modules/audio_processing/aec3/echo_canceller3.h
index f5520ba..0d07702 100644
--- a/modules/audio_processing/aec3/echo_canceller3.h
+++ b/modules/audio_processing/aec3/echo_canceller3.h
@@ -11,7 +11,13 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_CANCELLER3_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ECHO_CANCELLER3_H_
 
+#include <stddef.h>
+#include <memory>
+#include <vector>
+
+#include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
+#include "api/audio/echo_control.h"
 #include "modules/audio_processing/aec3/block_delay_buffer.h"
 #include "modules/audio_processing/aec3/block_framer.h"
 #include "modules/audio_processing/aec3/block_processor.h"
@@ -19,9 +25,11 @@
 #include "modules/audio_processing/aec3/frame_blocker.h"
 #include "modules/audio_processing/audio_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/race_checker.h"
 #include "rtc_base/swap_queue.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator.cc b/modules/audio_processing/aec3/echo_path_delay_estimator.cc
index 891f15e..5c838ae 100644
--- a/modules/audio_processing/aec3/echo_path_delay_estimator.cc
+++ b/modules/audio_processing/aec3/echo_path_delay_estimator.cc
@@ -9,31 +9,21 @@
  */
 #include "modules/audio_processing/aec3/echo_path_delay_estimator.h"
 
-#include <algorithm>
 #include <array>
 
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
-namespace {
-size_t GetDownSamplingFactor(const EchoCanceller3Config& config) {
-  // Do not use down sampling factor 8 if kill switch is triggered.
-  return (config.delay.down_sampling_factor == 8 &&
-          field_trial::IsEnabled("WebRTC-Aec3DownSamplingFactor8KillSwitch"))
-             ? 4
-             : config.delay.down_sampling_factor;
-}
-}  // namespace
 
 EchoPathDelayEstimator::EchoPathDelayEstimator(
     ApmDataDumper* data_dumper,
     const EchoCanceller3Config& config)
     : data_dumper_(data_dumper),
-      down_sampling_factor_(GetDownSamplingFactor(config)),
+      down_sampling_factor_(config.delay.down_sampling_factor),
       sub_block_size_(down_sampling_factor_ != 0
                           ? kBlockSize / down_sampling_factor_
                           : kBlockSize),
@@ -45,7 +35,7 @@
           kMatchedFilterWindowSizeSubBlocks,
           config.delay.num_filters,
           kMatchedFilterAlignmentShiftSizeSubBlocks,
-          GetDownSamplingFactor(config) == 8
+          config.delay.down_sampling_factor == 8
               ? config.render_levels.poor_excitation_render_limit_ds8
               : config.render_levels.poor_excitation_render_limit,
           config.delay.delay_estimate_smoothing,
diff --git a/modules/audio_processing/aec3/echo_path_delay_estimator.h b/modules/audio_processing/aec3/echo_path_delay_estimator.h
index 55d82be..060c875 100644
--- a/modules/audio_processing/aec3/echo_path_delay_estimator.h
+++ b/modules/audio_processing/aec3/echo_path_delay_estimator.h
@@ -11,13 +11,12 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_PATH_DELAY_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ECHO_PATH_DELAY_ESTIMATOR_H_
 
-#include <vector>
+#include <stddef.h>
 
 #include "absl/types/optional.h"
-#include "api/audio/echo_canceller3_config.h"
+#include "api/array_view.h"
 #include "modules/audio_processing/aec3/decimator.h"
 #include "modules/audio_processing/aec3/delay_estimate.h"
-#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 #include "modules/audio_processing/aec3/matched_filter.h"
 #include "modules/audio_processing/aec3/matched_filter_lag_aggregator.h"
 #include "rtc_base/constructormagic.h"
@@ -25,6 +24,8 @@
 namespace webrtc {
 
 class ApmDataDumper;
+struct DownsampledRenderBuffer;
+struct EchoCanceller3Config;
 
 // Estimates the delay of the echo path.
 class EchoPathDelayEstimator {
diff --git a/modules/audio_processing/aec3/echo_remover.cc b/modules/audio_processing/aec3/echo_remover.cc
index 063c476..cfb7395 100644
--- a/modules/audio_processing/aec3/echo_remover.cc
+++ b/modules/audio_processing/aec3/echo_remover.cc
@@ -10,26 +10,29 @@
 #include "modules/audio_processing/aec3/echo_remover.h"
 
 #include <math.h>
+#include <stddef.h>
 #include <algorithm>
+#include <array>
 #include <memory>
-#include <numeric>
-#include <string>
 
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/aec3/aec3_fft.h"
 #include "modules/audio_processing/aec3/aec_state.h"
 #include "modules/audio_processing/aec3/comfort_noise_generator.h"
 #include "modules/audio_processing/aec3/echo_path_variability.h"
 #include "modules/audio_processing/aec3/echo_remover_metrics.h"
 #include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
-#include "modules/audio_processing/aec3/render_delay_buffer.h"
+#include "modules/audio_processing/aec3/render_signal_analyzer.h"
 #include "modules/audio_processing/aec3/residual_echo_estimator.h"
 #include "modules/audio_processing/aec3/subtractor.h"
+#include "modules/audio_processing/aec3/subtractor_output.h"
 #include "modules/audio_processing/aec3/suppression_filter.h"
 #include "modules/audio_processing/aec3/suppression_gain.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/logging.h"
 #include "system_wrappers/include/field_trial.h"
diff --git a/modules/audio_processing/aec3/echo_remover_metrics.cc b/modules/audio_processing/aec3/echo_remover_metrics.cc
index a04026b..da7a224 100644
--- a/modules/audio_processing/aec3/echo_remover_metrics.cc
+++ b/modules/audio_processing/aec3/echo_remover_metrics.cc
@@ -11,9 +11,11 @@
 #include "modules/audio_processing/aec3/echo_remover_metrics.h"
 
 #include <math.h>
+#include <stddef.h>
 #include <algorithm>
 #include <numeric>
 
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 #include "system_wrappers/include/metrics.h"
 
diff --git a/modules/audio_processing/aec3/echo_remover_metrics.h b/modules/audio_processing/aec3/echo_remover_metrics.h
index 17b803a..0707a5f 100644
--- a/modules/audio_processing/aec3/echo_remover_metrics.h
+++ b/modules/audio_processing/aec3/echo_remover_metrics.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_METRICS_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ECHO_REMOVER_METRICS_H_
 
+#include <array>
+
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec_state.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_processing/aec3/erl_estimator.cc b/modules/audio_processing/aec3/erl_estimator.cc
index 2da9cd8..85b1e02 100644
--- a/modules/audio_processing/aec3/erl_estimator.cc
+++ b/modules/audio_processing/aec3/erl_estimator.cc
@@ -13,6 +13,8 @@
 #include <algorithm>
 #include <numeric>
 
+#include "rtc_base/checks.h"
+
 namespace webrtc {
 
 namespace {
diff --git a/modules/audio_processing/aec3/erl_estimator.h b/modules/audio_processing/aec3/erl_estimator.h
index dacd546..29718c3 100644
--- a/modules/audio_processing/aec3/erl_estimator.h
+++ b/modules/audio_processing/aec3/erl_estimator.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ERL_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ERL_ESTIMATOR_H_
 
+#include <stddef.h>
 #include <array>
 
 #include "api/array_view.h"
diff --git a/modules/audio_processing/aec3/erle_estimator.cc b/modules/audio_processing/aec3/erle_estimator.cc
index 711085f..539a59b 100644
--- a/modules/audio_processing/aec3/erle_estimator.cc
+++ b/modules/audio_processing/aec3/erle_estimator.cc
@@ -13,6 +13,7 @@
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
@@ -36,15 +37,15 @@
   }
 }
 
-void ErleEstimator::Update(rtc::ArrayView<const float> render_spectrum,
+void ErleEstimator::Update(rtc::ArrayView<const float> reverb_render_spectrum,
                            rtc::ArrayView<const float> capture_spectrum,
                            rtc::ArrayView<const float> subtractor_spectrum,
                            bool converged_filter,
                            bool onset_detection) {
-  RTC_DCHECK_EQ(kFftLengthBy2Plus1, render_spectrum.size());
+  RTC_DCHECK_EQ(kFftLengthBy2Plus1, reverb_render_spectrum.size());
   RTC_DCHECK_EQ(kFftLengthBy2Plus1, capture_spectrum.size());
   RTC_DCHECK_EQ(kFftLengthBy2Plus1, subtractor_spectrum.size());
-  const auto& X2 = render_spectrum;
+  const auto& X2_reverb = reverb_render_spectrum;
   const auto& Y2 = capture_spectrum;
   const auto& E2 = subtractor_spectrum;
 
@@ -52,8 +53,9 @@
     return;
   }
 
-  subband_erle_estimator_.Update(X2, Y2, E2, converged_filter, onset_detection);
-  fullband_erle_estimator_.Update(X2, Y2, E2, converged_filter);
+  subband_erle_estimator_.Update(X2_reverb, Y2, E2, converged_filter,
+                                 onset_detection);
+  fullband_erle_estimator_.Update(X2_reverb, Y2, E2, converged_filter);
 }
 
 void ErleEstimator::Dump(
diff --git a/modules/audio_processing/aec3/erle_estimator.h b/modules/audio_processing/aec3/erle_estimator.h
index 8ca605f..2d2c3ae 100644
--- a/modules/audio_processing/aec3/erle_estimator.h
+++ b/modules/audio_processing/aec3/erle_estimator.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_ERLE_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_ERLE_ESTIMATOR_H_
 
+#include <stddef.h>
 #include <array>
 #include <memory>
 
@@ -37,7 +38,7 @@
   void Reset(bool delay_change);
 
   // Updates the ERLE estimates.
-  void Update(rtc::ArrayView<const float> render_spectrum,
+  void Update(rtc::ArrayView<const float> reverb_render_spectrum,
               rtc::ArrayView<const float> capture_spectrum,
               rtc::ArrayView<const float> subtractor_spectrum,
               bool converged_filter,
diff --git a/modules/audio_processing/aec3/fft_buffer.h b/modules/audio_processing/aec3/fft_buffer.h
index 47ede41..9f81a91 100644
--- a/modules/audio_processing/aec3/fft_buffer.h
+++ b/modules/audio_processing/aec3/fft_buffer.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_FFT_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_FFT_BUFFER_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "modules/audio_processing/aec3/fft_data.h"
diff --git a/modules/audio_processing/aec3/filter_analyzer.cc b/modules/audio_processing/aec3/filter_analyzer.cc
index 790cb1e..5b890d7 100644
--- a/modules/audio_processing/aec3/filter_analyzer.cc
+++ b/modules/audio_processing/aec3/filter_analyzer.cc
@@ -16,6 +16,7 @@
 #include <numeric>
 
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/aec3/render_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/aec3/filter_analyzer.h b/modules/audio_processing/aec3/filter_analyzer.h
index 47e9533..99a0e25 100644
--- a/modules/audio_processing/aec3/filter_analyzer.h
+++ b/modules/audio_processing/aec3/filter_analyzer.h
@@ -11,20 +11,20 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
 
+#include <stddef.h>
 #include <array>
+#include <memory>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/aec3/cascaded_biquad_filter.h"
-#include "modules/audio_processing/aec3/render_buffer.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
 class ApmDataDumper;
+class RenderBuffer;
 
 // Class for analyzing the properties of an adaptive filter.
 class FilterAnalyzer {
diff --git a/modules/audio_processing/aec3/frame_blocker.cc b/modules/audio_processing/aec3/frame_blocker.cc
index 0a0c0e2..ca122e5 100644
--- a/modules/audio_processing/aec3/frame_blocker.cc
+++ b/modules/audio_processing/aec3/frame_blocker.cc
@@ -10,8 +10,7 @@
 
 #include "modules/audio_processing/aec3/frame_blocker.h"
 
-#include <algorithm>
-
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/fullband_erle_estimator.cc b/modules/audio_processing/aec3/fullband_erle_estimator.cc
index db9be7c..dc74509 100644
--- a/modules/audio_processing/aec3/fullband_erle_estimator.cc
+++ b/modules/audio_processing/aec3/fullband_erle_estimator.cc
@@ -18,6 +18,7 @@
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/main_filter_update_gain.cc b/modules/audio_processing/aec3/main_filter_update_gain.cc
index ec5347e..ef87d14 100644
--- a/modules/audio_processing/aec3/main_filter_update_gain.cc
+++ b/modules/audio_processing/aec3/main_filter_update_gain.cc
@@ -13,7 +13,12 @@
 #include <algorithm>
 #include <functional>
 
+#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/aec3/echo_path_variability.h"
+#include "modules/audio_processing/aec3/fft_data.h"
+#include "modules/audio_processing/aec3/render_signal_analyzer.h"
+#include "modules/audio_processing/aec3/subtractor_output.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/aec3/main_filter_update_gain.h b/modules/audio_processing/aec3/main_filter_update_gain.h
index 525b522..892ff68 100644
--- a/modules/audio_processing/aec3/main_filter_update_gain.h
+++ b/modules/audio_processing/aec3/main_filter_update_gain.h
@@ -11,20 +11,22 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MAIN_FILTER_UPDATE_GAIN_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MAIN_FILTER_UPDATE_GAIN_H_
 
+#include <stddef.h>
+#include <array>
 #include <memory>
-#include <vector>
 
 #include "api/audio/echo_canceller3_config.h"
-#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/aec3/echo_path_variability.h"
-#include "modules/audio_processing/aec3/render_signal_analyzer.h"
-#include "modules/audio_processing/aec3/subtractor_output.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
+class AdaptiveFirFilter;
 class ApmDataDumper;
+struct EchoPathVariability;
+struct FftData;
+class RenderSignalAnalyzer;
+struct SubtractorOutput;
 
 // Provides functionality for  computing the adaptive gain for the main filter.
 class MainFilterUpdateGain {
diff --git a/modules/audio_processing/aec3/matched_filter.cc b/modules/audio_processing/aec3/matched_filter.cc
index 6744bd5..757219d 100644
--- a/modules/audio_processing/aec3/matched_filter.cc
+++ b/modules/audio_processing/aec3/matched_filter.cc
@@ -19,10 +19,14 @@
 #include <emmintrin.h>
 #endif
 #include <algorithm>
+#include <cstddef>
+#include <initializer_list>
+#include <iterator>
 #include <numeric>
 
-#include "api/audio/echo_canceller3_config.h"
+#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/matched_filter.h b/modules/audio_processing/aec3/matched_filter.h
index 2ef4828..2a65339 100644
--- a/modules/audio_processing/aec3/matched_filter.h
+++ b/modules/audio_processing/aec3/matched_filter.h
@@ -11,18 +11,19 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MATCHED_FILTER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MATCHED_FILTER_H_
 
-#include <array>
-#include <memory>
+#include <stddef.h>
 #include <vector>
 
-#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/system/arch.h"
 
 namespace webrtc {
+
+class ApmDataDumper;
+struct DownsampledRenderBuffer;
+
 namespace aec3 {
 
 #if defined(WEBRTC_HAS_NEON)
@@ -65,7 +66,6 @@
 
 }  // namespace aec3
 
-class ApmDataDumper;
 
 // Produces recursively updated cross-correlation estimates for several signal
 // shifts where the intra-shift spacing is uniform.
diff --git a/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc b/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc
index 0a73768..f59525e 100644
--- a/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc
+++ b/modules/audio_processing/aec3/matched_filter_lag_aggregator.cc
@@ -9,7 +9,11 @@
  */
 #include "modules/audio_processing/aec3/matched_filter_lag_aggregator.h"
 
+#include <algorithm>
+#include <iterator>
+
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/matrix_buffer.cc b/modules/audio_processing/aec3/matrix_buffer.cc
index f95e7f4..bd6daea 100644
--- a/modules/audio_processing/aec3/matrix_buffer.cc
+++ b/modules/audio_processing/aec3/matrix_buffer.cc
@@ -10,7 +10,7 @@
 
 #include "modules/audio_processing/aec3/matrix_buffer.h"
 
-#include "modules/audio_processing/aec3/aec3_common.h"
+#include <algorithm>
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/matrix_buffer.h b/modules/audio_processing/aec3/matrix_buffer.h
index 64aac0a..cae3759 100644
--- a/modules/audio_processing/aec3/matrix_buffer.h
+++ b/modules/audio_processing/aec3/matrix_buffer.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MATRIX_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MATRIX_BUFFER_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/aec3/moving_average.cc b/modules/audio_processing/aec3/moving_average.cc
index e9d64e6..7a81ee8 100644
--- a/modules/audio_processing/aec3/moving_average.cc
+++ b/modules/audio_processing/aec3/moving_average.cc
@@ -14,6 +14,8 @@
 #include <algorithm>
 #include <functional>
 
+#include "rtc_base/checks.h"
+
 namespace webrtc {
 namespace aec3 {
 
diff --git a/modules/audio_processing/aec3/moving_average.h b/modules/audio_processing/aec3/moving_average.h
index 94497d7..0f855be 100644
--- a/modules/audio_processing/aec3/moving_average.h
+++ b/modules/audio_processing/aec3/moving_average.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_MOVING_AVERAGE_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_MOVING_AVERAGE_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "api/array_view.h"
diff --git a/modules/audio_processing/aec3/render_buffer.h b/modules/audio_processing/aec3/render_buffer.h
index dd67268..4c7c60c 100644
--- a/modules/audio_processing/aec3/render_buffer.h
+++ b/modules/audio_processing/aec3/render_buffer.h
@@ -11,14 +11,17 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_RENDER_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_RENDER_BUFFER_H_
 
+#include <stddef.h>
 #include <array>
-#include <memory>
+#include <vector>
 
 #include "api/array_view.h"
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/fft_buffer.h"
 #include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/aec3/matrix_buffer.h"
 #include "modules/audio_processing/aec3/vector_buffer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/render_delay_buffer.cc b/modules/audio_processing/aec3/render_delay_buffer.cc
index 37a2378..1ec2779 100644
--- a/modules/audio_processing/aec3/render_delay_buffer.cc
+++ b/modules/audio_processing/aec3/render_delay_buffer.cc
@@ -10,17 +10,21 @@
 
 #include "modules/audio_processing/aec3/render_delay_buffer.h"
 
-#include <string.h>
+#include <stdlib.h>
 #include <algorithm>
+#include <memory>
 #include <numeric>
 
+#include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec3_fft.h"
-#include "modules/audio_processing/aec3/block_processor.h"
 #include "modules/audio_processing/aec3/decimator.h"
 #include "modules/audio_processing/aec3/fft_buffer.h"
 #include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/aec3/matrix_buffer.h"
+#include "modules/audio_processing/aec3/vector_buffer.h"
+#include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
@@ -35,14 +39,6 @@
       "WebRTC-Aec3ZeroExternalDelayHeadroomKillSwitch");
 }
 
-size_t GetDownSamplingFactor(const EchoCanceller3Config& config) {
-  // Do not use down sampling factor 8 if kill switch is triggered.
-  return (config.delay.down_sampling_factor == 8 &&
-          field_trial::IsEnabled("WebRTC-Aec3DownSamplingFactor8KillSwitch"))
-             ? 4
-             : config.delay.down_sampling_factor;
-}
-
 class RenderDelayBufferImpl final : public RenderDelayBuffer {
  public:
   RenderDelayBufferImpl(const EchoCanceller3Config& config, size_t num_bands);
@@ -177,7 +173,7 @@
           new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
       optimization_(DetectOptimization()),
       config_(config),
-      down_sampling_factor_(GetDownSamplingFactor(config)),
+      down_sampling_factor_(config.delay.down_sampling_factor),
       use_zero_external_delay_headroom_(EnableZeroExternalDelayHeadroom()),
       sub_block_size_(static_cast<int>(down_sampling_factor_ > 0
                                            ? kBlockSize / down_sampling_factor_
diff --git a/modules/audio_processing/aec3/render_delay_buffer.h b/modules/audio_processing/aec3/render_delay_buffer.h
index 8c5667e..bd242f7 100644
--- a/modules/audio_processing/aec3/render_delay_buffer.h
+++ b/modules/audio_processing/aec3/render_delay_buffer.h
@@ -12,15 +12,10 @@
 #define MODULES_AUDIO_PROCESSING_AEC3_RENDER_DELAY_BUFFER_H_
 
 #include <stddef.h>
-#include <array>
 #include <vector>
 
-#include "absl/types/optional.h"
-#include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
-#include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/downsampled_render_buffer.h"
-#include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/render_delay_controller.cc b/modules/audio_processing/aec3/render_delay_controller.cc
index 646acde..36e75d9 100644
--- a/modules/audio_processing/aec3/render_delay_controller.cc
+++ b/modules/audio_processing/aec3/render_delay_controller.cc
@@ -9,10 +9,9 @@
  */
 #include "modules/audio_processing/aec3/render_delay_controller.h"
 
+#include <stdlib.h>
 #include <algorithm>
 #include <memory>
-#include <numeric>
-#include <string>
 #include <vector>
 
 #include "api/audio/echo_canceller3_config.h"
@@ -20,7 +19,9 @@
 #include "modules/audio_processing/aec3/echo_path_delay_estimator.h"
 #include "modules/audio_processing/aec3/render_delay_controller_metrics.h"
 #include "modules/audio_processing/aec3/skew_estimator.h"
+#include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/logging.h"
 #include "system_wrappers/include/field_trial.h"
diff --git a/modules/audio_processing/aec3/render_delay_controller2.cc b/modules/audio_processing/aec3/render_delay_controller2.cc
index e27d5f3..1b7c18d 100644
--- a/modules/audio_processing/aec3/render_delay_controller2.cc
+++ b/modules/audio_processing/aec3/render_delay_controller2.cc
@@ -127,7 +127,7 @@
   delay_samples_ = absl::nullopt;
   delay_estimator_.Reset(reset_delay_confidence);
   delay_change_counter_ = 0;
-  if (reset_delay_confidence) {
+  if (reset_delay_confidence || true) {
     last_delay_estimate_quality_ = DelayEstimate::Quality::kCoarse;
   }
 }
diff --git a/modules/audio_processing/aec3/render_delay_controller_metrics.cc b/modules/audio_processing/aec3/render_delay_controller_metrics.cc
index 09db339..c51d468 100644
--- a/modules/audio_processing/aec3/render_delay_controller_metrics.cc
+++ b/modules/audio_processing/aec3/render_delay_controller_metrics.cc
@@ -13,6 +13,7 @@
 #include <algorithm>
 
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "rtc_base/checks.h"
 #include "system_wrappers/include/metrics.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/render_delay_controller_metrics.h b/modules/audio_processing/aec3/render_delay_controller_metrics.h
index 1cfe899..50e60bb 100644
--- a/modules/audio_processing/aec3/render_delay_controller_metrics.h
+++ b/modules/audio_processing/aec3/render_delay_controller_metrics.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_RENDER_DELAY_CONTROLLER_METRICS_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_RENDER_DELAY_CONTROLLER_METRICS_H_
 
+#include <stddef.h>
+
 #include "absl/types/optional.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/audio_processing/aec3/render_reverb_model.cc b/modules/audio_processing/aec3/render_reverb_model.cc
new file mode 100644
index 0000000..8ad54c0
--- /dev/null
+++ b/modules/audio_processing/aec3/render_reverb_model.cc
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/audio_processing/aec3/render_reverb_model.h"
+
+#include <algorithm>
+
+#include "api/array_view.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RenderReverbModel::RenderReverbModel() {
+  Reset();
+}
+
+RenderReverbModel::~RenderReverbModel() = default;
+
+void RenderReverbModel::Reset() {
+  render_reverb_.Reset();
+}
+
+void RenderReverbModel::Apply(const VectorBuffer& spectrum_buffer,
+                              int delay_blocks,
+                              float reverb_decay,
+                              rtc::ArrayView<float> reverb_power_spectrum) {
+  int idx_at_delay =
+      spectrum_buffer.OffsetIndex(spectrum_buffer.read, delay_blocks);
+  int idx_past = spectrum_buffer.IncIndex(idx_at_delay);
+  const auto& X2 = spectrum_buffer.buffer[idx_at_delay];
+  RTC_DCHECK_EQ(X2.size(), reverb_power_spectrum.size());
+  std::copy(X2.begin(), X2.end(), reverb_power_spectrum.begin());
+  render_reverb_.AddReverbNoFreqShaping(spectrum_buffer.buffer[idx_past], 1.0f,
+                                        reverb_decay, reverb_power_spectrum);
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_processing/aec3/render_reverb_model.h b/modules/audio_processing/aec3/render_reverb_model.h
new file mode 100644
index 0000000..d404a69
--- /dev/null
+++ b/modules/audio_processing/aec3/render_reverb_model.h
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef MODULES_AUDIO_PROCESSING_AEC3_RENDER_REVERB_MODEL_H_
+#define MODULES_AUDIO_PROCESSING_AEC3_RENDER_REVERB_MODEL_H_
+
+#include "api/array_view.h"
+#include "modules/audio_processing/aec3/reverb_model.h"
+#include "modules/audio_processing/aec3/vector_buffer.h"
+
+namespace webrtc {
+
+// The RenderReverbModel class applies an exponential reverberant model over the
+// render spectrum.
+class RenderReverbModel {
+ public:
+  RenderReverbModel();
+  ~RenderReverbModel();
+
+  // Resets the state.
+  void Reset();
+
+  // Applies the reverberation model over the render spectrum. It also returns
+  // the reverberation render power spectrum in the array reverb_power_spectrum.
+  void Apply(const VectorBuffer& spectrum_buffer,
+             int delay_blocks,
+             float reverb_decay,
+             rtc::ArrayView<float> reverb_power_spectrum);
+
+  // Gets the reverberation spectrum that was added to the render spectrum for
+  // computing the reverberation render spectrum.
+  rtc::ArrayView<const float> GetReverbContributionPowerSpectrum() const {
+    return render_reverb_.GetPowerSpectrum();
+  }
+
+ private:
+  ReverbModel render_reverb_;
+};
+
+}  // namespace webrtc.
+
+#endif  // MODULES_AUDIO_PROCESSING_AEC3_RENDER_REVERB_MODEL_H_
diff --git a/modules/audio_processing/aec3/render_signal_analyzer.cc b/modules/audio_processing/aec3/render_signal_analyzer.cc
index 50c34ce..33b04bf 100644
--- a/modules/audio_processing/aec3/render_signal_analyzer.cc
+++ b/modules/audio_processing/aec3/render_signal_analyzer.cc
@@ -12,7 +12,10 @@
 
 #include <math.h>
 #include <algorithm>
+#include <utility>
+#include <vector>
 
+#include "api/array_view.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/render_signal_analyzer.h b/modules/audio_processing/aec3/render_signal_analyzer.h
index c603c92..8a44232 100644
--- a/modules/audio_processing/aec3/render_signal_analyzer.h
+++ b/modules/audio_processing/aec3/render_signal_analyzer.h
@@ -11,13 +11,15 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_RENDER_SIGNAL_ANALYZER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_RENDER_SIGNAL_ANALYZER_H_
 
+#include <algorithm>
 #include <array>
-#include <memory>
+#include <cstddef>
 
 #include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/residual_echo_estimator.cc b/modules/audio_processing/aec3/residual_echo_estimator.cc
index 7b063c1..627dd90 100644
--- a/modules/audio_processing/aec3/residual_echo_estimator.cc
+++ b/modules/audio_processing/aec3/residual_echo_estimator.cc
@@ -11,9 +11,11 @@
 
 #include "modules/audio_processing/aec3/residual_echo_estimator.h"
 
-#include <numeric>
+#include <stddef.h>
+#include <algorithm>
 #include <vector>
 
+#include "api/array_view.h"
 #include "modules/audio_processing/aec3/reverb_model.h"
 #include "modules/audio_processing/aec3/reverb_model_fallback.h"
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/aec3/residual_echo_estimator.h b/modules/audio_processing/aec3/residual_echo_estimator.h
index 6dcf24f..52885a5 100644
--- a/modules/audio_processing/aec3/residual_echo_estimator.h
+++ b/modules/audio_processing/aec3/residual_echo_estimator.h
@@ -11,18 +11,18 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_RESIDUAL_ECHO_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_RESIDUAL_ECHO_ESTIMATOR_H_
 
-#include <algorithm>
 #include <array>
 #include <memory>
-#include <vector>
 
-#include "api/array_view.h"
+#include "absl/types/optional.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec_state.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
 #include "modules/audio_processing/aec3/reverb_model.h"
 #include "modules/audio_processing/aec3/reverb_model_fallback.h"
+#include "modules/audio_processing/aec3/vector_buffer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
@@ -39,7 +39,7 @@
                 std::array<float, kFftLengthBy2Plus1>* R2);
 
   // Returns the reverberant power spectrum contributions to the echo residual.
-  const std::array<float, kFftLengthBy2Plus1>& GetReverbPowerSpectrum() const {
+  rtc::ArrayView<const float> GetReverbPowerSpectrum() const {
     if (echo_reverb_) {
       return echo_reverb_->GetPowerSpectrum();
     } else {
@@ -66,7 +66,6 @@
                          const std::array<float, kFftLengthBy2Plus1>& Y2,
                          std::array<float, kFftLengthBy2Plus1>* R2);
 
-
   // Estimates the echo generating signal power as gated maximal power over a
   // time window.
   void EchoGeneratingPower(const VectorBuffer& spectrum_buffer,
diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.cc b/modules/audio_processing/aec3/reverb_decay_estimator.cc
index f80afa2..95fd13a 100644
--- a/modules/audio_processing/aec3/reverb_decay_estimator.cc
+++ b/modules/audio_processing/aec3/reverb_decay_estimator.cc
@@ -10,11 +10,13 @@
 
 #include "modules/audio_processing/aec3/reverb_decay_estimator.h"
 
+#include <stddef.h>
 #include <algorithm>
 #include <cmath>
 #include <numeric>
 
 #include "api/array_view.h"
+#include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
 #include "system_wrappers/include/field_trial.h"
diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.h b/modules/audio_processing/aec3/reverb_decay_estimator.h
index 67a84ab..4c8d0c6 100644
--- a/modules/audio_processing/aec3/reverb_decay_estimator.h
+++ b/modules/audio_processing/aec3/reverb_decay_estimator.h
@@ -16,12 +16,12 @@
 
 #include "absl/types/optional.h"
 #include "api/array_view.h"
-#include "api/audio/echo_canceller3_config.h"
-#include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/aec3/aec3_common.h"  // kMaxAdaptiveFilter...
 
 namespace webrtc {
 
 class ApmDataDumper;
+struct EchoCanceller3Config;
 
 // Class for estimating the decay of the late reverb.
 class ReverbDecayEstimator {
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.cc b/modules/audio_processing/aec3/reverb_frequency_response.cc
index 0d82515..d2103d4 100644
--- a/modules/audio_processing/aec3/reverb_frequency_response.cc
+++ b/modules/audio_processing/aec3/reverb_frequency_response.cc
@@ -10,14 +10,12 @@
 
 #include "modules/audio_processing/aec3/reverb_frequency_response.h"
 
+#include <stddef.h>
 #include <algorithm>
 #include <array>
-#include <cmath>
-#include <memory>
 #include <numeric>
 
 #include "api/array_view.h"
-#include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "rtc_base/checks.h"
 #include "system_wrappers/include/field_trial.h"
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.h b/modules/audio_processing/aec3/reverb_frequency_response.h
index 23485e0..eb63b8e 100644
--- a/modules/audio_processing/aec3/reverb_frequency_response.h
+++ b/modules/audio_processing/aec3/reverb_frequency_response.h
@@ -11,13 +11,12 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_REVERB_FREQUENCY_RESPONSE_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_FREQUENCY_RESPONSE_H_
 
-#include <memory>
+#include <array>
 #include <vector>
 
 #include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/reverb_model.cc b/modules/audio_processing/aec3/reverb_model.cc
index 0ca248f..f0a24c0 100644
--- a/modules/audio_processing/aec3/reverb_model.cc
+++ b/modules/audio_processing/aec3/reverb_model.cc
@@ -10,13 +10,11 @@
 
 #include "modules/audio_processing/aec3/reverb_model.h"
 
-#include <math.h>
-
+#include <stddef.h>
 #include <algorithm>
 #include <functional>
 
 #include "api/array_view.h"
-#include "modules/audio_processing/aec3/aec3_common.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/reverb_model.h b/modules/audio_processing/aec3/reverb_model.h
index d3087a7..56e2266 100644
--- a/modules/audio_processing/aec3/reverb_model.h
+++ b/modules/audio_processing/aec3/reverb_model.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_H_
 
+#include <array>
+
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 
@@ -50,9 +52,7 @@
       float reverb_decay);
 
   // Returns the current power spectrum reverberation contributions.
-  const std::array<float, kFftLengthBy2Plus1>& GetPowerSpectrum() const {
-    return reverb_;
-  }
+  rtc::ArrayView<const float> GetPowerSpectrum() const { return reverb_; }
 
  private:
   // Updates the reverberation contributions.
diff --git a/modules/audio_processing/aec3/reverb_model_estimator.h b/modules/audio_processing/aec3/reverb_model_estimator.h
index b6a3591..1112f93 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator.h
+++ b/modules/audio_processing/aec3/reverb_model_estimator.h
@@ -11,11 +11,13 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_ESTIMATOR_H_
 
+#include <array>
 #include <vector>
 
 #include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
+#include "modules/audio_processing/aec3/aec3_common.h"  // kFftLengthBy2Plus1
 #include "modules/audio_processing/aec3/reverb_decay_estimator.h"
 #include "modules/audio_processing/aec3/reverb_frequency_response.h"
 
diff --git a/modules/audio_processing/aec3/reverb_model_fallback.h b/modules/audio_processing/aec3/reverb_model_fallback.h
index 1b2a953..1bd2b59 100644
--- a/modules/audio_processing/aec3/reverb_model_fallback.h
+++ b/modules/audio_processing/aec3/reverb_model_fallback.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_FALLBACK_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_FALLBACK_H_
 
+#include <stddef.h>
 #include <array>
 #include <vector>
 
diff --git a/modules/audio_processing/aec3/shadow_filter_update_gain.h b/modules/audio_processing/aec3/shadow_filter_update_gain.h
index a92bc3b..05e632f 100644
--- a/modules/audio_processing/aec3/shadow_filter_update_gain.h
+++ b/modules/audio_processing/aec3/shadow_filter_update_gain.h
@@ -11,11 +11,13 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_SHADOW_FILTER_UPDATE_GAIN_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_SHADOW_FILTER_UPDATE_GAIN_H_
 
+#include <stddef.h>
+#include <array>
+
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/aec3/render_buffer.h"
+#include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/aec3/render_signal_analyzer.h"
-#include "rtc_base/constructormagic.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/skew_estimator.cc b/modules/audio_processing/aec3/skew_estimator.cc
index 310e4e9..a2099fc 100644
--- a/modules/audio_processing/aec3/skew_estimator.cc
+++ b/modules/audio_processing/aec3/skew_estimator.cc
@@ -10,7 +10,6 @@
 #include "modules/audio_processing/aec3/skew_estimator.h"
 
 #include <algorithm>
-#include <numeric>
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/skew_estimator.h b/modules/audio_processing/aec3/skew_estimator.h
index ff25260..b0946d8 100644
--- a/modules/audio_processing/aec3/skew_estimator.h
+++ b/modules/audio_processing/aec3/skew_estimator.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_SKEW_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_SKEW_ESTIMATOR_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "absl/types/optional.h"
diff --git a/modules/audio_processing/aec3/stationarity_estimator.cc b/modules/audio_processing/aec3/stationarity_estimator.cc
index efeabf1..25100bf 100644
--- a/modules/audio_processing/aec3/stationarity_estimator.cc
+++ b/modules/audio_processing/aec3/stationarity_estimator.cc
@@ -14,6 +14,7 @@
 #include <array>
 #include <vector>
 
+#include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/vector_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
@@ -40,7 +41,6 @@
   noise_.Reset();
   hangovers_.fill(0);
   stationarity_flags_.fill(false);
-  render_reverb_.Reset();
 }
 
 // Update just the noise estimator. Usefull until the delay is known
@@ -54,9 +54,9 @@
 
 void StationarityEstimator::UpdateStationarityFlags(
     const VectorBuffer& spectrum_buffer,
+    rtc::ArrayView<const float> render_reverb_contribution_spectrum,
     int idx_current,
-    int num_lookahead,
-    float reverb_decay) {
+    int num_lookahead) {
   std::array<int, kWindowLength> indexes;
   int num_lookahead_bounded = std::min(num_lookahead, kWindowLength - 1);
   int idx = idx_current;
@@ -79,12 +79,9 @@
       spectrum_buffer.DecIndex(indexes[kWindowLength - 1]),
       spectrum_buffer.OffsetIndex(idx_current, -(num_lookahead_bounded + 1)));
 
-  int idx_past = spectrum_buffer.IncIndex(idx_current);
-  render_reverb_.UpdateReverbContributionsNoFreqShaping(
-      spectrum_buffer.buffer[idx_past], 1.0f, reverb_decay);
   for (size_t k = 0; k < stationarity_flags_.size(); ++k) {
     stationarity_flags_[k] = EstimateBandStationarity(
-        spectrum_buffer, render_reverb_.GetPowerSpectrum(), indexes, k);
+        spectrum_buffer, render_reverb_contribution_spectrum, indexes, k);
   }
   UpdateHangover();
   SmoothStationaryPerFreq();
@@ -102,7 +99,7 @@
 
 bool StationarityEstimator::EstimateBandStationarity(
     const VectorBuffer& spectrum_buffer,
-    const std::array<float, kFftLengthBy2Plus1>& reverb,
+    rtc::ArrayView<const float> reverb,
     const std::array<int, kWindowLength>& indexes,
     size_t band) const {
   constexpr float kThrStationarity = 10.f;
diff --git a/modules/audio_processing/aec3/stationarity_estimator.h b/modules/audio_processing/aec3/stationarity_estimator.h
index e2c5a62..704859a 100644
--- a/modules/audio_processing/aec3/stationarity_estimator.h
+++ b/modules/audio_processing/aec3/stationarity_estimator.h
@@ -11,18 +11,19 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_STATIONARITY_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_STATIONARITY_ESTIMATOR_H_
 
+#include <stddef.h>
 #include <array>
 #include <memory>
-#include <vector>
 
 #include "api/array_view.h"
-#include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/aec3/aec3_common.h"  // kFftLengthBy2Plus1...
 #include "modules/audio_processing/aec3/reverb_model.h"
-#include "modules/audio_processing/aec3/vector_buffer.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
 class ApmDataDumper;
+struct VectorBuffer;
 
 class StationarityEstimator {
  public:
@@ -37,10 +38,11 @@
 
   // Update the flag indicating whether this current frame is stationary. For
   // getting a more robust estimation, it looks at future and/or past frames.
-  void UpdateStationarityFlags(const VectorBuffer& spectrum_buffer,
-                               int idx_current,
-                               int num_lookahead,
-                               float reverb_decay);
+  void UpdateStationarityFlags(
+      const VectorBuffer& spectrum_buffer,
+      rtc::ArrayView<const float> render_reverb_contribution_spectrum,
+      int idx_current,
+      int num_lookahead);
 
   // Returns true if the current band is stationary.
   bool IsBandStationary(size_t band) const {
@@ -57,11 +59,10 @@
 
   // Get an estimation of the stationarity for the current band by looking
   // at the past/present/future available data.
-  bool EstimateBandStationarity(
-      const VectorBuffer& spectrum_buffer,
-      const std::array<float, kFftLengthBy2Plus1>& reverb,
-      const std::array<int, kWindowLength>& indexes,
-      size_t band) const;
+  bool EstimateBandStationarity(const VectorBuffer& spectrum_buffer,
+                                rtc::ArrayView<const float> reverb,
+                                const std::array<int, kWindowLength>& indexes,
+                                size_t band) const;
 
   // True if all bands at the current point are stationary.
   bool AreAllBandsStationary();
@@ -111,7 +112,6 @@
   NoiseSpectrum noise_;
   std::array<int, kFftLengthBy2Plus1> hangovers_;
   std::array<bool, kFftLengthBy2Plus1> stationarity_flags_;
-  ReverbModel render_reverb_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/aec3/subband_erle_estimator.cc b/modules/audio_processing/aec3/subband_erle_estimator.cc
index d8cb7a7..2cb5acc 100644
--- a/modules/audio_processing/aec3/subband_erle_estimator.cc
+++ b/modules/audio_processing/aec3/subband_erle_estimator.cc
@@ -17,6 +17,7 @@
 #include "api/array_view.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 #include "system_wrappers/include/field_trial.h"
 
diff --git a/modules/audio_processing/aec3/subband_erle_estimator.h b/modules/audio_processing/aec3/subband_erle_estimator.h
index aa5e5cc..7693b6a 100644
--- a/modules/audio_processing/aec3/subband_erle_estimator.h
+++ b/modules/audio_processing/aec3/subband_erle_estimator.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_SUBBAND_ERLE_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_SUBBAND_ERLE_ESTIMATOR_H_
 
+#include <stddef.h>
 #include <array>
 #include <memory>
 
diff --git a/modules/audio_processing/aec3/subtractor.cc b/modules/audio_processing/aec3/subtractor.cc
index 9856a74..90069c7 100644
--- a/modules/audio_processing/aec3/subtractor.cc
+++ b/modules/audio_processing/aec3/subtractor.cc
@@ -11,12 +11,12 @@
 #include "modules/audio_processing/aec3/subtractor.h"
 
 #include <algorithm>
-#include <numeric>
+#include <utility>
 
 #include "api/array_view.h"
+#include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_minmax.h"
 #include "system_wrappers/include/field_trial.h"
 
diff --git a/modules/audio_processing/aec3/subtractor.h b/modules/audio_processing/aec3/subtractor.h
index c92a971..bec014d 100644
--- a/modules/audio_processing/aec3/subtractor.h
+++ b/modules/audio_processing/aec3/subtractor.h
@@ -11,11 +11,13 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_SUBTRACTOR_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_SUBTRACTOR_H_
 
-#include <algorithm>
+#include <math.h>
+#include <stddef.h>
 #include <array>
 #include <vector>
-#include "math.h"
 
+#include "api/array_view.h"
+#include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/adaptive_fir_filter.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec3_fft.h"
@@ -23,10 +25,11 @@
 #include "modules/audio_processing/aec3/echo_path_variability.h"
 #include "modules/audio_processing/aec3/main_filter_update_gain.h"
 #include "modules/audio_processing/aec3/render_buffer.h"
+#include "modules/audio_processing/aec3/render_signal_analyzer.h"
 #include "modules/audio_processing/aec3/shadow_filter_update_gain.h"
 #include "modules/audio_processing/aec3/subtractor_output.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "modules/audio_processing/utility/ooura_fft.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/subtractor_output_analyzer.cc b/modules/audio_processing/aec3/subtractor_output_analyzer.cc
index 3cacb45..9374b80 100644
--- a/modules/audio_processing/aec3/subtractor_output_analyzer.cc
+++ b/modules/audio_processing/aec3/subtractor_output_analyzer.cc
@@ -10,9 +10,9 @@
 
 #include "modules/audio_processing/aec3/subtractor_output_analyzer.h"
 
-#include <array>
-#include <numeric>
+#include <algorithm>
 
+#include "modules/audio_processing/aec3/aec3_common.h"
 #include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/subtractor_output_analyzer.h b/modules/audio_processing/aec3/subtractor_output_analyzer.h
index b59a68e..0e23ad5 100644
--- a/modules/audio_processing/aec3/subtractor_output_analyzer.h
+++ b/modules/audio_processing/aec3/subtractor_output_analyzer.h
@@ -11,7 +11,6 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_SUBTRACTOR_OUTPUT_ANALYZER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_SUBTRACTOR_OUTPUT_ANALYZER_H_
 
-#include "api/array_view.h"
 #include "modules/audio_processing/aec3/subtractor_output.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/suppression_filter.cc b/modules/audio_processing/aec3/suppression_filter.cc
index 35b7b8c..6fe296c 100644
--- a/modules/audio_processing/aec3/suppression_filter.cc
+++ b/modules/audio_processing/aec3/suppression_filter.cc
@@ -10,15 +10,13 @@
 
 #include "modules/audio_processing/aec3/suppression_filter.h"
 
-#include <math.h>
 #include <algorithm>
 #include <cmath>
 #include <cstring>
 #include <functional>
-#include <numeric>
+#include <iterator>
 
 #include "modules/audio_processing/aec3/vector_math.h"
-#include "modules/audio_processing/utility/ooura_fft.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 
diff --git a/modules/audio_processing/aec3/suppression_filter.h b/modules/audio_processing/aec3/suppression_filter.h
index 1628e3e..edd1290 100644
--- a/modules/audio_processing/aec3/suppression_filter.h
+++ b/modules/audio_processing/aec3/suppression_filter.h
@@ -16,6 +16,8 @@
 
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec3_fft.h"
+#include "modules/audio_processing/aec3/fft_data.h"
+#include "modules/audio_processing/utility/ooura_fft.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/aec3/suppression_gain.cc b/modules/audio_processing/aec3/suppression_gain.cc
index ce7ea33..88cfc0a 100644
--- a/modules/audio_processing/aec3/suppression_gain.cc
+++ b/modules/audio_processing/aec3/suppression_gain.cc
@@ -11,8 +11,8 @@
 #include "modules/audio_processing/aec3/suppression_gain.h"
 
 #include <math.h>
+#include <stddef.h>
 #include <algorithm>
-#include <functional>
 #include <numeric>
 
 #include "modules/audio_processing/aec3/moving_average.h"
@@ -20,15 +20,10 @@
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
-#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 namespace {
 
-bool EnableNewSuppression() {
-  return !field_trial::IsEnabled("WebRTC-Aec3NewSuppressionKillSwitch");
-}
-
 // Adjust the gains according to the presence of known external filters.
 void AdjustForExternalFilters(std::array<float, kFftLengthBy2Plus1>* gain) {
   // Limit the low frequency gains to avoid the impact of the high-pass filter
@@ -83,57 +78,6 @@
   weigh(threshold, normalizer, 7, kFftLengthBy2Plus1, echo, weighted_echo);
 }
 
-// Computes the gain to reduce the echo to a non audible level.
-void GainToNoAudibleEchoFallback(
-    const EchoCanceller3Config& config,
-    bool low_noise_render,
-    bool saturated_echo,
-    bool linear_echo_estimate,
-    const std::array<float, kFftLengthBy2Plus1>& nearend,
-    const std::array<float, kFftLengthBy2Plus1>& weighted_echo,
-    const std::array<float, kFftLengthBy2Plus1>& masker,
-    const std::array<float, kFftLengthBy2Plus1>& min_gain,
-    const std::array<float, kFftLengthBy2Plus1>& max_gain,
-    const std::array<float, kFftLengthBy2Plus1>& one_by_weighted_echo,
-    std::array<float, kFftLengthBy2Plus1>* gain) {
-  float nearend_masking_margin = 0.f;
-  if (linear_echo_estimate) {
-    nearend_masking_margin =
-        low_noise_render
-            ? config.gain_mask.m9
-            : (saturated_echo ? config.gain_mask.m2 : config.gain_mask.m3);
-  } else {
-    nearend_masking_margin = config.gain_mask.m7;
-  }
-
-  RTC_DCHECK_LE(0.f, nearend_masking_margin);
-  RTC_DCHECK_GT(1.f, nearend_masking_margin);
-
-  const float masker_margin =
-      linear_echo_estimate ? config.gain_mask.m0 : config.gain_mask.m8;
-
-  for (size_t k = 0; k < gain->size(); ++k) {
-    // TODO(devicentepena): Experiment by removing the reverberation estimation
-    // from the nearend signal before computing the gains.
-    const float unity_gain_masker = std::max(nearend[k], masker[k]);
-    RTC_DCHECK_LE(0.f, nearend_masking_margin * unity_gain_masker);
-    if (weighted_echo[k] <= nearend_masking_margin * unity_gain_masker ||
-        unity_gain_masker <= 0.f) {
-      (*gain)[k] = 1.f;
-    } else {
-      RTC_DCHECK_LT(0.f, unity_gain_masker);
-      (*gain)[k] =
-          std::max(0.f, (1.f - config.gain_mask.gain_curve_slope *
-                                   weighted_echo[k] / unity_gain_masker) *
-                            config.gain_mask.gain_curve_offset);
-      (*gain)[k] = std::max(masker_margin * masker[k] * one_by_weighted_echo[k],
-                            (*gain)[k]);
-    }
-
-    (*gain)[k] = std::min(std::max((*gain)[k], min_gain[k]), max_gain[k]);
-  }
-}
-
 // TODO(peah): Make adaptive to take the actual filter error into account.
 constexpr size_t kUpperAccurateBandPlus1 = 29;
 
@@ -321,30 +265,9 @@
   std::array<float, kFftLengthBy2Plus1> max_gain;
   GetMaxGain(max_gain);
 
-  // Iteratively compute the gain required to attenuate the echo to a non
-  // noticeable level.
-
-  if (enable_new_suppression_) {
     GainToNoAudibleEcho(nearend, weighted_residual_echo, comfort_noise,
                         min_gain, max_gain, gain);
     AdjustForExternalFilters(gain);
-  } else {
-    const bool linear_echo_estimate = aec_state.UsableLinearEstimate();
-    std::array<float, kFftLengthBy2Plus1> masker;
-    std::array<float, kFftLengthBy2Plus1> one_by_weighted_echo;
-    std::transform(weighted_residual_echo.begin(), weighted_residual_echo.end(),
-                   one_by_weighted_echo.begin(),
-                   [](float e) { return e > 0.f ? 1.f / e : 1.f; });
-    gain->fill(0.f);
-    for (int k = 0; k < 2; ++k) {
-      std::copy(comfort_noise.begin(), comfort_noise.end(), masker.begin());
-      GainToNoAudibleEchoFallback(config_, low_noise_render, saturated_echo,
-                                  linear_echo_estimate, nearend,
-                                  weighted_residual_echo, masker, min_gain,
-                                  max_gain, one_by_weighted_echo, gain);
-      AdjustForExternalFilters(gain);
-    }
-  }
 
   // Adjust the gain for frequencies which have not yet converged.
   AdjustNonConvergedFrequencies(gain);
@@ -372,7 +295,6 @@
       config_(config),
       state_change_duration_blocks_(
           static_cast<int>(config_.filter.config_change_duration_blocks)),
-      enable_new_suppression_(EnableNewSuppression()),
       moving_average_(kFftLengthBy2Plus1,
                       config.suppressor.nearend_average_blocks),
       nearend_params_(config_.suppressor.nearend_tuning),
diff --git a/modules/audio_processing/aec3/suppression_gain.h b/modules/audio_processing/aec3/suppression_gain.h
index 836ec51..e74cd96 100644
--- a/modules/audio_processing/aec3/suppression_gain.h
+++ b/modules/audio_processing/aec3/suppression_gain.h
@@ -12,13 +12,18 @@
 #define MODULES_AUDIO_PROCESSING_AEC3_SUPPRESSION_GAIN_H_
 
 #include <array>
+#include <memory>
 #include <vector>
 
+#include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "api/audio/echo_canceller3_config.h"
 #include "modules/audio_processing/aec3/aec3_common.h"
 #include "modules/audio_processing/aec3/aec_state.h"
+#include "modules/audio_processing/aec3/fft_data.h"
 #include "modules/audio_processing/aec3/moving_average.h"
 #include "modules/audio_processing/aec3/render_signal_analyzer.h"
+#include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
@@ -140,7 +145,6 @@
   LowNoiseRenderDetector low_render_detector_;
   bool initial_state_ = true;
   int initial_state_change_counter_ = 0;
-  const bool enable_new_suppression_;
   aec3::MovingAverage moving_average_;
   const GainParameters nearend_params_;
   const GainParameters normal_params_;
diff --git a/modules/audio_processing/aec3/suppression_gain_limiter.cc b/modules/audio_processing/aec3/suppression_gain_limiter.cc
index e3d7a66..6625a77 100644
--- a/modules/audio_processing/aec3/suppression_gain_limiter.cc
+++ b/modules/audio_processing/aec3/suppression_gain_limiter.cc
@@ -14,6 +14,7 @@
 #include <algorithm>
 
 #include "modules/audio_processing/aec3/aec3_common.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 namespace {
diff --git a/modules/audio_processing/aec3/vector_buffer.cc b/modules/audio_processing/aec3/vector_buffer.cc
index f491168..0682885 100644
--- a/modules/audio_processing/aec3/vector_buffer.cc
+++ b/modules/audio_processing/aec3/vector_buffer.cc
@@ -10,7 +10,7 @@
 
 #include "modules/audio_processing/aec3/vector_buffer.h"
 
-#include "modules/audio_processing/aec3/aec3_common.h"
+#include <algorithm>
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/aec3/vector_buffer.h b/modules/audio_processing/aec3/vector_buffer.h
index c7d4f68..4c0257c 100644
--- a/modules/audio_processing/aec3/vector_buffer.h
+++ b/modules/audio_processing/aec3/vector_buffer.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AEC3_VECTOR_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AEC3_VECTOR_BUFFER_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/aec_dump/BUILD.gn b/modules/audio_processing/aec_dump/BUILD.gn
index 5b55526..d4262ca 100644
--- a/modules/audio_processing/aec_dump/BUILD.gn
+++ b/modules/audio_processing/aec_dump/BUILD.gn
@@ -43,6 +43,7 @@
 
   deps = [
     ":mock_aec_dump",
+    "..:api",
     "../",
     "../../../rtc_base:rtc_base_approved",
     "//testing/gtest",
diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.cc b/modules/audio_processing/aec_dump/aec_dump_impl.cc
index 2732934..9020f2b 100644
--- a/modules/audio_processing/aec_dump/aec_dump_impl.cc
+++ b/modules/audio_processing/aec_dump/aec_dump_impl.cc
@@ -65,7 +65,7 @@
 
 AecDumpImpl::~AecDumpImpl() {
   // Block until all tasks have finished running.
-  rtc::Event thread_sync_event(false /* manual_reset */, false);
+  rtc::Event thread_sync_event;
   worker_queue_->PostTask([&thread_sync_event] { thread_sync_event.Set(); });
   // Wait until the event has been signaled with .Set(). By then all
   // pending tasks will have finished.
diff --git a/modules/audio_processing/aecm/aecm_core.cc b/modules/audio_processing/aecm/aecm_core.cc
index 0e56b50..67b70bf 100644
--- a/modules/audio_processing/aecm/aecm_core.cc
+++ b/modules/audio_processing/aecm/aecm_core.cc
@@ -12,16 +12,15 @@
 
 #include <stddef.h>
 #include <stdlib.h>
+#include <string.h>
 
 extern "C" {
 #include "common_audio/ring_buffer.h"
 #include "common_audio/signal_processing/include/real_fft.h"
 }
+#include "common_audio/signal_processing/include/signal_processing_library.h"
 #include "modules/audio_processing/aecm/echo_control_mobile.h"
 #include "modules/audio_processing/utility/delay_estimator_wrapper.h"
-extern "C" {
-#include "system_wrappers/include/cpu_features_wrapper.h"
-}
 
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/modules/audio_processing/aecm/echo_control_mobile.cc b/modules/audio_processing/aecm/echo_control_mobile.cc
index c947563..257dfbf 100644
--- a/modules/audio_processing/aecm/echo_control_mobile.cc
+++ b/modules/audio_processing/aecm/echo_control_mobile.cc
@@ -14,10 +14,12 @@
 #include <stdio.h>
 #endif
 #include <stdlib.h>
+#include <string.h>
 
 extern "C" {
 #include "common_audio/ring_buffer.h"
 #include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "modules/audio_processing/aecm/aecm_defines.h"
 }
 #include "modules/audio_processing/aecm/aecm_core.h"
 
diff --git a/modules/audio_processing/agc/agc.cc b/modules/audio_processing/agc/agc.cc
index 12c8cfb..c24db0d 100644
--- a/modules/audio_processing/agc/agc.cc
+++ b/modules/audio_processing/agc/agc.cc
@@ -12,8 +12,6 @@
 
 #include <cmath>
 #include <cstdlib>
-
-#include <algorithm>
 #include <vector>
 
 #include "modules/audio_processing/agc/loudness_histogram.h"
diff --git a/modules/audio_processing/agc/agc.h b/modules/audio_processing/agc/agc.h
index 5d34c21..abd68d5 100644
--- a/modules/audio_processing/agc/agc.h
+++ b/modules/audio_processing/agc/agc.h
@@ -17,7 +17,6 @@
 
 namespace webrtc {
 
-class AudioFrame;
 class LoudnessHistogram;
 
 class Agc {
diff --git a/modules/audio_processing/agc/agc_manager_direct.cc b/modules/audio_processing/agc/agc_manager_direct.cc
index dc6d451..5c4deec 100644
--- a/modules/audio_processing/agc/agc_manager_direct.cc
+++ b/modules/audio_processing/agc/agc_manager_direct.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_processing/agc/agc_manager_direct.h"
 
+#include <algorithm>
 #include <cmath>
 
 #ifdef WEBRTC_AGC_DEBUG_DUMP
diff --git a/modules/audio_processing/agc/loudness_histogram.cc b/modules/audio_processing/agc/loudness_histogram.cc
index 0ed5850..cd57b82 100644
--- a/modules/audio_processing/agc/loudness_histogram.cc
+++ b/modules/audio_processing/agc/loudness_histogram.cc
@@ -10,8 +10,8 @@
 
 #include "modules/audio_processing/agc/loudness_histogram.h"
 
+#include <string.h>
 #include <cmath>
-#include <cstring>
 
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/agc/loudness_histogram.h b/modules/audio_processing/agc/loudness_histogram.h
index d8ad751..b210be9 100644
--- a/modules/audio_processing/agc/loudness_histogram.h
+++ b/modules/audio_processing/agc/loudness_histogram.h
@@ -11,8 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC_LOUDNESS_HISTOGRAM_H_
 #define MODULES_AUDIO_PROCESSING_AGC_LOUDNESS_HISTOGRAM_H_
 
-#include <string.h>
-
+#include <stdint.h>
 #include <memory>
 
 namespace webrtc {
diff --git a/modules/audio_processing/agc2/BUILD.gn b/modules/audio_processing/agc2/BUILD.gn
index 1865fde..18f2d78 100644
--- a/modules/audio_processing/agc2/BUILD.gn
+++ b/modules/audio_processing/agc2/BUILD.gn
@@ -96,12 +96,10 @@
   sources = [
     "fixed_digital_level_estimator.cc",
     "fixed_digital_level_estimator.h",
-    "fixed_gain_controller.cc",
-    "fixed_gain_controller.h",
-    "gain_curve_applier.cc",
-    "gain_curve_applier.h",
     "interpolated_gain_curve.cc",
     "interpolated_gain_curve.h",
+    "limiter.cc",
+    "limiter.h",
   ]
 
   configs += [ "..:apm_debug_dump" ]
@@ -128,6 +126,7 @@
   deps = [
     ":common",
     "..:audio_frame_view",
+    "../../../api:array_view",
     "../../../rtc_base:safe_minmax",
   ]
 }
@@ -216,11 +215,10 @@
     "compute_interpolated_gain_curve.cc",
     "compute_interpolated_gain_curve.h",
     "fixed_digital_level_estimator_unittest.cc",
-    "fixed_gain_controller_unittest.cc",
-    "gain_curve_applier_unittest.cc",
     "interpolated_gain_curve_unittest.cc",
-    "limiter.cc",
-    "limiter.h",
+    "limiter_db_gain_curve.cc",
+    "limiter_db_gain_curve.h",
+    "limiter_db_gain_curve_unittest.cc",
     "limiter_unittest.cc",
   ]
   deps = [
@@ -261,7 +259,10 @@
 
 rtc_source_set("test_utils") {
   testonly = true
-  visibility = [ ":*" ]
+  visibility = [
+    ":*",
+    "..:audio_processing_unittests",
+  ]
   sources = [
     "agc2_testing_common.cc",
     "agc2_testing_common.h",
diff --git a/modules/audio_processing/agc2/adaptive_agc.cc b/modules/audio_processing/agc2/adaptive_agc.cc
index c7346c6..795b8b5 100644
--- a/modules/audio_processing/agc2/adaptive_agc.cc
+++ b/modules/audio_processing/agc2/adaptive_agc.cc
@@ -10,12 +10,10 @@
 
 #include "modules/audio_processing/agc2/adaptive_agc.h"
 
-#include <algorithm>
-#include <numeric>
-
 #include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/agc2/vad_with_level.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
@@ -27,6 +25,15 @@
   RTC_DCHECK(apm_data_dumper);
 }
 
+AdaptiveAgc::AdaptiveAgc(ApmDataDumper* apm_data_dumper,
+                         float extra_saturation_margin_db)
+    : speech_level_estimator_(apm_data_dumper, extra_saturation_margin_db),
+      gain_applier_(apm_data_dumper),
+      apm_data_dumper_(apm_data_dumper),
+      noise_level_estimator_(apm_data_dumper) {
+  RTC_DCHECK(apm_data_dumper);
+}
+
 AdaptiveAgc::~AdaptiveAgc() = default;
 
 void AdaptiveAgc::Process(AudioFrameView<float> float_frame,
diff --git a/modules/audio_processing/agc2/adaptive_agc.h b/modules/audio_processing/agc2/adaptive_agc.h
index 792b2bc..6c0917a 100644
--- a/modules/audio_processing/agc2/adaptive_agc.h
+++ b/modules/audio_processing/agc2/adaptive_agc.h
@@ -11,8 +11,6 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_AGC_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_AGC_H_
 
-#include <memory>
-
 #include "modules/audio_processing/agc2/adaptive_digital_gain_applier.h"
 #include "modules/audio_processing/agc2/adaptive_mode_level_estimator.h"
 #include "modules/audio_processing/agc2/noise_level_estimator.h"
@@ -25,6 +23,7 @@
 class AdaptiveAgc {
  public:
   explicit AdaptiveAgc(ApmDataDumper* apm_data_dumper);
+  AdaptiveAgc(ApmDataDumper* apm_data_dumper, float extra_saturation_margin_db);
   ~AdaptiveAgc();
 
   void Process(AudioFrameView<float> float_frame, float last_audio_level);
diff --git a/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc b/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc
index d4560ca..6ece83b 100644
--- a/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc
+++ b/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc
@@ -15,6 +15,7 @@
 #include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/agc2/agc2_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 #include "system_wrappers/include/metrics.h"
 
diff --git a/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc b/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc
index b670f4b..138faec 100644
--- a/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc
+++ b/modules/audio_processing/agc2/adaptive_mode_level_estimator.cc
@@ -12,6 +12,7 @@
 
 #include "modules/audio_processing/agc2/agc2_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
 
 namespace webrtc {
@@ -21,6 +22,12 @@
     : saturation_protector_(apm_data_dumper),
       apm_data_dumper_(apm_data_dumper) {}
 
+AdaptiveModeLevelEstimator::AdaptiveModeLevelEstimator(
+    ApmDataDumper* apm_data_dumper,
+    float extra_saturation_margin_db)
+    : saturation_protector_(apm_data_dumper, extra_saturation_margin_db),
+      apm_data_dumper_(apm_data_dumper) {}
+
 void AdaptiveModeLevelEstimator::UpdateEstimation(
     const VadWithLevel::LevelAndProbability& vad_data) {
   RTC_DCHECK_GT(vad_data.speech_rms_dbfs, -150.f);
diff --git a/modules/audio_processing/agc2/adaptive_mode_level_estimator.h b/modules/audio_processing/agc2/adaptive_mode_level_estimator.h
index 4d4180c..f887268 100644
--- a/modules/audio_processing/agc2/adaptive_mode_level_estimator.h
+++ b/modules/audio_processing/agc2/adaptive_mode_level_estimator.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_MODE_LEVEL_ESTIMATOR_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_MODE_LEVEL_ESTIMATOR_H_
 
+#include <stddef.h>
+
+#include "modules/audio_processing/agc2/agc2_common.h"  // kFullBufferSizeMs...
 #include "modules/audio_processing/agc2/saturation_protector.h"
 #include "modules/audio_processing/agc2/vad_with_level.h"
 
@@ -20,6 +23,8 @@
 class AdaptiveModeLevelEstimator {
  public:
   explicit AdaptiveModeLevelEstimator(ApmDataDumper* apm_data_dumper);
+  AdaptiveModeLevelEstimator(ApmDataDumper* apm_data_dumper,
+                             float extra_saturation_margin_db);
   void UpdateEstimation(const VadWithLevel::LevelAndProbability& vad_data);
   float LatestLevelEstimate() const;
   void Reset();
diff --git a/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc b/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc
index 4cee963..b7c6437 100644
--- a/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc
+++ b/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.cc
@@ -10,6 +10,10 @@
 
 #include "modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h"
 
+#include <cmath>
+#include <vector>
+
+#include "modules/audio_processing/agc2/agc2_common.h"
 #include "modules/audio_processing/include/audio_frame_view.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h b/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h
index 484b128..6d12339 100644
--- a/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h
+++ b/modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h
@@ -11,10 +11,12 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_MODE_LEVEL_ESTIMATOR_AGC_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_ADAPTIVE_MODE_LEVEL_ESTIMATOR_AGC_H_
 
-#include <vector>
+#include <stddef.h>
+#include <stdint.h>
 
 #include "modules/audio_processing/agc/agc.h"
 #include "modules/audio_processing/agc2/adaptive_mode_level_estimator.h"
+#include "modules/audio_processing/agc2/saturation_protector.h"
 #include "modules/audio_processing/agc2/vad_with_level.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/agc2/agc2_common.cc b/modules/audio_processing/agc2/agc2_common.cc
index 5da353f..af943df 100644
--- a/modules/audio_processing/agc2/agc2_common.cc
+++ b/modules/audio_processing/agc2/agc2_common.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_processing/agc2/agc2_common.h"
 
+#include <stdio.h>
 #include <string>
 
 #include "system_wrappers/include/field_trial.h"
diff --git a/modules/audio_processing/agc2/agc2_common.h b/modules/audio_processing/agc2/agc2_common.h
index 71d33e5..55dd648 100644
--- a/modules/audio_processing/agc2/agc2_common.h
+++ b/modules/audio_processing/agc2/agc2_common.h
@@ -13,8 +13,6 @@
 
 #include <stddef.h>
 
-#include <cmath>
-
 namespace webrtc {
 
 constexpr float kMinFloatS16Value = -32768.f;
diff --git a/modules/audio_processing/agc2/biquad_filter.cc b/modules/audio_processing/agc2/biquad_filter.cc
index 9858d50..da8557c 100644
--- a/modules/audio_processing/agc2/biquad_filter.cc
+++ b/modules/audio_processing/agc2/biquad_filter.cc
@@ -10,6 +10,8 @@
 
 #include "modules/audio_processing/agc2/biquad_filter.h"
 
+#include <stddef.h>
+
 namespace webrtc {
 
 // Transposed direct form I implementation of a bi-quad filter applied to an
diff --git a/modules/audio_processing/agc2/biquad_filter.h b/modules/audio_processing/agc2/biquad_filter.h
index 284930c..3d78c07 100644
--- a/modules/audio_processing/agc2/biquad_filter.h
+++ b/modules/audio_processing/agc2/biquad_filter.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_BIQUAD_FILTER_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_BIQUAD_FILTER_H_
 
+#include <algorithm>
+
 #include "api/array_view.h"
 #include "rtc_base/arraysize.h"
 #include "rtc_base/constructormagic.h"
diff --git a/modules/audio_processing/agc2/compute_interpolated_gain_curve.cc b/modules/audio_processing/agc2/compute_interpolated_gain_curve.cc
index f395bce..bc92613 100644
--- a/modules/audio_processing/agc2/compute_interpolated_gain_curve.cc
+++ b/modules/audio_processing/agc2/compute_interpolated_gain_curve.cc
@@ -19,23 +19,24 @@
 
 #include "modules/audio_processing/agc2/agc2_common.h"
 #include "modules/audio_processing/agc2/agc2_testing_common.h"
-#include "modules/audio_processing/agc2/limiter.h"
+#include "modules/audio_processing/agc2/limiter_db_gain_curve.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
 namespace {
 
 std::pair<double, double> ComputeLinearApproximationParams(
-    const Limiter* limiter,
+    const LimiterDbGainCurve* limiter,
     const double x) {
   const double m = limiter->GetGainFirstDerivativeLinear(x);
   const double q = limiter->GetGainLinear(x) - m * x;
   return {m, q};
 }
 
-double ComputeAreaUnderPiecewiseLinearApproximation(const Limiter* limiter,
-                                                    const double x0,
-                                                    const double x1) {
+double ComputeAreaUnderPiecewiseLinearApproximation(
+    const LimiterDbGainCurve* limiter,
+    const double x0,
+    const double x1) {
   RTC_CHECK_LT(x0, x1);
 
   // Linear approximation in x0 and x1.
@@ -60,7 +61,7 @@
 // Computes the approximation error in the limiter region for a given interval.
 // The error is computed as the difference between the areas beneath the limiter
 // curve to approximate and its linear under-approximation.
-double LimiterUnderApproximationNegativeError(const Limiter* limiter,
+double LimiterUnderApproximationNegativeError(const LimiterDbGainCurve* limiter,
                                               const double x0,
                                               const double x1) {
   const double area_limiter = limiter->GetGainIntegralLinear(x0, x1);
@@ -77,7 +78,7 @@
 // are assigned by halving intervals (starting with the whole beyond-knee region
 // as a single interval). However, even if sub-optimal, this algorithm works
 // well in practice and it is efficiently implemented using priority queues.
-std::vector<double> SampleLimiterRegion(const Limiter* limiter) {
+std::vector<double> SampleLimiterRegion(const LimiterDbGainCurve* limiter) {
   static_assert(kInterpolatedGainCurveBeyondKneePoints > 2, "");
 
   struct Interval {
@@ -131,7 +132,7 @@
 // Compute the parameters to over-approximate the knee region via linear
 // interpolation. Over-approximating is saturation-safe since the knee region is
 // convex.
-void PrecomputeKneeApproxParams(const Limiter* limiter,
+void PrecomputeKneeApproxParams(const LimiterDbGainCurve* limiter,
                                 test::InterpolatedParameters* parameters) {
   static_assert(kInterpolatedGainCurveKneePoints > 2, "");
   // Get |kInterpolatedGainCurveKneePoints| - 1 equally spaced points.
@@ -165,7 +166,7 @@
 // interpolation and greedy sampling. Under-approximating is saturation-safe
 // since the beyond-knee region is concave.
 void PrecomputeBeyondKneeApproxParams(
-    const Limiter* limiter,
+    const LimiterDbGainCurve* limiter,
     test::InterpolatedParameters* parameters) {
   // Find points on which the linear pieces are tangent to the gain curve.
   const auto samples = SampleLimiterRegion(limiter);
@@ -216,7 +217,7 @@
 
 InterpolatedParameters ComputeInterpolatedGainCurveApproximationParams() {
   InterpolatedParameters parameters;
-  Limiter limiter;
+  LimiterDbGainCurve limiter;
   parameters.computed_approximation_params_x.fill(0.0f);
   parameters.computed_approximation_params_m.fill(0.0f);
   parameters.computed_approximation_params_q.fill(0.0f);
diff --git a/modules/audio_processing/agc2/fixed_digital_level_estimator.cc b/modules/audio_processing/agc2/fixed_digital_level_estimator.cc
index 39cc764..971f4f6 100644
--- a/modules/audio_processing/agc2/fixed_digital_level_estimator.cc
+++ b/modules/audio_processing/agc2/fixed_digital_level_estimator.cc
@@ -13,6 +13,7 @@
 #include <algorithm>
 #include <cmath>
 
+#include "api/array_view.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/agc2/fixed_gain_controller.cc b/modules/audio_processing/agc2/fixed_gain_controller.cc
index 0d7e3a6..ef908dc 100644
--- a/modules/audio_processing/agc2/fixed_gain_controller.cc
+++ b/modules/audio_processing/agc2/fixed_gain_controller.cc
@@ -10,13 +10,9 @@
 
 #include "modules/audio_processing/agc2/fixed_gain_controller.h"
 
-#include <algorithm>
-#include <cmath>
-
 #include "api/array_view.h"
 #include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/agc2/agc2_common.h"
-#include "modules/audio_processing/agc2/interpolated_gain_curve.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -39,7 +35,7 @@
 FixedGainController::FixedGainController(ApmDataDumper* apm_data_dumper,
                                          std::string histogram_name_prefix)
     : apm_data_dumper_(apm_data_dumper),
-      gain_curve_applier_(48000, apm_data_dumper_, histogram_name_prefix) {
+      limiter_(48000, apm_data_dumper_, histogram_name_prefix) {
   // Do update histograms.xml when adding name prefixes.
   RTC_DCHECK(histogram_name_prefix == "" || histogram_name_prefix == "Test" ||
              histogram_name_prefix == "AudioMixer" ||
@@ -61,12 +57,12 @@
   // Reset the gain curve applier to quickly react on abrupt level changes
   // caused by large changes of the applied gain.
   if (previous_applied_gained != gain_to_apply_) {
-    gain_curve_applier_.Reset();
+    limiter_.Reset();
   }
 }
 
 void FixedGainController::SetSampleRate(size_t sample_rate_hz) {
-  gain_curve_applier_.SetSampleRate(sample_rate_hz);
+  limiter_.SetSampleRate(sample_rate_hz);
 }
 
 void FixedGainController::Process(AudioFrameView<float> signal) {
@@ -84,7 +80,7 @@
   }
 
   // Use the limiter.
-  gain_curve_applier_.Process(signal);
+  limiter_.Process(signal);
 
   // Dump data for debug.
   const auto channel_view = signal.channel(0);
@@ -100,6 +96,6 @@
 }
 
 float FixedGainController::LastAudioLevel() const {
-  return gain_curve_applier_.LastAudioLevel();
+  return limiter_.LastAudioLevel();
 }
 }  // namespace webrtc
diff --git a/modules/audio_processing/agc2/fixed_gain_controller.h b/modules/audio_processing/agc2/fixed_gain_controller.h
deleted file mode 100644
index ff6ab81..0000000
--- a/modules/audio_processing/agc2/fixed_gain_controller.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AGC2_FIXED_GAIN_CONTROLLER_H_
-#define MODULES_AUDIO_PROCESSING_AGC2_FIXED_GAIN_CONTROLLER_H_
-
-#include "modules/audio_processing/agc2/gain_curve_applier.h"
-#include "modules/audio_processing/include/audio_frame_view.h"
-
-namespace webrtc {
-class ApmDataDumper;
-
-class FixedGainController {
- public:
-  explicit FixedGainController(ApmDataDumper* apm_data_dumper);
-  FixedGainController(ApmDataDumper* apm_data_dumper,
-                      std::string histogram_name_prefix);
-
-  void Process(AudioFrameView<float> signal);
-
-  // Rate and gain may be changed at any time (but not concurrently
-  // with any other method call).
-  void SetGain(float gain_to_apply_db);
-  void SetSampleRate(size_t sample_rate_hz);
-  float LastAudioLevel() const;
-
- private:
-  float gain_to_apply_ = 1.f;
-  ApmDataDumper* apm_data_dumper_ = nullptr;
-  GainCurveApplier gain_curve_applier_;
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_AGC2_FIXED_GAIN_CONTROLLER_H_
diff --git a/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc b/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc
deleted file mode 100644
index db1732a..0000000
--- a/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/agc2/fixed_gain_controller.h"
-
-#include "absl/memory/memory.h"
-#include "api/array_view.h"
-#include "modules/audio_processing/agc2/agc2_testing_common.h"
-#include "modules/audio_processing/agc2/vector_float_frame.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "rtc_base/gunit.h"
-#include "system_wrappers/include/metrics.h"
-
-namespace webrtc {
-namespace {
-
-constexpr float kInputLevelLinear = 15000.f;
-
-constexpr float kGainToApplyDb = 15.f;
-
-float RunFixedGainControllerWithConstantInput(FixedGainController* fixed_gc,
-                                              const float input_level,
-                                              const size_t num_frames,
-                                              const int sample_rate) {
-  // Give time to the level etimator to converge.
-  for (size_t i = 0; i < num_frames; ++i) {
-    VectorFloatFrame vectors_with_float_frame(
-        1, rtc::CheckedDivExact(sample_rate, 100), input_level);
-    fixed_gc->Process(vectors_with_float_frame.float_frame_view());
-  }
-
-  // Process the last frame with constant input level.
-  VectorFloatFrame vectors_with_float_frame_last(
-      1, rtc::CheckedDivExact(sample_rate, 100), input_level);
-  fixed_gc->Process(vectors_with_float_frame_last.float_frame_view());
-
-  // Return the last sample from the last processed frame.
-  const auto channel =
-      vectors_with_float_frame_last.float_frame_view().channel(0);
-  return channel[channel.size() - 1];
-}
-
-std::unique_ptr<ApmDataDumper> GetApmDataDumper() {
-  return absl::make_unique<ApmDataDumper>(0);
-}
-
-std::unique_ptr<FixedGainController> CreateFixedGainController(
-    float gain_to_apply,
-    size_t rate,
-    std::string histogram_name_prefix,
-    ApmDataDumper* test_data_dumper) {
-  std::unique_ptr<FixedGainController> fgc =
-      absl::make_unique<FixedGainController>(test_data_dumper,
-                                             histogram_name_prefix);
-  fgc->SetGain(gain_to_apply);
-  fgc->SetSampleRate(rate);
-  return fgc;
-}
-
-std::unique_ptr<FixedGainController> CreateFixedGainController(
-    float gain_to_apply,
-    size_t rate,
-    ApmDataDumper* test_data_dumper) {
-  return CreateFixedGainController(gain_to_apply, rate, "", test_data_dumper);
-}
-
-}  // namespace
-
-TEST(AutomaticGainController2FixedDigital, CreateUse) {
-  const int kSampleRate = 44000;
-  auto test_data_dumper = GetApmDataDumper();
-  std::unique_ptr<FixedGainController> fixed_gc = CreateFixedGainController(
-      kGainToApplyDb, kSampleRate, test_data_dumper.get());
-  VectorFloatFrame vectors_with_float_frame(
-      1, rtc::CheckedDivExact(kSampleRate, 100), kInputLevelLinear);
-  auto float_frame = vectors_with_float_frame.float_frame_view();
-  fixed_gc->Process(float_frame);
-  const auto channel = float_frame.channel(0);
-  EXPECT_LT(kInputLevelLinear, channel[0]);
-}
-
-TEST(AutomaticGainController2FixedDigital, CheckSaturationBehaviorWithLimiter) {
-  const float kInputLevel = 32767.f;
-  const size_t kNumFrames = 5;
-  const size_t kSampleRate = 42000;
-
-  auto test_data_dumper = GetApmDataDumper();
-
-  const auto gains_no_saturation =
-      test::LinSpace(0.1, test::kLimiterMaxInputLevelDbFs - 0.01, 10);
-  for (const auto gain_db : gains_no_saturation) {
-    // Since |test::kLimiterMaxInputLevelDbFs| > |gain_db|, the
-    // limiter will not saturate the signal.
-    std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
-        CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
-
-    // Saturation not expected.
-    SCOPED_TRACE(std::to_string(gain_db));
-    EXPECT_LT(
-        RunFixedGainControllerWithConstantInput(
-            fixed_gc_no_saturation.get(), kInputLevel, kNumFrames, kSampleRate),
-        32767.f);
-  }
-
-  const auto gains_saturation =
-      test::LinSpace(test::kLimiterMaxInputLevelDbFs + 0.01, 10, 10);
-  for (const auto gain_db : gains_saturation) {
-    // Since |test::kLimiterMaxInputLevelDbFs| < |gain|, the limiter
-    // will saturate the signal.
-    std::unique_ptr<FixedGainController> fixed_gc_saturation =
-        CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
-
-    // Saturation expected.
-    SCOPED_TRACE(std::to_string(gain_db));
-    EXPECT_FLOAT_EQ(
-        RunFixedGainControllerWithConstantInput(
-            fixed_gc_saturation.get(), kInputLevel, kNumFrames, kSampleRate),
-        32767.f);
-  }
-}
-
-TEST(AutomaticGainController2FixedDigital,
-     CheckSaturationBehaviorWithLimiterSingleSample) {
-  const float kInputLevel = 32767.f;
-  const size_t kNumFrames = 5;
-  const size_t kSampleRate = 8000;
-
-  auto test_data_dumper = GetApmDataDumper();
-
-  const auto gains_no_saturation =
-      test::LinSpace(0.1, test::kLimiterMaxInputLevelDbFs - 0.01, 10);
-  for (const auto gain_db : gains_no_saturation) {
-    // Since |gain| > |test::kLimiterMaxInputLevelDbFs|, the limiter will
-    // not saturate the signal.
-    std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
-        CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
-
-    // Saturation not expected.
-    SCOPED_TRACE(std::to_string(gain_db));
-    EXPECT_LT(
-        RunFixedGainControllerWithConstantInput(
-            fixed_gc_no_saturation.get(), kInputLevel, kNumFrames, kSampleRate),
-        32767.f);
-  }
-
-  const auto gains_saturation =
-      test::LinSpace(test::kLimiterMaxInputLevelDbFs + 0.01, 10, 10);
-  for (const auto gain_db : gains_saturation) {
-    // Singe |gain| < |test::kLimiterMaxInputLevelDbFs|, the limiter will
-    // saturate the signal.
-    std::unique_ptr<FixedGainController> fixed_gc_saturation =
-        CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
-
-    // Saturation expected.
-    SCOPED_TRACE(std::to_string(gain_db));
-    EXPECT_FLOAT_EQ(
-        RunFixedGainControllerWithConstantInput(
-            fixed_gc_saturation.get(), kInputLevel, kNumFrames, kSampleRate),
-        32767.f);
-  }
-}
-
-TEST(AutomaticGainController2FixedDigital, GainShouldChangeOnSetGain) {
-  constexpr float kInputLevel = 1000.f;
-  constexpr size_t kNumFrames = 5;
-  constexpr size_t kSampleRate = 8000;
-  constexpr float kGainDbNoChange = 0.f;
-  constexpr float kGainDbFactor10 = 20.f;
-
-  auto test_data_dumper = GetApmDataDumper();
-  std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
-      CreateFixedGainController(kGainDbNoChange, kSampleRate,
-                                test_data_dumper.get());
-
-  // Signal level is unchanged with 0 db gain.
-  EXPECT_FLOAT_EQ(
-      RunFixedGainControllerWithConstantInput(
-          fixed_gc_no_saturation.get(), kInputLevel, kNumFrames, kSampleRate),
-      kInputLevel);
-
-  fixed_gc_no_saturation->SetGain(kGainDbFactor10);
-
-  // +20db should increase signal by a factor of 10.
-  EXPECT_FLOAT_EQ(
-      RunFixedGainControllerWithConstantInput(
-          fixed_gc_no_saturation.get(), kInputLevel, kNumFrames, kSampleRate),
-      kInputLevel * 10);
-}
-
-TEST(AutomaticGainController2FixedDigital,
-     SetGainShouldBeFastAndTimeInvariant) {
-  // Number of frames required for the fixed gain controller to adapt on the
-  // input signal when the gain changes.
-  constexpr size_t kNumFrames = 5;
-
-  constexpr float kInputLevel = 1000.f;
-  constexpr size_t kSampleRate = 8000;
-  constexpr float kGainDbLow = 0.f;
-  constexpr float kGainDbHigh = 40.f;
-  static_assert(kGainDbLow < kGainDbHigh, "");
-
-  auto test_data_dumper = GetApmDataDumper();
-  std::unique_ptr<FixedGainController> fixed_gc = CreateFixedGainController(
-      kGainDbLow, kSampleRate, test_data_dumper.get());
-
-  fixed_gc->SetGain(kGainDbLow);
-  const float output_level_pre = RunFixedGainControllerWithConstantInput(
-      fixed_gc.get(), kInputLevel, kNumFrames, kSampleRate);
-
-  fixed_gc->SetGain(kGainDbHigh);
-  RunFixedGainControllerWithConstantInput(fixed_gc.get(), kInputLevel,
-                                          kNumFrames, kSampleRate);
-
-  fixed_gc->SetGain(kGainDbLow);
-  const float output_level_post = RunFixedGainControllerWithConstantInput(
-      fixed_gc.get(), kInputLevel, kNumFrames, kSampleRate);
-
-  EXPECT_EQ(output_level_pre, output_level_post);
-}
-
-TEST(AutomaticGainController2FixedDigital, RegionHistogramIsUpdated) {
-  constexpr size_t kSampleRate = 8000;
-  constexpr float kGainDb = 0.f;
-  constexpr float kInputLevel = 1000.f;
-  constexpr size_t kNumFrames = 5;
-
-  metrics::Reset();
-
-  auto test_data_dumper = GetApmDataDumper();
-  std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
-      CreateFixedGainController(kGainDb, kSampleRate, "Test",
-                                test_data_dumper.get());
-
-  static_cast<void>(RunFixedGainControllerWithConstantInput(
-      fixed_gc_no_saturation.get(), kInputLevel, kNumFrames, kSampleRate));
-
-  // Destroying FixedGainController should cause the last limiter region to be
-  // logged.
-  fixed_gc_no_saturation.reset();
-
-  EXPECT_EQ(1, metrics::NumSamples(
-                   "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Identity"));
-  EXPECT_EQ(0, metrics::NumSamples(
-                   "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Knee"));
-  EXPECT_EQ(0, metrics::NumSamples(
-                   "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Limiter"));
-  EXPECT_EQ(0, metrics::NumSamples(
-                   "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Saturation"));
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/agc2/gain_applier.cc b/modules/audio_processing/agc2/gain_applier.cc
index 38eb1de..8c43717 100644
--- a/modules/audio_processing/agc2/gain_applier.cc
+++ b/modules/audio_processing/agc2/gain_applier.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_processing/agc2/gain_applier.h"
 
+#include "api/array_view.h"
 #include "modules/audio_processing/agc2/agc2_common.h"
 #include "rtc_base/numerics/safe_minmax.h"
 
diff --git a/modules/audio_processing/agc2/gain_applier.h b/modules/audio_processing/agc2/gain_applier.h
index e2567b1..7f9f00e 100644
--- a/modules/audio_processing/agc2/gain_applier.h
+++ b/modules/audio_processing/agc2/gain_applier.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_GAIN_APPLIER_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_GAIN_APPLIER_H_
 
+#include <stddef.h>
+
 #include "modules/audio_processing/include/audio_frame_view.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/agc2/gain_curve_applier.cc b/modules/audio_processing/agc2/gain_curve_applier.cc
deleted file mode 100644
index 1eca21b..0000000
--- a/modules/audio_processing/agc2/gain_curve_applier.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/agc2/gain_curve_applier.h"
-
-#include <algorithm>
-#include <array>
-#include <cmath>
-
-#include "api/array_view.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "rtc_base/checks.h"
-
-namespace webrtc {
-namespace {
-
-// This constant affects the way scaling factors are interpolated for the first
-// sub-frame of a frame. Only in the case in which the first sub-frame has an
-// estimated level which is greater than the that of the previous analyzed
-// sub-frame, linear interpolation is replaced with a power function which
-// reduces the chances of over-shooting (and hence saturation), however reducing
-// the fixed gain effectiveness.
-constexpr float kAttackFirstSubframeInterpolationPower = 8.f;
-
-void InterpolateFirstSubframe(float last_factor,
-                              float current_factor,
-                              rtc::ArrayView<float> subframe) {
-  const auto n = subframe.size();
-  constexpr auto p = kAttackFirstSubframeInterpolationPower;
-  for (size_t i = 0; i < n; ++i) {
-    subframe[i] = std::pow(1.f - i / n, p) * (last_factor - current_factor) +
-                  current_factor;
-  }
-}
-
-void ComputePerSampleSubframeFactors(
-    const std::array<float, kSubFramesInFrame + 1>& scaling_factors,
-    size_t samples_per_channel,
-    rtc::ArrayView<float> per_sample_scaling_factors) {
-  const size_t num_subframes = scaling_factors.size() - 1;
-  const size_t subframe_size =
-      rtc::CheckedDivExact(samples_per_channel, num_subframes);
-
-  // Handle first sub-frame differently in case of attack.
-  const bool is_attack = scaling_factors[0] > scaling_factors[1];
-  if (is_attack) {
-    InterpolateFirstSubframe(
-        scaling_factors[0], scaling_factors[1],
-        rtc::ArrayView<float>(
-            per_sample_scaling_factors.subview(0, subframe_size)));
-  }
-
-  for (size_t i = is_attack ? 1 : 0; i < num_subframes; ++i) {
-    const size_t subframe_start = i * subframe_size;
-    const float scaling_start = scaling_factors[i];
-    const float scaling_end = scaling_factors[i + 1];
-    const float scaling_diff = (scaling_end - scaling_start) / subframe_size;
-    for (size_t j = 0; j < subframe_size; ++j) {
-      per_sample_scaling_factors[subframe_start + j] =
-          scaling_start + scaling_diff * j;
-    }
-  }
-}
-
-void ScaleSamples(rtc::ArrayView<const float> per_sample_scaling_factors,
-                  AudioFrameView<float> signal) {
-  const size_t samples_per_channel = signal.samples_per_channel();
-  RTC_DCHECK_EQ(samples_per_channel, per_sample_scaling_factors.size());
-  for (size_t i = 0; i < signal.num_channels(); ++i) {
-    auto channel = signal.channel(i);
-    for (size_t j = 0; j < samples_per_channel; ++j) {
-      channel[j] *= per_sample_scaling_factors[j];
-    }
-  }
-}
-
-}  // namespace
-
-GainCurveApplier::GainCurveApplier(size_t sample_rate_hz,
-                                   ApmDataDumper* apm_data_dumper,
-                                   std::string histogram_name)
-    : interp_gain_curve_(apm_data_dumper, histogram_name),
-      level_estimator_(sample_rate_hz, apm_data_dumper),
-      apm_data_dumper_(apm_data_dumper) {}
-
-GainCurveApplier::~GainCurveApplier() = default;
-
-void GainCurveApplier::Process(AudioFrameView<float> signal) {
-  const auto level_estimate = level_estimator_.ComputeLevel(signal);
-
-  RTC_DCHECK_EQ(level_estimate.size() + 1, scaling_factors_.size());
-  scaling_factors_[0] = last_scaling_factor_;
-  std::transform(level_estimate.begin(), level_estimate.end(),
-                 scaling_factors_.begin() + 1, [this](float x) {
-                   return interp_gain_curve_.LookUpGainToApply(x);
-                 });
-
-  const size_t samples_per_channel = signal.samples_per_channel();
-  RTC_DCHECK_LE(samples_per_channel, kMaximalNumberOfSamplesPerChannel);
-
-  auto per_sample_scaling_factors = rtc::ArrayView<float>(
-      &per_sample_scaling_factors_[0], samples_per_channel);
-  ComputePerSampleSubframeFactors(scaling_factors_, samples_per_channel,
-                                  per_sample_scaling_factors);
-  ScaleSamples(per_sample_scaling_factors, signal);
-
-  last_scaling_factor_ = scaling_factors_.back();
-
-  // Dump data for debug.
-  apm_data_dumper_->DumpRaw("agc2_gain_curve_applier_scaling_factors",
-                            samples_per_channel,
-                            per_sample_scaling_factors_.data());
-}
-
-InterpolatedGainCurve::Stats GainCurveApplier::GetGainCurveStats() const {
-  return interp_gain_curve_.get_stats();
-}
-
-void GainCurveApplier::SetSampleRate(size_t sample_rate_hz) {
-  level_estimator_.SetSampleRate(sample_rate_hz);
-  // Check that per_sample_scaling_factors_ is large enough.
-  RTC_DCHECK_LE(sample_rate_hz,
-                kMaximalNumberOfSamplesPerChannel * 1000 / kFrameDurationMs);
-}
-
-void GainCurveApplier::Reset() {
-  level_estimator_.Reset();
-}
-
-float GainCurveApplier::LastAudioLevel() const {
-  return level_estimator_.LastAudioLevel();
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/agc2/gain_curve_applier.h b/modules/audio_processing/agc2/gain_curve_applier.h
deleted file mode 100644
index e0be19e..0000000
--- a/modules/audio_processing/agc2/gain_curve_applier.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AGC2_GAIN_CURVE_APPLIER_H_
-#define MODULES_AUDIO_PROCESSING_AGC2_GAIN_CURVE_APPLIER_H_
-
-#include <vector>
-
-#include "modules/audio_processing/agc2/fixed_digital_level_estimator.h"
-#include "modules/audio_processing/agc2/interpolated_gain_curve.h"
-#include "modules/audio_processing/include/audio_frame_view.h"
-#include "rtc_base/constructormagic.h"
-
-namespace webrtc {
-class ApmDataDumper;
-
-class GainCurveApplier {
- public:
-  GainCurveApplier(size_t sample_rate_hz,
-                   ApmDataDumper* apm_data_dumper,
-                   std::string histogram_name_prefix);
-
-  ~GainCurveApplier();
-
-  void Process(AudioFrameView<float> signal);
-  InterpolatedGainCurve::Stats GetGainCurveStats() const;
-
-  // Supported rates must be
-  // * supported by FixedDigitalLevelEstimator
-  // * below kMaximalNumberOfSamplesPerChannel*1000/kFrameDurationMs
-  //   so that samples_per_channel fit in the
-  //   per_sample_scaling_factors_ array.
-  void SetSampleRate(size_t sample_rate_hz);
-
-  // Resets the internal state.
-  void Reset();
-
-  float LastAudioLevel() const;
-
- private:
-  const InterpolatedGainCurve interp_gain_curve_;
-  FixedDigitalLevelEstimator level_estimator_;
-  ApmDataDumper* const apm_data_dumper_ = nullptr;
-
-  // Work array containing the sub-frame scaling factors to be interpolated.
-  std::array<float, kSubFramesInFrame + 1> scaling_factors_ = {};
-  std::array<float, kMaximalNumberOfSamplesPerChannel>
-      per_sample_scaling_factors_ = {};
-  float last_scaling_factor_ = 1.f;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(GainCurveApplier);
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_AGC2_GAIN_CURVE_APPLIER_H_
diff --git a/modules/audio_processing/agc2/gain_curve_applier_unittest.cc b/modules/audio_processing/agc2/gain_curve_applier_unittest.cc
deleted file mode 100644
index 0f75f62..0000000
--- a/modules/audio_processing/agc2/gain_curve_applier_unittest.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/agc2/gain_curve_applier.h"
-
-#include "common_audio/include/audio_util.h"
-#include "modules/audio_processing/agc2/agc2_common.h"
-#include "modules/audio_processing/agc2/agc2_testing_common.h"
-#include "modules/audio_processing/agc2/vector_float_frame.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "rtc_base/gunit.h"
-
-namespace webrtc {
-
-TEST(GainCurveApplier, GainCurveApplierShouldConstructAndRun) {
-  const int sample_rate_hz = 48000;
-  ApmDataDumper apm_data_dumper(0);
-
-  GainCurveApplier gain_curve_applier(sample_rate_hz, &apm_data_dumper, "");
-
-  VectorFloatFrame vectors_with_float_frame(1, sample_rate_hz / 100,
-                                            kMaxAbsFloatS16Value);
-  gain_curve_applier.Process(vectors_with_float_frame.float_frame_view());
-}
-
-TEST(GainCurveApplier, OutputVolumeAboveThreshold) {
-  const int sample_rate_hz = 48000;
-  const float input_level =
-      (kMaxAbsFloatS16Value + DbfsToFloatS16(test::kLimiterMaxInputLevelDbFs)) /
-      2.f;
-  ApmDataDumper apm_data_dumper(0);
-
-  GainCurveApplier gain_curve_applier(sample_rate_hz, &apm_data_dumper, "");
-
-  // Give the level estimator time to adapt.
-  for (int i = 0; i < 5; ++i) {
-    VectorFloatFrame vectors_with_float_frame(1, sample_rate_hz / 100,
-                                              input_level);
-    gain_curve_applier.Process(vectors_with_float_frame.float_frame_view());
-  }
-
-  VectorFloatFrame vectors_with_float_frame(1, sample_rate_hz / 100,
-                                            input_level);
-  gain_curve_applier.Process(vectors_with_float_frame.float_frame_view());
-  rtc::ArrayView<const float> channel =
-      vectors_with_float_frame.float_frame_view().channel(0);
-
-  for (const auto& sample : channel) {
-    EXPECT_LT(0.9f * kMaxAbsFloatS16Value, sample);
-  }
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/agc2/interpolated_gain_curve.cc b/modules/audio_processing/agc2/interpolated_gain_curve.cc
index 73e6a8e..f5d6b47 100644
--- a/modules/audio_processing/agc2/interpolated_gain_curve.cc
+++ b/modules/audio_processing/agc2/interpolated_gain_curve.cc
@@ -10,10 +10,12 @@
 
 #include "modules/audio_processing/agc2/interpolated_gain_curve.h"
 
+#include <algorithm>
+#include <iterator>
+
 #include "modules/audio_processing/agc2/agc2_common.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc b/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc
index dd69631..a8e0f23 100644
--- a/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc
+++ b/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc
@@ -9,6 +9,7 @@
  */
 
 #include <array>
+#include <type_traits>
 #include <vector>
 
 #include "api/array_view.h"
@@ -16,7 +17,7 @@
 #include "modules/audio_processing/agc2/agc2_common.h"
 #include "modules/audio_processing/agc2/compute_interpolated_gain_curve.h"
 #include "modules/audio_processing/agc2/interpolated_gain_curve.h"
-#include "modules/audio_processing/agc2/limiter.h"
+#include "modules/audio_processing/agc2/limiter_db_gain_curve.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/gunit.h"
@@ -27,7 +28,8 @@
 constexpr double kLevelEpsilon = 1e-2 * kMaxAbsFloatS16Value;
 constexpr float kInterpolatedGainCurveTolerance = 1.f / 32768.f;
 ApmDataDumper apm_data_dumper(0);
-const Limiter limiter;
+static_assert(std::is_trivially_destructible<LimiterDbGainCurve>::value, "");
+const LimiterDbGainCurve limiter;
 
 }  // namespace
 
diff --git a/modules/audio_processing/agc2/limiter.cc b/modules/audio_processing/agc2/limiter.cc
index d2b9877..1589f07 100644
--- a/modules/audio_processing/agc2/limiter.cc
+++ b/modules/audio_processing/agc2/limiter.cc
@@ -10,128 +10,141 @@
 
 #include "modules/audio_processing/agc2/limiter.h"
 
+#include <algorithm>
+#include <array>
 #include <cmath>
 
-#include "common_audio/include/audio_util.h"
+#include "api/array_view.h"
 #include "modules/audio_processing/agc2/agc2_common.h"
+#include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/numerics/safe_minmax.h"
 
 namespace webrtc {
 namespace {
 
-double ComputeKneeStart(double max_input_level_db,
-                        double knee_smoothness_db,
-                        double compression_ratio) {
-  RTC_CHECK_LT((compression_ratio - 1.0) * knee_smoothness_db /
-                   (2.0 * compression_ratio),
-               max_input_level_db);
-  return -knee_smoothness_db / 2.0 -
-         max_input_level_db / (compression_ratio - 1.0);
+// This constant affects the way scaling factors are interpolated for the first
+// sub-frame of a frame. Only in the case in which the first sub-frame has an
+// estimated level which is greater than the that of the previous analyzed
+// sub-frame, linear interpolation is replaced with a power function which
+// reduces the chances of over-shooting (and hence saturation), however reducing
+// the fixed gain effectiveness.
+constexpr float kAttackFirstSubframeInterpolationPower = 8.f;
+
+void InterpolateFirstSubframe(float last_factor,
+                              float current_factor,
+                              rtc::ArrayView<float> subframe) {
+  const auto n = subframe.size();
+  constexpr auto p = kAttackFirstSubframeInterpolationPower;
+  for (size_t i = 0; i < n; ++i) {
+    subframe[i] = std::pow(1.f - i / n, p) * (last_factor - current_factor) +
+                  current_factor;
+  }
 }
 
-std::array<double, 3> ComputeKneeRegionPolynomial(double knee_start_dbfs,
-                                                  double knee_smoothness_db,
-                                                  double compression_ratio) {
-  const double a = (1.0 - compression_ratio) /
-                   (2.0 * knee_smoothness_db * compression_ratio);
-  const double b = 1.0 - 2.0 * a * knee_start_dbfs;
-  const double c = a * knee_start_dbfs * knee_start_dbfs;
-  return {{a, b, c}};
+void ComputePerSampleSubframeFactors(
+    const std::array<float, kSubFramesInFrame + 1>& scaling_factors,
+    size_t samples_per_channel,
+    rtc::ArrayView<float> per_sample_scaling_factors) {
+  const size_t num_subframes = scaling_factors.size() - 1;
+  const size_t subframe_size =
+      rtc::CheckedDivExact(samples_per_channel, num_subframes);
+
+  // Handle first sub-frame differently in case of attack.
+  const bool is_attack = scaling_factors[0] > scaling_factors[1];
+  if (is_attack) {
+    InterpolateFirstSubframe(
+        scaling_factors[0], scaling_factors[1],
+        rtc::ArrayView<float>(
+            per_sample_scaling_factors.subview(0, subframe_size)));
+  }
+
+  for (size_t i = is_attack ? 1 : 0; i < num_subframes; ++i) {
+    const size_t subframe_start = i * subframe_size;
+    const float scaling_start = scaling_factors[i];
+    const float scaling_end = scaling_factors[i + 1];
+    const float scaling_diff = (scaling_end - scaling_start) / subframe_size;
+    for (size_t j = 0; j < subframe_size; ++j) {
+      per_sample_scaling_factors[subframe_start + j] =
+          scaling_start + scaling_diff * j;
+    }
+  }
 }
 
-double ComputeLimiterD1(double max_input_level_db, double compression_ratio) {
-  return (std::pow(10.0, -max_input_level_db / (20.0 * compression_ratio)) *
-          (1.0 - compression_ratio) / compression_ratio) /
-         kMaxAbsFloatS16Value;
+void ScaleSamples(rtc::ArrayView<const float> per_sample_scaling_factors,
+                  AudioFrameView<float> signal) {
+  const size_t samples_per_channel = signal.samples_per_channel();
+  RTC_DCHECK_EQ(samples_per_channel, per_sample_scaling_factors.size());
+  for (size_t i = 0; i < signal.num_channels(); ++i) {
+    auto channel = signal.channel(i);
+    for (size_t j = 0; j < samples_per_channel; ++j) {
+      channel[j] = rtc::SafeClamp(channel[j] * per_sample_scaling_factors[j],
+                                  kMinFloatS16Value, kMaxFloatS16Value);
+    }
+  }
 }
 
-constexpr double ComputeLimiterD2(double compression_ratio) {
-  return (1.0 - 2.0 * compression_ratio) / compression_ratio;
-}
-
-double ComputeLimiterI2(double max_input_level_db,
-                        double compression_ratio,
-                        double gain_curve_limiter_i1) {
-  RTC_CHECK_NE(gain_curve_limiter_i1, 0.f);
-  return std::pow(10.0, -max_input_level_db / (20.0 * compression_ratio)) /
-         gain_curve_limiter_i1 /
-         std::pow(kMaxAbsFloatS16Value, gain_curve_limiter_i1 - 1);
+void CheckLimiterSampleRate(size_t sample_rate_hz) {
+  // Check that per_sample_scaling_factors_ is large enough.
+  RTC_DCHECK_LE(sample_rate_hz,
+                kMaximalNumberOfSamplesPerChannel * 1000 / kFrameDurationMs);
 }
 
 }  // namespace
 
-Limiter::Limiter()
-    : max_input_level_linear_(DbfsToFloatS16(max_input_level_db_)),
-      knee_start_dbfs_(ComputeKneeStart(max_input_level_db_,
-                                        knee_smoothness_db_,
-                                        compression_ratio_)),
-      knee_start_linear_(DbfsToFloatS16(knee_start_dbfs_)),
-      limiter_start_dbfs_(knee_start_dbfs_ + knee_smoothness_db_),
-      limiter_start_linear_(DbfsToFloatS16(limiter_start_dbfs_)),
-      knee_region_polynomial_(ComputeKneeRegionPolynomial(knee_start_dbfs_,
-                                                          knee_smoothness_db_,
-                                                          compression_ratio_)),
-      gain_curve_limiter_d1_(
-          ComputeLimiterD1(max_input_level_db_, compression_ratio_)),
-      gain_curve_limiter_d2_(ComputeLimiterD2(compression_ratio_)),
-      gain_curve_limiter_i1_(1.0 / compression_ratio_),
-      gain_curve_limiter_i2_(ComputeLimiterI2(max_input_level_db_,
-                                              compression_ratio_,
-                                              gain_curve_limiter_i1_)) {
-  static_assert(knee_smoothness_db_ > 0.0f, "");
-  static_assert(compression_ratio_ > 1.0f, "");
-  RTC_CHECK_GE(max_input_level_db_, knee_start_dbfs_ + knee_smoothness_db_);
+Limiter::Limiter(size_t sample_rate_hz,
+                 ApmDataDumper* apm_data_dumper,
+                 std::string histogram_name)
+    : interp_gain_curve_(apm_data_dumper, histogram_name),
+      level_estimator_(sample_rate_hz, apm_data_dumper),
+      apm_data_dumper_(apm_data_dumper) {
+  CheckLimiterSampleRate(sample_rate_hz);
 }
 
-constexpr double Limiter::max_input_level_db_;
-constexpr double Limiter::knee_smoothness_db_;
-constexpr double Limiter::compression_ratio_;
+Limiter::~Limiter() = default;
 
-double Limiter::GetOutputLevelDbfs(double input_level_dbfs) const {
-  if (input_level_dbfs < knee_start_dbfs_) {
-    return input_level_dbfs;
-  } else if (input_level_dbfs < limiter_start_dbfs_) {
-    return GetKneeRegionOutputLevelDbfs(input_level_dbfs);
-  }
-  return GetCompressorRegionOutputLevelDbfs(input_level_dbfs);
+void Limiter::Process(AudioFrameView<float> signal) {
+  const auto level_estimate = level_estimator_.ComputeLevel(signal);
+
+  RTC_DCHECK_EQ(level_estimate.size() + 1, scaling_factors_.size());
+  scaling_factors_[0] = last_scaling_factor_;
+  std::transform(level_estimate.begin(), level_estimate.end(),
+                 scaling_factors_.begin() + 1, [this](float x) {
+                   return interp_gain_curve_.LookUpGainToApply(x);
+                 });
+
+  const size_t samples_per_channel = signal.samples_per_channel();
+  RTC_DCHECK_LE(samples_per_channel, kMaximalNumberOfSamplesPerChannel);
+
+  auto per_sample_scaling_factors = rtc::ArrayView<float>(
+      &per_sample_scaling_factors_[0], samples_per_channel);
+  ComputePerSampleSubframeFactors(scaling_factors_, samples_per_channel,
+                                  per_sample_scaling_factors);
+  ScaleSamples(per_sample_scaling_factors, signal);
+
+  last_scaling_factor_ = scaling_factors_.back();
+
+  // Dump data for debug.
+  apm_data_dumper_->DumpRaw("agc2_gain_curve_applier_scaling_factors",
+                            samples_per_channel,
+                            per_sample_scaling_factors_.data());
 }
 
-double Limiter::GetGainLinear(double input_level_linear) const {
-  if (input_level_linear < knee_start_linear_) {
-    return 1.0;
-  }
-  return DbfsToFloatS16(
-             GetOutputLevelDbfs(FloatS16ToDbfs(input_level_linear))) /
-         input_level_linear;
+InterpolatedGainCurve::Stats Limiter::GetGainCurveStats() const {
+  return interp_gain_curve_.get_stats();
 }
 
-// Computes the first derivative of GetGainLinear() in |x|.
-double Limiter::GetGainFirstDerivativeLinear(double x) const {
-  // Beyond-knee region only.
-  RTC_CHECK_GE(x, limiter_start_linear_ - 1e-7 * kMaxAbsFloatS16Value);
-  return gain_curve_limiter_d1_ *
-         std::pow(x / kMaxAbsFloatS16Value, gain_curve_limiter_d2_);
+void Limiter::SetSampleRate(size_t sample_rate_hz) {
+  CheckLimiterSampleRate(sample_rate_hz);
+  level_estimator_.SetSampleRate(sample_rate_hz);
 }
 
-// Computes the integral of GetGainLinear() in the range [x0, x1].
-double Limiter::GetGainIntegralLinear(double x0, double x1) const {
-  RTC_CHECK_LE(x0, x1);                     // Valid interval.
-  RTC_CHECK_GE(x0, limiter_start_linear_);  // Beyond-knee region only.
-  auto limiter_integral = [this](const double& x) {
-    return gain_curve_limiter_i2_ * std::pow(x, gain_curve_limiter_i1_);
-  };
-  return limiter_integral(x1) - limiter_integral(x0);
+void Limiter::Reset() {
+  level_estimator_.Reset();
 }
 
-double Limiter::GetKneeRegionOutputLevelDbfs(double input_level_dbfs) const {
-  return knee_region_polynomial_[0] * input_level_dbfs * input_level_dbfs +
-         knee_region_polynomial_[1] * input_level_dbfs +
-         knee_region_polynomial_[2];
-}
-
-double Limiter::GetCompressorRegionOutputLevelDbfs(
-    double input_level_dbfs) const {
-  return (input_level_dbfs - max_input_level_db_) / compression_ratio_;
+float Limiter::LastAudioLevel() const {
+  return level_estimator_.LastAudioLevel();
 }
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/agc2/limiter.h b/modules/audio_processing/agc2/limiter.h
index f350bae..1e0ab71 100644
--- a/modules/audio_processing/agc2/limiter.h
+++ b/modules/audio_processing/agc2/limiter.h
@@ -11,62 +11,52 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_LIMITER_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_LIMITER_H_
 
-#include <array>
+#include <string>
+#include <vector>
 
-#include "modules/audio_processing/agc2/agc2_testing_common.h"
+#include "modules/audio_processing/agc2/fixed_digital_level_estimator.h"
+#include "modules/audio_processing/agc2/interpolated_gain_curve.h"
+#include "modules/audio_processing/include/audio_frame_view.h"
+#include "rtc_base/constructormagic.h"
 
 namespace webrtc {
+class ApmDataDumper;
 
-// A class for computing gain curve parameters. The gain curve is
-// defined by constants kLimiterMaxInputLevelDbFs, kLimiterKneeSmoothnessDb,
-// kLimiterCompressionRatio. The curve consints of one linear part,
-// one quadratic polynomial part and another linear part. The
-// constants define the parameters of the parts.
 class Limiter {
  public:
-  Limiter();
+  Limiter(size_t sample_rate_hz,
+          ApmDataDumper* apm_data_dumper,
+          std::string histogram_name_prefix);
+  Limiter(const Limiter& limiter) = delete;
+  Limiter& operator=(const Limiter& limiter) = delete;
+  ~Limiter();
 
-  double max_input_level_db() const { return max_input_level_db_; }
-  double max_input_level_linear() const { return max_input_level_linear_; }
-  double knee_start_linear() const { return knee_start_linear_; }
-  double limiter_start_linear() const { return limiter_start_linear_; }
+  // Applies limiter and hard-clipping to |signal|.
+  void Process(AudioFrameView<float> signal);
+  InterpolatedGainCurve::Stats GetGainCurveStats() const;
 
-  // These methods can be marked 'constexpr' in C++ 14.
-  double GetOutputLevelDbfs(double input_level_dbfs) const;
-  double GetGainLinear(double input_level_linear) const;
-  double GetGainFirstDerivativeLinear(double x) const;
-  double GetGainIntegralLinear(double x0, double x1) const;
+  // Supported rates must be
+  // * supported by FixedDigitalLevelEstimator
+  // * below kMaximalNumberOfSamplesPerChannel*1000/kFrameDurationMs
+  //   so that samples_per_channel fit in the
+  //   per_sample_scaling_factors_ array.
+  void SetSampleRate(size_t sample_rate_hz);
+
+  // Resets the internal state.
+  void Reset();
+
+  float LastAudioLevel() const;
 
  private:
-  double GetKneeRegionOutputLevelDbfs(double input_level_dbfs) const;
-  double GetCompressorRegionOutputLevelDbfs(double input_level_dbfs) const;
+  const InterpolatedGainCurve interp_gain_curve_;
+  FixedDigitalLevelEstimator level_estimator_;
+  ApmDataDumper* const apm_data_dumper_ = nullptr;
 
-  static constexpr double max_input_level_db_ = test::kLimiterMaxInputLevelDbFs;
-  static constexpr double knee_smoothness_db_ = test::kLimiterKneeSmoothnessDb;
-  static constexpr double compression_ratio_ = test::kLimiterCompressionRatio;
-
-  const double max_input_level_linear_;
-
-  // Do not modify signal with level <= knee_start_dbfs_.
-  const double knee_start_dbfs_;
-  const double knee_start_linear_;
-
-  // The upper end of the knee region, which is between knee_start_dbfs_ and
-  // limiter_start_dbfs_.
-  const double limiter_start_dbfs_;
-  const double limiter_start_linear_;
-
-  // Coefficients {a, b, c} of the knee region polynomial
-  // ax^2 + bx + c in the DB scale.
-  const std::array<double, 3> knee_region_polynomial_;
-
-  // Parameters for the computation of the first derivative of GetGainLinear().
-  const double gain_curve_limiter_d1_;
-  const double gain_curve_limiter_d2_;
-
-  // Parameters for the computation of the integral of GetGainLinear().
-  const double gain_curve_limiter_i1_;
-  const double gain_curve_limiter_i2_;
+  // Work array containing the sub-frame scaling factors to be interpolated.
+  std::array<float, kSubFramesInFrame + 1> scaling_factors_ = {};
+  std::array<float, kMaximalNumberOfSamplesPerChannel>
+      per_sample_scaling_factors_ = {};
+  float last_scaling_factor_ = 1.f;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/agc2/limiter_db_gain_curve.cc b/modules/audio_processing/agc2/limiter_db_gain_curve.cc
new file mode 100644
index 0000000..d55ed5d
--- /dev/null
+++ b/modules/audio_processing/agc2/limiter_db_gain_curve.cc
@@ -0,0 +1,138 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/audio_processing/agc2/limiter_db_gain_curve.h"
+
+#include <cmath>
+
+#include "common_audio/include/audio_util.h"
+#include "modules/audio_processing/agc2/agc2_common.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace {
+
+double ComputeKneeStart(double max_input_level_db,
+                        double knee_smoothness_db,
+                        double compression_ratio) {
+  RTC_CHECK_LT((compression_ratio - 1.0) * knee_smoothness_db /
+                   (2.0 * compression_ratio),
+               max_input_level_db);
+  return -knee_smoothness_db / 2.0 -
+         max_input_level_db / (compression_ratio - 1.0);
+}
+
+std::array<double, 3> ComputeKneeRegionPolynomial(double knee_start_dbfs,
+                                                  double knee_smoothness_db,
+                                                  double compression_ratio) {
+  const double a = (1.0 - compression_ratio) /
+                   (2.0 * knee_smoothness_db * compression_ratio);
+  const double b = 1.0 - 2.0 * a * knee_start_dbfs;
+  const double c = a * knee_start_dbfs * knee_start_dbfs;
+  return {{a, b, c}};
+}
+
+double ComputeLimiterD1(double max_input_level_db, double compression_ratio) {
+  return (std::pow(10.0, -max_input_level_db / (20.0 * compression_ratio)) *
+          (1.0 - compression_ratio) / compression_ratio) /
+         kMaxAbsFloatS16Value;
+}
+
+constexpr double ComputeLimiterD2(double compression_ratio) {
+  return (1.0 - 2.0 * compression_ratio) / compression_ratio;
+}
+
+double ComputeLimiterI2(double max_input_level_db,
+                        double compression_ratio,
+                        double gain_curve_limiter_i1) {
+  RTC_CHECK_NE(gain_curve_limiter_i1, 0.f);
+  return std::pow(10.0, -max_input_level_db / (20.0 * compression_ratio)) /
+         gain_curve_limiter_i1 /
+         std::pow(kMaxAbsFloatS16Value, gain_curve_limiter_i1 - 1);
+}
+
+}  // namespace
+
+LimiterDbGainCurve::LimiterDbGainCurve()
+    : max_input_level_linear_(DbfsToFloatS16(max_input_level_db_)),
+      knee_start_dbfs_(ComputeKneeStart(max_input_level_db_,
+                                        knee_smoothness_db_,
+                                        compression_ratio_)),
+      knee_start_linear_(DbfsToFloatS16(knee_start_dbfs_)),
+      limiter_start_dbfs_(knee_start_dbfs_ + knee_smoothness_db_),
+      limiter_start_linear_(DbfsToFloatS16(limiter_start_dbfs_)),
+      knee_region_polynomial_(ComputeKneeRegionPolynomial(knee_start_dbfs_,
+                                                          knee_smoothness_db_,
+                                                          compression_ratio_)),
+      gain_curve_limiter_d1_(
+          Comput