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_(
+          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_);
+}
+
+constexpr double LimiterDbGainCurve::max_input_level_db_;
+constexpr double LimiterDbGainCurve::knee_smoothness_db_;
+constexpr double LimiterDbGainCurve::compression_ratio_;
+
+double LimiterDbGainCurve::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);
+}
+
+double LimiterDbGainCurve::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;
+}
+
+// Computes the first derivative of GetGainLinear() in |x|.
+double LimiterDbGainCurve::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_);
+}
+
+// Computes the integral of GetGainLinear() in the range [x0, x1].
+double LimiterDbGainCurve::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);
+}
+
+double LimiterDbGainCurve::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 LimiterDbGainCurve::GetCompressorRegionOutputLevelDbfs(
+    double input_level_dbfs) const {
+  return (input_level_dbfs - max_input_level_db_) / compression_ratio_;
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_processing/agc2/limiter_db_gain_curve.h b/modules/audio_processing/agc2/limiter_db_gain_curve.h
new file mode 100644
index 0000000..9086e26
--- /dev/null
+++ b/modules/audio_processing/agc2/limiter_db_gain_curve.h
@@ -0,0 +1,76 @@
+/*
+ *  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_LIMITER_DB_GAIN_CURVE_H_
+#define MODULES_AUDIO_PROCESSING_AGC2_LIMITER_DB_GAIN_CURVE_H_
+
+#include <array>
+
+#include "modules/audio_processing/agc2/agc2_testing_common.h"
+
+namespace webrtc {
+
+// A class for computing a limiter gain curve (in dB scale) given a set of
+// hard-coded parameters (namely, kLimiterDbGainCurveMaxInputLevelDbFs,
+// kLimiterDbGainCurveKneeSmoothnessDb, and
+// kLimiterDbGainCurveCompressionRatio). The generated curve consists of four
+// regions: identity (linear), knee (quadratic polynomial), compression
+// (linear), saturation (linear). The aforementioned constants are used to shape
+// the different regions.
+class LimiterDbGainCurve {
+ public:
+  LimiterDbGainCurve();
+
+  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_; }
+
+  // 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;
+
+ private:
+  double GetKneeRegionOutputLevelDbfs(double input_level_dbfs) const;
+  double GetCompressorRegionOutputLevelDbfs(double input_level_dbfs) const;
+
+  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_;
+};
+
+}  // namespace webrtc
+
+#endif  // MODULES_AUDIO_PROCESSING_AGC2_LIMITER_DB_GAIN_CURVE_H_
diff --git a/modules/audio_processing/agc2/limiter_db_gain_curve_unittest.cc b/modules/audio_processing/agc2/limiter_db_gain_curve_unittest.cc
new file mode 100644
index 0000000..049c8d5
--- /dev/null
+++ b/modules/audio_processing/agc2/limiter_db_gain_curve_unittest.cc
@@ -0,0 +1,60 @@
+/*
+ *  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 "rtc_base/gunit.h"
+
+namespace webrtc {
+
+TEST(FixedDigitalGainController2Limiter, ConstructDestruct) {
+  LimiterDbGainCurve l;
+}
+
+TEST(FixedDigitalGainController2Limiter, GainCurveShouldBeMonotone) {
+  LimiterDbGainCurve l;
+  float last_output_level = 0.f;
+  bool has_last_output_level = false;
+  for (float level = -90.f; level <= l.max_input_level_db(); level += 0.5f) {
+    const float current_output_level = l.GetOutputLevelDbfs(level);
+    if (!has_last_output_level) {
+      last_output_level = current_output_level;
+      has_last_output_level = true;
+    }
+    EXPECT_LE(last_output_level, current_output_level);
+    last_output_level = current_output_level;
+  }
+}
+
+TEST(FixedDigitalGainController2Limiter, GainCurveShouldBeContinuous) {
+  LimiterDbGainCurve l;
+  float last_output_level = 0.f;
+  bool has_last_output_level = false;
+  constexpr float kMaxDelta = 0.5f;
+  for (float level = -90.f; level <= l.max_input_level_db(); level += 0.5f) {
+    const float current_output_level = l.GetOutputLevelDbfs(level);
+    if (!has_last_output_level) {
+      last_output_level = current_output_level;
+      has_last_output_level = true;
+    }
+    EXPECT_LE(current_output_level, last_output_level + kMaxDelta);
+    last_output_level = current_output_level;
+  }
+}
+
+TEST(FixedDigitalGainController2Limiter, OutputGainShouldBeLessThanFullScale) {
+  LimiterDbGainCurve l;
+  for (float level = -90.f; level <= l.max_input_level_db(); level += 0.5f) {
+    const float current_output_level = l.GetOutputLevelDbfs(level);
+    EXPECT_LE(current_output_level, 0.f);
+  }
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_processing/agc2/limiter_unittest.cc b/modules/audio_processing/agc2/limiter_unittest.cc
index 7079812..e662a7f 100644
--- a/modules/audio_processing/agc2/limiter_unittest.cc
+++ b/modules/audio_processing/agc2/limiter_unittest.cc
@@ -10,50 +10,50 @@
 
 #include "modules/audio_processing/agc2/limiter.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(FixedDigitalGainController2Limiter, ConstructDestruct) {
-  Limiter l;
+TEST(Limiter, LimiterShouldConstructAndRun) {
+  const int sample_rate_hz = 48000;
+  ApmDataDumper apm_data_dumper(0);
+
+  Limiter limiter(sample_rate_hz, &apm_data_dumper, "");
+
+  VectorFloatFrame vectors_with_float_frame(1, sample_rate_hz / 100,
+                                            kMaxAbsFloatS16Value);
+  limiter.Process(vectors_with_float_frame.float_frame_view());
 }
 
-TEST(FixedDigitalGainController2Limiter, GainCurveShouldBeMonotone) {
-  Limiter l;
-  float last_output_level = 0.f;
-  bool has_last_output_level = false;
-  for (float level = -90.f; level <= l.max_input_level_db(); level += 0.5f) {
-    const float current_output_level = l.GetOutputLevelDbfs(level);
-    if (!has_last_output_level) {
-      last_output_level = current_output_level;
-      has_last_output_level = true;
-    }
-    EXPECT_LE(last_output_level, current_output_level);
-    last_output_level = current_output_level;
+TEST(Limiter, OutputVolumeAboveThreshold) {
+  const int sample_rate_hz = 48000;
+  const float input_level =
+      (kMaxAbsFloatS16Value + DbfsToFloatS16(test::kLimiterMaxInputLevelDbFs)) /
+      2.f;
+  ApmDataDumper apm_data_dumper(0);
+
+  Limiter limiter(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);
+    limiter.Process(vectors_with_float_frame.float_frame_view());
   }
-}
 
-TEST(FixedDigitalGainController2Limiter, GainCurveShouldBeContinuous) {
-  Limiter l;
-  float last_output_level = 0.f;
-  bool has_last_output_level = false;
-  constexpr float kMaxDelta = 0.5f;
-  for (float level = -90.f; level <= l.max_input_level_db(); level += 0.5f) {
-    const float current_output_level = l.GetOutputLevelDbfs(level);
-    if (!has_last_output_level) {
-      last_output_level = current_output_level;
-      has_last_output_level = true;
-    }
-    EXPECT_LE(current_output_level, last_output_level + kMaxDelta);
-    last_output_level = current_output_level;
-  }
-}
+  VectorFloatFrame vectors_with_float_frame(1, sample_rate_hz / 100,
+                                            input_level);
+  limiter.Process(vectors_with_float_frame.float_frame_view());
+  rtc::ArrayView<const float> channel =
+      vectors_with_float_frame.float_frame_view().channel(0);
 
-TEST(FixedDigitalGainController2Limiter, OutputGainShouldBeLessThanFullScale) {
-  Limiter l;
-  for (float level = -90.f; level <= l.max_input_level_db(); level += 0.5f) {
-    const float current_output_level = l.GetOutputLevelDbfs(level);
-    EXPECT_LE(current_output_level, 0.f);
+  for (const auto& sample : channel) {
+    EXPECT_LT(0.9f * kMaxAbsFloatS16Value, sample);
   }
 }
 
diff --git a/modules/audio_processing/agc2/noise_level_estimator.cc b/modules/audio_processing/agc2/noise_level_estimator.cc
index d9aaf1f..6e43672 100644
--- a/modules/audio_processing/agc2/noise_level_estimator.cc
+++ b/modules/audio_processing/agc2/noise_level_estimator.cc
@@ -10,13 +10,15 @@
 
 #include "modules/audio_processing/agc2/noise_level_estimator.h"
 
-#include <math.h>
-
+#include <stddef.h>
 #include <algorithm>
+#include <cmath>
 #include <numeric>
 
+#include "api/array_view.h"
 #include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/agc2/noise_spectrum_estimator.cc b/modules/audio_processing/agc2/noise_spectrum_estimator.cc
index 9e08126..5735faf 100644
--- a/modules/audio_processing/agc2/noise_spectrum_estimator.cc
+++ b/modules/audio_processing/agc2/noise_spectrum_estimator.cc
@@ -16,6 +16,7 @@
 #include "api/array_view.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/arraysize.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 namespace {
diff --git a/modules/audio_processing/agc2/rnn_vad/features_extraction.cc b/modules/audio_processing/agc2/rnn_vad/features_extraction.cc
index 8ab5673..8f472a5 100644
--- a/modules/audio_processing/agc2/rnn_vad/features_extraction.cc
+++ b/modules/audio_processing/agc2/rnn_vad/features_extraction.cc
@@ -10,6 +10,8 @@
 
 #include "modules/audio_processing/agc2/rnn_vad/features_extraction.h"
 
+#include <array>
+
 #include "modules/audio_processing/agc2/rnn_vad/lp_residual.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/agc2/rnn_vad/features_extraction.h b/modules/audio_processing/agc2/rnn_vad/features_extraction.h
index 1f63885..ce5cce1 100644
--- a/modules/audio_processing/agc2/rnn_vad/features_extraction.h
+++ b/modules/audio_processing/agc2/rnn_vad/features_extraction.h
@@ -11,12 +11,12 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_FEATURES_EXTRACTION_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_FEATURES_EXTRACTION_H_
 
-#include <memory>
 #include <vector>
 
 #include "api/array_view.h"
 #include "modules/audio_processing/agc2/biquad_filter.h"
 #include "modules/audio_processing/agc2/rnn_vad/common.h"
+#include "modules/audio_processing/agc2/rnn_vad/pitch_info.h"
 #include "modules/audio_processing/agc2/rnn_vad/pitch_search.h"
 #include "modules/audio_processing/agc2/rnn_vad/sequence_buffer.h"
 #include "modules/audio_processing/agc2/rnn_vad/spectral_features.h"
diff --git a/modules/audio_processing/agc2/rnn_vad/fft_util.cc b/modules/audio_processing/agc2/rnn_vad/fft_util.cc
index 1017400..a1c5dac 100644
--- a/modules/audio_processing/agc2/rnn_vad/fft_util.cc
+++ b/modules/audio_processing/agc2/rnn_vad/fft_util.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_processing/agc2/rnn_vad/fft_util.h"
 
+#include <stddef.h>
 #include <cmath>
 
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/agc2/rnn_vad/lp_residual.h b/modules/audio_processing/agc2/rnn_vad/lp_residual.h
index bffafd2..cddedca 100644
--- a/modules/audio_processing/agc2/rnn_vad/lp_residual.h
+++ b/modules/audio_processing/agc2/rnn_vad/lp_residual.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_LP_RESIDUAL_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_LP_RESIDUAL_H_
 
+#include <stddef.h>
+
 #include "api/array_view.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/agc2/rnn_vad/pitch_search.cc b/modules/audio_processing/agc2/rnn_vad/pitch_search.cc
index 1f8859d..aa0b751 100644
--- a/modules/audio_processing/agc2/rnn_vad/pitch_search.cc
+++ b/modules/audio_processing/agc2/rnn_vad/pitch_search.cc
@@ -10,6 +10,11 @@
 
 #include "modules/audio_processing/agc2/rnn_vad/pitch_search.h"
 
+#include <array>
+#include <cstddef>
+
+#include "rtc_base/checks.h"
+
 namespace webrtc {
 namespace rnn_vad {
 
diff --git a/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc b/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc
index b7b44d2..32ee8c0 100644
--- a/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc
+++ b/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.cc
@@ -10,10 +10,12 @@
 
 #include "modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h"
 
+#include <stdlib.h>
 #include <algorithm>
 #include <cmath>
+#include <complex>
+#include <cstddef>
 #include <numeric>
-#include <utility>
 
 #include "modules/audio_processing/agc2/rnn_vad/common.h"
 #include "rtc_base/checks.h"
diff --git a/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h b/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h
index 75f7f17..bb747bb 100644
--- a/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h
+++ b/modules/audio_processing/agc2/rnn_vad/pitch_search_internal.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_PITCH_SEARCH_INTERNAL_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_PITCH_SEARCH_INTERNAL_H_
 
+#include <stddef.h>
 #include <array>
 
 #include "api/array_view.h"
diff --git a/modules/audio_processing/agc2/rnn_vad/rnn.h b/modules/audio_processing/agc2/rnn_vad/rnn.h
index b3a3b9c..a7d057d 100644
--- a/modules/audio_processing/agc2/rnn_vad/rnn.h
+++ b/modules/audio_processing/agc2/rnn_vad/rnn.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_RNN_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_RNN_H_
 
+#include <stddef.h>
+#include <sys/types.h>
 #include <array>
 
 #include "api/array_view.h"
diff --git a/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc b/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc
index 5fba0bf..b66dfd6 100644
--- a/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc
+++ b/modules/audio_processing/agc2/rnn_vad/rnn_vad_tool.cc
@@ -25,22 +25,22 @@
 namespace test {
 namespace {
 
-DEFINE_string(i, "", "Path to the input wav file");
+WEBRTC_DEFINE_string(i, "", "Path to the input wav file");
 std::string InputWavFile() {
   return static_cast<std::string>(FLAG_i);
 }
 
-DEFINE_string(f, "", "Path to the output features file");
+WEBRTC_DEFINE_string(f, "", "Path to the output features file");
 std::string OutputFeaturesFile() {
   return static_cast<std::string>(FLAG_f);
 }
 
-DEFINE_string(o, "", "Path to the output VAD probabilities file");
+WEBRTC_DEFINE_string(o, "", "Path to the output VAD probabilities file");
 std::string OutputVadProbsFile() {
   return static_cast<std::string>(FLAG_o);
 }
 
-DEFINE_bool(help, false, "Prints this message");
+WEBRTC_DEFINE_bool(help, false, "Prints this message");
 
 }  // namespace
 
diff --git a/modules/audio_processing/agc2/rnn_vad/spectral_features.h b/modules/audio_processing/agc2/rnn_vad/spectral_features.h
index bedd7ab..5c33dcd 100644
--- a/modules/audio_processing/agc2/rnn_vad/spectral_features.h
+++ b/modules/audio_processing/agc2/rnn_vad/spectral_features.h
@@ -13,6 +13,7 @@
 
 #include <array>
 #include <complex>
+#include <cstddef>
 #include <vector>
 
 #include "api/array_view.h"
diff --git a/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc b/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc
index 9f4e218..74211fe 100644
--- a/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc
+++ b/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.cc
@@ -12,6 +12,7 @@
 
 #include <algorithm>
 #include <cmath>
+#include <cstddef>
 
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h b/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h
index 45bb382..edfd18c 100644
--- a/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h
+++ b/modules/audio_processing/agc2/rnn_vad/spectral_features_internal.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_SPECTRAL_FEATURES_INTERNAL_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_RNN_VAD_SPECTRAL_FEATURES_INTERNAL_H_
 
+#include <stddef.h>
 #include <array>
 #include <complex>
 
diff --git a/modules/audio_processing/agc2/saturation_protector.cc b/modules/audio_processing/agc2/saturation_protector.cc
index 0895583..94a52ea 100644
--- a/modules/audio_processing/agc2/saturation_protector.cc
+++ b/modules/audio_processing/agc2/saturation_protector.cc
@@ -11,6 +11,7 @@
 #include "modules/audio_processing/agc2/saturation_protector.h"
 
 #include <algorithm>
+#include <iterator>
 
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/numerics/safe_minmax.h"
@@ -56,9 +57,14 @@
 }
 
 SaturationProtector::SaturationProtector(ApmDataDumper* apm_data_dumper)
+    : SaturationProtector(apm_data_dumper, GetExtraSaturationMarginOffsetDb()) {
+}
+
+SaturationProtector::SaturationProtector(ApmDataDumper* apm_data_dumper,
+                                         float extra_saturation_margin_db)
     : apm_data_dumper_(apm_data_dumper),
       last_margin_(GetInitialSaturationMarginDb()),
-      extra_saturation_margin_db_(GetExtraSaturationMarginOffsetDb()) {}
+      extra_saturation_margin_db_(extra_saturation_margin_db) {}
 
 void SaturationProtector::UpdateMargin(
     const VadWithLevel::LevelAndProbability& vad_data,
diff --git a/modules/audio_processing/agc2/saturation_protector.h b/modules/audio_processing/agc2/saturation_protector.h
index 1705f6a..e637469 100644
--- a/modules/audio_processing/agc2/saturation_protector.h
+++ b/modules/audio_processing/agc2/saturation_protector.h
@@ -24,6 +24,9 @@
  public:
   explicit SaturationProtector(ApmDataDumper* apm_data_dumper);
 
+  SaturationProtector(ApmDataDumper* apm_data_dumper,
+                      float extra_saturation_margin_db);
+
   // Update and return margin estimate. This method should be called
   // whenever a frame is reliably classified as 'speech'.
   //
@@ -60,7 +63,7 @@
 
   float last_margin_;
   PeakEnveloper peak_enveloper_;
-  float extra_saturation_margin_db_;
+  const float extra_saturation_margin_db_;
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/agc2/signal_classifier.cc b/modules/audio_processing/agc2/signal_classifier.cc
index 0ec3414..8778c49 100644
--- a/modules/audio_processing/agc2/signal_classifier.cc
+++ b/modules/audio_processing/agc2/signal_classifier.cc
@@ -18,7 +18,7 @@
 #include "modules/audio_processing/agc2/down_sampler.h"
 #include "modules/audio_processing/agc2/noise_spectrum_estimator.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "rtc_base/constructormagic.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 namespace {
diff --git a/modules/audio_processing/agc2/vad_with_level.cc b/modules/audio_processing/agc2/vad_with_level.cc
index decfacd..52970df 100644
--- a/modules/audio_processing/agc2/vad_with_level.cc
+++ b/modules/audio_processing/agc2/vad_with_level.cc
@@ -11,10 +11,12 @@
 #include "modules/audio_processing/agc2/vad_with_level.h"
 
 #include <algorithm>
+#include <array>
+#include <cmath>
 
+#include "api/array_view.h"
 #include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/agc2/rnn_vad/common.h"
-#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/agc2/vad_with_level.h b/modules/audio_processing/agc2/vad_with_level.h
index 67a00ce..b0ad868 100644
--- a/modules/audio_processing/agc2/vad_with_level.h
+++ b/modules/audio_processing/agc2/vad_with_level.h
@@ -11,7 +11,6 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC2_VAD_WITH_LEVEL_H_
 #define MODULES_AUDIO_PROCESSING_AGC2_VAD_WITH_LEVEL_H_
 
-#include "api/array_view.h"
 #include "common_audio/resampler/include/push_resampler.h"
 #include "modules/audio_processing/agc2/rnn_vad/features_extraction.h"
 #include "modules/audio_processing/agc2/rnn_vad/rnn.h"
diff --git a/modules/audio_processing/audio_buffer.cc b/modules/audio_processing/audio_buffer.cc
index f163f5a..0c38a4f 100644
--- a/modules/audio_processing/audio_buffer.cc
+++ b/modules/audio_processing/audio_buffer.cc
@@ -10,11 +10,13 @@
 
 #include "modules/audio_processing/audio_buffer.h"
 
+#include <string.h>
+#include <cstdint>
+
 #include "common_audio/channel_buffer.h"
 #include "common_audio/include/audio_util.h"
 #include "common_audio/resampler/push_sinc_resampler.h"
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "modules/audio_processing/common.h"
+#include "modules/audio_processing/splitting_filter.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/audio_buffer.h b/modules/audio_processing/audio_buffer.h
index ade3eec..469646e 100644
--- a/modules/audio_processing/audio_buffer.h
+++ b/modules/audio_processing/audio_buffer.h
@@ -11,18 +11,21 @@
 #ifndef MODULES_AUDIO_PROCESSING_AUDIO_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_AUDIO_BUFFER_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <vector>
 
 #include "api/audio/audio_frame.h"
 #include "common_audio/channel_buffer.h"
 #include "modules/audio_processing/include/audio_processing.h"
-#include "modules/audio_processing/splitting_filter.h"
+#include "rtc_base/gtest_prod_util.h"
 
 namespace webrtc {
 
-class PushSincResampler;
 class IFChannelBuffer;
+class PushSincResampler;
+class SplittingFilter;
 
 enum Band { kBand0To8kHz = 0, kBand8To16kHz = 1, kBand16To24kHz = 2 };
 
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index b9153fa..3764647 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -10,15 +10,16 @@
 
 #include "modules/audio_processing/audio_processing_impl.h"
 
-#include <math.h>
 #include <algorithm>
+#include <cstdint>
 #include <string>
+#include <type_traits>
+#include <utility>
 
+#include "absl/types/optional.h"
+#include "api/array_view.h"
 #include "common_audio/audio_converter.h"
-#include "common_audio/channel_buffer.h"
 #include "common_audio/include/audio_util.h"
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "modules/audio_processing/aec/aec_core.h"
 #include "modules/audio_processing/agc/agc_manager_direct.h"
 #include "modules/audio_processing/agc2/gain_applier.h"
 #include "modules/audio_processing/audio_buffer.h"
@@ -28,6 +29,7 @@
 #include "modules/audio_processing/gain_control_for_experimental_agc.h"
 #include "modules/audio_processing/gain_control_impl.h"
 #include "modules/audio_processing/gain_controller2.h"
+#include "modules/audio_processing/include/audio_frame_view.h"
 #include "modules/audio_processing/level_estimator_impl.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "modules/audio_processing/low_cut_filter.h"
@@ -37,10 +39,9 @@
 #include "modules/audio_processing/voice_detection_impl.h"
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/constructormagic.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/platform_file.h"
 #include "rtc_base/refcountedobject.h"
-#include "rtc_base/system/arch.h"
 #include "rtc_base/timeutils.h"
 #include "rtc_base/trace_event.h"
 #include "system_wrappers/include/metrics.h"
@@ -115,29 +116,6 @@
 // TODO(peah): Decrease this once we properly handle hugely unbalanced
 // reverse and forward call numbers.
 static const size_t kMaxNumFramesToBuffer = 100;
-
-class HighPassFilterImpl : public HighPassFilter {
- public:
-  explicit HighPassFilterImpl(AudioProcessingImpl* apm) : apm_(apm) {}
-  ~HighPassFilterImpl() override = default;
-
-  // HighPassFilter implementation.
-  int Enable(bool enable) override {
-    apm_->MutateConfig([enable](AudioProcessing::Config* config) {
-      config->high_pass_filter.enabled = enable;
-    });
-
-    return AudioProcessing::kNoError;
-  }
-
-  bool is_enabled() const override {
-    return apm_->GetConfig().high_pass_filter.enabled;
-  }
-
- private:
-  AudioProcessingImpl* apm_;
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(HighPassFilterImpl);
-};
 }  // namespace
 
 // Throughout webrtc, it's assumed that success is represented by zero.
@@ -249,8 +227,6 @@
 struct AudioProcessingImpl::ApmPublicSubmodules {
   ApmPublicSubmodules() {}
   // Accessed externally of APM without any lock acquired.
-  std::unique_ptr<EchoCancellationImpl> echo_cancellation;
-  std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
   std::unique_ptr<GainControlImpl> gain_control;
   std::unique_ptr<LevelEstimatorImpl> level_estimator;
   std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
@@ -276,7 +252,9 @@
   std::unique_ptr<GainController2> gain_controller2;
   std::unique_ptr<LowCutFilter> low_cut_filter;
   rtc::scoped_refptr<EchoDetector> echo_detector;
+  std::unique_ptr<EchoCancellationImpl> echo_cancellation;
   std::unique_ptr<EchoControl> echo_controller;
+  std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
   std::unique_ptr<CustomProcessing> capture_post_processor;
   std::unique_ptr<CustomProcessing> render_pre_processor;
   std::unique_ptr<GainApplier> pre_amplifier;
@@ -352,7 +330,6 @@
       render_runtime_settings_(kRuntimeSettingQueueSize),
       capture_runtime_settings_enqueuer_(&capture_runtime_settings_),
       render_runtime_settings_enqueuer_(&render_runtime_settings_),
-      high_pass_filter_impl_(new HighPassFilterImpl(this)),
       echo_control_factory_(std::move(echo_control_factory)),
       submodule_states_(!!capture_post_processor,
                         !!render_pre_processor,
@@ -390,10 +367,6 @@
     capture_nonlocked_.echo_controller_enabled =
         static_cast<bool>(echo_control_factory_);
 
-    public_submodules_->echo_cancellation.reset(
-        new EchoCancellationImpl(&crit_render_, &crit_capture_));
-    public_submodules_->echo_control_mobile.reset(
-        new EchoControlMobileImpl(&crit_render_, &crit_capture_));
     public_submodules_->gain_control.reset(
         new GainControlImpl(&crit_render_, &crit_capture_));
     public_submodules_->level_estimator.reset(
@@ -412,6 +385,8 @@
           new rtc::RefCountedObject<ResidualEchoDetector>();
     }
 
+    private_submodules_->echo_cancellation.reset(new EchoCancellationImpl());
+    private_submodules_->echo_control_mobile.reset(new EchoControlMobileImpl());
     // TODO(alessiob): Move the injected gain controller once injection is
     // implemented.
     private_submodules_->gain_controller2.reset(new GainController2());
@@ -530,16 +505,16 @@
                       formats_.api_format.output_stream().num_channels(),
                       formats_.api_format.output_stream().num_frames()));
 
-  public_submodules_->echo_cancellation->Initialize(
+  private_submodules_->echo_cancellation->Initialize(
       proc_sample_rate_hz(), num_reverse_channels(), num_output_channels(),
       num_proc_channels());
   AllocateRenderQueue();
 
-  int success = public_submodules_->echo_cancellation->enable_metrics(true);
+  int success = private_submodules_->echo_cancellation->enable_metrics(true);
   RTC_DCHECK_EQ(0, success);
-  success = public_submodules_->echo_cancellation->enable_delay_logging(true);
+  success = private_submodules_->echo_cancellation->enable_delay_logging(true);
   RTC_DCHECK_EQ(0, success);
-  public_submodules_->echo_control_mobile->Initialize(
+  private_submodules_->echo_control_mobile->Initialize(
       proc_split_sample_rate_hz(), num_reverse_channels(),
       num_output_channels());
 
@@ -662,18 +637,18 @@
 }
 
 void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
-  config_ = config;
-
   // Run in a single-threaded manner when applying the settings.
   rtc::CritScope cs_render(&crit_render_);
   rtc::CritScope cs_capture(&crit_capture_);
 
-  public_submodules_->echo_cancellation->Enable(
+  config_ = config;
+
+  private_submodules_->echo_cancellation->Enable(
       config_.echo_canceller.enabled && !config_.echo_canceller.mobile_mode);
-  public_submodules_->echo_control_mobile->Enable(
+  private_submodules_->echo_control_mobile->Enable(
       config_.echo_canceller.enabled && config_.echo_canceller.mobile_mode);
 
-  public_submodules_->echo_cancellation->set_suppression_level(
+  private_submodules_->echo_cancellation->set_suppression_level(
       config.echo_canceller.legacy_moderate_suppression_level
           ? EchoCancellationImpl::SuppressionLevel::kModerateSuppression
           : EchoCancellationImpl::SuppressionLevel::kHighSuppression);
@@ -705,7 +680,7 @@
   rtc::CritScope cs_render(&crit_render_);
   rtc::CritScope cs_capture(&crit_capture_);
 
-  public_submodules_->echo_cancellation->SetExtraOptions(config);
+  private_submodules_->echo_cancellation->SetExtraOptions(config);
 
   if (capture_.transient_suppressor_enabled !=
       config.Get<ExperimentalNs>().enabled) {
@@ -1082,12 +1057,12 @@
 void AudioProcessingImpl::EmptyQueuedRenderAudio() {
   rtc::CritScope cs_capture(&crit_capture_);
   while (aec_render_signal_queue_->Remove(&aec_capture_queue_buffer_)) {
-    public_submodules_->echo_cancellation->ProcessRenderAudio(
+    private_submodules_->echo_cancellation->ProcessRenderAudio(
         aec_capture_queue_buffer_);
   }
 
   while (aecm_render_signal_queue_->Remove(&aecm_capture_queue_buffer_)) {
-    public_submodules_->echo_control_mobile->ProcessRenderAudio(
+    private_submodules_->echo_control_mobile->ProcessRenderAudio(
         aecm_capture_queue_buffer_);
   }
 
@@ -1109,9 +1084,6 @@
     // Acquire the capture lock in order to safely call the function
     // that retrieves the render side data. This function accesses APM
     // getters that need the capture lock held when being called.
-    // The lock needs to be released as
-    // public_submodules_->echo_control_mobile->is_enabled() acquires this lock
-    // as well.
     rtc::CritScope cs_capture(&crit_capture_);
     EmptyQueuedRenderAudio();
   }
@@ -1180,8 +1152,8 @@
   // Ensure that not both the AEC and AECM are active at the same time.
   // TODO(peah): Simplify once the public API Enable functions for these
   // are moved to APM.
-  RTC_DCHECK(!(public_submodules_->echo_cancellation->is_enabled() &&
-               public_submodules_->echo_control_mobile->is_enabled()));
+  RTC_DCHECK(!(private_submodules_->echo_cancellation->is_enabled() &&
+               private_submodules_->echo_control_mobile->is_enabled()));
 
   MaybeUpdateHistograms();
 
@@ -1265,7 +1237,7 @@
 
   // Ensure that the stream delay was set before the call to the
   // AEC ProcessCaptureAudio function.
-  if (public_submodules_->echo_cancellation->is_enabled() &&
+  if (private_submodules_->echo_cancellation->is_enabled() &&
       !private_submodules_->echo_controller && !was_stream_delay_set()) {
     return AudioProcessing::kStreamParameterNotSetError;
   }
@@ -1281,11 +1253,11 @@
     private_submodules_->echo_controller->ProcessCapture(
         capture_buffer, capture_.echo_path_gain_change);
   } else {
-    RETURN_ON_ERR(public_submodules_->echo_cancellation->ProcessCaptureAudio(
+    RETURN_ON_ERR(private_submodules_->echo_cancellation->ProcessCaptureAudio(
         capture_buffer, stream_delay_ms()));
   }
 
-  if (public_submodules_->echo_control_mobile->is_enabled() &&
+  if (private_submodules_->echo_control_mobile->is_enabled() &&
       public_submodules_->noise_suppression->is_enabled()) {
     capture_buffer->CopyLowPassToReference();
   }
@@ -1293,14 +1265,14 @@
 
   // Ensure that the stream delay was set before the call to the
   // AECM ProcessCaptureAudio function.
-  if (public_submodules_->echo_control_mobile->is_enabled() &&
+  if (private_submodules_->echo_control_mobile->is_enabled() &&
       !was_stream_delay_set()) {
     return AudioProcessing::kStreamParameterNotSetError;
   }
 
   if (!(private_submodules_->echo_controller ||
-        public_submodules_->echo_cancellation->is_enabled())) {
-    RETURN_ON_ERR(public_submodules_->echo_control_mobile->ProcessCaptureAudio(
+        private_submodules_->echo_cancellation->is_enabled())) {
+    RETURN_ON_ERR(private_submodules_->echo_control_mobile->ProcessCaptureAudio(
         capture_buffer, stream_delay_ms()));
   }
 
@@ -1315,7 +1287,7 @@
   }
   RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio(
       capture_buffer,
-      public_submodules_->echo_cancellation->stream_has_echo()));
+      private_submodules_->echo_cancellation->stream_has_echo()));
 
   if (submodule_states_.CaptureMultiBandProcessingActive() &&
       SampleRateSupportsMultiBand(
@@ -1613,79 +1585,19 @@
   // Delete audio generator, if one is attached.
 }
 
-AudioProcessing::AudioProcessingStatistics::AudioProcessingStatistics() {
-  residual_echo_return_loss.Set(-100.0f, -100.0f, -100.0f, -100.0f);
-  echo_return_loss.Set(-100.0f, -100.0f, -100.0f, -100.0f);
-  echo_return_loss_enhancement.Set(-100.0f, -100.0f, -100.0f, -100.0f);
-  a_nlp.Set(-100.0f, -100.0f, -100.0f, -100.0f);
-}
-
-AudioProcessing::AudioProcessingStatistics::AudioProcessingStatistics(
-    const AudioProcessingStatistics& other) = default;
-
-AudioProcessing::AudioProcessingStatistics::~AudioProcessingStatistics() =
-    default;
-
-// TODO(ivoc): Remove this when GetStatistics() becomes pure virtual.
-AudioProcessing::AudioProcessingStatistics AudioProcessing::GetStatistics()
-    const {
-  return AudioProcessingStatistics();
-}
-
-// TODO(ivoc): Remove this when GetStatistics() becomes pure virtual.
-AudioProcessingStats AudioProcessing::GetStatistics(
-    bool has_remote_tracks) const {
-  return AudioProcessingStats();
-}
-
-AudioProcessing::AudioProcessingStatistics AudioProcessingImpl::GetStatistics()
-    const {
-  AudioProcessingStatistics stats;
-  EchoCancellationImpl::Metrics metrics;
-  if (private_submodules_->echo_controller) {
-    rtc::CritScope cs_capture(&crit_capture_);
-    auto ec_metrics = private_submodules_->echo_controller->GetMetrics();
-    float erl = static_cast<float>(ec_metrics.echo_return_loss);
-    float erle = static_cast<float>(ec_metrics.echo_return_loss_enhancement);
-    // Instant value will also be used for min, max and average.
-    stats.echo_return_loss.Set(erl, erl, erl, erl);
-    stats.echo_return_loss_enhancement.Set(erle, erle, erle, erle);
-  } else if (public_submodules_->echo_cancellation->GetMetrics(&metrics) ==
-             Error::kNoError) {
-    stats.a_nlp.Set(metrics.a_nlp);
-    stats.divergent_filter_fraction = metrics.divergent_filter_fraction;
-    stats.echo_return_loss.Set(metrics.echo_return_loss);
-    stats.echo_return_loss_enhancement.Set(
-        metrics.echo_return_loss_enhancement);
-    stats.residual_echo_return_loss.Set(metrics.residual_echo_return_loss);
-  }
-  {
-    rtc::CritScope cs_capture(&crit_capture_);
-    RTC_DCHECK(private_submodules_->echo_detector);
-    auto ed_metrics = private_submodules_->echo_detector->GetMetrics();
-    stats.residual_echo_likelihood = ed_metrics.echo_likelihood;
-    stats.residual_echo_likelihood_recent_max =
-        ed_metrics.echo_likelihood_recent_max;
-  }
-  public_submodules_->echo_cancellation->GetDelayMetrics(
-      &stats.delay_median, &stats.delay_standard_deviation,
-      &stats.fraction_poor_delays);
-  return stats;
-}
-
 AudioProcessingStats AudioProcessingImpl::GetStatistics(
     bool has_remote_tracks) const {
   AudioProcessingStats stats;
   if (has_remote_tracks) {
     EchoCancellationImpl::Metrics metrics;
+    rtc::CritScope cs_capture(&crit_capture_);
     if (private_submodules_->echo_controller) {
-      rtc::CritScope cs_capture(&crit_capture_);
       auto ec_metrics = private_submodules_->echo_controller->GetMetrics();
       stats.echo_return_loss = ec_metrics.echo_return_loss;
       stats.echo_return_loss_enhancement =
           ec_metrics.echo_return_loss_enhancement;
       stats.delay_ms = ec_metrics.delay_ms;
-    } else if (public_submodules_->echo_cancellation->GetMetrics(&metrics) ==
+    } else if (private_submodules_->echo_cancellation->GetMetrics(&metrics) ==
                Error::kNoError) {
       if (metrics.divergent_filter_fraction != -1.0f) {
         stats.divergent_filter_fraction =
@@ -1701,7 +1613,6 @@
       }
     }
     if (config_.residual_echo_detector.enabled) {
-      rtc::CritScope cs_capture(&crit_capture_);
       RTC_DCHECK(private_submodules_->echo_detector);
       auto ed_metrics = private_submodules_->echo_detector->GetMetrics();
       stats.residual_echo_likelihood = ed_metrics.echo_likelihood;
@@ -1710,7 +1621,7 @@
     }
     int delay_median, delay_std;
     float fraction_poor_delays;
-    if (public_submodules_->echo_cancellation->GetDelayMetrics(
+    if (private_submodules_->echo_cancellation->GetDelayMetrics(
             &delay_median, &delay_std, &fraction_poor_delays) ==
         Error::kNoError) {
       if (delay_median >= 0) {
@@ -1731,10 +1642,6 @@
   return public_submodules_->gain_control.get();
 }
 
-HighPassFilter* AudioProcessingImpl::high_pass_filter() const {
-  return high_pass_filter_impl_.get();
-}
-
 LevelEstimator* AudioProcessingImpl::level_estimator() const {
   return public_submodules_->level_estimator.get();
 }
@@ -1764,8 +1671,8 @@
 bool AudioProcessingImpl::UpdateActiveSubmoduleStates() {
   return submodule_states_.Update(
       config_.high_pass_filter.enabled,
-      public_submodules_->echo_cancellation->is_enabled(),
-      public_submodules_->echo_control_mobile->is_enabled(),
+      private_submodules_->echo_cancellation->is_enabled(),
+      private_submodules_->echo_control_mobile->is_enabled(),
       config_.residual_echo_detector.enabled,
       public_submodules_->noise_suppression->is_enabled(),
       public_submodules_->gain_control->is_enabled(),
@@ -1852,15 +1759,15 @@
 void AudioProcessingImpl::MaybeUpdateHistograms() {
   static const int kMinDiffDelayMs = 60;
 
-  if (public_submodules_->echo_cancellation->is_enabled()) {
+  if (private_submodules_->echo_cancellation->is_enabled()) {
     // Activate delay_jumps_ counters if we know echo_cancellation is running.
     // If a stream has echo we know that the echo_cancellation is in process.
     if (capture_.stream_delay_jumps == -1 &&
-        public_submodules_->echo_cancellation->stream_has_echo()) {
+        private_submodules_->echo_cancellation->stream_has_echo()) {
       capture_.stream_delay_jumps = 0;
     }
     if (capture_.aec_system_delay_jumps == -1 &&
-        public_submodules_->echo_cancellation->stream_has_echo()) {
+        private_submodules_->echo_cancellation->stream_has_echo()) {
       capture_.aec_system_delay_jumps = 0;
     }
 
@@ -1883,7 +1790,7 @@
         rtc::CheckedDivExact(capture_nonlocked_.split_rate, 1000);
     RTC_DCHECK_LT(0, samples_per_ms);
     const int aec_system_delay_ms =
-        public_submodules_->echo_cancellation->GetSystemDelayInSamples() /
+        private_submodules_->echo_cancellation->GetSystemDelayInSamples() /
         samples_per_ms;
     const int diff_aec_system_delay_ms =
         aec_system_delay_ms - capture_.last_aec_system_delay_ms;
@@ -1927,7 +1834,7 @@
     return;
   }
   std::string experiments_description =
-      public_submodules_->echo_cancellation->GetExperimentsDescription();
+      private_submodules_->echo_cancellation->GetExperimentsDescription();
   // TODO(peah): Add semicolon-separated concatenations of experiment
   // descriptions for other submodules.
   if (constants_.agc_clipped_level_min != kClippedLevelMin) {
@@ -1942,22 +1849,22 @@
 
   InternalAPMConfig apm_config;
 
-  apm_config.aec_enabled = public_submodules_->echo_cancellation->is_enabled();
+  apm_config.aec_enabled = private_submodules_->echo_cancellation->is_enabled();
   apm_config.aec_delay_agnostic_enabled =
-      public_submodules_->echo_cancellation->is_delay_agnostic_enabled();
+      private_submodules_->echo_cancellation->is_delay_agnostic_enabled();
   apm_config.aec_drift_compensation_enabled =
-      public_submodules_->echo_cancellation->is_drift_compensation_enabled();
+      private_submodules_->echo_cancellation->is_drift_compensation_enabled();
   apm_config.aec_extended_filter_enabled =
-      public_submodules_->echo_cancellation->is_extended_filter_enabled();
+      private_submodules_->echo_cancellation->is_extended_filter_enabled();
   apm_config.aec_suppression_level = static_cast<int>(
-      public_submodules_->echo_cancellation->suppression_level());
+      private_submodules_->echo_cancellation->suppression_level());
 
   apm_config.aecm_enabled =
-      public_submodules_->echo_control_mobile->is_enabled();
+      private_submodules_->echo_control_mobile->is_enabled();
   apm_config.aecm_comfort_noise_enabled =
-      public_submodules_->echo_control_mobile->is_comfort_noise_enabled();
-  apm_config.aecm_routing_mode =
-      static_cast<int>(public_submodules_->echo_control_mobile->routing_mode());
+      private_submodules_->echo_control_mobile->is_comfort_noise_enabled();
+  apm_config.aecm_routing_mode = static_cast<int>(
+      private_submodules_->echo_control_mobile->routing_mode());
 
   apm_config.agc_enabled = public_submodules_->gain_control->is_enabled();
   apm_config.agc_mode =
@@ -2032,7 +1939,7 @@
   AecDump::AudioProcessingState audio_proc_state;
   audio_proc_state.delay = capture_nonlocked_.stream_delay_ms;
   audio_proc_state.drift =
-      public_submodules_->echo_cancellation->stream_drift_samples();
+      private_submodules_->echo_cancellation->stream_drift_samples();
   audio_proc_state.level = gain_control()->stream_analog_level();
   audio_proc_state.keypress = capture_.key_pressed;
   aec_dump_->AddAudioProcessingState(audio_proc_state);
diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h
index 50cb82b..e376a74 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -109,7 +109,6 @@
   bool was_stream_delay_set() const override
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
 
-  AudioProcessingStatistics GetStatistics() const override;
   AudioProcessingStats GetStatistics(bool has_remote_tracks) const override;
 
   // Methods returning pointers to APM submodules.
@@ -118,8 +117,6 @@
   // created only once in a single-treaded manner
   // during APM creation).
   GainControl* gain_control() const override;
-  // TODO(peah): Deprecate this API call.
-  HighPassFilter* high_pass_filter() const override;
   LevelEstimator* level_estimator() const override;
   NoiseSuppression* noise_suppression() const override;
   VoiceDetection* voice_detection() const override;
@@ -164,9 +161,6 @@
   RuntimeSettingEnqueuer capture_runtime_settings_enqueuer_;
   RuntimeSettingEnqueuer render_runtime_settings_enqueuer_;
 
-  // Submodule interface implementations.
-  std::unique_ptr<HighPassFilter> high_pass_filter_impl_;
-
   // EchoControl factory.
   std::unique_ptr<EchoControlFactory> echo_control_factory_;
 
diff --git a/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
index 0e0a33f..9685ef9 100644
--- a/modules/audio_processing/audio_processing_impl_locking_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
@@ -487,10 +487,7 @@
 }
 
 AudioProcessingImplLockTest::AudioProcessingImplLockTest()
-    : test_complete_(false, false),
-      render_call_event_(false, false),
-      capture_call_event_(false, false),
-      render_thread_(RenderProcessorThreadFunc, this, "render"),
+    : render_thread_(RenderProcessorThreadFunc, this, "render"),
       capture_thread_(CaptureProcessorThreadFunc, this, "capture"),
       stats_thread_(StatsProcessorThreadFunc, this, "stats"),
       apm_(AudioProcessingBuilder().Create()),
diff --git a/modules/audio_processing/audio_processing_performance_unittest.cc b/modules/audio_processing/audio_processing_performance_unittest.cc
index 95f736c..84cb574 100644
--- a/modules/audio_processing/audio_processing_performance_unittest.cc
+++ b/modules/audio_processing/audio_processing_performance_unittest.cc
@@ -18,11 +18,11 @@
 #include "api/array_view.h"
 #include "modules/audio_processing/test/test_utils.h"
 #include "rtc_base/atomicops.h"
+#include "rtc_base/event.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/platform_thread.h"
 #include "rtc_base/random.h"
 #include "system_wrappers/include/clock.h"
-#include "system_wrappers/include/event_wrapper.h"
 #include "test/gtest.h"
 #include "test/testsupport/perf_test.h"
 
@@ -391,8 +391,7 @@
 class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
  public:
   CallSimulator()
-      : test_complete_(EventWrapper::Create()),
-        render_thread_(
+      : render_thread_(
             new rtc::PlatformThread(RenderProcessorThreadFunc, this, "render")),
         capture_thread_(new rtc::PlatformThread(CaptureProcessorThreadFunc,
                                                 this,
@@ -401,10 +400,10 @@
         simulation_config_(static_cast<SimulationConfig>(GetParam())) {}
 
   // Run the call simulation with a timeout.
-  EventTypeWrapper Run() {
+  bool Run() {
     StartThreads();
 
-    EventTypeWrapper result = test_complete_->Wait(kTestTimeout);
+    bool result = test_complete_.Wait(kTestTimeout);
 
     StopThreads();
 
@@ -420,7 +419,7 @@
   // done.
   bool MaybeEndTest() {
     if (frame_counters_.BothCountersExceedeThreshold(kMinNumFramesToProcess)) {
-      test_complete_->Set();
+      test_complete_.Set();
       return true;
     }
     return false;
@@ -570,7 +569,7 @@
   }
 
   // Event handler for the test.
-  const std::unique_ptr<EventWrapper> test_complete_;
+  rtc::Event test_complete_;
 
   // Thread related variables.
   std::unique_ptr<rtc::PlatformThread> render_thread_;
@@ -619,7 +618,7 @@
 // TODO(peah): Reactivate once issue 7712 has been resolved.
 TEST_P(CallSimulator, DISABLED_ApiCallDurationTest) {
   // Run test and verify that it did not time out.
-  EXPECT_EQ(kEventSignaled, Run());
+  EXPECT_TRUE(Run());
 }
 
 INSTANTIATE_TEST_CASE_P(
diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc
index 3f0decc..18e669f 100644
--- a/modules/audio_processing/audio_processing_unittest.cc
+++ b/modules/audio_processing/audio_processing_unittest.cc
@@ -1278,7 +1278,6 @@
   EXPECT_FALSE(config.echo_canceller.enabled);
   EXPECT_FALSE(config.high_pass_filter.enabled);
   EXPECT_FALSE(apm_->gain_control()->is_enabled());
-  EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
   EXPECT_FALSE(apm_->level_estimator()->is_enabled());
   EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
   EXPECT_FALSE(apm_->voice_detection()->is_enabled());
diff --git a/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc b/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc
index 7f60c4b..af0741e 100644
--- a/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc
+++ b/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc
@@ -74,9 +74,7 @@
     EchoCancellationImpl::SuppressionLevel suppression_level,
     bool stream_has_echo_reference,
     const rtc::ArrayView<const float>& output_reference) {
-  rtc::CriticalSection crit_render;
-  rtc::CriticalSection crit_capture;
-  EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
+  EchoCancellationImpl echo_canceller;
   SetupComponent(sample_rate_hz, suppression_level, drift_compensation_enabled,
                  &echo_canceller);
 
diff --git a/modules/audio_processing/echo_cancellation_impl.cc b/modules/audio_processing/echo_cancellation_impl.cc
index e6fe769..73fe51b 100644
--- a/modules/audio_processing/echo_cancellation_impl.cc
+++ b/modules/audio_processing/echo_cancellation_impl.cc
@@ -10,11 +10,13 @@
 
 #include "modules/audio_processing/echo_cancellation_impl.h"
 
+#include <stdint.h>
 #include <string.h>
 
 #include "modules/audio_processing/aec/aec_core.h"
 #include "modules/audio_processing/aec/echo_cancellation.h"
 #include "modules/audio_processing/audio_buffer.h"
+#include "modules/audio_processing/include/config.h"
 #include "rtc_base/checks.h"
 #include "system_wrappers/include/field_trial.h"
 
@@ -103,11 +105,8 @@
   void* state_;
 };
 
-EchoCancellationImpl::EchoCancellationImpl(rtc::CriticalSection* crit_render,
-                                           rtc::CriticalSection* crit_capture)
-    : crit_render_(crit_render),
-      crit_capture_(crit_capture),
-      drift_compensation_enabled_(false),
+EchoCancellationImpl::EchoCancellationImpl()
+    : drift_compensation_enabled_(false),
       metrics_enabled_(true),
       suppression_level_(kHighSuppression),
       stream_drift_samples_(0),
@@ -116,16 +115,12 @@
       delay_logging_enabled_(true),
       extended_filter_enabled_(false),
       delay_agnostic_enabled_(false),
-      enforce_zero_stream_delay_(EnforceZeroStreamDelay()) {
-  RTC_DCHECK(crit_render);
-  RTC_DCHECK(crit_capture);
-}
+      enforce_zero_stream_delay_(EnforceZeroStreamDelay()) {}
 
 EchoCancellationImpl::~EchoCancellationImpl() = default;
 
 void EchoCancellationImpl::ProcessRenderAudio(
     rtc::ArrayView<const float> packed_render_audio) {
-  rtc::CritScope cs_capture(crit_capture_);
   if (!enabled_) {
     return;
   }
@@ -149,7 +144,6 @@
 
 int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio,
                                               int stream_delay_ms) {
-  rtc::CritScope cs_capture(crit_capture_);
   if (!enabled_) {
     return AudioProcessing::kNoError;
   }
@@ -206,10 +200,6 @@
 }
 
 int EchoCancellationImpl::Enable(bool enable) {
-  // Run in a single-threaded manner.
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
-
   if (enable && !enabled_) {
     enabled_ = enable;  // Must be set before Initialize() is called.
 
@@ -227,68 +217,52 @@
 }
 
 bool EchoCancellationImpl::is_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return enabled_;
 }
 
 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) {
-  {
-    if (MapSetting(level) == -1) {
-      return AudioProcessing::kBadParameterError;
-    }
-    rtc::CritScope cs(crit_capture_);
-    suppression_level_ = level;
+  if (MapSetting(level) == -1) {
+    return AudioProcessing::kBadParameterError;
   }
+  suppression_level_ = level;
   return Configure();
 }
 
 EchoCancellationImpl::SuppressionLevel EchoCancellationImpl::suppression_level()
     const {
-  rtc::CritScope cs(crit_capture_);
   return suppression_level_;
 }
 
 int EchoCancellationImpl::enable_drift_compensation(bool enable) {
-  {
-    rtc::CritScope cs(crit_capture_);
-    drift_compensation_enabled_ = enable;
-  }
+  drift_compensation_enabled_ = enable;
   return Configure();
 }
 
 bool EchoCancellationImpl::is_drift_compensation_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return drift_compensation_enabled_;
 }
 
 void EchoCancellationImpl::set_stream_drift_samples(int drift) {
-  rtc::CritScope cs(crit_capture_);
   was_stream_drift_set_ = true;
   stream_drift_samples_ = drift;
 }
 
 int EchoCancellationImpl::stream_drift_samples() const {
-  rtc::CritScope cs(crit_capture_);
   return stream_drift_samples_;
 }
 
 int EchoCancellationImpl::enable_metrics(bool enable) {
-  {
-    rtc::CritScope cs(crit_capture_);
-    metrics_enabled_ = enable;
-  }
+  metrics_enabled_ = enable;
   return Configure();
 }
 
 bool EchoCancellationImpl::are_metrics_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return enabled_ && metrics_enabled_;
 }
 
 // TODO(ajm): we currently just use the metrics from the first AEC. Think more
 //            aboue the best way to extend this to multi-channel.
 int EchoCancellationImpl::GetMetrics(Metrics* metrics) {
-  rtc::CritScope cs(crit_capture_);
   if (metrics == NULL) {
     return AudioProcessing::kNullPointerError;
   }
@@ -331,46 +305,36 @@
 }
 
 bool EchoCancellationImpl::stream_has_echo() const {
-  rtc::CritScope cs(crit_capture_);
   return stream_has_echo_;
 }
 
 int EchoCancellationImpl::enable_delay_logging(bool enable) {
-  {
-    rtc::CritScope cs(crit_capture_);
-    delay_logging_enabled_ = enable;
-  }
+  delay_logging_enabled_ = enable;
   return Configure();
 }
 
 bool EchoCancellationImpl::is_delay_logging_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return enabled_ && delay_logging_enabled_;
 }
 
 bool EchoCancellationImpl::is_delay_agnostic_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return delay_agnostic_enabled_;
 }
 
 std::string EchoCancellationImpl::GetExperimentsDescription() {
-  rtc::CritScope cs(crit_capture_);
   return refined_adaptive_filter_enabled_ ? "RefinedAdaptiveFilter;" : "";
 }
 
 bool EchoCancellationImpl::is_refined_adaptive_filter_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return refined_adaptive_filter_enabled_;
 }
 
 bool EchoCancellationImpl::is_extended_filter_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return extended_filter_enabled_;
 }
 
 // TODO(bjornv): How should we handle the multi-channel case?
 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) {
-  rtc::CritScope cs(crit_capture_);
   float fraction_poor_delays = 0;
   return GetDelayMetrics(median, std, &fraction_poor_delays);
 }
@@ -378,7 +342,6 @@
 int EchoCancellationImpl::GetDelayMetrics(int* median,
                                           int* std,
                                           float* fraction_poor_delays) {
-  rtc::CritScope cs(crit_capture_);
   if (median == NULL) {
     return AudioProcessing::kNullPointerError;
   }
@@ -400,7 +363,6 @@
 }
 
 struct AecCore* EchoCancellationImpl::aec_core() const {
-  rtc::CritScope cs(crit_capture_);
   if (!enabled_) {
     return NULL;
   }
@@ -411,9 +373,6 @@
                                       size_t num_reverse_channels,
                                       size_t num_output_channels,
                                       size_t num_proc_channels) {
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
-
   stream_properties_.reset(
       new StreamProperties(sample_rate_hz, num_reverse_channels,
                            num_output_channels, num_proc_channels));
@@ -442,7 +401,6 @@
 }
 
 int EchoCancellationImpl::GetSystemDelayInSamples() const {
-  rtc::CritScope cs(crit_capture_);
   RTC_DCHECK(enabled_);
   // Report the delay for the first AEC component.
   return WebRtcAec_system_delay(WebRtcAec_aec_core(cancellers_[0]->state()));
@@ -471,7 +429,6 @@
 
 void EchoCancellationImpl::SetExtraOptions(const webrtc::Config& config) {
   {
-    rtc::CritScope cs(crit_capture_);
     extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled;
     delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled;
     refined_adaptive_filter_enabled_ =
@@ -481,8 +438,6 @@
 }
 
 int EchoCancellationImpl::Configure() {
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
   AecConfig config;
   config.metricsMode = metrics_enabled_;
   config.nlpMode = MapSetting(suppression_level_);
diff --git a/modules/audio_processing/echo_cancellation_impl.h b/modules/audio_processing/echo_cancellation_impl.h
index 091a7b5..a8b43a8 100644
--- a/modules/audio_processing/echo_cancellation_impl.h
+++ b/modules/audio_processing/echo_cancellation_impl.h
@@ -11,12 +11,16 @@
 #ifndef MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
 #define MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
 
+#include <stddef.h>
 #include <memory>
+#include <string>
 #include <vector>
 
+#include "api/array_view.h"
 #include "modules/audio_processing/include/audio_processing.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
@@ -28,8 +32,7 @@
 // for PC and IP phone applications.
 class EchoCancellationImpl {
  public:
-  EchoCancellationImpl(rtc::CriticalSection* crit_render,
-                       rtc::CriticalSection* crit_capture);
+  explicit EchoCancellationImpl();
   ~EchoCancellationImpl();
 
   void ProcessRenderAudio(rtc::ArrayView<const float> packed_render_audio);
@@ -80,17 +83,23 @@
   // P_a:    Internal signal power at the point before the AEC's non-linear
   //         processor.
   struct Metrics {
+    struct Statistic {
+      int instant = 0;  // Instantaneous value.
+      int average = 0;  // Long-term average.
+      int maximum = 0;  // Long-term maximum.
+      int minimum = 0;  // Long-term minimum.
+    };
     // RERL = ERL + ERLE
-    AudioProcessing::Statistic residual_echo_return_loss;
+    Statistic residual_echo_return_loss;
 
     // ERL = 10log_10(P_far / P_echo)
-    AudioProcessing::Statistic echo_return_loss;
+    Statistic echo_return_loss;
 
     // ERLE = 10log_10(P_echo / P_out)
-    AudioProcessing::Statistic echo_return_loss_enhancement;
+    Statistic echo_return_loss_enhancement;
 
     // (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
-    AudioProcessing::Statistic a_nlp;
+    Statistic a_nlp;
 
     // Fraction of time that the AEC linear filter is divergent, in a 1-second
     // non-overlapped aggregation window.
@@ -150,28 +159,23 @@
   void AllocateRenderQueue();
   int Configure();
 
-  rtc::CriticalSection* const crit_render_ RTC_ACQUIRED_BEFORE(crit_capture_);
-  rtc::CriticalSection* const crit_capture_;
-
   bool enabled_ = false;
-  bool drift_compensation_enabled_ RTC_GUARDED_BY(crit_capture_);
-  bool metrics_enabled_ RTC_GUARDED_BY(crit_capture_);
-  SuppressionLevel suppression_level_ RTC_GUARDED_BY(crit_capture_);
-  int stream_drift_samples_ RTC_GUARDED_BY(crit_capture_);
-  bool was_stream_drift_set_ RTC_GUARDED_BY(crit_capture_);
-  bool stream_has_echo_ RTC_GUARDED_BY(crit_capture_);
-  bool delay_logging_enabled_ RTC_GUARDED_BY(crit_capture_);
-  bool extended_filter_enabled_ RTC_GUARDED_BY(crit_capture_);
-  bool delay_agnostic_enabled_ RTC_GUARDED_BY(crit_capture_);
-  bool refined_adaptive_filter_enabled_ RTC_GUARDED_BY(crit_capture_) = false;
+  bool drift_compensation_enabled_;
+  bool metrics_enabled_;
+  SuppressionLevel suppression_level_;
+  int stream_drift_samples_;
+  bool was_stream_drift_set_;
+  bool stream_has_echo_;
+  bool delay_logging_enabled_;
+  bool extended_filter_enabled_;
+  bool delay_agnostic_enabled_;
+  bool refined_adaptive_filter_enabled_ = false;
 
   // Only active on Chrome OS devices.
-  const bool enforce_zero_stream_delay_ RTC_GUARDED_BY(crit_capture_);
+  const bool enforce_zero_stream_delay_;
 
   std::vector<std::unique_ptr<Canceller>> cancellers_;
   std::unique_ptr<StreamProperties> stream_properties_;
-
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationImpl);
 };
 
 }  // namespace webrtc
diff --git a/modules/audio_processing/echo_cancellation_impl_unittest.cc b/modules/audio_processing/echo_cancellation_impl_unittest.cc
index c50c52f..9d81c1d 100644
--- a/modules/audio_processing/echo_cancellation_impl_unittest.cc
+++ b/modules/audio_processing/echo_cancellation_impl_unittest.cc
@@ -18,9 +18,7 @@
 
 namespace webrtc {
 TEST(EchoCancellationInternalTest, ExtendedFilter) {
-  rtc::CriticalSection crit_render;
-  rtc::CriticalSection crit_capture;
-  EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
+  EchoCancellationImpl echo_canceller;
   echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
 
   EXPECT_TRUE(echo_canceller.aec_core() == nullptr);
@@ -51,9 +49,7 @@
 }
 
 TEST(EchoCancellationInternalTest, DelayAgnostic) {
-  rtc::CriticalSection crit_render;
-  rtc::CriticalSection crit_capture;
-  EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
+  EchoCancellationImpl echo_canceller;
   echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 1, 1, 1);
 
   EXPECT_TRUE(echo_canceller.aec_core() == NULL);
@@ -85,9 +81,7 @@
 }
 
 TEST(EchoCancellationInternalTest, InterfaceConfiguration) {
-  rtc::CriticalSection crit_render;
-  rtc::CriticalSection crit_capture;
-  EchoCancellationImpl echo_canceller(&crit_render, &crit_capture);
+  EchoCancellationImpl echo_canceller;
   echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 1, 1, 1);
 
   EXPECT_EQ(0, echo_canceller.enable_drift_compensation(true));
diff --git a/modules/audio_processing/echo_control_mobile_bit_exact_unittest.cc b/modules/audio_processing/echo_control_mobile_bit_exact_unittest.cc
index 8b83692..7844daf 100644
--- a/modules/audio_processing/echo_control_mobile_bit_exact_unittest.cc
+++ b/modules/audio_processing/echo_control_mobile_bit_exact_unittest.cc
@@ -64,9 +64,7 @@
                          EchoControlMobileImpl::RoutingMode routing_mode,
                          bool comfort_noise_enabled,
                          const rtc::ArrayView<const float>& output_reference) {
-  rtc::CriticalSection crit_render;
-  rtc::CriticalSection crit_capture;
-  EchoControlMobileImpl echo_control_mobile(&crit_render, &crit_capture);
+  EchoControlMobileImpl echo_control_mobile;
   SetupComponent(sample_rate_hz, routing_mode, comfort_noise_enabled,
                  &echo_control_mobile);
 
diff --git a/modules/audio_processing/echo_control_mobile_impl.cc b/modules/audio_processing/echo_control_mobile_impl.cc
index bd125c6..b9fbf42 100644
--- a/modules/audio_processing/echo_control_mobile_impl.cc
+++ b/modules/audio_processing/echo_control_mobile_impl.cc
@@ -11,11 +11,13 @@
 #include "modules/audio_processing/echo_control_mobile_impl.h"
 
 #include <string.h>
+#include <cstdint>
 
 #include "modules/audio_processing/aecm/echo_control_mobile.h"
 #include "modules/audio_processing/audio_buffer.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
-#include "rtc_base/logging.h"
 
 namespace webrtc {
 
@@ -55,10 +57,6 @@
 }
 }  // namespace
 
-size_t EchoControlMobileImpl::echo_path_size_bytes() {
-  return WebRtcAecm_echo_path_size_bytes();
-}
-
 struct EchoControlMobileImpl::StreamProperties {
   StreamProperties() = delete;
   StreamProperties(int sample_rate_hz,
@@ -90,17 +88,10 @@
     return state_;
   }
 
-  void Initialize(int sample_rate_hz,
-                  unsigned char* external_echo_path,
-                  size_t echo_path_size_bytes) {
+  void Initialize(int sample_rate_hz) {
     RTC_DCHECK(state_);
     int error = WebRtcAecm_Init(state_, sample_rate_hz);
     RTC_DCHECK_EQ(AudioProcessing::kNoError, error);
-    if (external_echo_path != NULL) {
-      error = WebRtcAecm_InitEchoPath(state_, external_echo_path,
-                                      echo_path_size_bytes);
-      RTC_DCHECK_EQ(AudioProcessing::kNoError, error);
-    }
   }
 
  private:
@@ -108,27 +99,13 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(Canceller);
 };
 
-EchoControlMobileImpl::EchoControlMobileImpl(rtc::CriticalSection* crit_render,
-                                             rtc::CriticalSection* crit_capture)
-    : crit_render_(crit_render),
-      crit_capture_(crit_capture),
-      routing_mode_(kSpeakerphone),
-      comfort_noise_enabled_(false),
-      external_echo_path_(NULL) {
-  RTC_DCHECK(crit_render);
-  RTC_DCHECK(crit_capture);
-}
+EchoControlMobileImpl::EchoControlMobileImpl()
+    : routing_mode_(kSpeakerphone), comfort_noise_enabled_(false) {}
 
-EchoControlMobileImpl::~EchoControlMobileImpl() {
-  if (external_echo_path_ != NULL) {
-    delete[] external_echo_path_;
-    external_echo_path_ = NULL;
-  }
-}
+EchoControlMobileImpl::~EchoControlMobileImpl() {}
 
 void EchoControlMobileImpl::ProcessRenderAudio(
     rtc::ArrayView<const int16_t> packed_render_audio) {
-  rtc::CritScope cs_capture(crit_capture_);
   if (!enabled_) {
     return;
   }
@@ -181,7 +158,6 @@
 
 int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio,
                                                int stream_delay_ms) {
-  rtc::CritScope cs_capture(crit_capture_);
   if (!enabled_) {
     return AudioProcessing::kNoError;
   }
@@ -228,8 +204,6 @@
 
 int EchoControlMobileImpl::Enable(bool enable) {
   // Ensure AEC and AECM are not both enabled.
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
   RTC_DCHECK(stream_properties_);
 
   if (enable &&
@@ -252,7 +226,6 @@
 }
 
 bool EchoControlMobileImpl::is_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return enabled_;
 }
 
@@ -260,90 +233,26 @@
   if (MapSetting(mode) == -1) {
     return AudioProcessing::kBadParameterError;
   }
-
-  {
-    rtc::CritScope cs(crit_capture_);
     routing_mode_ = mode;
-  }
   return Configure();
 }
 
 EchoControlMobileImpl::RoutingMode EchoControlMobileImpl::routing_mode() const {
-  rtc::CritScope cs(crit_capture_);
   return routing_mode_;
 }
 
 int EchoControlMobileImpl::enable_comfort_noise(bool enable) {
-  {
-    rtc::CritScope cs(crit_capture_);
     comfort_noise_enabled_ = enable;
-  }
   return Configure();
 }
 
 bool EchoControlMobileImpl::is_comfort_noise_enabled() const {
-  rtc::CritScope cs(crit_capture_);
   return comfort_noise_enabled_;
 }
 
-int EchoControlMobileImpl::SetEchoPath(const void* echo_path,
-                                       size_t size_bytes) {
-  {
-    rtc::CritScope cs_render(crit_render_);
-    rtc::CritScope cs_capture(crit_capture_);
-    if (echo_path == NULL) {
-      return AudioProcessing::kNullPointerError;
-    }
-    if (size_bytes != echo_path_size_bytes()) {
-      // Size mismatch
-      return AudioProcessing::kBadParameterError;
-    }
-
-    if (external_echo_path_ == NULL) {
-      external_echo_path_ = new unsigned char[size_bytes];
-    }
-    memcpy(external_echo_path_, echo_path, size_bytes);
-  }
-
-  // TODO(peah): Simplify once the Enable function has been removed from
-  // the public APM API.
-  RTC_DCHECK(stream_properties_);
-  Initialize(stream_properties_->sample_rate_hz,
-             stream_properties_->num_reverse_channels,
-             stream_properties_->num_output_channels);
-  return AudioProcessing::kNoError;
-}
-
-int EchoControlMobileImpl::GetEchoPath(void* echo_path,
-                                       size_t size_bytes) const {
-  rtc::CritScope cs(crit_capture_);
-  if (echo_path == NULL) {
-    return AudioProcessing::kNullPointerError;
-  }
-  if (size_bytes != echo_path_size_bytes()) {
-    // Size mismatch
-    return AudioProcessing::kBadParameterError;
-  }
-  if (!enabled_) {
-    return AudioProcessing::kNotEnabledError;
-  }
-
-  // Get the echo path from the first channel
-  int32_t err =
-      WebRtcAecm_GetEchoPath(cancellers_[0]->state(), echo_path, size_bytes);
-  if (err != 0) {
-    return MapError(err);
-  }
-
-  return AudioProcessing::kNoError;
-}
-
 void EchoControlMobileImpl::Initialize(int sample_rate_hz,
                                        size_t num_reverse_channels,
                                        size_t num_output_channels) {
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
-
   stream_properties_.reset(new StreamProperties(
       sample_rate_hz, num_reverse_channels, num_output_channels));
 
@@ -363,16 +272,12 @@
     if (!canceller) {
       canceller.reset(new Canceller());
     }
-    canceller->Initialize(sample_rate_hz, external_echo_path_,
-                          echo_path_size_bytes());
+    canceller->Initialize(sample_rate_hz);
   }
-
   Configure();
 }
 
 int EchoControlMobileImpl::Configure() {
-  rtc::CritScope cs_render(crit_render_);
-  rtc::CritScope cs_capture(crit_capture_);
   AecmConfig config;
   config.cngMode = comfort_noise_enabled_;
   config.echoMode = MapSetting(routing_mode_);
diff --git a/modules/audio_processing/echo_control_mobile_impl.h b/modules/audio_processing/echo_control_mobile_impl.h
index a5b66c8..d5a8b0b 100644
--- a/modules/audio_processing/echo_control_mobile_impl.h
+++ b/modules/audio_processing/echo_control_mobile_impl.h
@@ -11,14 +11,12 @@
 #ifndef MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_IMPL_H_
 #define MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_IMPL_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <vector>
 
-#include "modules/audio_processing/include/audio_processing.h"
-#include "modules/audio_processing/render_queue_item_verifier.h"
-#include "rtc_base/constructormagic.h"
-#include "rtc_base/criticalsection.h"
-#include "rtc_base/swap_queue.h"
+#include "api/array_view.h"
 
 namespace webrtc {
 
@@ -28,8 +26,7 @@
 // robust option intended for use on mobile devices.
 class EchoControlMobileImpl {
  public:
-  EchoControlMobileImpl(rtc::CriticalSection* crit_render,
-                        rtc::CriticalSection* crit_capture);
+  EchoControlMobileImpl();
 
   ~EchoControlMobileImpl();
 
@@ -57,26 +54,6 @@
   int enable_comfort_noise(bool enable);
   bool is_comfort_noise_enabled() const;
 
-  // A typical use case is to initialize the component with an echo path from a
-  // previous call. The echo path is retrieved using |GetEchoPath()|, typically
-  // at the end of a call. The data can then be stored for later use as an
-  // initializer before the next call, using |SetEchoPath()|.
-  //
-  // Controlling the echo path this way requires the data |size_bytes| to match
-  // the internal echo path size. This size can be acquired using
-  // |echo_path_size_bytes()|. |SetEchoPath()| causes an entire reset, worth
-  // noting if it is to be called during an ongoing call.
-  //
-  // It is possible that version incompatibilities may result in a stored echo
-  // path of the incorrect size. In this case, the stored path should be
-  // discarded.
-  int SetEchoPath(const void* echo_path, size_t size_bytes);
-  int GetEchoPath(void* echo_path, size_t size_bytes) const;
-
-  // The returned path size is guaranteed not to change for the lifetime of
-  // the application.
-  static size_t echo_path_size_bytes();
-
   void ProcessRenderAudio(rtc::ArrayView<const int16_t> packed_render_audio);
   int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);
 
@@ -98,20 +75,13 @@
 
   int Configure();
 
-  rtc::CriticalSection* const crit_render_ RTC_ACQUIRED_BEFORE(crit_capture_);
-  rtc::CriticalSection* const crit_capture_;
-
   bool enabled_ = false;
 
-  RoutingMode routing_mode_ RTC_GUARDED_BY(crit_capture_);
-  bool comfort_noise_enabled_ RTC_GUARDED_BY(crit_capture_);
-  unsigned char* external_echo_path_ RTC_GUARDED_BY(crit_render_)
-      RTC_GUARDED_BY(crit_capture_);
+  RoutingMode routing_mode_;
+  bool comfort_noise_enabled_;
 
   std::vector<std::unique_ptr<Canceller>> cancellers_;
   std::unique_ptr<StreamProperties> stream_properties_;
-
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoControlMobileImpl);
 };
 }  // namespace webrtc
 
diff --git a/modules/audio_processing/echo_control_mobile_unittest.cc b/modules/audio_processing/echo_control_mobile_unittest.cc
index d7e470c..f0e6048 100644
--- a/modules/audio_processing/echo_control_mobile_unittest.cc
+++ b/modules/audio_processing/echo_control_mobile_unittest.cc
@@ -18,9 +18,7 @@
 
 namespace webrtc {
 TEST(EchoControlMobileTest, InterfaceConfiguration) {
-  rtc::CriticalSection crit_render;
-  rtc::CriticalSection crit_capture;
-  EchoControlMobileImpl aecm(&crit_render, &crit_capture);
+  EchoControlMobileImpl aecm;
   aecm.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2);
 
   // Turn AECM on
@@ -46,28 +44,6 @@
   EXPECT_EQ(0, aecm.enable_comfort_noise(true));
   EXPECT_TRUE(aecm.is_comfort_noise_enabled());
 
-  // Set and get echo path
-  const size_t echo_path_size = aecm.echo_path_size_bytes();
-  std::vector<uint8_t> echo_path_in(echo_path_size);
-  std::vector<uint8_t> echo_path_out(echo_path_size);
-  EXPECT_EQ(AudioProcessing::kNullPointerError,
-            aecm.SetEchoPath(nullptr, echo_path_size));
-  EXPECT_EQ(AudioProcessing::kNullPointerError,
-            aecm.GetEchoPath(nullptr, echo_path_size));
-  EXPECT_EQ(AudioProcessing::kBadParameterError,
-            aecm.GetEchoPath(echo_path_out.data(), 1));
-  EXPECT_EQ(0, aecm.GetEchoPath(echo_path_out.data(), echo_path_size));
-  for (size_t i = 0; i < echo_path_size; i++) {
-    echo_path_in[i] = echo_path_out[i] + 1;
-  }
-  EXPECT_EQ(AudioProcessing::kBadParameterError,
-            aecm.SetEchoPath(echo_path_in.data(), 1));
-  EXPECT_EQ(0, aecm.SetEchoPath(echo_path_in.data(), echo_path_size));
-  EXPECT_EQ(0, aecm.GetEchoPath(echo_path_out.data(), echo_path_size));
-  for (size_t i = 0; i < echo_path_size; i++) {
-    EXPECT_EQ(echo_path_in[i], echo_path_out[i]);
-  }
-
   // Turn AECM off
   EXPECT_EQ(0, aecm.Enable(false));
   EXPECT_FALSE(aecm.is_enabled());
diff --git a/modules/audio_processing/echo_detector/circular_buffer.h b/modules/audio_processing/echo_detector/circular_buffer.h
index 9f5cdfa..c52311f 100644
--- a/modules/audio_processing/echo_detector/circular_buffer.h
+++ b/modules/audio_processing/echo_detector/circular_buffer.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_CIRCULAR_BUFFER_H_
 #define MODULES_AUDIO_PROCESSING_ECHO_DETECTOR_CIRCULAR_BUFFER_H_
 
+#include <stddef.h>
 #include <vector>
 
 #include "absl/types/optional.h"
diff --git a/modules/audio_processing/gain_control_for_experimental_agc.cc b/modules/audio_processing/gain_control_for_experimental_agc.cc
index 4ab856c..1479d58 100644
--- a/modules/audio_processing/gain_control_for_experimental_agc.cc
+++ b/modules/audio_processing/gain_control_for_experimental_agc.cc
@@ -13,7 +13,6 @@
 #include "modules/audio_processing/include/audio_processing.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
-#include "rtc_base/checks.h"
 #include "rtc_base/criticalsection.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/gain_control_impl.cc b/modules/audio_processing/gain_control_impl.cc
index 685a27f..d5118ba 100644
--- a/modules/audio_processing/gain_control_impl.cc
+++ b/modules/audio_processing/gain_control_impl.cc
@@ -10,10 +10,14 @@
 
 #include "modules/audio_processing/gain_control_impl.h"
 
+#include <cstdint>
+
 #include "absl/types/optional.h"
 #include "modules/audio_processing/agc/legacy/gain_control.h"
 #include "modules/audio_processing/audio_buffer.h"
+#include "modules/audio_processing/include/audio_processing.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/gain_control_impl.h b/modules/audio_processing/gain_control_impl.h
index 959422f..c21d911 100644
--- a/modules/audio_processing/gain_control_impl.h
+++ b/modules/audio_processing/gain_control_impl.h
@@ -11,14 +11,16 @@
 #ifndef MODULES_AUDIO_PROCESSING_GAIN_CONTROL_IMPL_H_
 #define MODULES_AUDIO_PROCESSING_GAIN_CONTROL_IMPL_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <vector>
 
-#include "modules/audio_processing/include/audio_processing.h"
-#include "modules/audio_processing/render_queue_item_verifier.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "modules/audio_processing/include/gain_control.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
-#include "rtc_base/swap_queue.h"
 #include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/gain_controller2.cc b/modules/audio_processing/gain_controller2.cc
index 29af962..f256be0 100644
--- a/modules/audio_processing/gain_controller2.cc
+++ b/modules/audio_processing/gain_controller2.cc
@@ -10,6 +10,7 @@
 
 #include "modules/audio_processing/gain_controller2.h"
 
+#include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/audio_buffer.h"
 #include "modules/audio_processing/include/audio_frame_view.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
@@ -24,8 +25,10 @@
 GainController2::GainController2()
     : data_dumper_(
           new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
-      fixed_gain_controller_(data_dumper_.get()),
-      adaptive_agc_(data_dumper_.get()) {}
+      gain_applier_(/*hard_clip_samples=*/false,
+                    /*initial_gain_factor=*/0.f),
+      adaptive_agc_(new AdaptiveAgc(data_dumper_.get())),
+      limiter_(static_cast<size_t>(48000), data_dumper_.get(), "Agc2") {}
 
 GainController2::~GainController2() = default;
 
@@ -34,7 +37,7 @@
              sample_rate_hz == AudioProcessing::kSampleRate16kHz ||
              sample_rate_hz == AudioProcessing::kSampleRate32kHz ||
              sample_rate_hz == AudioProcessing::kSampleRate48kHz);
-  fixed_gain_controller_.SetSampleRate(sample_rate_hz);
+  limiter_.SetSampleRate(sample_rate_hz);
   data_dumper_->InitiateNewSetOfRecordings();
   data_dumper_->DumpRaw("sample_rate_hz", sample_rate_hz);
 }
@@ -42,15 +45,17 @@
 void GainController2::Process(AudioBuffer* audio) {
   AudioFrameView<float> float_frame(audio->channels_f(), audio->num_channels(),
                                     audio->num_frames());
+  // Apply fixed gain first, then the adaptive one.
+  gain_applier_.ApplyGain(float_frame);
   if (adaptive_digital_mode_) {
-    adaptive_agc_.Process(float_frame, fixed_gain_controller_.LastAudioLevel());
+    adaptive_agc_->Process(float_frame, limiter_.LastAudioLevel());
   }
-  fixed_gain_controller_.Process(float_frame);
+  limiter_.Process(float_frame);
 }
 
 void GainController2::NotifyAnalogLevel(int level) {
   if (analog_level_ != level && adaptive_digital_mode_) {
-    adaptive_agc_.Reset();
+    adaptive_agc_->Reset();
   }
   analog_level_ = level;
 }
@@ -59,13 +64,22 @@
     const AudioProcessing::Config::GainController2& config) {
   RTC_DCHECK(Validate(config));
   config_ = config;
-  fixed_gain_controller_.SetGain(config_.fixed_gain_db);
+  if (gain_applier_.GetGainFactor() != config_.fixed_gain_db) {
+    // Reset the limiter to quickly react on abrupt level changes caused by
+    // large changes of the fixed gain.
+    limiter_.Reset();
+  }
+  gain_applier_.SetGainFactor(DbToRatio(config_.fixed_gain_db));
   adaptive_digital_mode_ = config_.adaptive_digital_mode;
+  adaptive_agc_.reset(
+      new AdaptiveAgc(data_dumper_.get(), config_.extra_saturation_margin_db));
 }
 
 bool GainController2::Validate(
     const AudioProcessing::Config::GainController2& config) {
-  return config.fixed_gain_db >= 0.f;
+  return config.fixed_gain_db >= 0.f &&
+         config.extra_saturation_margin_db >= 0.f &&
+         config.extra_saturation_margin_db <= 100.f;
 }
 
 std::string GainController2::ToString(
diff --git a/modules/audio_processing/gain_controller2.h b/modules/audio_processing/gain_controller2.h
index b4727d0..013385d 100644
--- a/modules/audio_processing/gain_controller2.h
+++ b/modules/audio_processing/gain_controller2.h
@@ -15,7 +15,8 @@
 #include <string>
 
 #include "modules/audio_processing/agc2/adaptive_agc.h"
-#include "modules/audio_processing/agc2/fixed_gain_controller.h"
+#include "modules/audio_processing/agc2/gain_applier.h"
+#include "modules/audio_processing/agc2/limiter.h"
 #include "modules/audio_processing/include/audio_processing.h"
 #include "rtc_base/constructormagic.h"
 
@@ -43,9 +44,10 @@
  private:
   static int instance_count_;
   std::unique_ptr<ApmDataDumper> data_dumper_;
-  FixedGainController fixed_gain_controller_;
   AudioProcessing::Config::GainController2 config_;
-  AdaptiveAgc adaptive_agc_;
+  GainApplier gain_applier_;
+  std::unique_ptr<AdaptiveAgc> adaptive_agc_;
+  Limiter limiter_;
   int analog_level_ = -1;
   bool adaptive_digital_mode_ = true;
 
diff --git a/modules/audio_processing/gain_controller2_unittest.cc b/modules/audio_processing/gain_controller2_unittest.cc
index 5bedccd..caaefdd 100644
--- a/modules/audio_processing/gain_controller2_unittest.cc
+++ b/modules/audio_processing/gain_controller2_unittest.cc
@@ -10,20 +10,20 @@
 
 #include <algorithm>
 
+#include "absl/memory/memory.h"
 #include "api/array_view.h"
+#include "modules/audio_processing/agc2/agc2_testing_common.h"
 #include "modules/audio_processing/audio_buffer.h"
 #include "modules/audio_processing/gain_controller2.h"
+#include "modules/audio_processing/test/audio_buffer_tools.h"
+#include "modules/audio_processing/test/bitexactness_tools.h"
 #include "rtc_base/checks.h"
 #include "test/gtest.h"
 
 namespace webrtc {
 namespace test {
-
 namespace {
 
-constexpr size_t kFrameSizeMs = 10u;
-constexpr size_t kStereo = 2u;
-
 void SetAudioBufferSamples(float value, AudioBuffer* ab) {
   // Sets all the samples in |ab| to |value|.
   for (size_t k = 0; k < ab->num_channels(); ++k) {
@@ -32,6 +32,75 @@
   }
 }
 
+float RunAgc2WithConstantInput(GainController2* agc2,
+                               float input_level,
+                               size_t num_frames,
+                               int sample_rate) {
+  const int num_samples = rtc::CheckedDivExact(sample_rate, 100);
+  AudioBuffer ab(num_samples, 1, num_samples, 1, num_samples);
+
+  // Give time to the level estimator to converge.
+  for (size_t i = 0; i < num_frames + 1; ++i) {
+    SetAudioBufferSamples(input_level, &ab);
+    agc2->Process(&ab);
+  }
+
+  // Return the last sample from the last processed frame.
+  return ab.channels_f()[0][num_samples - 1];
+}
+
+AudioProcessing::Config::GainController2 CreateAgc2FixedDigitalModeConfig(
+    float fixed_gain_db) {
+  AudioProcessing::Config::GainController2 config;
+  config.adaptive_digital_mode = false;
+  config.fixed_gain_db = fixed_gain_db;
+  // TODO(alessiob): Check why ASSERT_TRUE() below does not compile.
+  EXPECT_TRUE(GainController2::Validate(config));
+  return config;
+}
+
+std::unique_ptr<GainController2> CreateAgc2FixedDigitalMode(
+    float fixed_gain_db,
+    size_t sample_rate_hz) {
+  auto agc2 = absl::make_unique<GainController2>();
+  agc2->ApplyConfig(CreateAgc2FixedDigitalModeConfig(fixed_gain_db));
+  agc2->Initialize(sample_rate_hz);
+  return agc2;
+}
+
+float GainAfterProcessingFile(GainController2* gain_controller) {
+  // Set up an AudioBuffer to be filled from the speech file.
+  constexpr size_t kStereo = 2u;
+  const StreamConfig capture_config(AudioProcessing::kSampleRate48kHz, kStereo,
+                                    false);
+  AudioBuffer ab(capture_config.num_frames(), capture_config.num_channels(),
+                 capture_config.num_frames(), capture_config.num_channels(),
+                 capture_config.num_frames());
+  test::InputAudioFile capture_file(
+      test::GetApmCaptureTestVectorFileName(AudioProcessing::kSampleRate48kHz));
+  std::vector<float> capture_input(capture_config.num_frames() *
+                                   capture_config.num_channels());
+
+  // The file should contain at least this many frames. Every iteration, we put
+  // a frame through the gain controller.
+  const int kNumFramesToProcess = 100;
+  for (int frame_no = 0; frame_no < kNumFramesToProcess; ++frame_no) {
+    ReadFloatSamplesFromStereoFile(capture_config.num_frames(),
+                                   capture_config.num_channels(), &capture_file,
+                                   capture_input);
+
+    test::CopyVectorToAudioBuffer(capture_config, capture_input, &ab);
+    gain_controller->Process(&ab);
+  }
+
+  // Send in a last frame with values constant 1 (It's low enough to detect high
+  // gain, and for ease of computation). The applied gain is the result.
+  constexpr float sample_value = 1.f;
+  SetAudioBufferSamples(sample_value, &ab);
+  gain_controller->Process(&ab);
+  return ab.channels_f()[0][0];
+}
+
 }  // namespace
 
 TEST(GainController2, CreateApplyConfig) {
@@ -69,22 +138,149 @@
             GainController2::ToString(config));
 }
 
-TEST(GainController2, Usage) {
-  // Tests GainController2::Process() on an AudioBuffer instance.
-  std::unique_ptr<GainController2> gain_controller2(new GainController2());
-  gain_controller2->Initialize(AudioProcessing::kSampleRate48kHz);
-  const size_t num_frames = rtc::CheckedDivExact<size_t>(
-      kFrameSizeMs * AudioProcessing::kSampleRate48kHz, 1000);
-  AudioBuffer ab(num_frames, kStereo, num_frames, kStereo, num_frames);
-  constexpr float sample_value = 1000.f;
-  SetAudioBufferSamples(sample_value, &ab);
-  AudioProcessing::Config::GainController2 config;
+TEST(GainController2FixedDigital, GainShouldChangeOnSetGain) {
+  constexpr float kInputLevel = 1000.f;
+  constexpr size_t kNumFrames = 5;
+  constexpr size_t kSampleRateHz = 8000;
+  constexpr float kGain0Db = 0.f;
+  constexpr float kGain20Db = 20.f;
 
-  // Check that samples are amplified when the fixed gain is greater than 0 dB.
-  config.fixed_gain_db = 5.f;
-  gain_controller2->ApplyConfig(config);
-  gain_controller2->Process(&ab);
-  EXPECT_LT(sample_value, ab.channels_f()[0][0]);
+  auto agc2_fixed = CreateAgc2FixedDigitalMode(kGain0Db, kSampleRateHz);
+
+  // Signal level is unchanged with 0 db gain.
+  EXPECT_FLOAT_EQ(RunAgc2WithConstantInput(agc2_fixed.get(), kInputLevel,
+                                           kNumFrames, kSampleRateHz),
+                  kInputLevel);
+
+  // +20 db should increase signal by a factor of 10.
+  agc2_fixed->ApplyConfig(CreateAgc2FixedDigitalModeConfig(kGain20Db));
+  EXPECT_FLOAT_EQ(RunAgc2WithConstantInput(agc2_fixed.get(), kInputLevel,
+                                           kNumFrames, kSampleRateHz),
+                  kInputLevel * 10);
+}
+
+TEST(GainController2FixedDigital, ChangeFixedGainShouldBeFastAndTimeInvariant) {
+  // 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 kSampleRateHz = 8000;
+  constexpr float kGainDbLow = 0.f;
+  constexpr float kGainDbHigh = 25.f;
+  static_assert(kGainDbLow < kGainDbHigh, "");
+
+  auto agc2_fixed = CreateAgc2FixedDigitalMode(kGainDbLow, kSampleRateHz);
+
+  // Start with a lower gain.
+  const float output_level_pre = RunAgc2WithConstantInput(
+      agc2_fixed.get(), kInputLevel, kNumFrames, kSampleRateHz);
+
+  // Increase gain.
+  agc2_fixed->ApplyConfig(CreateAgc2FixedDigitalModeConfig(kGainDbHigh));
+  static_cast<void>(RunAgc2WithConstantInput(agc2_fixed.get(), kInputLevel,
+                                             kNumFrames, kSampleRateHz));
+
+  // Back to the lower gain.
+  agc2_fixed->ApplyConfig(CreateAgc2FixedDigitalModeConfig(kGainDbLow));
+  const float output_level_post = RunAgc2WithConstantInput(
+      agc2_fixed.get(), kInputLevel, kNumFrames, kSampleRateHz);
+
+  EXPECT_EQ(output_level_pre, output_level_post);
+}
+
+struct FixedDigitalTestParams {
+  FixedDigitalTestParams(float gain_db_min,
+                         float gain_db_max,
+                         size_t sample_rate,
+                         bool saturation_expected)
+      : gain_db_min(gain_db_min),
+        gain_db_max(gain_db_max),
+        sample_rate(sample_rate),
+        saturation_expected(saturation_expected) {}
+  float gain_db_min;
+  float gain_db_max;
+  size_t sample_rate;
+  bool saturation_expected;
+};
+
+class FixedDigitalTest
+    : public testing::Test,
+      public testing::WithParamInterface<FixedDigitalTestParams> {};
+
+TEST_P(FixedDigitalTest, CheckSaturationBehaviorWithLimiter) {
+  const float kInputLevel = 32767.f;
+  const size_t kNumFrames = 5;
+
+  const auto params = GetParam();
+
+  const auto gains_db =
+      test::LinSpace(params.gain_db_min, params.gain_db_max, 10);
+  for (const auto gain_db : gains_db) {
+    SCOPED_TRACE(std::to_string(gain_db));
+    auto agc2_fixed = CreateAgc2FixedDigitalMode(gain_db, params.sample_rate);
+    const float processed_sample = RunAgc2WithConstantInput(
+        agc2_fixed.get(), kInputLevel, kNumFrames, params.sample_rate);
+    if (params.saturation_expected) {
+      EXPECT_FLOAT_EQ(processed_sample, 32767.f);
+    } else {
+      EXPECT_LT(processed_sample, 32767.f);
+    }
+  }
+}
+
+static_assert(test::kLimiterMaxInputLevelDbFs < 10, "");
+INSTANTIATE_TEST_CASE_P(
+    GainController2,
+    FixedDigitalTest,
+    ::testing::Values(
+        // When gain < |test::kLimiterMaxInputLevelDbFs|, the limiter will not
+        // saturate the signal (at any sample rate).
+        FixedDigitalTestParams(0.1f,
+                               test::kLimiterMaxInputLevelDbFs - 0.01f,
+                               8000,
+                               false),
+        FixedDigitalTestParams(0.1,
+                               test::kLimiterMaxInputLevelDbFs - 0.01f,
+                               48000,
+                               false),
+        // When gain > |test::kLimiterMaxInputLevelDbFs|, the limiter will
+        // saturate the signal (at any sample rate).
+        FixedDigitalTestParams(test::kLimiterMaxInputLevelDbFs + 0.01f,
+                               10.f,
+                               8000,
+                               true),
+        FixedDigitalTestParams(test::kLimiterMaxInputLevelDbFs + 0.01f,
+                               10.f,
+                               48000,
+                               true)));
+
+TEST(GainController2, UsageSaturationMargin) {
+  GainController2 gain_controller2;
+  gain_controller2.Initialize(AudioProcessing::kSampleRate48kHz);
+
+  AudioProcessing::Config::GainController2 config;
+  // Check that samples are not amplified as much when extra margin is
+  // high. They should not be amplified at all, but only after convergence. GC2
+  // starts with a gain, and it takes time until it's down to 0 dB.
+  config.extra_saturation_margin_db = 50.f;
+  config.fixed_gain_db = 0.f;
+  gain_controller2.ApplyConfig(config);
+
+  EXPECT_LT(GainAfterProcessingFile(&gain_controller2), 2.f);
+}
+
+TEST(GainController2, UsageNoSaturationMargin) {
+  GainController2 gain_controller2;
+  gain_controller2.Initialize(AudioProcessing::kSampleRate48kHz);
+
+  AudioProcessing::Config::GainController2 config;
+  // Check that some gain is applied if there is no margin.
+  config.extra_saturation_margin_db = 0.f;
+  config.fixed_gain_db = 0.f;
+  gain_controller2.ApplyConfig(config);
+
+  EXPECT_GT(GainAfterProcessingFile(&gain_controller2), 2.f);
 }
 
 }  // namespace test
diff --git a/modules/audio_processing/include/aec_dump.h b/modules/audio_processing/include/aec_dump.h
index 313e9d7..b734adf 100644
--- a/modules/audio_processing/include/aec_dump.h
+++ b/modules/audio_processing/include/aec_dump.h
@@ -11,14 +11,13 @@
 #ifndef MODULES_AUDIO_PROCESSING_INCLUDE_AEC_DUMP_H_
 #define MODULES_AUDIO_PROCESSING_INCLUDE_AEC_DUMP_H_
 
-#include <memory>
+#include <stdint.h>
 #include <string>
-#include <vector>
 
-#include "api/array_view.h"
 #include "api/audio/audio_frame.h"
 #include "modules/audio_processing/include/audio_frame_view.h"
 #include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/deprecation.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/include/audio_processing.cc b/modules/audio_processing/include/audio_processing.cc
index 75eedaf..27cd882 100644
--- a/modules/audio_processing/include/audio_processing.cc
+++ b/modules/audio_processing/include/audio_processing.cc
@@ -10,8 +10,6 @@
 
 #include "modules/audio_processing/include/audio_processing.h"
 
-#include "rtc_base/checks.h"
-
 namespace webrtc {
 
 void CustomProcessing::SetRuntimeSetting(
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index 8af0cb2..b105ef1 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -49,7 +49,6 @@
 
 class EchoDetector;
 class GainControl;
-class HighPassFilter;
 class LevelEstimator;
 class NoiseSuppression;
 class CustomAudioAnalyzer;
@@ -241,7 +240,6 @@
   // by changing the default values in the AudioProcessing::Config struct.
   // The config is applied by passing the struct to the ApplyConfig method.
   struct Config {
-    // TODO(bugs.webrtc.org/9535): Currently unused. Use this to determine AEC.
     struct EchoCanceller {
       bool enabled = false;
       bool mobile_mode = false;
@@ -274,6 +272,7 @@
     struct GainController2 {
       bool enabled = false;
       bool adaptive_digital_mode = true;
+      float extra_saturation_margin_db = 2.f;
       float fixed_gain_db = 0.f;
     } gain_controller2;
 
@@ -521,85 +520,17 @@
   // specific member variables are reset.
   virtual void UpdateHistogramsOnCallEnd() = 0;
 
-  // TODO(ivoc): Remove when the calling code no longer uses the old Statistics
-  //             API.
-  struct Statistic {
-    int instant = 0;  // Instantaneous value.
-    int average = 0;  // Long-term average.
-    int maximum = 0;  // Long-term maximum.
-    int minimum = 0;  // Long-term minimum.
-  };
-
-  struct Stat {
-    void Set(const Statistic& other) {
-      Set(other.instant, other.average, other.maximum, other.minimum);
-    }
-    void Set(float instant, float average, float maximum, float minimum) {
-      instant_ = instant;
-      average_ = average;
-      maximum_ = maximum;
-      minimum_ = minimum;
-    }
-    float instant() const { return instant_; }
-    float average() const { return average_; }
-    float maximum() const { return maximum_; }
-    float minimum() const { return minimum_; }
-
-   private:
-    float instant_ = 0.0f;  // Instantaneous value.
-    float average_ = 0.0f;  // Long-term average.
-    float maximum_ = 0.0f;  // Long-term maximum.
-    float minimum_ = 0.0f;  // Long-term minimum.
-  };
-
-  struct RTC_EXPORT AudioProcessingStatistics {
-    AudioProcessingStatistics();
-    AudioProcessingStatistics(const AudioProcessingStatistics& other);
-    ~AudioProcessingStatistics();
-
-    // AEC Statistics.
-    // RERL = ERL + ERLE
-    Stat residual_echo_return_loss;
-    // ERL = 10log_10(P_far / P_echo)
-    Stat echo_return_loss;
-    // ERLE = 10log_10(P_echo / P_out)
-    Stat echo_return_loss_enhancement;
-    // (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
-    Stat a_nlp;
-    // Fraction of time that the AEC linear filter is divergent, in a 1-second
-    // non-overlapped aggregation window.
-    float divergent_filter_fraction = -1.0f;
-
-    // The delay metrics consists of the delay median and standard deviation. It
-    // also consists of the fraction of delay estimates that can make the echo
-    // cancellation perform poorly. The values are aggregated until the first
-    // call to |GetStatistics()| and afterwards aggregated and updated every
-    // second. Note that if there are several clients pulling metrics from
-    // |GetStatistics()| during a session the first call from any of them will
-    // change to one second aggregation window for all.
-    int delay_median = -1;
-    int delay_standard_deviation = -1;
-    float fraction_poor_delays = -1.0f;
-
-    // Residual echo detector likelihood.
-    float residual_echo_likelihood = -1.0f;
-    // Maximum residual echo likelihood from the last time period.
-    float residual_echo_likelihood_recent_max = -1.0f;
-  };
-
-  // TODO(ivoc): Make this pure virtual when all subclasses have been updated.
-  virtual AudioProcessingStatistics GetStatistics() const;
-
-  // This returns the stats as optionals and it will replace the regular
-  // GetStatistics.
-  virtual AudioProcessingStats GetStatistics(bool has_remote_tracks) const;
+  // Get audio processing 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
+  // AudioProcessing, because they only make sense if there is at least one
+  // remote track.
+  virtual AudioProcessingStats GetStatistics(bool has_remote_tracks) const = 0;
 
   // These provide access to the component interfaces and should never return
   // NULL. The pointers will be valid for the lifetime of the APM instance.
   // The memory for these objects is entirely managed internally.
   virtual GainControl* gain_control() const = 0;
-  // TODO(peah): Deprecate this API call.
-  virtual HighPassFilter* high_pass_filter() const = 0;
   virtual LevelEstimator* level_estimator() const = 0;
   virtual NoiseSuppression* noise_suppression() const = 0;
   virtual VoiceDetection* voice_detection() const = 0;
@@ -789,17 +720,6 @@
   StreamConfig streams[StreamName::kNumStreamNames];
 };
 
-// TODO(peah): Remove this interface.
-// A filtering component which removes DC offset and low-frequency noise.
-// Recommended to be enabled on the client-side.
-class HighPassFilter {
- public:
-  virtual int Enable(bool enable) = 0;
-  virtual bool is_enabled() const = 0;
-
-  virtual ~HighPassFilter() {}
-};
-
 // An estimation component used to retrieve level metrics.
 class LevelEstimator {
  public:
diff --git a/modules/audio_processing/include/audio_processing_statistics.h b/modules/audio_processing/include/audio_processing_statistics.h
index 2318bad..2ff2009 100644
--- a/modules/audio_processing/include/audio_processing_statistics.h
+++ b/modules/audio_processing/include/audio_processing_statistics.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_PROCESSING_STATISTICS_H_
 #define MODULES_AUDIO_PROCESSING_INCLUDE_AUDIO_PROCESSING_STATISTICS_H_
 
+#include <stdint.h>
+
 #include "absl/types/optional.h"
 #include "rtc_base/system/rtc_export.h"
 
diff --git a/modules/audio_processing/include/mock_audio_processing.h b/modules/audio_processing/include/mock_audio_processing.h
index 4a1fe62..f00a16d 100644
--- a/modules/audio_processing/include/mock_audio_processing.h
+++ b/modules/audio_processing/include/mock_audio_processing.h
@@ -42,13 +42,6 @@
   MOCK_CONST_METHOD0(stream_is_saturated, bool());
 };
 
-class MockHighPassFilter : public HighPassFilter {
- public:
-  virtual ~MockHighPassFilter() {}
-  MOCK_METHOD1(Enable, int(bool enable));
-  MOCK_CONST_METHOD0(is_enabled, bool());
-};
-
 class MockLevelEstimator : public LevelEstimator {
  public:
   virtual ~MockLevelEstimator() {}
@@ -114,7 +107,6 @@
  public:
   MockAudioProcessing()
       : gain_control_(new testing::NiceMock<MockGainControl>()),
-        high_pass_filter_(new testing::NiceMock<MockHighPassFilter>()),
         level_estimator_(new testing::NiceMock<MockLevelEstimator>()),
         noise_suppression_(new testing::NiceMock<MockNoiseSuppression>()),
         voice_detection_(new testing::NiceMock<MockVoiceDetection>()) {}
@@ -180,12 +172,8 @@
   MOCK_METHOD0(DetachPlayoutAudioGenerator, void());
 
   MOCK_METHOD0(UpdateHistogramsOnCallEnd, void());
-  MOCK_CONST_METHOD0(GetStatistics, AudioProcessingStatistics());
   MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool));
   virtual MockGainControl* gain_control() const { return gain_control_.get(); }
-  virtual MockHighPassFilter* high_pass_filter() const {
-    return high_pass_filter_.get();
-  }
   virtual MockLevelEstimator* level_estimator() const {
     return level_estimator_.get();
   }
@@ -200,7 +188,6 @@
 
  private:
   std::unique_ptr<MockGainControl> gain_control_;
-  std::unique_ptr<MockHighPassFilter> high_pass_filter_;
   std::unique_ptr<MockLevelEstimator> level_estimator_;
   std::unique_ptr<MockNoiseSuppression> noise_suppression_;
   std::unique_ptr<MockVoiceDetection> voice_detection_;
diff --git a/modules/audio_processing/level_estimator_impl.cc b/modules/audio_processing/level_estimator_impl.cc
index c937f84..5b49b35 100644
--- a/modules/audio_processing/level_estimator_impl.cc
+++ b/modules/audio_processing/level_estimator_impl.cc
@@ -10,9 +10,13 @@
 
 #include "modules/audio_processing/level_estimator_impl.h"
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "api/array_view.h"
 #include "modules/audio_processing/audio_buffer.h"
 #include "modules/audio_processing/rms_level.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/logging/apm_data_dumper.cc b/modules/audio_processing/logging/apm_data_dumper.cc
index e2e8602..45d8088 100644
--- a/modules/audio_processing/logging/apm_data_dumper.cc
+++ b/modules/audio_processing/logging/apm_data_dumper.cc
@@ -11,7 +11,6 @@
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 
 #include "rtc_base/strings/string_builder.h"
-#include "rtc_base/stringutils.h"
 
 // Check to verify that the define is properly set.
 #if !defined(WEBRTC_APM_DEBUG_DUMP) || \
@@ -47,6 +46,8 @@
 ApmDataDumper::~ApmDataDumper() {}
 
 #if WEBRTC_APM_DEBUG_DUMP == 1
+bool ApmDataDumper::recording_activated_ = false;
+;
 FILE* ApmDataDumper::GetRawFile(const char* name) {
   std::string filename =
       FormFileName(name, instance_index_, recording_set_index_, ".dat");
diff --git a/modules/audio_processing/logging/apm_data_dumper.h b/modules/audio_processing/logging/apm_data_dumper.h
index d045027..f0c5978 100644
--- a/modules/audio_processing/logging/apm_data_dumper.h
+++ b/modules/audio_processing/logging/apm_data_dumper.h
@@ -11,14 +11,17 @@
 #ifndef MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_
 #define MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_
 
+#include <stdint.h>
 #include <stdio.h>
 
-#include <memory>
-#include <string>
+#if WEBRTC_APM_DEBUG_DUMP == 1
 #include <unordered_map>
+#endif
 
 #include "api/array_view.h"
+#if WEBRTC_APM_DEBUG_DUMP == 1
 #include "common_audio/wav_file.h"
+#endif
 #include "rtc_base/constructormagic.h"
 
 // Check to verify that the define is properly set.
@@ -47,6 +50,13 @@
 
   ~ApmDataDumper();
 
+  // Activates or deactivate the dumping functionality.
+  static void SetActivated(bool activated) {
+#if WEBRTC_APM_DEBUG_DUMP == 1
+    recording_activated_ = activated;
+#endif
+  }
+
   // Reinitializes the data dumping such that new versions
   // of all files being dumped to are created.
   void InitiateNewSetOfRecordings() {
@@ -59,117 +69,151 @@
   // various formats.
   void DumpRaw(const char* name, double v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(&v, sizeof(v), 1, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(&v, sizeof(v), 1, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v_length, const double* v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(v, sizeof(v[0]), v_length, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(v, sizeof(v[0]), v_length, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, rtc::ArrayView<const double> v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpRaw(name, v.size(), v.data());
+    if (recording_activated_) {
+      DumpRaw(name, v.size(), v.data());
+    }
 #endif
   }
 
   void DumpRaw(const char* name, float v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(&v, sizeof(v), 1, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(&v, sizeof(v), 1, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v_length, const float* v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(v, sizeof(v[0]), v_length, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(v, sizeof(v[0]), v_length, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, rtc::ArrayView<const float> v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpRaw(name, v.size(), v.data());
+    if (recording_activated_) {
+      DumpRaw(name, v.size(), v.data());
+    }
 #endif
   }
 
   void DumpRaw(const char* name, bool v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpRaw(name, static_cast<int16_t>(v));
+    if (recording_activated_) {
+      DumpRaw(name, static_cast<int16_t>(v));
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v_length, const bool* v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    for (size_t k = 0; k < v_length; ++k) {
-      int16_t value = static_cast<int16_t>(v[k]);
-      fwrite(&value, sizeof(value), 1, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      for (size_t k = 0; k < v_length; ++k) {
+        int16_t value = static_cast<int16_t>(v[k]);
+        fwrite(&value, sizeof(value), 1, file);
+      }
     }
 #endif
   }
 
   void DumpRaw(const char* name, rtc::ArrayView<const bool> v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpRaw(name, v.size(), v.data());
+    if (recording_activated_) {
+      DumpRaw(name, v.size(), v.data());
+    }
 #endif
   }
 
   void DumpRaw(const char* name, int16_t v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(&v, sizeof(v), 1, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(&v, sizeof(v), 1, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v_length, const int16_t* v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(v, sizeof(v[0]), v_length, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(v, sizeof(v[0]), v_length, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, rtc::ArrayView<const int16_t> v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpRaw(name, v.size(), v.data());
+    if (recording_activated_) {
+      DumpRaw(name, v.size(), v.data());
+    }
 #endif
   }
 
   void DumpRaw(const char* name, int32_t v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(&v, sizeof(v), 1, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(&v, sizeof(v), 1, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v_length, const int32_t* v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(v, sizeof(v[0]), v_length, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(v, sizeof(v[0]), v_length, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(&v, sizeof(v), 1, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(&v, sizeof(v), 1, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, size_t v_length, const size_t* v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    FILE* file = GetRawFile(name);
-    fwrite(v, sizeof(v[0]), v_length, file);
+    if (recording_activated_) {
+      FILE* file = GetRawFile(name);
+      fwrite(v, sizeof(v[0]), v_length, file);
+    }
 #endif
   }
 
   void DumpRaw(const char* name, rtc::ArrayView<const int32_t> v) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpRaw(name, v.size(), v.data());
+    if (recording_activated_) {
+      DumpRaw(name, v.size(), v.data());
+    }
 #endif
   }
 
@@ -179,8 +223,10 @@
                int sample_rate_hz,
                int num_channels) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    WavWriter* file = GetWavFile(name, sample_rate_hz, num_channels);
-    file->WriteSamples(v, v_length);
+    if (recording_activated_) {
+      WavWriter* file = GetWavFile(name, sample_rate_hz, num_channels);
+      file->WriteSamples(v, v_length);
+    }
 #endif
   }
 
@@ -189,12 +235,15 @@
                int sample_rate_hz,
                int num_channels) {
 #if WEBRTC_APM_DEBUG_DUMP == 1
-    DumpWav(name, v.size(), v.data(), sample_rate_hz, num_channels);
+    if (recording_activated_) {
+      DumpWav(name, v.size(), v.data(), sample_rate_hz, num_channels);
+    }
 #endif
   }
 
  private:
 #if WEBRTC_APM_DEBUG_DUMP == 1
+  static bool recording_activated_;
   const int instance_index_;
   int recording_set_index_ = 0;
   std::unordered_map<std::string, std::unique_ptr<FILE, RawFileCloseFunctor>>
diff --git a/modules/audio_processing/low_cut_filter.cc b/modules/audio_processing/low_cut_filter.cc
index 5245c68..581d6bc 100644
--- a/modules/audio_processing/low_cut_filter.cc
+++ b/modules/audio_processing/low_cut_filter.cc
@@ -10,8 +10,13 @@
 
 #include "modules/audio_processing/low_cut_filter.h"
 
+#include <stdint.h>
+#include <cstring>
+
 #include "common_audio/signal_processing/include/signal_processing_library.h"
 #include "modules/audio_processing/audio_buffer.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/checks.h"
 
 namespace webrtc {
 namespace {
diff --git a/modules/audio_processing/module.mk b/modules/audio_processing/module.mk
index e7beb84..1b1754f 100644
--- a/modules/audio_processing/module.mk
+++ b/modules/audio_processing/module.mk
@@ -122,6 +122,7 @@
 	modules/audio_processing/aec3/render_delay_controller.o \
 	modules/audio_processing/aec3/render_delay_controller2.o \
 	modules/audio_processing/aec3/render_delay_controller_metrics.o \
+	modules/audio_processing/aec3/render_reverb_model.o \
 	modules/audio_processing/aec3/render_signal_analyzer.o \
 	modules/audio_processing/aec3/residual_echo_estimator.o \
 	modules/audio_processing/aec3/reverb_decay_estimator.o \
@@ -157,11 +158,10 @@
 	modules/audio_processing/agc2/compute_interpolated_gain_curve.o \
 	modules/audio_processing/agc2/down_sampler.o \
 	modules/audio_processing/agc2/fixed_digital_level_estimator.o \
-	modules/audio_processing/agc2/fixed_gain_controller.o \
 	modules/audio_processing/agc2/gain_applier.o \
-	modules/audio_processing/agc2/gain_curve_applier.o \
 	modules/audio_processing/agc2/interpolated_gain_curve.o \
 	modules/audio_processing/agc2/limiter.o \
+	modules/audio_processing/agc2/limiter_db_gain_curve.o \
 	modules/audio_processing/agc2/noise_level_estimator.o \
 	modules/audio_processing/agc2/noise_spectrum_estimator.o \
 	modules/audio_processing/agc2/saturation_protector.o \
diff --git a/modules/audio_processing/noise_suppression_impl.cc b/modules/audio_processing/noise_suppression_impl.cc
index 15d4043..d8d9e32 100644
--- a/modules/audio_processing/noise_suppression_impl.cc
+++ b/modules/audio_processing/noise_suppression_impl.cc
@@ -11,9 +11,11 @@
 #include "modules/audio_processing/noise_suppression_impl.h"
 
 #include "modules/audio_processing/audio_buffer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 #if defined(WEBRTC_NS_FLOAT)
 #include "modules/audio_processing/ns/noise_suppression.h"
+
 #define NS_CREATE WebRtcNs_Create
 #define NS_FREE WebRtcNs_Free
 #define NS_INIT WebRtcNs_Init
@@ -21,6 +23,7 @@
 typedef NsHandle NsState;
 #elif defined(WEBRTC_NS_FIXED)
 #include "modules/audio_processing/ns/noise_suppression_x.h"
+
 #define NS_CREATE WebRtcNsx_Create
 #define NS_FREE WebRtcNsx_Free
 #define NS_INIT WebRtcNsx_Init
diff --git a/modules/audio_processing/residual_echo_detector.cc b/modules/audio_processing/residual_echo_detector.cc
index e805013..3454214 100644
--- a/modules/audio_processing/residual_echo_detector.cc
+++ b/modules/audio_processing/residual_echo_detector.cc
@@ -13,9 +13,11 @@
 #include <algorithm>
 #include <numeric>
 
+#include "absl/types/optional.h"
 #include "modules/audio_processing/audio_buffer.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
 #include "rtc_base/atomicops.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "system_wrappers/include/metrics.h"
 
diff --git a/modules/audio_processing/rms_level.h b/modules/audio_processing/rms_level.h
index 9aa549a..e6b5849 100644
--- a/modules/audio_processing/rms_level.h
+++ b/modules/audio_processing/rms_level.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
 #define MODULES_AUDIO_PROCESSING_RMS_LEVEL_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "absl/types/optional.h"
 #include "api/array_view.h"
 
diff --git a/modules/audio_processing/transient/moving_moments.cc b/modules/audio_processing/transient/moving_moments.cc
index a199bb0..83810bf 100644
--- a/modules/audio_processing/transient/moving_moments.cc
+++ b/modules/audio_processing/transient/moving_moments.cc
@@ -10,7 +10,7 @@
 
 #include "modules/audio_processing/transient/moving_moments.h"
 
-#include <cmath>
+#include <algorithm>
 
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/transient/transient_detector.cc b/modules/audio_processing/transient/transient_detector.cc
index c3bf282..8997d4c 100644
--- a/modules/audio_processing/transient/transient_detector.cc
+++ b/modules/audio_processing/transient/transient_detector.cc
@@ -13,12 +13,12 @@
 #include <float.h>
 #include <math.h>
 #include <string.h>
-
 #include <algorithm>
 
 #include "modules/audio_processing/transient/common.h"
 #include "modules/audio_processing/transient/daubechies_8_wavelet_coeffs.h"
 #include "modules/audio_processing/transient/moving_moments.h"
+#include "modules/audio_processing/transient/wpd_node.h"
 #include "modules/audio_processing/transient/wpd_tree.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/transient/transient_detector.h b/modules/audio_processing/transient/transient_detector.h
index 3267b3a..23b88f8 100644
--- a/modules/audio_processing/transient/transient_detector.h
+++ b/modules/audio_processing/transient/transient_detector.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_DETECTOR_H_
 #define MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_DETECTOR_H_
 
+#include <stddef.h>
 #include <deque>
 #include <memory>
 
diff --git a/modules/audio_processing/transient/transient_suppression_test.cc b/modules/audio_processing/transient/transient_suppression_test.cc
index 9e7ecd5..e15f69c 100644
--- a/modules/audio_processing/transient/transient_suppression_test.cc
+++ b/modules/audio_processing/transient/transient_suppression_test.cc
@@ -23,26 +23,28 @@
 #include "test/gtest.h"
 #include "test/testsupport/fileutils.h"
 
-DEFINE_string(in_file_name, "", "PCM file that contains the signal.");
-DEFINE_string(detection_file_name,
-              "",
-              "PCM file that contains the detection signal.");
-DEFINE_string(reference_file_name,
-              "",
-              "PCM file that contains the reference signal.");
+WEBRTC_DEFINE_string(in_file_name, "", "PCM file that contains the signal.");
+WEBRTC_DEFINE_string(detection_file_name,
+                     "",
+                     "PCM file that contains the detection signal.");
+WEBRTC_DEFINE_string(reference_file_name,
+                     "",
+                     "PCM file that contains the reference signal.");
 
-DEFINE_int(chunk_size_ms,
-           10,
-           "Time between each chunk of samples in milliseconds.");
+WEBRTC_DEFINE_int(chunk_size_ms,
+                  10,
+                  "Time between each chunk of samples in milliseconds.");
 
-DEFINE_int(sample_rate_hz, 16000, "Sampling frequency of the signal in Hertz.");
-DEFINE_int(detection_rate_hz,
-           0,
-           "Sampling frequency of the detection signal in Hertz.");
+WEBRTC_DEFINE_int(sample_rate_hz,
+                  16000,
+                  "Sampling frequency of the signal in Hertz.");
+WEBRTC_DEFINE_int(detection_rate_hz,
+                  0,
+                  "Sampling frequency of the detection signal in Hertz.");
 
-DEFINE_int(num_channels, 1, "Number of channels.");
+WEBRTC_DEFINE_int(num_channels, 1, "Number of channels.");
 
-DEFINE_bool(help, false, "Print this message.");
+WEBRTC_DEFINE_bool(help, false, "Print this message.");
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/transient/transient_suppressor.h b/modules/audio_processing/transient/transient_suppressor.h
index 9ae3fc6..ae51966 100644
--- a/modules/audio_processing/transient/transient_suppressor.h
+++ b/modules/audio_processing/transient/transient_suppressor.h
@@ -11,9 +11,9 @@
 #ifndef MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_SUPPRESSOR_H_
 #define MODULES_AUDIO_PROCESSING_TRANSIENT_TRANSIENT_SUPPRESSOR_H_
 
-#include <deque>
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
-#include <set>
 
 #include "rtc_base/gtest_prod_util.h"
 
diff --git a/modules/audio_processing/transient/wpd_tree.cc b/modules/audio_processing/transient/wpd_tree.cc
index 72f4d76..c8aa615 100644
--- a/modules/audio_processing/transient/wpd_tree.cc
+++ b/modules/audio_processing/transient/wpd_tree.cc
@@ -10,10 +10,8 @@
 
 #include "modules/audio_processing/transient/wpd_tree.h"
 
-#include <math.h>
 #include <string.h>
 
-#include "modules/audio_processing/transient/dyadic_decimator.h"
 #include "modules/audio_processing/transient/wpd_node.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_processing/transient/wpd_tree.h b/modules/audio_processing/transient/wpd_tree.h
index 707a89d..b62135d 100644
--- a/modules/audio_processing/transient/wpd_tree.h
+++ b/modules/audio_processing/transient/wpd_tree.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_AUDIO_PROCESSING_TRANSIENT_WPD_TREE_H_
 #define MODULES_AUDIO_PROCESSING_TRANSIENT_WPD_TREE_H_
 
+#include <stddef.h>
 #include <memory>
 
 #include "modules/audio_processing/transient/wpd_node.h"
diff --git a/modules/audio_processing/utility/ooura_fft.cc b/modules/audio_processing/utility/ooura_fft.cc
index c3333ce..8628bd3 100644
--- a/modules/audio_processing/utility/ooura_fft.cc
+++ b/modules/audio_processing/utility/ooura_fft.cc
@@ -23,8 +23,6 @@
 
 #include "modules/audio_processing/utility/ooura_fft.h"
 
-#include <math.h>
-
 #include "modules/audio_processing/utility/ooura_fft_tables_common.h"
 #include "rtc_base/system/arch.h"
 #include "system_wrappers/include/cpu_features_wrapper.h"
diff --git a/modules/audio_processing/utility/ooura_fft_sse2.cc b/modules/audio_processing/utility/ooura_fft_sse2.cc
index 9b5d0f3..0e4a44b 100644
--- a/modules/audio_processing/utility/ooura_fft_sse2.cc
+++ b/modules/audio_processing/utility/ooura_fft_sse2.cc
@@ -8,10 +8,10 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/audio_processing/utility/ooura_fft.h"
-
 #include <emmintrin.h>
+#include <xmmintrin.h>
 
+#include "modules/audio_processing/utility/ooura_fft.h"
 #include "modules/audio_processing/utility/ooura_fft_tables_common.h"
 #include "modules/audio_processing/utility/ooura_fft_tables_neon_sse2.h"
 #include "rtc_base/system/arch.h"
diff --git a/modules/audio_processing/vad/gmm.cc b/modules/audio_processing/vad/gmm.cc
index cd8a1a8..3b8764c 100644
--- a/modules/audio_processing/vad/gmm.cc
+++ b/modules/audio_processing/vad/gmm.cc
@@ -11,7 +11,6 @@
 #include "modules/audio_processing/vad/gmm.h"
 
 #include <math.h>
-#include <stdlib.h>
 
 namespace webrtc {
 
diff --git a/modules/audio_processing/vad/pitch_based_vad.cc b/modules/audio_processing/vad/pitch_based_vad.cc
index 025ef20..68e60dc 100644
--- a/modules/audio_processing/vad/pitch_based_vad.cc
+++ b/modules/audio_processing/vad/pitch_based_vad.cc
@@ -10,7 +10,6 @@
 
 #include "modules/audio_processing/vad/pitch_based_vad.h"
 
-#include <math.h>
 #include <string.h>
 
 #include "modules/audio_processing/vad/common.h"
diff --git a/modules/audio_processing/vad/pitch_based_vad.h b/modules/audio_processing/vad/pitch_based_vad.h
index 4d32765..22bc0f2 100644
--- a/modules/audio_processing/vad/pitch_based_vad.h
+++ b/modules/audio_processing/vad/pitch_based_vad.h
@@ -18,7 +18,6 @@
 
 namespace webrtc {
 
-class AudioFrame;
 class VadCircularBuffer;
 
 // Computes the probability of the input audio frame to be active given
diff --git a/modules/audio_processing/vad/pole_zero_filter.cc b/modules/audio_processing/vad/pole_zero_filter.cc
index b9967d7..4156d7e 100644
--- a/modules/audio_processing/vad/pole_zero_filter.cc
+++ b/modules/audio_processing/vad/pole_zero_filter.cc
@@ -10,7 +10,6 @@
 
 #include "modules/audio_processing/vad/pole_zero_filter.h"
 
-#include <stdlib.h>
 #include <string.h>
 #include <algorithm>
 
diff --git a/modules/audio_processing/vad/standalone_vad.cc b/modules/audio_processing/vad/standalone_vad.cc
index 19a5282..1397668 100644
--- a/modules/audio_processing/vad/standalone_vad.cc
+++ b/modules/audio_processing/vad/standalone_vad.cc
@@ -12,7 +12,7 @@
 
 #include <string.h>
 
-#include "audio/utility/audio_frame_operations.h"
+#include "common_audio/vad/include/webrtc_vad.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/vad/standalone_vad.h b/modules/audio_processing/vad/standalone_vad.h
index 79650fb..3dff416 100644
--- a/modules/audio_processing/vad/standalone_vad.h
+++ b/modules/audio_processing/vad/standalone_vad.h
@@ -11,13 +11,14 @@
 #ifndef MODULES_AUDIO_PROCESSING_AGC_STANDALONE_VAD_H_
 #define MODULES_AUDIO_PROCESSING_AGC_STANDALONE_VAD_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "common_audio/vad/include/webrtc_vad.h"
 #include "modules/audio_processing/vad/common.h"
 
 namespace webrtc {
 
-class AudioFrame;
-
 class StandaloneVad {
  public:
   static StandaloneVad* Create();
diff --git a/modules/audio_processing/vad/vad_audio_proc.h b/modules/audio_processing/vad/vad_audio_proc.h
index e34091b..9be3467 100644
--- a/modules/audio_processing/vad/vad_audio_proc.h
+++ b/modules/audio_processing/vad/vad_audio_proc.h
@@ -11,13 +11,14 @@
 #ifndef MODULES_AUDIO_PROCESSING_VAD_VAD_AUDIO_PROC_H_
 #define MODULES_AUDIO_PROCESSING_VAD_VAD_AUDIO_PROC_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 
-#include "modules/audio_processing/vad/common.h"
+#include "modules/audio_processing/vad/common.h"  // AudioFeatures, kSampleR...
 
 namespace webrtc {
 
-class AudioFrame;
 class PoleZeroFilter;
 
 class VadAudioProc {
diff --git a/modules/audio_processing/vad/voice_activity_detector.h b/modules/audio_processing/vad/voice_activity_detector.h
index e424ac1..d140fe2 100644
--- a/modules/audio_processing/vad/voice_activity_detector.h
+++ b/modules/audio_processing/vad/voice_activity_detector.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_AUDIO_PROCESSING_VAD_VOICE_ACTIVITY_DETECTOR_H_
 #define MODULES_AUDIO_PROCESSING_VAD_VOICE_ACTIVITY_DETECTOR_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <vector>
 
diff --git a/modules/audio_processing/voice_detection_impl.cc b/modules/audio_processing/voice_detection_impl.cc
index 9280be1..c55ca4a 100644
--- a/modules/audio_processing/voice_detection_impl.cc
+++ b/modules/audio_processing/voice_detection_impl.cc
@@ -10,8 +10,10 @@
 
 #include "modules/audio_processing/voice_detection_impl.h"
 
+#include "api/audio/audio_frame.h"
 #include "common_audio/vad/include/webrtc_vad.h"
 #include "modules/audio_processing/audio_buffer.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/audio_processing/voice_detection_impl.h b/modules/audio_processing/voice_detection_impl.h
index 4b724bd..c438473 100644
--- a/modules/audio_processing/voice_detection_impl.h
+++ b/modules/audio_processing/voice_detection_impl.h
@@ -11,11 +11,13 @@
 #ifndef MODULES_AUDIO_PROCESSING_VOICE_DETECTION_IMPL_H_
 #define MODULES_AUDIO_PROCESSING_VOICE_DETECTION_IMPL_H_
 
+#include <stddef.h>
 #include <memory>
 
 #include "modules/audio_processing/include/audio_processing.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
@@ -42,6 +44,7 @@
 
  private:
   class Vad;
+
   rtc::CriticalSection* const crit_;
   bool enabled_ RTC_GUARDED_BY(crit_) = false;
   bool stream_has_voice_ RTC_GUARDED_BY(crit_) = false;
diff --git a/modules/include/module_common_types.cc b/modules/include/module_common_types.cc
index 4ad5d14..80eba2e 100644
--- a/modules/include/module_common_types.cc
+++ b/modules/include/module_common_types.cc
@@ -11,6 +11,7 @@
 #include "modules/include/module_common_types.h"
 
 #include <string.h>
+#include <cstdint>
 #include <utility>
 
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/modules/include/module_common_types.h b/modules/include/module_common_types.h
index 98ff767..e058cc8 100644
--- a/modules/include/module_common_types.h
+++ b/modules/include/module_common_types.h
@@ -19,6 +19,7 @@
 #include "modules/include/module_common_types_public.h"
 #include "modules/include/module_fec_types.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
@@ -33,7 +34,7 @@
   int64_t ntp_time_ms;
 };
 
-class RTPFragmentationHeader {
+class RTC_EXPORT RTPFragmentationHeader {
  public:
   RTPFragmentationHeader();
   RTPFragmentationHeader(const RTPFragmentationHeader&) = delete;
diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn
index a4774d8..4f62184 100644
--- a/modules/rtp_rtcp/BUILD.gn
+++ b/modules/rtp_rtcp/BUILD.gn
@@ -85,6 +85,7 @@
 
   deps = [
     "..:module_api",
+    "..:module_api_public",
     "../..:webrtc_common",
     "../../api:array_view",
     "../../api:libjingle_peerconnection_api",
@@ -96,6 +97,7 @@
     "../../rtc_base:deprecation",
     "../../rtc_base:rtc_base_approved",
     "../../system_wrappers",
+    "../video_coding:codec_globals_headers",
     "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
@@ -186,7 +188,10 @@
 
   deps = [
     ":rtp_rtcp_format",
+    ":rtp_video_header",
     "..:module_api",
+    "..:module_api_public",
+    "..:module_fec_api",
     "../..:webrtc_common",
     "../../api:array_view",
     "../../api:libjingle_peerconnection_api",
@@ -194,6 +199,7 @@
     "../../api/audio_codecs:audio_codecs_api",
     "../../api/video:video_bitrate_allocation",
     "../../api/video:video_bitrate_allocator",
+    "../../api/video:video_frame",
     "../../api/video_codecs:video_codecs_api",
     "../../call:rtp_interfaces",
     "../../common_video",
@@ -216,9 +222,12 @@
     "../../system_wrappers:metrics",
     "../audio_coding:audio_format_conversion",
     "../remote_bitrate_estimator",
+    "../video_coding:codec_globals_headers",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
+    "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
 
@@ -263,6 +272,7 @@
     "../../api/video:video_frame",
     "../../modules/video_coding:codec_globals_headers",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
+    "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:variant",
   ]
 }
@@ -321,6 +331,7 @@
       ":rtp_rtcp",
       "../../test:fileutils",
       "../../test:test_main",
+      "../../test:test_support",
       "//testing/gtest",
     ]
   }  # test_packet_masks_metrics
diff --git a/modules/rtp_rtcp/include/flexfec_receiver.h b/modules/rtp_rtcp/include/flexfec_receiver.h
index f006111..f0ed576 100644
--- a/modules/rtp_rtcp/include/flexfec_receiver.h
+++ b/modules/rtp_rtcp/include/flexfec_receiver.h
@@ -11,16 +11,20 @@
 #ifndef MODULES_RTP_RTCP_INCLUDE_FLEXFEC_RECEIVER_H_
 #define MODULES_RTP_RTCP_INCLUDE_FLEXFEC_RECEIVER_H_
 
+#include <stdint.h>
 #include <memory>
 
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/include/ulpfec_receiver.h"
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 #include "rtc_base/sequenced_task_checker.h"
-#include "system_wrappers/include/clock.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
+class Clock;
+
 class FlexfecReceiver {
  public:
   FlexfecReceiver(uint32_t ssrc,
diff --git a/modules/rtp_rtcp/include/flexfec_sender.h b/modules/rtp_rtcp/include/flexfec_sender.h
index 12277e1..acee117 100644
--- a/modules/rtp_rtcp/include/flexfec_sender.h
+++ b/modules/rtp_rtcp/include/flexfec_sender.h
@@ -18,17 +18,15 @@
 #include "api/array_view.h"
 #include "api/rtpparameters.h"
 #include "modules/include/module_common_types.h"
-#include "modules/rtp_rtcp/include/flexfec_sender.h"
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_header_extension_size.h"
-#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
 #include "modules/rtp_rtcp/source/ulpfec_generator.h"
 #include "rtc_base/random.h"
-#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 
+class Clock;
 class RtpPacketToSend;
 
 // Note that this class is not thread safe, and thus requires external
diff --git a/modules/rtp_rtcp/include/remote_ntp_time_estimator.h b/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
index 5195e8a..e6d269c 100644
--- a/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
+++ b/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
@@ -11,7 +11,7 @@
 #ifndef MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
 #define MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
 
-#include <memory>
+#include <stdint.h>
 
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/numerics/moving_median_filter.h"
diff --git a/modules/rtp_rtcp/include/rtp_header_extension_map.h b/modules/rtp_rtcp/include/rtp_header_extension_map.h
index b8f27a1..391c5be 100644
--- a/modules/rtp_rtcp/include/rtp_header_extension_map.h
+++ b/modules/rtp_rtcp/include/rtp_header_extension_map.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_EXTENSION_MAP_H_
 #define MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_EXTENSION_MAP_H_
 
+#include <stdint.h>
 #include <string>
 
 #include "api/array_view.h"
@@ -26,6 +27,7 @@
   static constexpr int kInvalidId = 0;
 
   RtpHeaderExtensionMap();
+  explicit RtpHeaderExtensionMap(bool extmap_allow_mixed);
   explicit RtpHeaderExtensionMap(rtc::ArrayView<const RtpExtension> extensions);
 
   template <typename Extension>
@@ -53,18 +55,19 @@
   }
   int32_t Deregister(RTPExtensionType type);
 
-  bool IsMixedOneTwoByteHeaderSupported() const {
-    return mixed_one_two_byte_header_supported_;
-  }
-  void SetMixedOneTwoByteHeaderSupported(bool supported) {
-    mixed_one_two_byte_header_supported_ = supported;
+  // Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
+  // Set to true if it's allowed to mix one- and two-byte RTP header extensions
+  // in the same stream.
+  bool ExtmapAllowMixed() const { return extmap_allow_mixed_; }
+  void SetExtmapAllowMixed(bool extmap_allow_mixed) {
+    extmap_allow_mixed_ = extmap_allow_mixed;
   }
 
  private:
   bool Register(int id, RTPExtensionType type, const char* uri);
 
   uint8_t ids_[kRtpExtensionNumberOfExtensions];
-  bool mixed_one_two_byte_header_supported_;
+  bool extmap_allow_mixed_;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index a99544c..265046c 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -28,6 +28,7 @@
 namespace webrtc {
 
 // Forward declarations.
+class FrameEncryptorInterface;
 class OverheadObserver;
 class RateLimiter;
 class ReceiveStatisticsProvider;
@@ -97,6 +98,14 @@
     // Update network2 instead of pacer_exit field of video timing extension.
     bool populate_network2_timestamp = false;
 
+    // E2EE Custom Video Frame Encryption
+    FrameEncryptorInterface* frame_encryptor = nullptr;
+    // Require all outgoing frames to be encrypted with a FrameEncryptor.
+    bool require_frame_encryption = false;
+
+    // Corresponds to extmap-allow-mixed in SDP negotiation.
+    bool extmap_allow_mixed = false;
+
    private:
     RTC_DISALLOW_COPY_AND_ASSIGN(Configuration);
   };
@@ -136,6 +145,8 @@
   // Returns -1 on failure else 0.
   virtual int32_t DeRegisterSendPayload(int8_t payload_type) = 0;
 
+  virtual void SetExtmapAllowMixed(bool extmap_allow_mixed) = 0;
+
   // (De)registers RTP header extension type and id.
   // Returns -1 on failure else 0.
   virtual int32_t RegisterSendRtpHeaderExtension(RTPExtensionType type,
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.cc b/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
index e1dca33..1da8ade 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
@@ -10,6 +10,13 @@
 
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 
+#include <ctype.h>
+#include <string.h>
+#include <algorithm>
+#include <type_traits>
+
+#include "api/array_view.h"
+
 namespace webrtc {
 
 StreamDataCounters::StreamDataCounters() : first_packet_time_ms(-1) {}
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
index e587313..5b9a051 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -32,9 +32,9 @@
 }
 
 const int kVideoPayloadTypeFrequency = 90000;
-// TODO(solenberg): RTP time stamp rate for RTCP is fixed at 8k, this is legacy
-// and should be fixed.
-// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6458
+
+// TODO(bugs.webrtc.org/6458): Remove this when all the depending projects are
+// updated to correctly set rtp rate for RtcpSender.
 const int kBogusRtpRateForAudioRtcp = 8000;
 
 // Minimum RTP header size in bytes.
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index e95bdd3..9f00654 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -52,6 +52,7 @@
   MOCK_METHOD2(RegisterVideoSendPayload,
                void(int payload_type, const char* payload_name));
   MOCK_METHOD1(DeRegisterSendPayload, int32_t(int8_t payload_type));
+  MOCK_METHOD1(SetExtmapAllowMixed, void(bool extmap_allow_mixed));
   MOCK_METHOD2(RegisterSendRtpHeaderExtension,
                int32_t(RTPExtensionType type, uint8_t id));
   MOCK_METHOD2(RegisterRtpHeaderExtension,
diff --git a/modules/rtp_rtcp/source/contributing_sources.cc b/modules/rtp_rtcp/source/contributing_sources.cc
index 853706c..64dc443 100644
--- a/modules/rtp_rtcp/source/contributing_sources.cc
+++ b/modules/rtp_rtcp/source/contributing_sources.cc
@@ -25,9 +25,11 @@
 ContributingSources::~ContributingSources() = default;
 
 void ContributingSources::Update(int64_t now_ms,
-                                 rtc::ArrayView<const uint32_t> csrcs) {
+                                 rtc::ArrayView<const uint32_t> csrcs,
+                                 absl::optional<uint8_t> audio_level) {
+  Entry entry = { now_ms, audio_level };
   for (uint32_t csrc : csrcs) {
-    last_seen_ms_[csrc] = now_ms;
+    active_csrcs_[csrc] = entry;
   }
   if (!next_pruning_ms_) {
     next_pruning_ms_ = now_ms + kPruningIntervalMs;
@@ -43,9 +45,16 @@
 // non-const.
 std::vector<RtpSource> ContributingSources::GetSources(int64_t now_ms) const {
   std::vector<RtpSource> sources;
-  for (auto& record : last_seen_ms_) {
-    if (record.second >= now_ms - kHistoryMs) {
-      sources.emplace_back(record.second, record.first, RtpSourceType::CSRC);
+  for (auto& record : active_csrcs_) {
+    if (record.second.last_seen_ms >= now_ms - kHistoryMs) {
+      if (record.second.audio_level.has_value()) {
+        sources.emplace_back(record.second.last_seen_ms, record.first,
+                             RtpSourceType::CSRC,
+                             *record.second.audio_level);
+      } else {
+        sources.emplace_back(record.second.last_seen_ms, record.first,
+                             RtpSourceType::CSRC);
+      }
     }
   }
 
@@ -54,15 +63,20 @@
 
 // Delete stale entries.
 void ContributingSources::DeleteOldEntries(int64_t now_ms) {
-  for (auto it = last_seen_ms_.begin(); it != last_seen_ms_.end();) {
-    if (it->second >= now_ms - kHistoryMs) {
+  for (auto it = active_csrcs_.begin(); it != active_csrcs_.end();) {
+    if (it->second.last_seen_ms >= now_ms - kHistoryMs) {
       // Still relevant.
       ++it;
     } else {
-      it = last_seen_ms_.erase(it);
+      it = active_csrcs_.erase(it);
     }
   }
   next_pruning_ms_ = now_ms + kPruningIntervalMs;
 }
 
+ContributingSources::Entry::Entry() = default;
+ContributingSources::Entry::Entry(int64_t timestamp_ms,
+                                  absl::optional<uint8_t> audio_level_arg)
+    : last_seen_ms(timestamp_ms), audio_level(audio_level_arg) {}
+
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/contributing_sources.h b/modules/rtp_rtcp/source/contributing_sources.h
index b6201ce..5e34539 100644
--- a/modules/rtp_rtcp/source/contributing_sources.h
+++ b/modules/rtp_rtcp/source/contributing_sources.h
@@ -32,18 +32,25 @@
   ContributingSources();
   ~ContributingSources();
 
-  // TODO(bugs.webrtc.org/3333): Needs to be extended with audio-level, to
-  // support RFC6465.
-  void Update(int64_t now_ms, rtc::ArrayView<const uint32_t> csrcs);
+  void Update(int64_t now_ms, rtc::ArrayView<const uint32_t> csrcs,
+              absl::optional<uint8_t> audio_level);
 
   // Returns contributing sources seen the last 10 s.
   std::vector<RtpSource> GetSources(int64_t now_ms) const;
 
  private:
+  struct Entry {
+    Entry();
+    Entry(int64_t timestamp_ms, absl::optional<uint8_t> audio_level);
+
+    int64_t last_seen_ms;
+    absl::optional<uint8_t> audio_level;
+  };
+
   void DeleteOldEntries(int64_t now_ms);
 
   // Indexed by csrc.
-  std::map<uint32_t, int64_t> last_seen_ms_;
+  std::map<uint32_t, Entry> active_csrcs_;
   absl::optional<int64_t> next_pruning_ms_;
 };
 
diff --git a/modules/rtp_rtcp/source/contributing_sources_unittest.cc b/modules/rtp_rtcp/source/contributing_sources_unittest.cc
index 8b22d26..5f1d8d3 100644
--- a/modules/rtp_rtcp/source/contributing_sources_unittest.cc
+++ b/modules/rtp_rtcp/source/contributing_sources_unittest.cc
@@ -30,7 +30,7 @@
   ContributingSources csrcs;
   constexpr uint32_t kCsrcs[] = {kCsrc1, kCsrc2};
   constexpr int64_t kTime1 = 10;
-  csrcs.Update(kTime1, kCsrcs);
+  csrcs.Update(kTime1, kCsrcs, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime1),
       UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
@@ -45,12 +45,12 @@
   constexpr uint32_t kCsrcs2[] = {kCsrc2, kCsrc3};
   constexpr int64_t kTime1 = 10;
   constexpr int64_t kTime2 = kTime1 + 5 * rtc::kNumMillisecsPerSec;
-  csrcs.Update(kTime1, kCsrcs1);
+  csrcs.Update(kTime1, kCsrcs1, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime1),
       UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
                            RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
-  csrcs.Update(kTime2, kCsrcs2);
+  csrcs.Update(kTime2, kCsrcs2, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime2),
       UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
@@ -65,12 +65,12 @@
   constexpr int64_t kTime1 = 10;
   constexpr int64_t kTime2 = kTime1 + 5 * rtc::kNumMillisecsPerSec;
   constexpr int64_t kTime3 = kTime1 + 12 * rtc::kNumMillisecsPerSec;
-  csrcs.Update(kTime1, kCsrcs1);
+  csrcs.Update(kTime1, kCsrcs1, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime1),
       UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
                            RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
-  csrcs.Update(kTime2, kCsrcs2);
+  csrcs.Update(kTime2, kCsrcs2, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime3),
       UnorderedElementsAre(RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC),
@@ -84,18 +84,18 @@
   constexpr int64_t kTime1 = 10;
   constexpr int64_t kTime2 = kTime1 + 10 * rtc::kNumMillisecsPerSec;
   constexpr int64_t kTime3 = kTime1 + 20 * rtc::kNumMillisecsPerSec;
-  csrcs.Update(kTime1, kCsrcs1);
+  csrcs.Update(kTime1, kCsrcs1, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime2),
       UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
                            RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
-  csrcs.Update(kTime2, kCsrcs2);
+  csrcs.Update(kTime2, kCsrcs2, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime2),
       UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
                            RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC),
                            RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC)));
-  csrcs.Update(kTime3, kCsrcs2);
+  csrcs.Update(kTime3, kCsrcs2, absl::nullopt);
   EXPECT_THAT(
       csrcs.GetSources(kTime3),
       UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC),
@@ -108,4 +108,22 @@
                            RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC)));
 }
 
+TEST(ContributingSourcesTest, AudioLevel) {
+  ContributingSources csrcs;
+  constexpr uint32_t kCsrcs[] = {kCsrc1, kCsrc2};
+  constexpr int64_t kTime1 = 10;
+  csrcs.Update(kTime1, kCsrcs, 47);
+  EXPECT_THAT(
+      csrcs.GetSources(kTime1),
+      UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, 47),
+                           RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, 47)));
+
+  constexpr uint32_t kCsrcsSubset[] = {kCsrc1};
+  csrcs.Update(kTime1 + 1, kCsrcsSubset, absl::nullopt);
+  EXPECT_THAT(
+      csrcs.GetSources(kTime1 + 1),
+      UnorderedElementsAre(RtpSource(kTime1 + 1, kCsrc1, RtpSourceType::CSRC),
+                           RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, 47)));
+}
+
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/dtmf_queue.cc b/modules/rtp_rtcp/source/dtmf_queue.cc
index 86ddb10..10e6747 100644
--- a/modules/rtp_rtcp/source/dtmf_queue.cc
+++ b/modules/rtp_rtcp/source/dtmf_queue.cc
@@ -10,6 +10,10 @@
 
 #include "modules/rtp_rtcp/source/dtmf_queue.h"
 
+#include <stddef.h>
+
+#include "rtc_base/checks.h"
+
 namespace {
 constexpr size_t kDtmfOutbandMax = 20;
 }
diff --git a/modules/rtp_rtcp/source/dtmf_queue.h b/modules/rtp_rtcp/source/dtmf_queue.h
index db70c97..e5955a1 100644
--- a/modules/rtp_rtcp/source/dtmf_queue.h
+++ b/modules/rtp_rtcp/source/dtmf_queue.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_DTMF_QUEUE_H_
 #define MODULES_RTP_RTCP_SOURCE_DTMF_QUEUE_H_
 
+#include <stdint.h>
 #include <list>
 
 #include "rtc_base/criticalsection.h"
diff --git a/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc b/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc
index d7666e1..b813340 100644
--- a/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc
+++ b/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc
@@ -12,12 +12,11 @@
 
 #include <string.h>
 
-#include <utility>
-
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/scoped_ref_ptr.h"
 
 namespace webrtc {
 
diff --git a/modules/rtp_rtcp/source/flexfec_header_reader_writer.h b/modules/rtp_rtcp/source/flexfec_header_reader_writer.h
index 1d6ddda..d305c4c 100644
--- a/modules/rtp_rtcp/source/flexfec_header_reader_writer.h
+++ b/modules/rtp_rtcp/source/flexfec_header_reader_writer.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_FLEXFEC_HEADER_READER_WRITER_H_
 #define MODULES_RTP_RTCP_SOURCE_FLEXFEC_HEADER_READER_WRITER_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/flexfec_receiver.cc b/modules/rtp_rtcp/source/flexfec_receiver.cc
index c3ed4d5..1a62bce 100644
--- a/modules/rtp_rtcp/source/flexfec_receiver.cc
+++ b/modules/rtp_rtcp/source/flexfec_receiver.cc
@@ -10,6 +10,9 @@
 
 #include "modules/rtp_rtcp/include/flexfec_receiver.h"
 
+#include <string.h>
+
+#include "api/array_view.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/scoped_ref_ptr.h"
diff --git a/modules/rtp_rtcp/source/flexfec_sender.cc b/modules/rtp_rtcp/source/flexfec_sender.cc
index 286f47c..1204b2d 100644
--- a/modules/rtp_rtcp/source/flexfec_sender.cc
+++ b/modules/rtp_rtcp/source/flexfec_sender.cc
@@ -10,11 +10,15 @@
 
 #include "modules/rtp_rtcp/include/flexfec_sender.h"
 
+#include <string.h>
+#include <list>
 #include <utility>
 
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
+#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/forward_error_correction.cc b/modules/rtp_rtcp/source/forward_error_correction.cc
index b743110..a52feca 100644
--- a/modules/rtp_rtcp/source/forward_error_correction.cc
+++ b/modules/rtp_rtcp/source/forward_error_correction.cc
@@ -11,11 +11,10 @@
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
 
 #include <string.h>
-
 #include <algorithm>
-#include <iterator>
 #include <utility>
 
+#include "modules/include/module_common_types_public.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/flexfec_header_reader_writer.h"
diff --git a/modules/rtp_rtcp/source/forward_error_correction.h b/modules/rtp_rtcp/source/forward_error_correction.h
index 819f6bc..adb7572 100644
--- a/modules/rtp_rtcp/source/forward_error_correction.h
+++ b/modules/rtp_rtcp/source/forward_error_correction.h
@@ -11,16 +11,15 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
 #define MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
 
+#include <stddef.h>
 #include <stdint.h>
-
 #include <list>
 #include <memory>
 #include <vector>
 
+#include "modules/include/module_fec_types.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
-#include "rtc_base/constructormagic.h"
-#include "rtc_base/refcount.h"
 #include "rtc_base/scoped_ref_ptr.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/forward_error_correction_internal.cc b/modules/rtp_rtcp/source/forward_error_correction_internal.cc
index 7e5fd91..9b02026 100644
--- a/modules/rtp_rtcp/source/forward_error_correction_internal.cc
+++ b/modules/rtp_rtcp/source/forward_error_correction_internal.cc
@@ -10,6 +10,7 @@
 
 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
 
+#include <string.h>
 #include <algorithm>
 
 #include "modules/rtp_rtcp/source/fec_private_tables_bursty.h"
diff --git a/modules/rtp_rtcp/source/forward_error_correction_internal.h b/modules/rtp_rtcp/source/forward_error_correction_internal.h
index 2e8a202..ed93f52 100644
--- a/modules/rtp_rtcp/source/forward_error_correction_internal.h
+++ b/modules/rtp_rtcp/source/forward_error_correction_internal.h
@@ -11,9 +11,11 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_INTERNAL_H_
 #define MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_INTERNAL_H_
 
-#include "modules/include/module_common_types.h"
+#include <stddef.h>
+#include <stdint.h>
 
 #include "api/array_view.h"
+#include "modules/include/module_fec_types.h"
 
 namespace webrtc {
 
diff --git a/modules/rtp_rtcp/source/packet_loss_stats.cc b/modules/rtp_rtcp/source/packet_loss_stats.cc
index 076348d..36f0a63 100644
--- a/modules/rtp_rtcp/source/packet_loss_stats.cc
+++ b/modules/rtp_rtcp/source/packet_loss_stats.cc
@@ -10,6 +10,8 @@
 
 #include "modules/rtp_rtcp/source/packet_loss_stats.h"
 
+#include <cstdint>
+#include <iterator>
 #include <vector>
 
 #include "rtc_base/checks.h"
diff --git a/modules/rtp_rtcp/source/playout_delay_oracle.cc b/modules/rtp_rtcp/source/playout_delay_oracle.cc
index d3a75dd..dc33fad 100644
--- a/modules/rtp_rtcp/source/playout_delay_oracle.cc
+++ b/modules/rtp_rtcp/source/playout_delay_oracle.cc
@@ -13,7 +13,6 @@
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 
 namespace webrtc {
 
diff --git a/modules/rtp_rtcp/source/playout_delay_oracle.h b/modules/rtp_rtcp/source/playout_delay_oracle.h
index 6e6e253..0e3bd39 100644
--- a/modules/rtp_rtcp/source/playout_delay_oracle.h
+++ b/modules/rtp_rtcp/source/playout_delay_oracle.h
@@ -13,8 +13,10 @@
 
 #include <stdint.h>
 
-#include "modules/include/module_common_types.h"
+#include "common_types.h"  // NOLINT(build/include)
+#include "modules/include/module_common_types_public.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/thread_annotations.h"
 
diff --git a/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc b/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
index fc867a4..fd19b13 100644
--- a/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
+++ b/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
@@ -10,8 +10,9 @@
 
 #include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
 
+#include <cstdint>
+
 #include "rtc_base/logging.h"
-#include "rtc_base/time/timestamp_extrapolator.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtcp_nack_stats.cc b/modules/rtp_rtcp/source/rtcp_nack_stats.cc
index 24b7085..1d652d0 100644
--- a/modules/rtp_rtcp/source/rtcp_nack_stats.cc
+++ b/modules/rtp_rtcp/source/rtcp_nack_stats.cc
@@ -10,7 +10,7 @@
 
 #include "modules/rtp_rtcp/source/rtcp_nack_stats.h"
 
-#include "modules/include/module_common_types.h"
+#include "modules/include/module_common_types_public.h"
 
 namespace webrtc {
 
diff --git a/modules/rtp_rtcp/source/rtcp_packet.h b/modules/rtp_rtcp/source/rtcp_packet.h
index 11037cb..40e51e8 100644
--- a/modules/rtp_rtcp/source/rtcp_packet.h
+++ b/modules/rtp_rtcp/source/rtcp_packet.h
@@ -11,6 +11,10 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
+#include "api/array_view.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/function_view.h"
 
diff --git a/modules/rtp_rtcp/source/rtcp_packet/app.cc b/modules/rtp_rtcp/source/rtcp_packet/app.cc
index 4e21bc9..eadd4d9 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/app.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/app.cc
@@ -10,6 +10,9 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/app.h"
 
+#include <string.h>
+#include <cstdint>
+
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "rtc_base/checks.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/app.h b/modules/rtp_rtcp/source/rtcp_packet/app.h
index 19a97e0..a9602a8 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/app.h
+++ b/modules/rtp_rtcp/source/rtcp_packet/app.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_APP_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_APP_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/rtp_rtcp/source/rtcp_packet.h"
 #include "rtc_base/buffer.h"
 
diff --git a/modules/rtp_rtcp/source/rtcp_packet/bye.cc b/modules/rtp_rtcp/source/rtcp_packet/bye.cc
index 0e2eb9e..23ac35f 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/bye.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/bye.cc
@@ -10,6 +10,8 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
 
+#include <string.h>
+#include <cstdint>
 #include <utility>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc b/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc
index 27ed4cc..5e7dadd 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.cc
@@ -10,6 +10,7 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
 
+#include <cstdint>
 #include <utility>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc b/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
index 5513f37..2b5f9ca 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/extended_reports.cc
@@ -10,6 +10,8 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
 
+#include <vector>
+
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "rtc_base/checks.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/nack.cc b/modules/rtp_rtcp/source/rtcp_packet/nack.cc
index 6a4a0bd..6fe7ead 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/nack.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/nack.cc
@@ -11,6 +11,7 @@
 #include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
 
 #include <algorithm>
+#include <cstdint>
 #include <utility>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/psfb.h b/modules/rtp_rtcp/source/rtcp_packet/psfb.h
index ae66a17..46ee291 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/psfb.h
+++ b/modules/rtp_rtcp/source/rtcp_packet/psfb.h
@@ -12,6 +12,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_PSFB_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_PSFB_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/rtp_rtcp/source/rtcp_packet.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h b/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h
index 8f143da..7470d1d 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h
+++ b/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h
@@ -11,6 +11,8 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RECEIVER_REPORT_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RECEIVER_REPORT_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <vector>
 
 #include "modules/rtp_rtcp/source/rtcp_packet.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/remb.cc b/modules/rtp_rtcp/source/rtcp_packet/remb.cc
index 0240611..3ed1fbd 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/remb.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/remb.cc
@@ -10,6 +10,7 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
 
+#include <cstdint>
 #include <utility>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/rrtr.h b/modules/rtp_rtcp/source/rtcp_packet/rrtr.h
index a470b1a..8eb4ce6 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/rrtr.h
+++ b/modules/rtp_rtcp/source/rtcp_packet/rrtr.h
@@ -12,6 +12,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RRTR_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RRTR_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "system_wrappers/include/ntp_time.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h b/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h
index a040741..2197773 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h
+++ b/modules/rtp_rtcp/source/rtcp_packet/rtpfb.h
@@ -12,6 +12,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RTPFB_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_RTPFB_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/rtp_rtcp/source/rtcp_packet.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtcp_packet/sdes.cc b/modules/rtp_rtcp/source/rtcp_packet/sdes.cc
index 337c8b0..0ef4329 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/sdes.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/sdes.cc
@@ -10,6 +10,7 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
 
+#include <string.h>
 #include <utility>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc b/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
index 4d38b3b..f57e574 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/tmmbn.cc
@@ -10,7 +10,6 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
 
-#include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc b/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc
index d8f073b..9dc745e 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/tmmbr.cc
@@ -10,7 +10,6 @@
 
 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
 
-#include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
diff --git a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc
index 4703d31..2816559 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc
@@ -11,9 +11,10 @@
 #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
 
 #include <algorithm>
+#include <cstdint>
 #include <utility>
 
-#include "modules/include/module_common_types.h"
+#include "modules/include/module_common_types_public.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "rtc_base/checks.h"
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index 4966754..3635c4a 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -280,7 +280,8 @@
   std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis;
   last_xr_rtis.reserve(last_xr_rtis_size);
 
-  const uint32_t now_ntp = CompactNtp(clock_->CurrentNtpTime());
+  const uint32_t now_ntp =
+      CompactNtp(TimeMicrosToNtp(clock_->TimeInMicroseconds()));
 
   for (size_t i = 0; i < last_xr_rtis_size; ++i) {
     RrtrInformation& rrtr = received_rrtrs_.front();
@@ -427,7 +428,7 @@
 
     remote_sender_ntp_time_ = sender_report.ntp();
     remote_sender_rtp_time_ = sender_report.rtp_timestamp();
-    last_received_sr_ntp_ = clock_->CurrentNtpTime();
+    last_received_sr_ntp_ = TimeMicrosToNtp(clock_->TimeInMicroseconds());
   } else {
     // We will only store the send report from one source, but
     // we will store all the receive blocks.
@@ -503,10 +504,18 @@
   // If no SR has been received yet, the field is set to zero.
   // Receiver rtp_rtcp module is not expected to calculate rtt using
   // Sender Reports even if it accidentally can.
-  if (!receiver_only_ && send_time_ntp != 0) {
+
+  // TODO(nisse): Use this way to determine the RTT only when |receiver_only_|
+  // is false. However, that currently breaks the tests of the
+  // googCaptureStartNtpTimeMs stat for audio receive streams. To fix, either
+  // delete all dependencies on RTT measurements for audio receive streams, or
+  // ensure that audio receive streams that need RTT and stats that depend on it
+  // are configured with an associated audio send stream.
+  if (send_time_ntp != 0) {
     uint32_t delay_ntp = report_block.delay_since_last_sr();
     // Local NTP time.
-    uint32_t receive_time_ntp = CompactNtp(clock_->CurrentNtpTime());
+    uint32_t receive_time_ntp =
+        CompactNtp(TimeMicrosToNtp(clock_->TimeInMicroseconds()));
 
     // RTT in 1/(2^16) seconds.
     uint32_t rtt_ntp = receive_time_ntp - delay_ntp - send_time_ntp;
@@ -720,7 +729,8 @@
 void RTCPReceiver::HandleXrReceiveReferenceTime(uint32_t sender_ssrc,
                                                 const rtcp::Rrtr& rrtr) {
   uint32_t received_remote_mid_ntp_time = CompactNtp(rrtr.ntp());
-  uint32_t local_receive_mid_ntp_time = CompactNtp(clock_->CurrentNtpTime());
+  uint32_t local_receive_mid_ntp_time =
+      CompactNtp(TimeMicrosToNtp(clock_->TimeInMicroseconds()));
 
   auto it = received_rrtrs_ssrc_it_.find(sender_ssrc);
   if (it != received_rrtrs_ssrc_it_.end()) {
@@ -754,7 +764,7 @@
     return;
 
   uint32_t delay_ntp = rti.delay_since_last_rr;
-  uint32_t now_ntp = CompactNtp(clock_->CurrentNtpTime());
+  uint32_t now_ntp = CompactNtp(TimeMicrosToNtp(clock_->TimeInMicroseconds()));
 
   uint32_t rtt_ntp = now_ntp - delay_ntp - send_time_ntp;
   xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index c7708f0..4be8d73 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -208,7 +208,8 @@
   EXPECT_EQ(
       -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
 
-  uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
+  uint32_t sent_ntp =
+      CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
   system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
 
   rtcp::SenderReport sr;
@@ -238,7 +239,8 @@
   EXPECT_EQ(
       -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
 
-  uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
+  uint32_t sent_ntp =
+      CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
   system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
 
   rtcp::SenderReport sr;
@@ -266,7 +268,8 @@
   const uint32_t kDelayNtp = 123000;
   const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
 
-  uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
+  uint32_t sent_ntp =
+      CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
   system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
 
   rtcp::SenderReport sr;
@@ -737,7 +740,8 @@
 
   InjectRtcpPacket(xr);
 
-  uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
+  uint32_t compact_ntp_now =
+      CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
   EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
   uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
   EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
@@ -756,7 +760,8 @@
 
   InjectRtcpPacket(xr);
 
-  uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
+  uint32_t compact_ntp_now =
+      CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
   int64_t rtt_ms = 0;
   EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
   uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
@@ -818,7 +823,7 @@
   const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
   const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
   rtcp_receiver_.SetRtcpXrRrtrStatus(true);
-  NtpTime now = system_clock_.CurrentNtpTime();
+  NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
   uint32_t sent_ntp = CompactNtp(now);
   system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
 
@@ -838,7 +843,7 @@
   const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
   const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
   const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
-  NtpTime now = system_clock_.CurrentNtpTime();
+  NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
   uint32_t sent_ntp = CompactNtp(now);
   system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
   rtcp_receiver_.SetRtcpXrRrtrStatus(true);
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index bfddc422..ac50b32 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -99,16 +99,16 @@
   RtcpContext(const FeedbackState& feedback_state,
               int32_t nack_size,
               const uint16_t* nack_list,
-              NtpTime now)
+              int64_t now_us)
       : feedback_state_(feedback_state),
         nack_size_(nack_size),
         nack_list_(nack_list),
-        now_(now) {}
+        now_us_(now_us) {}
 
   const FeedbackState& feedback_state_;
   const int32_t nack_size_;
   const uint16_t* nack_list_;
-  const NtpTime now_;
+  const int64_t now_us_;
 };
 
 RTCPSender::RTCPSender(
@@ -126,7 +126,6 @@
       event_log_(event_log),
       transport_(outgoing_transport),
       interval_config_(interval_config),
-      using_nack_(false),
       sending_(false),
       next_time_to_send_rtcp_(0),
       timestamp_offset_(0),
@@ -151,7 +150,8 @@
 
       xr_send_receiver_reference_time_enabled_(false),
       packet_type_counter_observer_(packet_type_counter_observer),
-      send_video_bitrate_allocation_(false) {
+      send_video_bitrate_allocation_(false),
+      last_payload_type_(-1) {
   RTC_DCHECK(transport_ != nullptr);
 
   builders_[kRtcpSr] = &RTCPSender::BuildSR;
@@ -254,8 +254,14 @@
 }
 
 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
-                                int64_t capture_time_ms) {
+                                int64_t capture_time_ms,
+                                int8_t payload_type) {
   rtc::CritScope lock(&critical_section_rtcp_sender_);
+  // For compatibility with clients who don't set payload type correctly on all
+  // calls.
+  if (payload_type != -1) {
+    last_payload_type_ = payload_type;
+  }
   last_rtp_timestamp_ = rtp_timestamp;
   if (capture_time_ms < 0) {
     // We don't currently get a capture time from VoiceEngine.
@@ -265,6 +271,11 @@
   }
 }
 
+void RTCPSender::SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz) {
+  rtc::CritScope lock(&critical_section_rtcp_sender_);
+  rtp_clock_rates_khz_[payload_type] = rtp_clock_rate_hz / 1000;
+}
+
 uint32_t RTCPSender::SSRC() const {
   rtc::CritScope lock(&critical_section_rtcp_sender_);
   return ssrc_;
@@ -411,15 +422,21 @@
   // the frame being captured at this moment. We are calculating that
   // timestamp as the last frame's timestamp + the time since the last frame
   // was captured.
-  uint32_t rtp_rate =
-      (audio_ ? kBogusRtpRateForAudioRtcp : kVideoPayloadTypeFrequency) / 1000;
+  int rtp_rate = rtp_clock_rates_khz_[last_payload_type_];
+  if (rtp_rate <= 0) {
+    rtp_rate =
+        (audio_ ? kBogusRtpRateForAudioRtcp : kVideoPayloadTypeFrequency) /
+        1000;
+  }
+  // Round now_us_ to the closest millisecond, because Ntp time is rounded
+  // when converted to milliseconds,
   uint32_t rtp_timestamp =
       timestamp_offset_ + last_rtp_timestamp_ +
-      (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * rtp_rate;
+      ((ctx.now_us_ + 500) / 1000 - last_frame_capture_time_ms_) * rtp_rate;
 
   rtcp::SenderReport* report = new rtcp::SenderReport();
   report->SetSenderSsrc(ssrc_);
-  report->SetNtp(ctx.now_);
+  report->SetNtp(TimeMicrosToNtp(ctx.now_us_));
   report->SetRtpTimestamp(rtp_timestamp);
   report->SetPacketCount(ctx.feedback_state_.packets_sent);
   report->SetOctetCount(ctx.feedback_state_.media_bytes_sent);
@@ -600,7 +617,7 @@
 
   if (!sending_ && xr_send_receiver_reference_time_enabled_) {
     rtcp::Rrtr rrtr;
-    rrtr.SetNtp(ctx.now_);
+    rrtr.SetNtp(TimeMicrosToNtp(ctx.now_us_));
     xr->SetRrtr(rrtr);
   }
 
@@ -675,7 +692,7 @@
 
     // We need to send our NTP even if we haven't received any reports.
     RtcpContext context(feedback_state, nack_size, nack_list,
-                        clock_->CurrentNtpTime());
+                        clock_->TimeInMicroseconds());
 
     PrepareReport(feedback_state);
 
@@ -791,7 +808,7 @@
   if (!result.empty() && ((feedback_state.last_rr_ntp_secs != 0) ||
                           (feedback_state.last_rr_ntp_frac != 0))) {
     // Get our NTP as late as possible to avoid a race.
-    uint32_t now = CompactNtp(clock_->CurrentNtpTime());
+    uint32_t now = CompactNtp(TimeMicrosToNtp(clock_->TimeInMicroseconds()));
 
     uint32_t receive_time = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
     receive_time <<= 16;
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index c9220dd..2720e0a 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -82,7 +82,13 @@
 
   void SetTimestampOffset(uint32_t timestamp_offset);
 
-  void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms);
+  // TODO(bugs.webrtc.org/6458): Remove default parameter value when all the
+  // depending projects are updated to correctly set payload type.
+  void SetLastRtpTime(uint32_t rtp_timestamp,
+                      int64_t capture_time_ms,
+                      int8_t payload_type = -1);
+
+  void SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz);
 
   uint32_t SSRC() const;
 
@@ -187,7 +193,6 @@
   const RtcpIntervalConfig interval_config_;
 
   rtc::CriticalSection critical_section_rtcp_sender_;
-  bool using_nack_ RTC_GUARDED_BY(critical_section_rtcp_sender_);
   bool sending_ RTC_GUARDED_BY(critical_section_rtcp_sender_);
 
   int64_t next_time_to_send_rtcp_ RTC_GUARDED_BY(critical_section_rtcp_sender_);
@@ -244,6 +249,11 @@
       RTC_GUARDED_BY(critical_section_rtcp_sender_);
   bool send_video_bitrate_allocation_
       RTC_GUARDED_BY(critical_section_rtcp_sender_);
+
+  std::map<int8_t, int> rtp_clock_rates_khz_
+      RTC_GUARDED_BY(critical_section_rtcp_sender_);
+  int8_t last_payload_type_ RTC_GUARDED_BY(critical_section_rtcp_sender_);
+
   absl::optional<VideoBitrateAllocation> CheckAndUpdateLayerStructure(
       const VideoBitrateAllocation& bitrate) const
       RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index bcffc81..3e37cc6 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -11,11 +11,13 @@
 #include <memory>
 
 #include "common_types.h"  // NOLINT(build/include)
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
 #include "modules/rtp_rtcp/source/rtcp_sender.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 #include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
+#include "modules/rtp_rtcp/source/time_util.h"
 #include "rtc_base/rate_limiter.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -90,7 +92,8 @@
     rtcp_sender_->SetSSRC(kSenderSsrc);
     rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
     rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
-    rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
+    rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
+                                 /*paylpad_type=*/0);
   }
 
   void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
@@ -141,7 +144,7 @@
   rtcp_sender_->SetSendingStatus(feedback_state, true);
   feedback_state.packets_sent = kPacketCount;
   feedback_state.media_bytes_sent = kOctetCount;
-  NtpTime ntp = clock_.CurrentNtpTime();
+  NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
   EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
   EXPECT_EQ(1, parser()->sender_report()->num_packets());
   EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
@@ -153,6 +156,39 @@
   EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
 }
 
+TEST_F(RtcpSenderTest, SendConsecutiveSrWithExactSlope) {
+  const uint32_t kPacketCount = 0x12345;
+  const uint32_t kOctetCount = 0x23456;
+  const int kTimeBetweenSRsUs = 10043;  // Not exact value in milliseconds.
+  const int kExtraPackets = 30;
+  // Make sure clock is not exactly at some milliseconds point.
+  clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
+  rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
+  RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
+  rtcp_sender_->SetSendingStatus(feedback_state, true);
+  feedback_state.packets_sent = kPacketCount;
+  feedback_state.media_bytes_sent = kOctetCount;
+
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
+  EXPECT_EQ(1, parser()->sender_report()->num_packets());
+  NtpTime ntp1 = parser()->sender_report()->ntp();
+  uint32_t rtp1 = parser()->sender_report()->rtp_timestamp();
+
+  // Send more SRs to ensure slope is always exact for different offsets
+  for (int packets = 1; packets <= kExtraPackets; ++packets) {
+    clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
+    EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
+    EXPECT_EQ(packets + 1, parser()->sender_report()->num_packets());
+
+    NtpTime ntp2 = parser()->sender_report()->ntp();
+    uint32_t rtp2 = parser()->sender_report()->rtp_timestamp();
+
+    uint32_t ntp_diff_in_rtp_units =
+        (ntp2.ToMs() - ntp1.ToMs()) * (kVideoPayloadTypeFrequency / 1000);
+    EXPECT_EQ(rtp2 - rtp1, ntp_diff_in_rtp_units);
+  }
+}
+
 TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
   rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
                                     nullptr, nullptr, &test_transport_,
@@ -447,7 +483,7 @@
   rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
   EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
   rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
-  NtpTime ntp = clock_.CurrentNtpTime();
+  NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
   EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
   EXPECT_EQ(1, parser()->xr()->num_packets());
   EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
@@ -603,7 +639,8 @@
   rtcp_sender_->SetSSRC(kSenderSsrc);
   rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
   rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
-  rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
+  rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
+                               /*paylpad_type=*/0);
 
   // Set up REMB info to be included with BYE.
   rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver.cc b/modules/rtp_rtcp/source/rtcp_transceiver.cc
index 77b10ca..57d2142 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver.cc
@@ -39,10 +39,10 @@
   RTC_DCHECK(!rtcp_transceiver_);
 }
 
-void RtcpTransceiver::Stop(std::unique_ptr<rtc::QueuedTask> on_destroyed) {
+void RtcpTransceiver::Stop(std::function<void()> on_destroyed) {
   RTC_DCHECK(rtcp_transceiver_);
-  task_queue_->PostTaskAndReply(Destructor{std::move(rtcp_transceiver_)},
-                                std::move(on_destroyed));
+  task_queue_->PostTask(rtc::NewClosure(
+      Destructor{std::move(rtcp_transceiver_)}, std::move(on_destroyed)));
   RTC_DCHECK(!rtcp_transceiver_);
 }
 
@@ -59,13 +59,14 @@
 void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
     uint32_t remote_ssrc,
     MediaReceiverRtcpObserver* observer,
-    std::unique_ptr<rtc::QueuedTask> on_removed) {
+    std::function<void()> on_removed) {
   RTC_CHECK(rtcp_transceiver_);
   RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
   auto remove = [ptr, remote_ssrc, observer] {
     ptr->RemoveMediaReceiverRtcpObserver(remote_ssrc, observer);
   };
-  task_queue_->PostTaskAndReply(std::move(remove), std::move(on_removed));
+  task_queue_->PostTask(
+      rtc::NewClosure(std::move(remove), std::move(on_removed)));
 }
 
 void RtcpTransceiver::SetReadyToSend(bool ready) {
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver.h b/modules/rtp_rtcp/source/rtcp_transceiver.h
index fc9488c..9c96751 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver.h
+++ b/modules/rtp_rtcp/source/rtcp_transceiver.h
@@ -11,6 +11,7 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_TRANSCEIVER_H_
 #define MODULES_RTP_RTCP_SOURCE_RTCP_TRANSCEIVER_H_
 
+#include <functional>
 #include <memory>
 #include <string>
 #include <vector>
@@ -42,18 +43,17 @@
   // Note that interfaces provided in constructor or registered with AddObserver
   // still might be used by the transceiver on the task queue
   // until |on_destroyed| runs.
-  void Stop(std::unique_ptr<rtc::QueuedTask> on_destroyed);
+  void Stop(std::function<void()> on_destroyed);
 
   // Registers observer to be notified about incoming rtcp packets.
   // Calls to observer will be done on the |config.task_queue|.
   void AddMediaReceiverRtcpObserver(uint32_t remote_ssrc,
                                     MediaReceiverRtcpObserver* observer);
   // Deregisters the observer. Might return before observer is deregistered.
-  // Posts |on_removed| task when observer is deregistered.
-  void RemoveMediaReceiverRtcpObserver(
-      uint32_t remote_ssrc,
-      MediaReceiverRtcpObserver* observer,
-      std::unique_ptr<rtc::QueuedTask> on_removed);
+  // Runs |on_removed| when observer is deregistered.
+  void RemoveMediaReceiverRtcpObserver(uint32_t remote_ssrc,
+                                       MediaReceiverRtcpObserver* observer,
+                                       std::function<void()> on_removed);
 
   // Enables/disables sending rtcp packets eventually.
   // Packets may be sent after the SetReadyToSend(false) returns, but no new
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
index e5db086..1e684a3 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl_unittest.cc
@@ -77,7 +77,6 @@
 // Helper to wait for an rtcp packet produced on a different thread/task queue.
 class FakeRtcpTransport : public webrtc::Transport {
  public:
-  FakeRtcpTransport() : sent_rtcp_(false, false) {}
   bool SendRtcp(const uint8_t* data, size_t size) override {
     sent_rtcp_.Set();
     return true;
@@ -148,7 +147,7 @@
   // Wait for a periodic packet.
   EXPECT_TRUE(transport.WaitPacket());
 
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue.PostTask([rtcp_transceiver, &done] {
     delete rtcp_transceiver;
     done.Set();
@@ -187,7 +186,7 @@
   EXPECT_GE(rtc::TimeMillis() - started_ms, config.initial_report_delay_ms);
 
   // Cleanup.
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue.PostTask([&] {
     rtcp_transceiver.reset();
     done.Set();
@@ -220,7 +219,7 @@
             config.report_period_ms - 1);
 
   // Cleanup.
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue.PostTask([&] {
     rtcp_transceiver.reset();
     done.Set();
@@ -242,7 +241,7 @@
   // Wait for first packet.
   EXPECT_TRUE(transport.WaitPacket());
   // Send non periodic one after half period.
-  rtc::Event non_periodic(false, false);
+  rtc::Event non_periodic;
   int64_t time_of_non_periodic_packet_ms = 0;
   queue.PostDelayedTask(
       [&] {
@@ -265,7 +264,7 @@
             config.report_period_ms - 1);
 
   // Cleanup.
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue.PostTask([&] {
     rtcp_transceiver.reset();
     done.Set();
@@ -329,7 +328,7 @@
   EXPECT_TRUE(transport.WaitPacket());
 
   // Cleanup.
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue.PostTask([&] {
     rtcp_transceiver.reset();
     done.Set();
diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_transceiver_unittest.cc
index 2ea5bc9..d71918d 100644
--- a/modules/rtp_rtcp/source/rtcp_transceiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_transceiver_unittest.cc
@@ -41,7 +41,7 @@
 constexpr int kTimeoutMs = 1000;
 
 void WaitPostedTasks(rtc::TaskQueue* queue) {
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue->PostTask([&done] { done.Set(); });
   ASSERT_TRUE(done.Wait(kTimeoutMs));
 }
@@ -108,8 +108,8 @@
   auto* rtcp_transceiver = new RtcpTransceiver(config);
   rtcp_transceiver->SendCompoundPacket();
 
-  rtc::Event done(false, false);
-  rtc::Event heavy_task(false, false);
+  rtc::Event done;
+  rtc::Event heavy_task;
   queue.PostTask([&] {
     EXPECT_TRUE(heavy_task.Wait(kTimeoutMs));
     done.Set();
@@ -128,7 +128,7 @@
   config.task_queue = &queue;
   auto* rtcp_transceiver = new RtcpTransceiver(config);
 
-  rtc::Event heavy_task(false, false);
+  rtc::Event heavy_task;
   queue.PostTask([&] { EXPECT_TRUE(heavy_task.Wait(kTimeoutMs)); });
   rtcp_transceiver->SendCompoundPacket();
   delete rtcp_transceiver;
@@ -158,7 +158,7 @@
   config.outgoing_transport = &null_transport;
   config.task_queue = &queue;
   RtcpTransceiver rtcp_transceiver(config);
-  rtc::Event observer_deleted(false, false);
+  rtc::Event observer_deleted;
 
   auto observer = absl::make_unique<MockMediaReceiverRtcpObserver>();
   EXPECT_CALL(*observer, OnSenderReport(kRemoteSsrc, _, 1));
@@ -166,12 +166,11 @@
 
   rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, observer.get());
   rtcp_transceiver.ReceivePacket(CreateSenderReport(kRemoteSsrc, 1));
-  rtcp_transceiver.RemoveMediaReceiverRtcpObserver(
-      kRemoteSsrc, observer.get(),
-      /*on_removed=*/rtc::NewClosure([&] {
-        observer.reset();
-        observer_deleted.Set();
-      }));
+  rtcp_transceiver.RemoveMediaReceiverRtcpObserver(kRemoteSsrc, observer.get(),
+                                                   /*on_removed=*/[&] {
+                                                     observer.reset();
+                                                     observer_deleted.Set();
+                                                   });
   rtcp_transceiver.ReceivePacket(CreateSenderReport(kRemoteSsrc, 2));
 
   EXPECT_TRUE(observer_deleted.Wait(kTimeoutMs));
@@ -189,15 +188,14 @@
   auto observer = absl::make_unique<MockMediaReceiverRtcpObserver>();
   rtcp_transceiver.AddMediaReceiverRtcpObserver(kRemoteSsrc, observer.get());
 
-  rtc::Event queue_blocker(false, false);
-  rtc::Event observer_deleted(false, false);
+  rtc::Event queue_blocker;
+  rtc::Event observer_deleted;
   queue.PostTask([&] { EXPECT_TRUE(queue_blocker.Wait(kTimeoutMs)); });
-  rtcp_transceiver.RemoveMediaReceiverRtcpObserver(
-      kRemoteSsrc, observer.get(),
-      /*on_removed=*/rtc::NewClosure([&] {
-        observer.reset();
-        observer_deleted.Set();
-      }));
+  rtcp_transceiver.RemoveMediaReceiverRtcpObserver(kRemoteSsrc, observer.get(),
+                                                   /*on_removed=*/[&] {
+                                                     observer.reset();
+                                                     observer_deleted.Set();
+                                                   });
 
   EXPECT_THAT(observer, Not(IsNull()));
   queue_blocker.Set();
@@ -242,12 +240,12 @@
   config.schedule_periodic_compound_packets = true;
 
   auto rtcp_transceiver = absl::make_unique<RtcpTransceiver>(config);
-  rtc::Event done(false, false);
+  rtc::Event done;
   rtcp_transceiver->SendCompoundPacket();
-  rtcp_transceiver->Stop(rtc::NewClosure([&] {
+  rtcp_transceiver->Stop([&] {
     EXPECT_CALL(outgoing_transport, SendRtcp).Times(0);
     done.Set();
-  }));
+  });
   rtcp_transceiver = nullptr;
   EXPECT_TRUE(done.Wait(kTimeoutMs));
 }
diff --git a/modules/rtp_rtcp/source/rtp_format.cc b/modules/rtp_rtcp/source/rtp_format.cc
index 13ec0af..0010d90 100644
--- a/modules/rtp_rtcp/source/rtp_format.cc
+++ b/modules/rtp_rtcp/source/rtp_format.cc
@@ -10,13 +10,15 @@
 
 #include "modules/rtp_rtcp/source/rtp_format.h"
 
-#include <utility>
-
 #include "absl/memory/memory.h"
+#include "absl/types/variant.h"
 #include "modules/rtp_rtcp/source/rtp_format_h264.h"
 #include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
 #include "modules/rtp_rtcp/source/rtp_format_vp8.h"
 #include "modules/rtp_rtcp/source/rtp_format_vp9.h"
+#include "modules/video_coding/codecs/h264/include/h264_globals.h"
+#include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
+#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
@@ -63,6 +65,11 @@
   RTC_DCHECK_GE(limits.last_packet_reduction_len, 0);
 
   std::vector<int> result;
+  if (limits.max_payload_len >=
+      limits.single_packet_reduction_len + payload_len) {
+    result.push_back(payload_len);
+    return result;
+  }
   if (limits.max_payload_len - limits.first_packet_reduction_len < 1 ||
       limits.max_payload_len - limits.last_packet_reduction_len < 1) {
     // Capacity is not enough to put a single byte into one of the packets.
@@ -77,6 +84,10 @@
   // Integer divisions with rounding up.
   int num_packets_left =
       (total_bytes + limits.max_payload_len - 1) / limits.max_payload_len;
+  if (num_packets_left == 1) {
+    // Single packet is a special case handled above.
+    num_packets_left = 2;
+  }
 
   if (payload_len < num_packets_left) {
     // Edge case where limits force to have more packets than there are payload
diff --git a/modules/rtp_rtcp/source/rtp_format.h b/modules/rtp_rtcp/source/rtp_format.h
index 9fad4cf..71c7dc5 100644
--- a/modules/rtp_rtcp/source/rtp_format.h
+++ b/modules/rtp_rtcp/source/rtp_format.h
@@ -11,17 +11,17 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H_
 
+#include <stdint.h>
 #include <memory>
-#include <string>
 #include <vector>
 
 #include "api/array_view.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/include/module_common_types.h"
-#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "rtc_base/constructormagic.h"
+#include "modules/rtp_rtcp/source/rtp_video_header.h"
 
 namespace webrtc {
+
 class RtpPacketToSend;
 
 class RtpPacketizer {
@@ -30,6 +30,8 @@
     int max_payload_len = 1200;
     int first_packet_reduction_len = 0;
     int last_packet_reduction_len = 0;
+    // Reduction len for packet that is first & last at the same time.
+    int single_packet_reduction_len = 0;
   };
   static std::unique_ptr<RtpPacketizer> Create(
       VideoCodecType type,
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.cc b/modules/rtp_rtcp/source/rtp_format_h264.cc
index 9793eba..7a7bcdf 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264.cc
@@ -11,10 +11,16 @@
 #include "modules/rtp_rtcp/source/rtp_format_h264.h"
 
 #include <string.h>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
 #include <memory>
 #include <utility>
 #include <vector>
 
+#include "absl/types/optional.h"
+#include "absl/types/variant.h"
+#include "common_types.h"  // NOLINT(build/include)
 #include "common_video/h264/h264_common.h"
 #include "common_video/h264/pps_parser.h"
 #include "common_video/h264/sps_parser.h"
@@ -186,9 +192,11 @@
       case H264PacketizationMode::NonInterleaved:
         int fragment_len = input_fragments_[i].length;
         int single_packet_capacity = limits_.max_payload_len;
-        if (i == 0)
+        if (input_fragments_.size() == 1)
+          single_packet_capacity -= limits_.single_packet_reduction_len;
+        else if (i == 0)
           single_packet_capacity -= limits_.first_packet_reduction_len;
-        if (i + 1 == input_fragments_.size())
+        else if (i + 1 == input_fragments_.size())
           single_packet_capacity -= limits_.last_packet_reduction_len;
 
         if (fragment_len > single_packet_capacity) {
@@ -211,7 +219,10 @@
   PayloadSizeLimits limits = limits_;
   // Leave room for the FU-A header.
   limits.max_payload_len -= kFuAHeaderSize;
-  // Ignore first/last packet reductions unless it is first/last fragment.
+  // Ignore single/first/last packet reductions unless it is single/first/last
+  // fragment.
+  if (input_fragments_.size() != 1)
+    limits.single_packet_reduction_len = 0;
   if (fragment_index != 0)
     limits.first_packet_reduction_len = 0;
   if (fragment_index != input_fragments_.size() - 1)
@@ -243,17 +254,31 @@
 size_t RtpPacketizerH264::PacketizeStapA(size_t fragment_index) {
   // Aggregate fragments into one packet (STAP-A).
   size_t payload_size_left = limits_.max_payload_len;
-  if (fragment_index == 0)
+  if (input_fragments_.size() == 1)
+    payload_size_left -= limits_.single_packet_reduction_len;
+  else if (fragment_index == 0)
     payload_size_left -= limits_.first_packet_reduction_len;
   int aggregated_fragments = 0;
   size_t fragment_headers_length = 0;
   const Fragment* fragment = &input_fragments_[fragment_index];
   RTC_CHECK_GE(payload_size_left, fragment->length);
   ++num_packets_left_;
-  while (payload_size_left >= fragment->length + fragment_headers_length &&
-         (fragment_index + 1 < input_fragments_.size() ||
-          payload_size_left >= fragment->length + fragment_headers_length +
-                                   limits_.last_packet_reduction_len)) {
+
+  auto payload_size_needed = [&] {
+    size_t fragment_size = fragment->length + fragment_headers_length;
+    if (input_fragments_.size() == 1) {
+      // Single fragment, single packet, payload_size_left already adjusted
+      // with limits_.single_packet_reduction_len.
+      return fragment_size;
+    }
+    if (fragment_index == input_fragments_.size() - 1) {
+      // Last fragment, so StrapA might be the last packet.
+      return fragment_size + limits_.last_packet_reduction_len;
+    }
+    return fragment_size;
+  };
+
+  while (payload_size_left >= payload_size_needed()) {
     RTC_CHECK_GT(fragment->length, 0);
     packets_.push(PacketUnit(*fragment, aggregated_fragments == 0, false, true,
                              fragment->buffer[0]));
@@ -282,9 +307,11 @@
 bool RtpPacketizerH264::PacketizeSingleNalu(size_t fragment_index) {
   // Add a single NALU to the queue, no aggregation.
   size_t payload_size_left = limits_.max_payload_len;
-  if (fragment_index == 0)
+  if (input_fragments_.size() == 1)
+    payload_size_left -= limits_.single_packet_reduction_len;
+  else if (fragment_index == 0)
     payload_size_left -= limits_.first_packet_reduction_len;
-  if (fragment_index + 1 == input_fragments_.size())
+  else if (fragment_index + 1 == input_fragments_.size())
     payload_size_left -= limits_.last_packet_reduction_len;
   const Fragment* fragment = &input_fragments_[fragment_index];
   if (payload_size_left < fragment->length) {
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.h b/modules/rtp_rtcp/source/rtp_format_h264.h
index 73e4087..fbd4fd9 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.h
+++ b/modules/rtp_rtcp/source/rtp_format_h264.h
@@ -11,12 +11,17 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H264_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H264_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <deque>
 #include <memory>
 #include <queue>
-#include <string>
 
+#include "api/array_view.h"
+#include "modules/include/module_common_types.h"
 #include "modules/rtp_rtcp/source/rtp_format.h"
+#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/video_coding/codecs/h264/include/h264_globals.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 
diff --git a/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc b/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
index edf907a..aeab813 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
@@ -390,7 +390,7 @@
                                NoFragmentation(frame));
   std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
 
-  RTC_CHECK_GE(packets.size(), 2);  // Single packet indicates it is not FuA.
+  EXPECT_GE(packets.size(), 2u);  // Single packet indicates it is not FuA.
   std::vector<uint16_t> fua_header;
   std::vector<int> payload_sizes;
 
@@ -422,6 +422,7 @@
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 1200;
   limits.first_packet_reduction_len = 4;
+  limits.single_packet_reduction_len = 4;
   EXPECT_THAT(TestFua(1198, limits), ElementsAre(597, 601));
 }
 
@@ -429,14 +430,14 @@
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 1200;
   limits.last_packet_reduction_len = 4;
+  limits.single_packet_reduction_len = 4;
   EXPECT_THAT(TestFua(1198, limits), ElementsAre(601, 597));
 }
 
-TEST(RtpPacketizerH264Test, FUAWithFirstAndLastPacketReduction) {
+TEST(RtpPacketizerH264Test, FUAWithSinglePacketReduction) {
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 1199;
-  limits.first_packet_reduction_len = 100;
-  limits.last_packet_reduction_len = 100;
+  limits.single_packet_reduction_len = 200;
   EXPECT_THAT(TestFua(1000, limits), ElementsAre(500, 500));
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_format_unittest.cc b/modules/rtp_rtcp/source/rtp_format_unittest.cc
index a79c434..ae1b5b0 100644
--- a/modules/rtp_rtcp/source/rtp_format_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_unittest.cc
@@ -199,21 +199,32 @@
 }
 
 TEST(RtpPacketizerSplitAboutEqually,
-     OnePacketWhenExtraSpaceIsEnoughForSumOfFirstAndLastPacketReductions) {
+     IgnoresFirstAndLastPacketReductionWhenPayloadFitsIntoSinglePacket) {
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 30;
-  limits.first_packet_reduction_len = 6;
-  limits.last_packet_reduction_len = 4;
+  limits.first_packet_reduction_len = 29;
+  limits.last_packet_reduction_len = 29;
+  limits.single_packet_reduction_len = 10;
 
   EXPECT_THAT(RtpPacketizer::SplitAboutEqually(20, limits), ElementsAre(20));
 }
 
 TEST(RtpPacketizerSplitAboutEqually,
-     TwoPacketsWhenExtraSpaceIsTooSmallForSumOfFirstAndLastPacketReductions) {
+     OnePacketWhenExtraSpaceIsEnoughForSinglePacketReduction) {
+  RtpPacketizer::PayloadSizeLimits limits;
+  limits.max_payload_len = 30;
+  limits.single_packet_reduction_len = 10;
+
+  EXPECT_THAT(RtpPacketizer::SplitAboutEqually(20, limits), ElementsAre(20));
+}
+
+TEST(RtpPacketizerSplitAboutEqually,
+     TwoPacketsWhenExtraSpaceIsTooSmallForSinglePacketReduction) {
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 29;
-  limits.first_packet_reduction_len = 6;
-  limits.last_packet_reduction_len = 4;
+  limits.first_packet_reduction_len = 3;
+  limits.last_packet_reduction_len = 1;
+  limits.single_packet_reduction_len = 10;
 
   // First packet needs two more extra bytes compared to last one,
   // so should have two less payload bytes.
@@ -246,8 +257,7 @@
 TEST(RtpPacketizerSplitAboutEqually, CantPutSinglePayloadByteInTwoPackets) {
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 10;
-  limits.first_packet_reduction_len = 6;
-  limits.last_packet_reduction_len = 4;
+  limits.single_packet_reduction_len = 10;
 
   EXPECT_THAT(RtpPacketizer::SplitAboutEqually(1, limits), IsEmpty());
 }
@@ -255,8 +265,7 @@
 TEST(RtpPacketizerSplitAboutEqually, CanPutTwoPayloadBytesInTwoPackets) {
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 10;
-  limits.first_packet_reduction_len = 6;
-  limits.last_packet_reduction_len = 4;
+  limits.single_packet_reduction_len = 10;
 
   EXPECT_THAT(RtpPacketizer::SplitAboutEqually(2, limits), ElementsAre(1, 1));
 }
@@ -264,8 +273,7 @@
 TEST(RtpPacketizerSplitAboutEqually, CanPutSinglePayloadByteInOnePacket) {
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = 11;
-  limits.first_packet_reduction_len = 6;
-  limits.last_packet_reduction_len = 4;
+  limits.single_packet_reduction_len = 10;
 
   EXPECT_THAT(RtpPacketizer::SplitAboutEqually(1, limits), ElementsAre(1));
 }
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
index edd1e3c..92aada4 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.cc
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
@@ -8,11 +8,13 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include <string>
+#include <assert.h>
+#include <string.h>
 
-#include "modules/include/module_common_types.h"
+#include "absl/types/optional.h"
 #include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.h b/modules/rtp_rtcp/source/rtp_format_video_generic.h
index 03509f5..3458d49 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.h
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.h
@@ -10,6 +10,7 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VIDEO_GENERIC_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VIDEO_GENERIC_H_
 
+#include <stdint.h>
 #include <vector>
 
 #include "api/array_view.h"
@@ -18,6 +19,10 @@
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
+
+class RtpPacketToSend;
+struct RTPVideoHeader;
+
 namespace RtpFormatVideoGeneric {
 static const uint8_t kKeyFrameBit = 0x01;
 static const uint8_t kFirstPacketBit = 0x02;
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.cc b/modules/rtp_rtcp/source/rtp_format_vp8.cc
index f40434e..a1248cf 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp8.cc
@@ -10,13 +10,13 @@
 
 #include "modules/rtp_rtcp/source/rtp_format_vp8.h"
 
+#include <stdint.h>
 #include <string.h>  // memcpy
-
-#include <limits>
-#include <utility>
 #include <vector>
 
+#include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/video_coding/codecs/interface/common_constants.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.h b/modules/rtp_rtcp/source/rtp_format_vp8.h
index e4bc36e..444298f 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8.h
+++ b/modules/rtp_rtcp/source/rtp_format_vp8.h
@@ -25,13 +25,15 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
 
-#include <string>
+#include <stddef.h>
+#include <cstdint>
 #include <vector>
 
 #include "absl/container/inlined_vector.h"
 #include "api/array_view.h"
-#include "modules/include/module_common_types.h"
 #include "modules/rtp_rtcp/source/rtp_format.h"
+#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_format_vp9.cc b/modules/rtp_rtcp/source/rtp_format_vp9.cc
index 4419d1a..9cd7514 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp9.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp9.cc
@@ -12,9 +12,9 @@
 
 #include <string.h>
 
-#include <cmath>
-
+#include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/video_coding/codecs/interface/common_constants.h"
 #include "rtc_base/bitbuffer.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -451,6 +451,7 @@
       remaining_payload_(payload) {
   limits.max_payload_len -= header_size_;
   limits.first_packet_reduction_len += first_packet_extra_header_size_;
+  limits.single_packet_reduction_len += first_packet_extra_header_size_;
 
   payload_sizes_ = SplitAboutEqually(payload.size(), limits);
   current_packet_ = payload_sizes_.begin();
diff --git a/modules/rtp_rtcp/source/rtp_format_vp9.h b/modules/rtp_rtcp/source/rtp_format_vp9.h
index 8a2a2a6..c3b8f17 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp9.h
+++ b/modules/rtp_rtcp/source/rtp_format_vp9.h
@@ -21,12 +21,14 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP9_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP9_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <vector>
 
 #include "api/array_view.h"
-#include "modules/include/module_common_types.h"
 #include "modules/rtp_rtcp/source/rtp_format.h"
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
 #include "rtc_base/constructormagic.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc
index 1b93132..c27fb6e 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc
@@ -10,6 +10,8 @@
 
 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
 
+#include <cstdint>
+
 #include "rtc_base/checks.h"
 
 namespace webrtc {
@@ -56,6 +58,16 @@
   spatial_layers_ = spatial_layers;
 }
 
+void RtpGenericFrameDescriptor::SetResolution(int width, int height) {
+  RTC_DCHECK(FirstPacketInSubFrame());
+  RTC_DCHECK_GE(width, 0);
+  RTC_DCHECK_LE(width, 0xFFFF);
+  RTC_DCHECK_GE(height, 0);
+  RTC_DCHECK_LE(height, 0xFFFF);
+  width_ = width;
+  height_ = height;
+}
+
 uint16_t RtpGenericFrameDescriptor::FrameId() const {
   RTC_DCHECK(FirstPacketInSubFrame());
   return frame_id_;
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
index 1bde4fa..3a6c34d 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
@@ -50,6 +50,10 @@
   uint8_t SpatialLayersBitmask() const;
   void SetSpatialLayersBitmask(uint8_t spatial_layers);
 
+  int Width() const { return width_; }
+  int Height() const { return height_; }
+  void SetResolution(int width, int height);
+
   uint16_t FrameId() const;
   void SetFrameId(uint16_t frame_id);
 
@@ -72,6 +76,9 @@
   uint8_t temporal_layer_ = 0;
   size_t num_frame_deps_ = 0;
   uint16_t frame_deps_id_diffs_[kMaxNumFrameDependencies];
+  int width_ = 0;
+  int height_ = 0;
+
   std::vector<uint8_t> byte_representation_;
 };
 
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.cc b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.cc
index c7b52d5..7cd120d 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.cc
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.cc
@@ -36,6 +36,14 @@
 // B:   +      FID      +
 //      |               |
 //      +-+-+-+-+-+-+-+-+
+//      |               |
+//      +     Width     +
+// B=1  |               |
+// and  +-+-+-+-+-+-+-+-+
+// D=0  |               |
+//      +     Height    +
+//      |               |
+//      +-+-+-+-+-+-+-+-+
 // D:   |    FDIFF  |X|M|
 //      +---------------+
 // X:   |      ...      |
@@ -75,6 +83,12 @@
   descriptor->ClearFrameDependencies();
   size_t offset = 4;
   bool has_more_dependencies = (data[0] & kFlagDependencies) != 0;
+  if (!has_more_dependencies && data.size() >= offset + 4) {
+    uint16_t width = (data[offset] << 8) | data[offset + 1];
+    uint16_t height = (data[offset + 2] << 8) | data[offset + 3];
+    descriptor->SetResolution(width, height);
+    offset += 4;
+  }
   while (has_more_dependencies) {
     if (data.size() == offset)
       return false;
@@ -91,7 +105,7 @@
     if (!descriptor->AddFrameDependencyDiff(fdiff))
       return false;
   }
-  return data.size() == offset;
+  return true;
 }
 
 size_t RtpGenericFrameDescriptorExtension::ValueSize(
@@ -103,6 +117,11 @@
   for (uint16_t fdiff : descriptor.FrameDependenciesDiffs()) {
     size += (fdiff >= (1 << 6)) ? 2 : 1;
   }
+  if (descriptor.FirstPacketInSubFrame() &&
+      descriptor.FrameDependenciesDiffs().empty() && descriptor.Width() > 0 &&
+      descriptor.Height() > 0) {
+    size += 4;
+  }
   return size;
 }
 
@@ -129,6 +148,13 @@
   data[3] = frame_id >> 8;
   rtc::ArrayView<const uint16_t> fdiffs = descriptor.FrameDependenciesDiffs();
   size_t offset = 4;
+  if (descriptor.FirstPacketInSubFrame() && fdiffs.empty() &&
+      descriptor.Width() > 0 && descriptor.Height() > 0) {
+    data[offset++] = (descriptor.Width() >> 8);
+    data[offset++] = (descriptor.Width() & 0xFF);
+    data[offset++] = (descriptor.Height() >> 8);
+    data[offset++] = (descriptor.Height() & 0xFF);
+  }
   for (size_t i = 0; i < fdiffs.size(); i++) {
     bool extended = fdiffs[i] >= (1 << 6);
     bool more = i < fdiffs.size() - 1;
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h
index 2dd9dd4..0d673e0 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h
@@ -21,6 +21,7 @@
 
 class RtpGenericFrameDescriptorExtension {
  public:
+  using value_type = RtpGenericFrameDescriptor;
   static constexpr RTPExtensionType kId = kRtpExtensionGenericFrameDescriptor;
   static constexpr char kUri[] =
       "http://www.webrtc.org/experiments/rtp-hdrext/"
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension_unittest.cc b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension_unittest.cc
index bb69e14..7f8fa2f 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension_unittest.cc
@@ -279,5 +279,32 @@
   EXPECT_THAT(buffer, ElementsAreArray(kRaw));
 }
 
+TEST(RtpGenericFrameDescriptorExtensionTest,
+     ParseResolutionOnIndependentFrame) {
+  constexpr int kWidth = 0x2468;
+  constexpr int kHeight = 0x6543;
+  constexpr uint8_t kRaw[] = {0x80, 0x01, 0x00, 0x00, 0x24, 0x68, 0x65, 0x43};
+  RtpGenericFrameDescriptor descriptor;
+
+  ASSERT_TRUE(RtpGenericFrameDescriptorExtension::Parse(kRaw, &descriptor));
+  EXPECT_EQ(descriptor.Width(), kWidth);
+  EXPECT_EQ(descriptor.Height(), kHeight);
+}
+
+TEST(RtpGenericFrameDescriptorExtensionTest,
+     WriteResolutionOnIndependentFrame) {
+  constexpr int kWidth = 0x2468;
+  constexpr int kHeight = 0x6543;
+  constexpr uint8_t kRaw[] = {0x80, 0x01, 0x00, 0x00, 0x24, 0x68, 0x65, 0x43};
+  RtpGenericFrameDescriptor descriptor;
+  descriptor.SetFirstPacketInSubFrame(true);
+  descriptor.SetResolution(kWidth, kHeight);
+
+  ASSERT_EQ(RtpGenericFrameDescriptorExtension::ValueSize(descriptor),
+            sizeof(kRaw));
+  uint8_t buffer[sizeof(kRaw)];
+  EXPECT_TRUE(RtpGenericFrameDescriptorExtension::Write(buffer, descriptor));
+  EXPECT_THAT(buffer, ElementsAreArray(kRaw));
+}
 }  // namespace
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_header_extension_map.cc b/modules/rtp_rtcp/source/rtp_header_extension_map.cc
index 168665a..dde25e3 100644
--- a/modules/rtp_rtcp/source/rtp_header_extension_map.cc
+++ b/modules/rtp_rtcp/source/rtp_header_extension_map.cc
@@ -56,15 +56,17 @@
 constexpr RTPExtensionType RtpHeaderExtensionMap::kInvalidType;
 constexpr int RtpHeaderExtensionMap::kInvalidId;
 
-RtpHeaderExtensionMap::RtpHeaderExtensionMap()
-    : mixed_one_two_byte_header_supported_(false) {
+RtpHeaderExtensionMap::RtpHeaderExtensionMap() : RtpHeaderExtensionMap(false) {}
+
+RtpHeaderExtensionMap::RtpHeaderExtensionMap(bool extmap_allow_mixed)
+    : extmap_allow_mixed_(extmap_allow_mixed) {
   for (auto& id : ids_)
     id = kInvalidId;
 }
 
 RtpHeaderExtensionMap::RtpHeaderExtensionMap(
     rtc::ArrayView<const RtpExtension> extensions)
-    : RtpHeaderExtensionMap() {
+    : RtpHeaderExtensionMap(false) {
   for (const RtpExtension& extension : extensions)
     RegisterByUri(extension.id, extension.uri);
 }
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.cc b/modules/rtp_rtcp/source/rtp_header_extensions.cc
index fc4b7ce..082e0e0 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.cc
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.cc
@@ -10,10 +10,13 @@
 
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
 
+#include <string.h>
+
 #include "modules/rtp_rtcp/include/rtp_cvo.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
+// TODO(bug:9855) Move kNoSpatialIdx from vp9_globals.h to common_constants
+#include "modules/video_coding/codecs/interface/common_constants.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
 
 namespace webrtc {
 // Absolute send time in RTP streams.
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.h b/modules/rtp_rtcp/source/rtp_header_extensions.h
index 84e9831..808356a 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -10,19 +10,24 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_
 
+#include <stddef.h>
 #include <stdint.h>
 #include <string>
 
 #include "api/array_view.h"
+#include "api/rtp_headers.h"
 #include "api/video/video_content_type.h"
+#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)
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 
 namespace webrtc {
 
 class AbsoluteSendTime {
  public:
+  using value_type = uint32_t;
   static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime;
   static constexpr uint8_t kValueSizeBytes = 3;
   static constexpr const char kUri[] =
@@ -57,6 +62,7 @@
 
 class TransmissionOffset {
  public:
+  using value_type = int32_t;
   static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
   static constexpr uint8_t kValueSizeBytes = 3;
   static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:toffset";
@@ -68,6 +74,7 @@
 
 class TransportSequenceNumber {
  public:
+  using value_type = uint16_t;
   static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
   static constexpr uint8_t kValueSizeBytes = 2;
   static constexpr const char kUri[] =
@@ -80,6 +87,7 @@
 
 class VideoOrientation {
  public:
+  using value_type = VideoRotation;
   static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
   static constexpr uint8_t kValueSizeBytes = 1;
   static constexpr const char kUri[] = "urn:3gpp:video-orientation";
@@ -94,6 +102,7 @@
 
 class PlayoutDelayLimits {
  public:
+  using value_type = PlayoutDelay;
   static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
   static constexpr uint8_t kValueSizeBytes = 3;
   static constexpr const char kUri[] =
@@ -117,6 +126,7 @@
 
 class VideoContentTypeExtension {
  public:
+  using value_type = VideoContentType;
   static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
   static constexpr uint8_t kValueSizeBytes = 1;
   static constexpr const char kUri[] =
@@ -133,6 +143,7 @@
 
 class VideoTimingExtension {
  public:
+  using value_type = VideoSendTiming;
   static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
   static constexpr uint8_t kValueSizeBytes = 13;
   static constexpr const char kUri[] =
@@ -155,6 +166,7 @@
 
 class FrameMarkingExtension {
  public:
+  using value_type = FrameMarking;
   static constexpr RTPExtensionType kId = kRtpExtensionFrameMarking;
   static constexpr const char kUri[] =
       "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07";
@@ -173,6 +185,7 @@
 // Subclasses must defined kId and kUri static constexpr members.
 class BaseRtpStringExtension {
  public:
+  using value_type = std::string;
   // String RTP header extensions are limited to 16 bytes because it is the
   // maximum length that can be encoded with one-byte header extensions.
   static constexpr uint8_t kMaxValueSizeBytes = 16;
diff --git a/modules/rtp_rtcp/source/rtp_header_parser.cc b/modules/rtp_rtcp/source/rtp_header_parser.cc
index df68f74..bc05033 100644
--- a/modules/rtp_rtcp/source/rtp_header_parser.cc
+++ b/modules/rtp_rtcp/source/rtp_header_parser.cc
@@ -9,9 +9,12 @@
  */
 #include "modules/rtp_rtcp/include/rtp_header_parser.h"
 
+#include <string.h>
+
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/source/rtp_utility.h"
 #include "rtc_base/criticalsection.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
diff --git a/modules/rtp_rtcp/source/rtp_packet.cc b/modules/rtp_rtcp/source/rtp_packet.cc
index 8cb8fd8..9d4dce4 100644
--- a/modules/rtp_rtcp/source/rtp_packet.cc
+++ b/modules/rtp_rtcp/source/rtp_packet.cc
@@ -10,11 +10,11 @@
 
 #include "modules/rtp_rtcp/source/rtp_packet.h"
 
+#include <cstdint>
 #include <cstring>
 #include <utility>
 
 #include "api/rtpparameters.h"
-#include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -211,8 +211,7 @@
   const bool two_byte_header_required =
       id > RtpExtension::kOneByteHeaderExtensionMaxId ||
       length > RtpExtension::kOneByteHeaderExtensionMaxValueSize || length == 0;
-  RTC_CHECK(!two_byte_header_required ||
-            extensions_.IsMixedOneTwoByteHeaderSupported());
+  RTC_CHECK(!two_byte_header_required || extensions_.ExtmapAllowMixed());
 
   uint16_t profile_id;
   if (extensions_size_ > 0) {
@@ -553,7 +552,7 @@
                                                      size_t length) {
   // TODO(webrtc:7990): Add support for empty extensions (length==0).
   if (length == 0 || length > RtpExtension::kMaxValueSize ||
-      (!extensions_.IsMixedOneTwoByteHeaderSupported() &&
+      (!extensions_.ExtmapAllowMixed() &&
        length > RtpExtension::kOneByteHeaderExtensionMaxValueSize)) {
     return nullptr;
   }
@@ -563,7 +562,7 @@
     // Extension not registered.
     return nullptr;
   }
-  if (!extensions_.IsMixedOneTwoByteHeaderSupported() &&
+  if (!extensions_.ExtmapAllowMixed() &&
       id > RtpExtension::kOneByteHeaderExtensionMaxId) {
     return nullptr;
   }
diff --git a/modules/rtp_rtcp/source/rtp_packet.h b/modules/rtp_rtcp/source/rtp_packet.h
index 3d7d90c..76666b7 100644
--- a/modules/rtp_rtcp/source/rtp_packet.h
+++ b/modules/rtp_rtcp/source/rtp_packet.h
@@ -12,6 +12,7 @@
 
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -95,8 +96,11 @@
   template <typename Extension>
   bool HasExtension() const;
 
-  template <typename Extension, typename... Values>
-  bool GetExtension(Values...) const;
+  template <typename Extension, typename FirstValue, typename... Values>
+  bool GetExtension(FirstValue, Values...) const;
+
+  template <typename Extension>
+  absl::optional<typename Extension::value_type> GetExtension() const;
 
   // Returns view of the raw extension or empty view on failure.
   template <typename Extension>
@@ -183,12 +187,21 @@
   return !FindExtension(Extension::kId).empty();
 }
 
-template <typename Extension, typename... Values>
-bool RtpPacket::GetExtension(Values... values) const {
+template <typename Extension, typename FirstValue, typename... Values>
+bool RtpPacket::GetExtension(FirstValue first, Values... values) const {
   auto raw = FindExtension(Extension::kId);
   if (raw.empty())
     return false;
-  return Extension::Parse(raw, values...);
+  return Extension::Parse(raw, first, values...);
+}
+
+template <typename Extension>
+absl::optional<typename Extension::value_type> RtpPacket::GetExtension() const {
+  absl::optional<typename Extension::value_type> result;
+  auto raw = FindExtension(Extension::kId);
+  if (raw.empty() || !Extension::Parse(raw, &result.emplace()))
+    result = absl::nullopt;
+  return result;
 }
 
 template <typename Extension>
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.cc b/modules/rtp_rtcp/source/rtp_packet_history.cc
index 211077b..8c1c8eb 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_history.cc
@@ -125,8 +125,7 @@
 }
 
 std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndSetSendTime(
-    uint16_t sequence_number,
-    bool verify_rtt) {
+    uint16_t sequence_number) {
   rtc::CritScope cs(&lock_);
   if (mode_ == StorageMode::kDisabled) {
     return nullptr;
@@ -139,7 +138,7 @@
   }
 
   StoredPacket& packet = rtp_it->second;
-  if (verify_rtt && !VerifyRtt(rtp_it->second, now_ms)) {
+  if (!VerifyRtt(rtp_it->second, now_ms)) {
     return nullptr;
   }
 
@@ -159,8 +158,7 @@
 }
 
 absl::optional<RtpPacketHistory::PacketState> RtpPacketHistory::GetPacketState(
-    uint16_t sequence_number,
-    bool verify_rtt) const {
+    uint16_t sequence_number) const {
   rtc::CritScope cs(&lock_);
   if (mode_ == StorageMode::kDisabled) {
     return absl::nullopt;
@@ -171,7 +169,7 @@
     return absl::nullopt;
   }
 
-  if (verify_rtt && !VerifyRtt(rtp_it->second, clock_->TimeInMilliseconds())) {
+  if (!VerifyRtt(rtp_it->second, clock_->TimeInMilliseconds())) {
     return absl::nullopt;
   }
 
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.h b/modules/rtp_rtcp/source/rtp_packet_history.h
index 1646ba7..095424e 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.h
+++ b/modules/rtp_rtcp/source/rtp_packet_history.h
@@ -76,16 +76,13 @@
                     absl::optional<int64_t> send_time_ms);
 
   // Gets stored RTP packet corresponding to the input |sequence number|.
-  // Returns nullptr if packet is not found. If |verify_rtt| is true, doesn't
-  // return packet that was (re)sent too recently.
+  // Returns nullptr if packet is not found or was (re)sent too recently.
   std::unique_ptr<RtpPacketToSend> GetPacketAndSetSendTime(
-      uint16_t sequence_number,
-      bool verify_rtt);
+      uint16_t sequence_number);
 
   // Similar to GetPacketAndSetSendTime(), but only returns a snapshot of the
   // current state for packet, and never updates internal state.
-  absl::optional<PacketState> GetPacketState(uint16_t sequence_number,
-                                             bool verify_rtt) const;
+  absl::optional<PacketState> GetPacketState(uint16_t sequence_number) const;
 
   // Get the packet (if any) from the history, with size closest to
   // |packet_size|. The exact size of the packet is not guaranteed.
diff --git a/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
index 85e9eb2..140434c 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
@@ -63,11 +63,11 @@
   // Store a packet, but with send-time. It should then not be removed.
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), kAllowRetransmission,
                      absl::nullopt);
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Changing store status, even to the current one, will clear the history.
   hist_.SetStorePacketsStatus(StorageMode::kStore, 10);
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, StartSeqResetAfterReset) {
@@ -75,16 +75,16 @@
   // Store a packet, but with send-time. It should then not be removed.
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), kAllowRetransmission,
                      absl::nullopt);
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Changing store status, to clear the history.
   hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
 
   // Add a new packet.
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1), kAllowRetransmission,
                      absl::nullopt);
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1));
 
   // Advance time past where packet expires.
   fake_clock_.AdvanceTimeMilliseconds(
@@ -94,9 +94,9 @@
   // Add one more packet and verify no state left from packet before reset.
   hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 2)),
                      kAllowRetransmission, absl::nullopt);
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1, false));
-  EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2), false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1));
+  EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
 }
 
 TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
@@ -104,21 +104,21 @@
   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, absl::nullopt);
   // Packet should not be stored.
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, GetRtpPacket_NotStored) {
   hist_.SetStorePacketsStatus(StorageMode::kStore, 10);
-  EXPECT_FALSE(hist_.GetPacketState(0, false));
+  EXPECT_FALSE(hist_.GetPacketState(0));
 }
 
 TEST_F(RtpPacketHistoryTest, PutRtpPacket) {
   hist_.SetStorePacketsStatus(StorageMode::kStore, 10);
   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
 
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, absl::nullopt);
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, GetRtpPacket) {
@@ -130,7 +130,7 @@
   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, absl::nullopt);
 
   std::unique_ptr<RtpPacketToSend> packet_out =
-      hist_.GetPacketAndSetSendTime(kStartSeqNum, false);
+      hist_.GetPacketAndSetSendTime(kStartSeqNum);
   EXPECT_TRUE(packet_out);
   EXPECT_EQ(buffer, packet_out->Buffer());
   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
@@ -146,7 +146,7 @@
   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, absl::nullopt);
 
   std::unique_ptr<RtpPacketToSend> packet_out =
-      hist_.GetPacketAndSetSendTime(kStartSeqNum, false);
+      hist_.GetPacketAndSetSendTime(kStartSeqNum);
   EXPECT_TRUE(packet_out);
   EXPECT_EQ(buffer, packet_out->Buffer());
   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
@@ -161,19 +161,21 @@
 
   // Get the packet and verify data.
   std::unique_ptr<RtpPacketToSend> packet_out;
-  packet_out = hist_.GetPacketAndSetSendTime(kStartSeqNum, false);
+  packet_out = hist_.GetPacketAndSetSendTime(kStartSeqNum);
   ASSERT_TRUE(packet_out);
   EXPECT_EQ(buffer.size(), packet_out->size());
   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
 
   // Non-retransmittable packets are immediately removed, so getting in again
   // should fail.
-  EXPECT_FALSE(hist_.GetPacketAndSetSendTime(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, PacketStateIsCorrect) {
   const uint32_t kSsrc = 92384762;
+  const int64_t kRttMs = 100;
   hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
+  hist_.SetRtt(kRttMs);
   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
   packet->SetSsrc(kSsrc);
   packet->SetPayloadSize(1234);
@@ -183,7 +185,7 @@
                      fake_clock_.TimeInMilliseconds());
 
   absl::optional<RtpPacketHistory::PacketState> state =
-      hist_.GetPacketState(kStartSeqNum, false);
+      hist_.GetPacketState(kStartSeqNum);
   ASSERT_TRUE(state);
   EXPECT_EQ(state->rtp_sequence_number, kStartSeqNum);
   EXPECT_EQ(state->send_time_ms, fake_clock_.TimeInMilliseconds());
@@ -193,9 +195,10 @@
   EXPECT_EQ(state->times_retransmitted, 0u);
 
   fake_clock_.AdvanceTimeMilliseconds(1);
-  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
+  fake_clock_.AdvanceTimeMilliseconds(kRttMs + 1);
 
-  state = hist_.GetPacketState(kStartSeqNum, false);
+  state = hist_.GetPacketState(kStartSeqNum);
   ASSERT_TRUE(state);
   EXPECT_EQ(state->times_retransmitted, 1u);
 }
@@ -211,7 +214,7 @@
   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, absl::nullopt);
 
   // First transmission: TimeToSendPacket() call from pacer.
-  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
 
   // First retransmission - allow early retransmission.
   fake_clock_.AdvanceTimeMilliseconds(1);
@@ -221,26 +224,24 @@
   //    packet is there and verify RTT constraints. Then we use the ssrc
   //    and sequence number to enqueue the retransmission in the pacer
   // 2) When the pacer determines that it is time to send the packet, it calls
-  //    GetPacketAndSetSendTime(). This time we do not need to verify RTT as
-  //    has that has already been done.
+  //    GetPacketAndSetSendTime().
   absl::optional<RtpPacketHistory::PacketState> packet_state =
-      hist_.GetPacketState(kStartSeqNum, /*verify_rtt=*/true);
+      hist_.GetPacketState(kStartSeqNum);
   EXPECT_TRUE(packet_state);
   EXPECT_EQ(len, packet_state->payload_size);
   EXPECT_EQ(capture_time_ms, packet_state->capture_time_ms);
 
   // Retransmission was allowed, next send it from pacer.
-  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum,
-                                            /*verify_rtt=*/false));
+  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
 
   // Second retransmission - advance time to just before retransmission OK.
   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, /*verify_rtt=*/true));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
 
   // Advance time to just after retransmission OK.
   fake_clock_.AdvanceTimeMilliseconds(1);
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, /*verify_rtt=*/true));
-  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, MinResendTimeWithoutPacer) {
@@ -256,18 +257,18 @@
 
   // First retransmission - allow early retransmission.
   fake_clock_.AdvanceTimeMilliseconds(1);
-  packet = hist_.GetPacketAndSetSendTime(kStartSeqNum, true);
+  packet = hist_.GetPacketAndSetSendTime(kStartSeqNum);
   EXPECT_TRUE(packet);
   EXPECT_EQ(len, packet->size());
   EXPECT_EQ(capture_time_ms, packet->capture_time_ms());
 
   // Second retransmission - advance time to just before retransmission OK.
   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
-  EXPECT_FALSE(hist_.GetPacketAndSetSendTime(kStartSeqNum, true));
+  EXPECT_FALSE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
 
   // Advance time to just after retransmission OK.
   fake_clock_.AdvanceTimeMilliseconds(1);
-  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum, true));
+  EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, RemovesOldestSentPacketWhenAtMaxSize) {
@@ -289,7 +290,7 @@
   }
 
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // History is full, oldest one should be overwritten.
   std::unique_ptr<RtpPacketToSend> packet =
@@ -298,8 +299,8 @@
                      fake_clock_.TimeInMilliseconds());
 
   // Oldest packet should be gone, but packet after than one still present.
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1));
 }
 
 TEST_F(RtpPacketHistoryTest, RemovesOldestPacketWhenAtMaxCapacity) {
@@ -317,7 +318,7 @@
   }
 
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // History is full, oldest one should be overwritten.
   std::unique_ptr<RtpPacketToSend> packet =
@@ -326,8 +327,8 @@
                      fake_clock_.TimeInMilliseconds());
 
   // Oldest packet should be gone, but packet after than one still present.
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1));
 }
 
 TEST_F(RtpPacketHistoryTest, DontRemoveUnsentPackets) {
@@ -343,25 +344,25 @@
   fake_clock_.AdvanceTimeMilliseconds(RtpPacketHistory::kMinPacketDurationMs);
 
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // History is full, but old packets not sent, so allow expansion.
   hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + kMaxNumPackets)),
                      kAllowRetransmission, fake_clock_.TimeInMilliseconds());
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Set all packet as sent and advance time past min packet duration time,
   // otherwise packets till still be prevented from being removed.
   for (size_t i = 0; i <= kMaxNumPackets; ++i) {
-    EXPECT_TRUE(hist_.GetPacketAndSetSendTime(To16u(kStartSeqNum + i), false));
+    EXPECT_TRUE(hist_.GetPacketAndSetSendTime(To16u(kStartSeqNum + i)));
   }
   fake_clock_.AdvanceTimeMilliseconds(RtpPacketHistory::kMinPacketDurationMs);
   // Add a new packet, this means the two oldest ones will be culled.
   hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + kMaxNumPackets + 1)),
                      kAllowRetransmission, fake_clock_.TimeInMilliseconds());
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum + 1, false));
-  EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2), false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum + 1));
+  EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
 }
 
 TEST_F(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPackets) {
@@ -378,15 +379,15 @@
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1), kAllowRetransmission,
                      fake_clock_.TimeInMilliseconds());
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Advance time to where packet will be eligible for removal and try again.
   fake_clock_.AdvanceTimeMilliseconds(1);
   hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 2)),
                      kAllowRetransmission, fake_clock_.TimeInMilliseconds());
   // First packet should no be gone, but next one still there.
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1));
 }
 
 TEST_F(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPacketsHighRtt) {
@@ -407,15 +408,15 @@
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1), kAllowRetransmission,
                      fake_clock_.TimeInMilliseconds());
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Advance time to where packet will be eligible for removal and try again.
   fake_clock_.AdvanceTimeMilliseconds(1);
   hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 2)),
                      kAllowRetransmission, fake_clock_.TimeInMilliseconds());
   // First packet should no be gone, but next one still there.
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum + 1));
 }
 
 TEST_F(RtpPacketHistoryTest, RemovesOldWithCulling) {
@@ -431,14 +432,14 @@
   fake_clock_.AdvanceTimeMilliseconds(kMaxPacketDurationMs - 1);
 
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Advance to where packet can be culled, even if buffer is not full.
   fake_clock_.AdvanceTimeMilliseconds(1);
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1), kAllowRetransmission,
                      fake_clock_.TimeInMilliseconds());
 
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, RemovesOldWithCullingHighRtt) {
@@ -457,14 +458,14 @@
   fake_clock_.AdvanceTimeMilliseconds(kMaxPacketDurationMs - 1);
 
   // First packet should still be there.
-  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
 
   // Advance to where packet can be culled, even if buffer is not full.
   fake_clock_.AdvanceTimeMilliseconds(1);
   hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1), kAllowRetransmission,
                      fake_clock_.TimeInMilliseconds());
 
-  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
 }
 
 TEST_F(RtpPacketHistoryTest, GetBestFittingPacket) {
@@ -503,7 +504,7 @@
   ASSERT_THAT(packet, ::testing::NotNull());
 
   // Send the packet and advance time past where packet expires.
-  ASSERT_THAT(hist_.GetPacketAndSetSendTime(kStartSeqNum, false),
+  ASSERT_THAT(hist_.GetPacketAndSetSendTime(kStartSeqNum),
               ::testing::NotNull());
   fake_clock_.AdvanceTimeMilliseconds(
       RtpPacketHistory::kPacketCullingDelayFactor *
@@ -513,7 +514,7 @@
   packet->SetPayloadSize(100);
   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission,
                      fake_clock_.TimeInMilliseconds());
-  ASSERT_FALSE(hist_.GetPacketState(kStartSeqNum, false));
+  ASSERT_FALSE(hist_.GetPacketState(kStartSeqNum));
 
   auto best_packet = hist_.GetBestFittingPacket(target_packet_size + 2);
   ASSERT_THAT(best_packet, ::testing::NotNull());
@@ -573,7 +574,7 @@
   hist_.PutRtpPacket(std::move(packet), kDontRetransmit,
                      fake_clock_.TimeInMilliseconds());
   EXPECT_THAT(hist_.GetBestFittingPacket(50), ::testing::IsNull());
-  EXPECT_THAT(hist_.GetPacketAndSetSendTime(kStartSeqNum, false),
+  EXPECT_THAT(hist_.GetPacketAndSetSendTime(kStartSeqNum),
               ::testing::NotNull());
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_packet_received.cc b/modules/rtp_rtcp/source/rtp_packet_received.cc
index c8deb99..93c0a1e 100644
--- a/modules/rtp_rtcp/source/rtp_packet_received.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_received.cc
@@ -10,6 +10,8 @@
 
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 
+#include <stddef.h>
+#include <cstdint>
 #include <vector>
 
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
diff --git a/modules/rtp_rtcp/source/rtp_packet_received.h b/modules/rtp_rtcp/source/rtp_packet_received.h
index 8690031..566b116 100644
--- a/modules/rtp_rtcp/source/rtp_packet_received.h
+++ b/modules/rtp_rtcp/source/rtp_packet_received.h
@@ -10,9 +10,11 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_PACKET_RECEIVED_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_RECEIVED_H_
 
+#include <stdint.h>
 #include <vector>
 
-#include "common_types.h"  // NOLINT(build/include)
+#include "api/array_view.h"
+#include "api/rtp_headers.h"
 #include "modules/rtp_rtcp/source/rtp_packet.h"
 #include "system_wrappers/include/ntp_time.h"
 
diff --git a/modules/rtp_rtcp/source/rtp_packet_to_send.cc b/modules/rtp_rtcp/source/rtp_packet_to_send.cc
index 0153bbe..b55e74a 100644
--- a/modules/rtp_rtcp/source/rtp_packet_to_send.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_to_send.cc
@@ -10,6 +10,8 @@
 
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
 
+#include <cstdint>
+
 namespace webrtc {
 
 RtpPacketToSend::RtpPacketToSend(const ExtensionManager* extensions)
diff --git a/modules/rtp_rtcp/source/rtp_packet_to_send.h b/modules/rtp_rtcp/source/rtp_packet_to_send.h
index 1ed7dda..56b1024 100644
--- a/modules/rtp_rtcp/source/rtp_packet_to_send.h
+++ b/modules/rtp_rtcp/source/rtp_packet_to_send.h
@@ -10,9 +10,12 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_PACKET_TO_SEND_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_TO_SEND_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <vector>
 
 #include "api/array_view.h"
+#include "api/video/video_timing.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
 #include "modules/rtp_rtcp/source/rtp_packet.h"
 
diff --git a/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
index 648ddc3..b485df6 100644
--- a/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -226,8 +226,7 @@
 }
 
 TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionFirst) {
-  RtpPacketToSend::ExtensionManager extensions;
-  extensions.SetMixedOneTwoByteHeaderSupported(true);
+  RtpPacketToSend::ExtensionManager extensions(true);
   extensions.Register(kRtpExtensionTransmissionTimeOffset,
                       kTransmissionOffsetExtensionId);
   extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
@@ -248,8 +247,7 @@
 
 TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionLast) {
   // This test will trigger RtpPacket::PromoteToTwoByteHeaderExtension().
-  RtpPacketToSend::ExtensionManager extensions;
-  extensions.SetMixedOneTwoByteHeaderSupported(true);
+  RtpPacketToSend::ExtensionManager extensions(true);
   extensions.Register(kRtpExtensionTransmissionTimeOffset,
                       kTransmissionOffsetExtensionId);
   extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
@@ -468,6 +466,23 @@
   EXPECT_EQ(0u, packet.padding_size());
 }
 
+TEST(RtpPacketTest, GetExtensionWithoutParametersReturnsOptionalValue) {
+  RtpPacket::ExtensionManager extensions;
+  extensions.Register<TransmissionOffset>(kTransmissionOffsetExtensionId);
+  extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
+
+  RtpPacketReceived packet(&extensions);
+  EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
+
+  auto time_offset = packet.GetExtension<TransmissionOffset>();
+  static_assert(
+      std::is_same<decltype(time_offset),
+                   absl::optional<TransmissionOffset::value_type>>::value,
+      "");
+  EXPECT_EQ(time_offset, kTimeOffset);
+  EXPECT_FALSE(packet.GetExtension<RtpStreamId>().has_value());
+}
+
 TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
   constexpr uint8_t kRawPacket[] = {
       // comment for clang-format to align kRawPacket nicer.
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 392b91d..5726284 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -11,12 +11,14 @@
 #include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
 
 #include <string.h>
-
 #include <algorithm>
+#include <cstdint>
 #include <set>
 #include <string>
+#include <utility>
 
-#include "api/rtpparameters.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
+#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 
@@ -99,7 +101,9 @@
         configuration.send_packet_observer,
         configuration.retransmission_rate_limiter,
         configuration.overhead_observer,
-        configuration.populate_network2_timestamp));
+        configuration.populate_network2_timestamp,
+        configuration.frame_encryptor, configuration.require_frame_encryption,
+        configuration.extmap_allow_mixed));
     // Make sure rtcp sender use same timestamp offset as rtp sender.
     rtcp_sender_.SetTimestampOffset(rtp_sender_->TimestampOffset());
 
@@ -253,6 +257,7 @@
 }
 
 int32_t ModuleRtpRtcpImpl::RegisterSendPayload(const CodecInst& voice_codec) {
+  rtcp_sender_.SetRtpClockRate(voice_codec.pltype, voice_codec.plfreq);
   return rtp_sender_->RegisterPayload(
       voice_codec.plname, voice_codec.pltype, voice_codec.plfreq,
       voice_codec.channels, (voice_codec.rate < 0) ? 0 : voice_codec.rate);
@@ -260,8 +265,10 @@
 
 void ModuleRtpRtcpImpl::RegisterVideoSendPayload(int payload_type,
                                                  const char* payload_name) {
-  RTC_CHECK_EQ(
-      0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000, 0, 0));
+  rtcp_sender_.SetRtpClockRate(payload_type, kVideoPayloadTypeFrequency);
+  RTC_CHECK_EQ(0,
+               rtp_sender_->RegisterPayload(payload_name, payload_type,
+                                            kVideoPayloadTypeFrequency, 0, 0));
 }
 
 int32_t ModuleRtpRtcpImpl::DeRegisterSendPayload(const int8_t payload_type) {
@@ -407,7 +414,7 @@
     const RTPFragmentationHeader* fragmentation,
     const RTPVideoHeader* rtp_video_header,
     uint32_t* transport_frame_id_out) {
-  rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms);
+  rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms, payload_type);
   // Make sure an RTCP report isn't queued behind a key frame.
   if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
     rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
@@ -609,6 +616,10 @@
   rtcp_sender_.UnsetRemb();
 }
 
+void ModuleRtpRtcpImpl::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+  rtp_sender_->SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
 int32_t ModuleRtpRtcpImpl::RegisterSendRtpHeaderExtension(
     const RTPExtensionType type,
     const uint8_t id) {
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 9c2b085..37516de 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -11,17 +11,24 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <set>
 #include <string>
-#include <utility>
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/rtp_headers.h"
 #include "api/video/video_bitrate_allocation.h"
+#include "common_types.h"  // NOLINT(build/include)
+#include "modules/include/module_common_types.h"
+#include "modules/include/module_fec_types.h"
+#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp.h"
-#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"  // RTCPPacketType
 #include "modules/rtp_rtcp/source/packet_loss_stats.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
 #include "modules/rtp_rtcp/source/rtcp_receiver.h"
 #include "modules/rtp_rtcp/source/rtcp_sender.h"
 #include "modules/rtp_rtcp/source/rtp_sender.h"
@@ -30,6 +37,10 @@
 
 namespace webrtc {
 
+class Clock;
+struct PacedPacketInfo;
+struct RTPVideoHeader;
+
 class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
  public:
   explicit ModuleRtpRtcpImpl(const RtpRtcp::Configuration& configuration);
@@ -59,6 +70,8 @@
 
   int32_t DeRegisterSendPayload(int8_t payload_type) override;
 
+  void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
+
   // Register RTP header extension.
   int32_t RegisterSendRtpHeaderExtension(RTPExtensionType type,
                                          uint8_t id) override;
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index 1678a03..38d6030 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -16,6 +16,7 @@
 #include <utility>
 
 #include "absl/memory/memory.h"
+#include "absl/strings/match.h"
 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
 #include "logging/rtc_event_log/rtc_event_log.h"
 #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
@@ -119,14 +120,22 @@
     SendPacketObserver* send_packet_observer,
     RateLimiter* retransmission_rate_limiter,
     OverheadObserver* overhead_observer,
-    bool populate_network2_timestamp)
+    bool populate_network2_timestamp,
+    FrameEncryptorInterface* frame_encryptor,
+    bool require_frame_encryption,
+    bool extmap_allow_mixed)
     : clock_(clock),
       // TODO(holmer): Remove this conversion?
       clock_delta_ms_(clock_->TimeInMilliseconds() - rtc::TimeMillis()),
       random_(clock_->TimeInMicroseconds()),
       audio_configured_(audio),
       audio_(audio ? new RTPSenderAudio(clock, this) : nullptr),
-      video_(audio ? nullptr : new RTPSenderVideo(clock, this, flexfec_sender)),
+      video_(audio ? nullptr
+                   : new RTPSenderVideo(clock,
+                                        this,
+                                        flexfec_sender,
+                                        frame_encryptor,
+                                        require_frame_encryption)),
       paced_sender_(paced_sender),
       transport_sequence_number_allocator_(sequence_number_allocator),
       transport_feedback_observer_(transport_feedback_observer),
@@ -137,7 +146,7 @@
       max_packet_size_(IP_PACKET_SIZE - 28),  // Default is IP-v4/UDP.
       last_payload_type_(-1),
       payload_type_map_(),
-      rtp_header_extension_map_(),
+      rtp_header_extension_map_(extmap_allow_mixed),
       packet_history_(clock),
       flexfec_packet_history_(clock),
       // Statistics
@@ -238,6 +247,11 @@
   return nack_bitrate_sent_.Rate(clock_->TimeInMilliseconds()).value_or(0);
 }
 
+void RTPSender::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+  rtc::CritScope lock(&send_critsect_);
+  rtp_header_extension_map_.SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
 int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type,
                                               uint8_t id) {
   rtc::CritScope lock(&send_critsect_);
@@ -259,13 +273,12 @@
   return rtp_header_extension_map_.Deregister(type);
 }
 
-int32_t RTPSender::RegisterPayload(
-    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    int8_t payload_number,
-    uint32_t frequency,
-    size_t channels,
-    uint32_t rate) {
-  RTC_DCHECK_LT(strlen(payload_name), RTP_PAYLOAD_NAME_SIZE);
+int32_t RTPSender::RegisterPayload(absl::string_view payload_name,
+                                   int8_t payload_number,
+                                   uint32_t frequency,
+                                   size_t channels,
+                                   uint32_t rate) {
+  RTC_DCHECK_LT(payload_name.size(), RTP_PAYLOAD_NAME_SIZE);
   rtc::CritScope lock(&send_critsect_);
 
   std::map<int8_t, RtpUtility::Payload*>::iterator it =
@@ -277,8 +290,7 @@
     RTC_DCHECK(payload);
 
     // Check if it's the same as we already have.
-    if (RtpUtility::StringCompare(payload->name, payload_name,
-                                  RTP_PAYLOAD_NAME_SIZE - 1)) {
+    if (absl::EqualsIgnoreCase(payload->name, payload_name)) {
       if (audio_configured_ && payload->typeSpecific.is_audio()) {
         auto& p = payload->typeSpecific.audio_payload();
         if (rtc::SafeEq(p.format.clockrate_hz, frequency) &&
@@ -654,7 +666,7 @@
   // Try to find packet in RTP packet history. Also verify RTT here, so that we
   // don't retransmit too often.
   absl::optional<RtpPacketHistory::PacketState> stored_packet =
-      packet_history_.GetPacketState(packet_id, true);
+      packet_history_.GetPacketState(packet_id);
   if (!stored_packet) {
     // Packet not found.
     return 0;
@@ -685,7 +697,7 @@
   }
 
   std::unique_ptr<RtpPacketToSend> packet =
-      packet_history_.GetPacketAndSetSendTime(packet_id, true);
+      packet_history_.GetPacketAndSetSendTime(packet_id);
   if (!packet) {
     // Packet could theoretically time out between the first check and this one.
     return 0;
@@ -763,17 +775,14 @@
     return true;
 
   std::unique_ptr<RtpPacketToSend> packet;
-  // No need to verify RTT here, it has already been checked before putting the
-  // packet into the pacer. But _do_ update the send time.
   if (ssrc == SSRC()) {
-    packet = packet_history_.GetPacketAndSetSendTime(sequence_number, false);
+    packet = packet_history_.GetPacketAndSetSendTime(sequence_number);
   } else if (ssrc == FlexfecSsrc()) {
-    packet =
-        flexfec_packet_history_.GetPacketAndSetSendTime(sequence_number, false);
+    packet = flexfec_packet_history_.GetPacketAndSetSendTime(sequence_number);
   }
 
   if (!packet) {
-    // Packet cannot be found.
+    // Packet cannot be found or was resend too recently.
     return true;
   }
 
@@ -1149,8 +1158,15 @@
 
 std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket() const {
   rtc::CritScope lock(&send_critsect_);
-  std::unique_ptr<RtpPacketToSend> packet(
-      new RtpPacketToSend(&rtp_header_extension_map_, max_packet_size_));
+  // TODO(danilchap): Find better motivator and value for extra capacity.
+  // RtpPacketizer might slightly miscalulate needed size,
+  // SRTP may benefit from extra space in the buffer and do encryption in place
+  // saving reallocation.
+  // While sending slightly oversized packet increase chance of dropped packet,
+  // it is better than crash on drop packet without trying to send it.
+  static constexpr int kExtraCapacity = 16;
+  auto packet = absl::make_unique<RtpPacketToSend>(
+      &rtp_header_extension_map_, max_packet_size_ + kExtraCapacity);
   RTC_DCHECK(ssrc_);
   packet->SetSsrc(*ssrc_);
   packet->SetCsrcs(csrcs_);
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index e9095d1..f9bbbdd 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -17,6 +17,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/call/transport.h"
@@ -37,6 +38,7 @@
 
 namespace webrtc {
 
+class FrameEncryptorInterface;
 class OverheadObserver;
 class RateLimiter;
 class RtcEventLog;
@@ -62,7 +64,10 @@
             SendPacketObserver* send_packet_observer,
             RateLimiter* nack_rate_limiter,
             OverheadObserver* overhead_observer,
-            bool populate_network2_timestamp);
+            bool populate_network2_timestamp,
+            FrameEncryptorInterface* frame_encryptor,
+            bool require_frame_encryption,
+            bool extmap_allow_mixed);
 
   ~RTPSender();
 
@@ -74,7 +79,7 @@
   uint32_t FecOverheadRate() const;
   uint32_t NackOverheadRate() const;
 
-  int32_t RegisterPayload(const char* payload_name,
+  int32_t RegisterPayload(absl::string_view payload_name,
                           const int8_t payload_type,
                           const uint32_t frequency,
                           const size_t channels,
@@ -115,6 +120,8 @@
                         uint32_t* transport_frame_id_out,
                         int64_t expected_retransmission_time_ms);
 
+  void SetExtmapAllowMixed(bool extmap_allow_mixed);
+
   // RTP header extension
   int32_t RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
   bool RegisterRtpHeaderExtension(const std::string& uri, int id);
diff --git a/modules/rtp_rtcp/source/rtp_sender_audio.cc b/modules/rtp_rtcp/source/rtp_sender_audio.cc
index bf86a39..636cccc 100644
--- a/modules/rtp_rtcp/source/rtp_sender_audio.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_audio.cc
@@ -11,16 +11,18 @@
 #include "modules/rtp_rtcp/source/rtp_sender_audio.h"
 
 #include <string.h>
-
 #include <memory>
 #include <utility>
 
+#include "absl/strings/match.h"
+#include "api/audio_codecs/audio_format.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
+#include "modules/rtp_rtcp/source/rtp_packet.h"
 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/timeutils.h"
 #include "rtc_base/trace_event.h"
 
 namespace webrtc {
@@ -30,14 +32,13 @@
 
 RTPSenderAudio::~RTPSenderAudio() {}
 
-int32_t RTPSenderAudio::RegisterAudioPayload(
-    const char payloadName[RTP_PAYLOAD_NAME_SIZE],
-    const int8_t payload_type,
-    const uint32_t frequency,
-    const size_t channels,
-    const uint32_t rate,
-    RtpUtility::Payload** payload) {
-  if (RtpUtility::StringCompare(payloadName, "cn", 2)) {
+int32_t RTPSenderAudio::RegisterAudioPayload(absl::string_view payload_name,
+                                             const int8_t payload_type,
+                                             const uint32_t frequency,
+                                             const size_t channels,
+                                             const uint32_t rate,
+                                             RtpUtility::Payload** payload) {
+  if (absl::EqualsIgnoreCase(payload_name, "cn")) {
     rtc::CritScope cs(&send_audio_critsect_);
     //  we can have multiple CNG payload types
     switch (frequency) {
@@ -56,7 +57,7 @@
       default:
         return -1;
     }
-  } else if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) {
+  } else if (absl::EqualsIgnoreCase(payload_name, "telephone-event")) {
     rtc::CritScope cs(&send_audio_critsect_);
     // Don't add it to the list
     // we dont want to allow send with a DTMF payloadtype
@@ -65,9 +66,9 @@
     return 0;
   }
   *payload = new RtpUtility::Payload(
-      payloadName,
+      payload_name,
       PayloadUnion(AudioPayload{
-          SdpAudioFormat(payloadName, frequency, channels), rate}));
+          SdpAudioFormat(payload_name, frequency, channels), rate}));
   return 0;
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_sender_audio.h b/modules/rtp_rtcp/source/rtp_sender_audio.h
index 63dfc2b..1dbe5b5 100644
--- a/modules/rtp_rtcp/source/rtp_sender_audio.h
+++ b/modules/rtp_rtcp/source/rtp_sender_audio.h
@@ -11,14 +11,19 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_SENDER_AUDIO_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_SENDER_AUDIO_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
+#include "absl/strings/string_view.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/source/dtmf_queue.h"
-#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
 #include "modules/rtp_rtcp/source/rtp_sender.h"
 #include "modules/rtp_rtcp/source/rtp_utility.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/onetimeevent.h"
+#include "rtc_base/thread_annotations.h"
+#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 
@@ -27,7 +32,7 @@
   RTPSenderAudio(Clock* clock, RTPSender* rtp_sender);
   ~RTPSenderAudio();
 
-  int32_t RegisterAudioPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE],
+  int32_t RegisterAudioPayload(absl::string_view payload_name,
                                int8_t payload_type,
                                uint32_t frequency,
                                size_t channels,
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 1b7e992..f30b383 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -184,7 +184,8 @@
         false, &fake_clock_, &transport_, pacer ? &mock_paced_sender_ : nullptr,
         nullptr, &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
         &mock_rtc_event_log_, &send_packet_observer_,
-        &retransmission_rate_limiter_, nullptr, populate_network2));
+        &retransmission_rate_limiter_, nullptr, populate_network2, nullptr,
+        false, false));
     rtp_sender_->SetSequenceNumber(kSeqNum);
     rtp_sender_->SetTimestampOffset(0);
     rtp_sender_->SetSSRC(kSsrc);
@@ -276,7 +277,7 @@
   TestRtpSenderVideo(Clock* clock,
                      RTPSender* rtp_sender,
                      FlexfecSender* flexfec_sender)
-      : RTPSenderVideo(clock, rtp_sender, flexfec_sender) {}
+      : RTPSenderVideo(clock, rtp_sender, flexfec_sender, nullptr, false) {}
   ~TestRtpSenderVideo() override {}
 
   StorageType GetStorageType(const RTPVideoHeader& header,
@@ -382,7 +383,8 @@
   rtp_sender_.reset(new RTPSender(
       kEnableAudio, &fake_clock_, &transport, &mock_paced_sender_, nullptr,
       nullptr, nullptr, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
-      nullptr, &retransmission_rate_limiter_, nullptr, false));
+      nullptr, &retransmission_rate_limiter_, nullptr, false, nullptr, false,
+      false));
   rtp_sender_->SetTimestampOffset(0);
   rtp_sender_->SetSSRC(kSsrc);
 
@@ -428,7 +430,8 @@
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
       &feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
-      nullptr, &retransmission_rate_limiter_, &mock_overhead_observer, false));
+      nullptr, &retransmission_rate_limiter_, &mock_overhead_observer, false,
+      nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
   EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                    kRtpExtensionTransportSequenceNumber,
@@ -455,7 +458,8 @@
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
       &feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
-      &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false));
+      &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
+      nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
   EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
                    kRtpExtensionTransportSequenceNumber,
@@ -486,7 +490,8 @@
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
       &feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
-      &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false));
+      &send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
+      nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
 
   SendGenericPayload();
@@ -537,10 +542,10 @@
 
 TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
   testing::StrictMock<MockSendSideDelayObserver> send_side_delay_observer_;
-  rtp_sender_.reset(
-      new RTPSender(false, &fake_clock_, &transport_, nullptr, nullptr, nullptr,
-                    nullptr, nullptr, nullptr, &send_side_delay_observer_,
-                    &mock_rtc_event_log_, nullptr, nullptr, nullptr, false));
+  rtp_sender_.reset(new RTPSender(
+      false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
+      nullptr, nullptr, &send_side_delay_observer_, &mock_rtc_event_log_,
+      nullptr, nullptr, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
 
   const uint8_t kPayloadType = 127;
@@ -618,7 +623,7 @@
       false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr,
       &seq_num_allocator_, &feedback_observer_, nullptr, nullptr, nullptr,
       &mock_rtc_event_log_, &send_packet_observer_,
-      &retransmission_rate_limiter_, nullptr, false));
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetSSRC(kSsrc);
   rtp_sender_->SetStorePacketsStatus(true, 10);
@@ -978,7 +983,7 @@
       false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr,
       nullptr /* TransportSequenceNumberAllocator */, nullptr, nullptr, nullptr,
       nullptr, nullptr, &send_packet_observer_, &retransmission_rate_limiter_,
-      nullptr, false));
+      nullptr, false, nullptr, false, false));
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetSSRC(kSsrc);
   EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
@@ -1004,7 +1009,7 @@
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport, &mock_paced_sender_, nullptr, nullptr,
       nullptr, nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
-      &retransmission_rate_limiter_, nullptr, false));
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetSSRC(kSsrc);
   rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
@@ -1128,7 +1133,7 @@
       false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
       &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
       &mock_rtc_event_log_, &send_packet_observer_,
-      &retransmission_rate_limiter_, nullptr, false));
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kMediaSsrc);
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetStorePacketsStatus(true, 10);
@@ -1188,7 +1193,7 @@
       false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
       &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
       &mock_rtc_event_log_, &send_packet_observer_,
-      &retransmission_rate_limiter_, nullptr, false));
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kMediaSsrc);
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetStorePacketsStatus(true, 10);
@@ -1283,11 +1288,11 @@
                                nullptr /* rtp_state */, &fake_clock_);
 
   // Reset |rtp_sender_| to use FlexFEC.
-  rtp_sender_.reset(
-      new RTPSender(false, &fake_clock_, &transport_, nullptr, &flexfec_sender,
-                    &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
-                    &mock_rtc_event_log_, &send_packet_observer_,
-                    &retransmission_rate_limiter_, nullptr, false));
+  rtp_sender_.reset(new RTPSender(
+      false, &fake_clock_, &transport_, nullptr, &flexfec_sender,
+      &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
+      &mock_rtc_event_log_, &send_packet_observer_,
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kMediaSsrc);
   rtp_sender_->SetSequenceNumber(kSeqNum);
 
@@ -1351,7 +1356,7 @@
       false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
       &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
       &mock_rtc_event_log_, &send_packet_observer_,
-      &retransmission_rate_limiter_, nullptr, false));
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kMediaSsrc);
   rtp_sender_->SetSequenceNumber(kSeqNum);
 
@@ -1403,7 +1408,7 @@
   rtp_sender_.reset(new RTPSender(
       false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr, nullptr,
       nullptr, nullptr, &callback, nullptr, nullptr, nullptr,
-      &retransmission_rate_limiter_, nullptr, false));
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
   char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC";
   const uint8_t payload_type = 127;
@@ -1463,10 +1468,10 @@
     uint32_t total_bitrate_;
     uint32_t retransmit_bitrate_;
   } callback;
-  rtp_sender_.reset(
-      new RTPSender(false, &fake_clock_, &transport_, nullptr, nullptr, nullptr,
-                    nullptr, &callback, nullptr, nullptr, nullptr, nullptr,
-                    &retransmission_rate_limiter_, nullptr, false));
+  rtp_sender_.reset(new RTPSender(
+      false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
+      &callback, nullptr, nullptr, nullptr, nullptr,
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
 
   // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
@@ -1523,10 +1528,10 @@
 
   void SetUp() override {
     payload_ = kAudioPayload;
-    rtp_sender_.reset(
-        new RTPSender(true, &fake_clock_, &transport_, nullptr, nullptr,
-                      nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
-                      nullptr, &retransmission_rate_limiter_, nullptr, false));
+    rtp_sender_.reset(new RTPSender(
+        true, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
+        nullptr, nullptr, nullptr, nullptr, nullptr,
+        &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
     rtp_sender_->SetSSRC(kSsrc);
     rtp_sender_->SetSequenceNumber(kSeqNum);
   }
@@ -2189,10 +2194,11 @@
 
 TEST_P(RtpSenderTest, OnOverheadChanged) {
   MockOverheadObserver mock_overhead_observer;
-  rtp_sender_.reset(new RTPSender(
-      false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
-      nullptr, nullptr, nullptr, nullptr, nullptr,
-      &retransmission_rate_limiter_, &mock_overhead_observer, false));
+  rtp_sender_.reset(
+      new RTPSender(false, &fake_clock_, &transport_, nullptr, nullptr, nullptr,
+                    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                    &retransmission_rate_limiter_, &mock_overhead_observer,
+                    false, nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
 
   // RTP overhead is 12B.
@@ -2210,10 +2216,11 @@
 
 TEST_P(RtpSenderTest, DoesNotUpdateOverheadOnEqualSize) {
   MockOverheadObserver mock_overhead_observer;
-  rtp_sender_.reset(new RTPSender(
-      false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
-      nullptr, nullptr, nullptr, nullptr, nullptr,
-      &retransmission_rate_limiter_, &mock_overhead_observer, false));
+  rtp_sender_.reset(
+      new RTPSender(false, &fake_clock_, &transport_, nullptr, nullptr, nullptr,
+                    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                    &retransmission_rate_limiter_, &mock_overhead_observer,
+                    false, nullptr, false, false));
   rtp_sender_->SetSSRC(kSsrc);
 
   EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
@@ -2223,10 +2230,10 @@
 
 TEST_P(RtpSenderTest, SendsKeepAlive) {
   MockTransport transport;
-  rtp_sender_.reset(
-      new RTPSender(false, &fake_clock_, &transport, nullptr, nullptr, nullptr,
-                    nullptr, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
-                    nullptr, &retransmission_rate_limiter_, nullptr, false));
+  rtp_sender_.reset(new RTPSender(
+      false, &fake_clock_, &transport, nullptr, nullptr, nullptr, nullptr,
+      nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
+      &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
   rtp_sender_->SetSequenceNumber(kSeqNum);
   rtp_sender_->SetTimestampOffset(0);
   rtp_sender_->SetSSRC(kSsrc);
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index e8f0ea5..cb0b665 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -19,6 +19,8 @@
 #include <vector>
 
 #include "absl/memory/memory.h"
+#include "absl/strings/match.h"
+#include "api/crypto/frameencryptorinterface.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
@@ -91,6 +93,11 @@
       generic_descriptor.SetSpatialLayersBitmask(spatial_bimask);
 
       generic_descriptor.SetTemporalLayer(video_header.generic->temporal_index);
+
+      if (frame_type == kVideoFrameKey) {
+        generic_descriptor.SetResolution(video_header.width,
+                                         video_header.height);
+      }
     }
     packet->SetExtension<RtpGenericFrameDescriptorExtension>(
         generic_descriptor);
@@ -115,7 +122,9 @@
 
 RTPSenderVideo::RTPSenderVideo(Clock* clock,
                                RTPSender* rtp_sender,
-                               FlexfecSender* flexfec_sender)
+                               FlexfecSender* flexfec_sender,
+                               FrameEncryptorInterface* frame_encryptor,
+                               bool require_frame_encryption)
     : rtp_sender_(rtp_sender),
       clock_(clock),
       video_type_(kVideoCodecGeneric),
@@ -128,7 +137,9 @@
       delta_fec_params_{0, 1, kFecMaskRandom},
       key_fec_params_{0, 1, kFecMaskRandom},
       fec_bitrate_(1000, RateStatistics::kBpsScale),
-      video_bitrate_(1000, RateStatistics::kBpsScale) {}
+      video_bitrate_(1000, RateStatistics::kBpsScale),
+      frame_encryptor_(frame_encryptor),
+      require_frame_encryption_(require_frame_encryption) {}
 
 RTPSenderVideo::~RTPSenderVideo() {}
 
@@ -142,18 +153,18 @@
 
 // Static.
 RtpUtility::Payload* RTPSenderVideo::CreateVideoPayload(
-    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
+    absl::string_view payload_name,
     int8_t payload_type) {
   enum VideoCodecType video_type = kVideoCodecGeneric;
-  if (RtpUtility::StringCompare(payload_name, "VP8", 3)) {
+  if (absl::EqualsIgnoreCase(payload_name, "VP8")) {
     video_type = kVideoCodecVP8;
-  } else if (RtpUtility::StringCompare(payload_name, "VP9", 3)) {
+  } else if (absl::EqualsIgnoreCase(payload_name, "VP9")) {
     video_type = kVideoCodecVP9;
-  } else if (RtpUtility::StringCompare(payload_name, "H264", 4)) {
+  } else if (absl::EqualsIgnoreCase(payload_name, "H264")) {
     video_type = kVideoCodecH264;
-  } else if (RtpUtility::StringCompare(payload_name, "I420", 4)) {
+  } else if (absl::EqualsIgnoreCase(payload_name, "I420")) {
     video_type = kVideoCodecGeneric;
-  } else if (RtpUtility::StringCompare(payload_name, "stereo", 6)) {
+  } else if (absl::EqualsIgnoreCase(payload_name, "stereo")) {
     video_type = kVideoCodecGeneric;
   } else {
     video_type = kVideoCodecGeneric;
@@ -387,33 +398,37 @@
   int packet_capacity = rtp_sender_->MaxRtpPacketSize() - fec_packet_overhead -
                         (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0);
 
-  auto create_packet = [&] {
-    std::unique_ptr<RtpPacketToSend> rtp_packet = rtp_sender_->AllocatePacket();
-    RTC_DCHECK_LE(packet_capacity, rtp_packet->capacity());
+  std::unique_ptr<RtpPacketToSend> single_packet =
+      rtp_sender_->AllocatePacket();
+  RTC_DCHECK_LE(packet_capacity, single_packet->capacity());
+  single_packet->SetPayloadType(payload_type);
+  single_packet->SetTimestamp(rtp_timestamp);
+  single_packet->set_capture_time_ms(capture_time_ms);
 
-    rtp_packet->SetPayloadType(payload_type);
-    rtp_packet->SetTimestamp(rtp_timestamp);
-    rtp_packet->set_capture_time_ms(capture_time_ms);
-    return rtp_packet;
-  };
-
-  auto first_packet = create_packet();
-  auto middle_packet = absl::make_unique<RtpPacketToSend>(*first_packet);
-  auto last_packet = absl::make_unique<RtpPacketToSend>(*first_packet);
+  auto first_packet = absl::make_unique<RtpPacketToSend>(*single_packet);
+  auto middle_packet = absl::make_unique<RtpPacketToSend>(*single_packet);
+  auto last_packet = absl::make_unique<RtpPacketToSend>(*single_packet);
   // Simplest way to estimate how much extensions would occupy is to set them.
   AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
+                         /*first=*/true, /*last=*/true, single_packet.get());
+  AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
                          /*first=*/true, /*last=*/false, first_packet.get());
   AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
                          /*first=*/false, /*last=*/false, middle_packet.get());
   AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
                          /*first=*/false, /*last=*/true, last_packet.get());
 
+  RTC_DCHECK_GT(packet_capacity, single_packet->headers_size());
   RTC_DCHECK_GT(packet_capacity, first_packet->headers_size());
   RTC_DCHECK_GT(packet_capacity, middle_packet->headers_size());
   RTC_DCHECK_GT(packet_capacity, last_packet->headers_size());
   RtpPacketizer::PayloadSizeLimits limits;
   limits.max_payload_len = packet_capacity - middle_packet->headers_size();
 
+  RTC_DCHECK_GE(single_packet->headers_size(), middle_packet->headers_size());
+  limits.single_packet_reduction_len =
+      single_packet->headers_size() - middle_packet->headers_size();
+
   RTC_DCHECK_GE(first_packet->headers_size(), middle_packet->headers_size());
   limits.first_packet_reduction_len =
       first_packet->headers_size() - middle_packet->headers_size();
@@ -424,9 +439,42 @@
 
   RTPVideoHeader minimized_video_header;
   const RTPVideoHeader* packetize_video_header = video_header;
-  if (first_packet->HasExtension<RtpGenericFrameDescriptorExtension>() &&
-      MinimizeDescriptor(*video_header, &minimized_video_header)) {
-    packetize_video_header = &minimized_video_header;
+  rtc::ArrayView<const uint8_t> generic_descriptor_raw =
+      first_packet->GetRawExtension<RtpGenericFrameDescriptorExtension>();
+  if (!generic_descriptor_raw.empty()) {
+    if (MinimizeDescriptor(*video_header, &minimized_video_header)) {
+      packetize_video_header = &minimized_video_header;
+    }
+  }
+
+  // TODO(benwright@webrtc.org) - Allocate enough to always encrypt inline.
+  rtc::Buffer encrypted_video_payload;
+  if (frame_encryptor_ != nullptr) {
+    if (generic_descriptor_raw.empty()) {
+      return false;
+    }
+
+    const size_t max_ciphertext_size =
+        frame_encryptor_->GetMaxCiphertextByteSize(cricket::MEDIA_TYPE_VIDEO,
+                                                   payload_size);
+    encrypted_video_payload.SetSize(max_ciphertext_size);
+
+    size_t bytes_written = 0;
+    if (frame_encryptor_->Encrypt(
+            cricket::MEDIA_TYPE_VIDEO, first_packet->Ssrc(),
+            /*additional_data=*/nullptr,
+            rtc::MakeArrayView(payload_data, payload_size),
+            encrypted_video_payload, &bytes_written) != 0) {
+      return false;
+    }
+
+    encrypted_video_payload.SetSize(bytes_written);
+    payload_data = encrypted_video_payload.data();
+    payload_size = encrypted_video_payload.size();
+  } else if (require_frame_encryption_) {
+    RTC_LOG(LS_WARNING)
+        << "No FrameEncryptor is attached to this video sending stream but "
+        << "one is required since require_frame_encryptor is set";
   }
 
   std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create(
@@ -447,16 +495,9 @@
     int expected_payload_capacity;
     // Choose right packet template:
     if (num_packets == 1) {
-      // No prepared template, create a new packet.
-      packet = create_packet();
-      AddRtpHeaderExtensions(*video_header, frame_type, set_video_rotation,
-                             /*first=*/true, /*last=*/true, packet.get());
-      // TODO(bugs.webrtc.org/7990): Revisit this case when two byte header
-      // extension are implemented because then single packet might need more
-      // space for extensions than sum of first and last packet reductions.
-      expected_payload_capacity = limits.max_payload_len -
-                                  limits.first_packet_reduction_len -
-                                  limits.last_packet_reduction_len;
+      packet = std::move(single_packet);
+      expected_payload_capacity =
+          limits.max_payload_len - limits.single_packet_reduction_len;
     } else if (i == 0) {
       packet = std::move(first_packet);
       expected_payload_capacity =
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index ce7be16..d3a898b 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -14,6 +14,7 @@
 #include <map>
 #include <memory>
 
+#include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/include/flexfec_sender.h"
@@ -29,6 +30,8 @@
 #include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
+
+class FrameEncryptorInterface;
 class RtpPacketizer;
 class RtpPacketToSend;
 
@@ -38,14 +41,15 @@
 
   RTPSenderVideo(Clock* clock,
                  RTPSender* rtpSender,
-                 FlexfecSender* flexfec_sender);
+                 FlexfecSender* flexfec_sender,
+                 FrameEncryptorInterface* frame_encryptor,
+                 bool require_frame_encryption);
   virtual ~RTPSenderVideo();
 
   virtual enum VideoCodecType VideoCodecType() const;
 
-  static RtpUtility::Payload* CreateVideoPayload(
-      const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      int8_t payload_type);
+  static RtpUtility::Payload* CreateVideoPayload(absl::string_view payload_name,
+                                                 int8_t payload_type);
 
   bool SendVideo(enum VideoCodecType video_type,
                  FrameType frame_type,
@@ -158,6 +162,13 @@
       RTC_GUARDED_BY(stats_crit_);
 
   OneTimeEvent first_frame_sent_;
+
+  // E2EE Custom Video Frame Encryptor (optional)
+  FrameEncryptorInterface* const frame_encryptor_ = nullptr;
+  // If set to true will require all outgoing frames to pass through an
+  // initialized frame_encryptor_ before being sent out of the network.
+  // Otherwise these payloads will be dropped.
+  bool require_frame_encryption_;
 };
 
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_utility.cc b/modules/rtp_rtcp/source/rtp_utility.cc
index 228572f..53a006d 100644
--- a/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/modules/rtp_rtcp/source/rtp_utility.cc
@@ -10,9 +10,19 @@
 
 #include "modules/rtp_rtcp/source/rtp_utility.h"
 
+#include <assert.h>
+#include <stddef.h>
+
+#include "api/array_view.h"
+#include "api/video/video_content_type.h"
+#include "api/video/video_frame_marking.h"
+#include "api/video/video_rotation.h"
+#include "api/video/video_timing.h"
 #include "modules/rtp_rtcp/include/rtp_cvo.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
+#include "modules/video_coding/codecs/interface/common_constants.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/stringutils.h"
 
@@ -33,10 +43,6 @@
  * Misc utility routines
  */
 
-bool StringCompare(const char* str1, const char* str2, const uint32_t length) {
-  return _strnicmp(str1, str2, length) == 0;
-}
-
 size_t Word32Align(size_t size) {
   uint32_t remainder = size % 4;
   if (remainder != 0)
diff --git a/modules/rtp_rtcp/source/rtp_utility.h b/modules/rtp_rtcp/source/rtp_utility.h
index 762f964..4085174 100644
--- a/modules/rtp_rtcp/source/rtp_utility.h
+++ b/modules/rtp_rtcp/source/rtp_utility.h
@@ -11,14 +11,14 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_UTILITY_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_UTILITY_H_
 
-#include <cstring>
-#include <map>
+#include <stdint.h>
+#include <algorithm>
 
-#include "modules/rtp_rtcp/include/receive_statistics.h"
+#include "absl/strings/string_view.h"
+#include "api/rtp_headers.h"
+#include "common_types.h"  // NOLINT(build/include)
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
-#include "rtc_base/deprecation.h"
 
 namespace webrtc {
 
@@ -27,16 +27,15 @@
 namespace RtpUtility {
 
 struct Payload {
-  Payload(const char* name, const PayloadUnion& pu) : typeSpecific(pu) {
-    std::strncpy(this->name, name, sizeof(this->name) - 1);
-    this->name[sizeof(this->name) - 1] = '\0';
+  Payload(absl::string_view payload_name, const PayloadUnion& pu)
+      : typeSpecific(pu) {
+    size_t clipped_size = payload_name.copy(name, sizeof(name) - 1);
+    name[clipped_size] = '\0';
   }
   char name[RTP_PAYLOAD_NAME_SIZE];
   PayloadUnion typeSpecific;
 };
 
-bool StringCompare(const char* str1, const char* str2, const uint32_t length);
-
 // Round up to the nearest size that is a multiple of 4.
 size_t Word32Align(size_t size);
 
diff --git a/modules/rtp_rtcp/source/rtp_video_header.h b/modules/rtp_rtcp/source/rtp_video_header.h
index 288b7d0..4426c41 100644
--- a/modules/rtp_rtcp/source/rtp_video_header.h
+++ b/modules/rtp_rtcp/source/rtp_video_header.h
@@ -10,7 +10,10 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_HEADER_H_
 #define MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_HEADER_H_
 
+#include <cstdint>
+
 #include "absl/container/inlined_vector.h"
+#include "absl/types/optional.h"
 #include "absl/types/variant.h"
 #include "api/video/video_content_type.h"
 #include "api/video/video_frame_marking.h"
diff --git a/modules/rtp_rtcp/source/time_util.cc b/modules/rtp_rtcp/source/time_util.cc
index 6ac280a..e65329d 100644
--- a/modules/rtp_rtcp/source/time_util.cc
+++ b/modules/rtp_rtcp/source/time_util.cc
@@ -12,6 +12,7 @@
 
 #include <algorithm>
 
+#include "rtc_base/checks.h"
 #include "rtc_base/timeutils.h"
 
 namespace webrtc {
@@ -22,20 +23,27 @@
   return (x + y / 2) / y;
 }
 
-int64_t NtpOffsetUs() {
+int64_t NtpOffsetMsCalledOnce() {
   constexpr int64_t kNtpJan1970Sec = 2208988800;
-  int64_t clock_time = rtc::TimeMicros();
-  int64_t utc_time = rtc::TimeUTCMicros();
-  return utc_time - clock_time + kNtpJan1970Sec * rtc::kNumMicrosecsPerSec;
+  int64_t clock_time = rtc::TimeMillis();
+  int64_t utc_time = rtc::TimeUTCMillis();
+  return utc_time - clock_time + kNtpJan1970Sec * rtc::kNumMillisecsPerSec;
 }
 
 }  // namespace
 
-NtpTime TimeMicrosToNtp(int64_t time_us) {
+int64_t NtpOffsetMs() {
   // Calculate the offset once.
-  static int64_t ntp_offset_us = NtpOffsetUs();
+  static int64_t ntp_offset_ms = NtpOffsetMsCalledOnce();
+  return ntp_offset_ms;
+}
 
-  int64_t time_ntp_us = time_us + ntp_offset_us;
+NtpTime TimeMicrosToNtp(int64_t time_us) {
+  // Since this doesn't return a wallclock time, but only NTP representation
+  // of rtc::TimeMillis() clock, the exact offset doesn't matter.
+  // To simplify conversions between NTP and RTP time, this offset is
+  // limited to milliseconds in resolution.
+  int64_t time_ntp_us = time_us + NtpOffsetMs() * 1000;
   RTC_DCHECK_GE(time_ntp_us, 0);  // Time before year 1900 is unsupported.
 
   // TODO(danilchap): Convert both seconds and fraction together using int128
diff --git a/modules/rtp_rtcp/source/time_util.h b/modules/rtp_rtcp/source/time_util.h
index 672722c..1e01c94 100644
--- a/modules/rtp_rtcp/source/time_util.h
+++ b/modules/rtp_rtcp/source/time_util.h
@@ -22,8 +22,15 @@
 // difference of the passed values.
 // As a result TimeMicrosToNtp(rtc::TimeMicros()) doesn't guarantee to match
 // system time.
+// However, TimeMicrosToNtp Guarantees that returned NtpTime will be offsetted
+// from rtc::TimeMicros() by integral number of milliseconds.
+// Use NtpOffsetMs() to get that offset value.
 NtpTime TimeMicrosToNtp(int64_t time_us);
 
+// Difference between Ntp time and local relative time returned by
+// rtc::TimeMicros()
+int64_t NtpOffsetMs();
+
 // Converts NTP timestamp to RTP timestamp.
 inline uint32_t NtpToRtp(NtpTime ntp, uint32_t freq) {
   uint32_t tmp = (static_cast<uint64_t>(ntp.fractions()) * freq) >> 32;
diff --git a/modules/rtp_rtcp/source/tmmbr_help.cc b/modules/rtp_rtcp/source/tmmbr_help.cc
index 8aa4530..315a4c2 100644
--- a/modules/rtp_rtcp/source/tmmbr_help.cc
+++ b/modules/rtp_rtcp/source/tmmbr_help.cc
@@ -10,6 +10,7 @@
 
 #include "modules/rtp_rtcp/source/tmmbr_help.h"
 
+#include <stddef.h>
 #include <algorithm>
 #include <limits>
 
diff --git a/modules/rtp_rtcp/source/tmmbr_help.h b/modules/rtp_rtcp/source/tmmbr_help.h
index 91aeaf4..bf86f65 100644
--- a/modules/rtp_rtcp/source/tmmbr_help.h
+++ b/modules/rtp_rtcp/source/tmmbr_help.h
@@ -11,7 +11,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_TMMBR_HELP_H_
 #define MODULES_RTP_RTCP_SOURCE_TMMBR_HELP_H_
 
+#include <stdint.h>
 #include <vector>
+
 #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/ulpfec_generator.cc b/modules/rtp_rtcp/source/ulpfec_generator.cc
index e5777ed..56dae29 100644
--- a/modules/rtp_rtcp/source/ulpfec_generator.cc
+++ b/modules/rtp_rtcp/source/ulpfec_generator.cc
@@ -10,12 +10,15 @@
 
 #include "modules/rtp_rtcp/source/ulpfec_generator.h"
 
+#include <string.h>
+#include <cstdint>
 #include <memory>
 #include <utility>
 
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
+#include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
 #include "modules/rtp_rtcp/source/rtp_utility.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/rtp_rtcp/source/ulpfec_generator.h b/modules/rtp_rtcp/source/ulpfec_generator.h
index efc753f..74a1d80 100644
--- a/modules/rtp_rtcp/source/ulpfec_generator.h
+++ b/modules/rtp_rtcp/source/ulpfec_generator.h
@@ -11,10 +11,13 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_ULPFEC_GENERATOR_H_
 #define MODULES_RTP_RTCP_SOURCE_ULPFEC_GENERATOR_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <list>
 #include <memory>
 #include <vector>
 
+#include "modules/include/module_fec_types.h"
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc
index c54d3cd..22af7e7 100644
--- a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc
+++ b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc
@@ -10,11 +10,12 @@
 
 #include "modules/rtp_rtcp/source/ulpfec_header_reader_writer.h"
 
-#include <utility>
+#include <string.h>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/scoped_ref_ptr.h"
 
 namespace webrtc {
 
diff --git a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h
index fc83afd..a8bb737 100644
--- a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h
+++ b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h
@@ -11,6 +11,9 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_ULPFEC_HEADER_READER_WRITER_H_
 #define MODULES_RTP_RTCP_SOURCE_ULPFEC_HEADER_READER_WRITER_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc b/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc
index eb09c95..7da6b88 100644
--- a/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc
+++ b/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc
@@ -10,12 +10,13 @@
 
 #include "modules/rtp_rtcp/source/ulpfec_receiver_impl.h"
 
+#include <string.h>
 #include <memory>
 #include <utility>
 
 #include "modules/rtp_rtcp/source/byte_io.h"
-#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/scoped_ref_ptr.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
diff --git a/modules/rtp_rtcp/source/ulpfec_receiver_impl.h b/modules/rtp_rtcp/source/ulpfec_receiver_impl.h
index 96367dc..0943266 100644
--- a/modules/rtp_rtcp/source/ulpfec_receiver_impl.h
+++ b/modules/rtp_rtcp/source/ulpfec_receiver_impl.h
@@ -11,9 +11,12 @@
 #ifndef MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_IMPL_H_
 #define MODULES_RTP_RTCP_SOURCE_ULPFEC_RECEIVER_IMPL_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <vector>
 
+#include "api/rtp_headers.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/rtp_rtcp/include/ulpfec_receiver.h"
 #include "modules/rtp_rtcp/source/forward_error_correction.h"
diff --git a/modules/video_coding/codecs/h264/include/h264.h b/modules/video_coding/codecs/h264/include/h264.h
index e23818b..f5cebcf 100644
--- a/modules/video_coding/codecs/h264/include/h264.h
+++ b/modules/video_coding/codecs/h264/include/h264.h
@@ -17,6 +17,7 @@
 
 #include "media/base/codec.h"
 #include "modules/video_coding/include/video_codec_interface.h"
+#include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
 
@@ -26,13 +27,13 @@
 // |rtc_use_h264| build flag is true (if false, this function does nothing).
 // This function should only be called before or during WebRTC initialization
 // and is not thread-safe.
-void DisableRtcUseH264();
+RTC_EXPORT void DisableRtcUseH264();
 
 // Returns a vector with all supported internal H264 profiles that we can
 // negotiate in SDP, in order of preference.
 std::vector<SdpVideoFormat> SupportedH264Codecs();
 
-class H264Encoder : public VideoEncoder {
+class RTC_EXPORT H264Encoder : public VideoEncoder {
  public:
   static std::unique_ptr<H264Encoder> Create(const cricket::VideoCodec& codec);
   // If H.264 is supported (any implementation).
@@ -41,7 +42,7 @@
   ~H264Encoder() override {}
 };
 
-class H264Decoder : public VideoDecoder {
+class RTC_EXPORT H264Decoder : public VideoDecoder {
  public:
   static std::unique_ptr<H264Decoder> Create();
   static bool IsSupported();
diff --git a/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h b/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h
index 9878ac9..ae14f68 100644
--- a/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h
+++ b/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h
@@ -15,7 +15,7 @@
 
 #include <memory>
 
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 
 namespace webrtc {
 
@@ -29,10 +29,10 @@
 
   virtual bool CheckTemporalConfig(
       bool frame_is_keyframe,
-      const TemporalLayers::FrameConfig& frame_config);
+      const Vp8TemporalLayers::FrameConfig& frame_config);
 
   static std::unique_ptr<TemporalLayersChecker> CreateTemporalLayersChecker(
-      TemporalLayersType type,
+      Vp8TemporalLayersType type,
       int num_temporal_layers);
 
  private:
@@ -46,7 +46,7 @@
                                  bool* need_sync,
                                  bool frame_is_keyframe,
                                  uint8_t temporal_layer,
-                                 webrtc::TemporalLayers::BufferFlags flags,
+                                 webrtc::Vp8TemporalLayers::BufferFlags flags,
                                  uint32_t sequence_number,
                                  uint32_t* lowest_sequence_referenced);
   BufferState last_;
diff --git a/modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h b/modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h
deleted file mode 100644
index b5dbc4e..0000000
--- a/modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h
+++ /dev/null
@@ -1,198 +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_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
-#define MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
-
-#include <memory>
-#include <vector>
-
-namespace webrtc {
-
-// Some notes on the prerequisites of the TemporalLayers interface.
-// * Implementations of TemporalLayers may not contain internal synchronization
-//   so caller must make sure doing so thread safe.
-// * The encoder is assumed to encode all frames in order, and callbacks to
-//   PopulateCodecSpecific() / FrameEncoded() must happen in the same order.
-//
-// This means that in the case of pipelining encoders, it is OK to have a chain
-// of calls such as this:
-// - UpdateLayerConfig(timestampA)
-// - UpdateLayerConfig(timestampB)
-// - PopulateCodecSpecific(timestampA, ...)
-// - UpdateLayerConfig(timestampC)
-// - OnEncodeDone(timestampA, 1234, ...)
-// - UpdateLayerConfig(timestampC)
-// - OnEncodeDone(timestampB, 0, ...)
-// - OnEncodeDone(timestampC, 1234, ...)
-// Note that UpdateLayerConfig() for a new frame can happen before
-// FrameEncoded() for a previous one, but calls themselves must be both
-// synchronized (e.g. run on a task queue) and in order (per type).
-
-enum class TemporalLayersType { kFixedPattern, kBitrateDynamic };
-
-struct CodecSpecificInfoVP8;
-enum class Vp8BufferReference : uint8_t {
-  kNone = 0,
-  kLast = 1,
-  kGolden = 2,
-  kAltref = 4
-};
-
-struct Vp8EncoderConfig {
-  static constexpr size_t kMaxPeriodicity = 16;
-  static constexpr size_t kMaxLayers = 5;
-
-  // Number of active temporal layers. Set to 0 if not used.
-  uint32_t ts_number_layers;
-  // Arrays of length |ts_number_layers|, indicating (cumulative) target bitrate
-  // and rate decimator (e.g. 4 if every 4th frame is in the given layer) for
-  // each active temporal layer, starting with temporal id 0.
-  uint32_t ts_target_bitrate[kMaxLayers];
-  uint32_t ts_rate_decimator[kMaxLayers];
-
-  // The periodicity of the temporal pattern. Set to 0 if not used.
-  uint32_t ts_periodicity;
-  // Array of length |ts_periodicity| indicating the sequence of temporal id's
-  // to assign to incoming frames.
-  uint32_t ts_layer_id[kMaxPeriodicity];
-
-  // Target bitrate, in bps.
-  uint32_t rc_target_bitrate;
-
-  // Clamp QP to min/max. Use 0 to disable clamping.
-  uint32_t rc_min_quantizer;
-  uint32_t rc_max_quantizer;
-};
-
-// This interface defines a way of getting the encoder settings needed to
-// realize a temporal layer structure of predefined size.
-class TemporalLayers {
- public:
-  enum BufferFlags : int {
-    kNone = 0,
-    kReference = 1,
-    kUpdate = 2,
-    kReferenceAndUpdate = kReference | kUpdate,
-  };
-  enum FreezeEntropy { kFreezeEntropy };
-
-  struct FrameConfig {
-    FrameConfig();
-
-    FrameConfig(BufferFlags last, BufferFlags golden, BufferFlags arf);
-    FrameConfig(BufferFlags last,
-                BufferFlags golden,
-                BufferFlags arf,
-                FreezeEntropy);
-
-    bool drop_frame;
-    BufferFlags last_buffer_flags;
-    BufferFlags golden_buffer_flags;
-    BufferFlags arf_buffer_flags;
-
-    // The encoder layer ID is used to utilize the correct bitrate allocator
-    // inside the encoder. It does not control references nor determine which
-    // "actual" temporal layer this is. The packetizer temporal index determines
-    // which layer the encoded frame should be packetized into.
-    // Normally these are the same, but current temporal-layer strategies for
-    // screenshare use one bitrate allocator for all layers, but attempt to
-    // packetize / utilize references to split a stream into multiple layers,
-    // with different quantizer settings, to hit target bitrate.
-    // TODO(pbos): Screenshare layers are being reconsidered at the time of
-    // writing, we might be able to remove this distinction, and have a temporal
-    // layer imply both (the normal case).
-    int encoder_layer_id;
-    int packetizer_temporal_idx;
-
-    bool layer_sync;
-
-    bool freeze_entropy;
-
-    // Indicates in which order the encoder should search the reference buffers
-    // when doing motion prediction. Set to kNone to use unspecified order. Any
-    // buffer indicated here must not have the corresponding no_ref bit set.
-    // If all three buffers can be reference, the one not listed here should be
-    // searched last.
-    Vp8BufferReference first_reference;
-    Vp8BufferReference second_reference;
-
-    bool operator==(const FrameConfig& o) const;
-    bool operator!=(const FrameConfig& o) const { return !(*this == o); }
-
-   private:
-    FrameConfig(BufferFlags last,
-                BufferFlags golden,
-                BufferFlags arf,
-                bool freeze_entropy);
-  };
-
-  // Factory for TemporalLayer strategy. Default behavior is a fixed pattern
-  // of temporal layers. See default_temporal_layers.cc
-  static std::unique_ptr<TemporalLayers> CreateTemporalLayers(
-      TemporalLayersType type,
-      int num_temporal_layers);
-
-  virtual ~TemporalLayers() = default;
-
-  // If this method returns true, the encoder is free to drop frames for
-  // instance in an effort to uphold encoding bitrate.
-  // If this return false, the encoder must not drop any frames unless:
-  //  1. Requested to do so via FrameConfig.drop_frame
-  //  2. The frame to be encoded is requested to be a keyframe
-  //  3. The encoded detected a large overshoot and decided to drop and then
-  //     re-encode the image at a low bitrate. In this case the encoder should
-  //     call OnEncodeDone() once with size = 0 to indicate drop, and then call
-  //     OnEncodeDone() again when the frame has actually been encoded.
-  virtual bool SupportsEncoderFrameDropping() const = 0;
-
-  // New target bitrate, per temporal layer.
-  virtual void OnRatesUpdated(const std::vector<uint32_t>& bitrates_bps,
-                              int framerate_fps) = 0;
-
-  // Called by the encoder before encoding a frame. |cfg| contains the current
-  // configuration. If the TemporalLayers instance wishes any part of that
-  // to be changed before the encode step, |cfg| should be changed and then
-  // return true. If false is returned, the encoder will proceed without
-  // updating the configuration.
-  virtual bool UpdateConfiguration(Vp8EncoderConfig* cfg) = 0;
-
-  // Returns the recommended VP8 encode flags needed, and moves the temporal
-  // pattern to the next frame.
-  // The timestamp may be used as both a time and a unique identifier, and so
-  // the caller must make sure no two frames use the same timestamp.
-  // The timestamp uses a 90kHz RTP clock.
-  // After calling this method, first call the actual encoder with the provided
-  // frame configuration, and then OnEncodeDone() below.
-  virtual FrameConfig UpdateLayerConfig(uint32_t rtp_timestamp) = 0;
-
-  // Called after the encode step is done. |rtp_timestamp| must match the
-  // parameter use in the UpdateLayerConfig() call.
-  // |is_keyframe| must be true iff the encoder decided to encode this frame as
-  // a keyframe.
-  // If the encoder decided to drop this frame, |size_bytes| must be set to 0,
-  // otherwise it should indicate the size in bytes of the encoded frame.
-  // If |size_bytes| > 0, and |vp8_info| is not null, the TemporalLayers
-  // instance my update |vp8_info| with codec specific data such as temporal id.
-  // Some fields of this struct may have already been populated by the encoder,
-  // check before overwriting.
-  // If |size_bytes| > 0, |qp| should indicate the frame-level QP this frame was
-  // encoded at. If the encoder does not support extracting this, |qp| should be
-  // set to 0.
-  virtual void OnEncodeDone(uint32_t rtp_timestamp,
-                            size_t size_bytes,
-                            bool is_keyframe,
-                            int qp,
-                            CodecSpecificInfoVP8* vp8_info) = 0;
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index f7f5bb8..f970278 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -68,7 +68,7 @@
 }
 
 # The subset of rtc_base approved for use outside of libjingle.
-# TODO(bugs.webrtc.org/9838): Create small and focues build targets and remove
+# TODO(bugs.webrtc.org/9838): Create small and focused build targets and remove
 # the old concept of rtc_base and rtc_base_approved.
 rtc_source_set("rtc_base_approved") {
   visibility = [ "*" ]
@@ -76,9 +76,12 @@
     ":checks",
     ":rtc_task_queue",
     ":safe_compare",
+    ":safe_minmax",
     ":type_traits",
     "..:webrtc_common",
     "../api:array_view",
+    "../system_wrappers:field_trial",
+    "experiments:field_trial_parser",
     "system:arch",
     "system:unused",
     "third_party/base64",
@@ -118,8 +121,6 @@
     "numerics/sample_counter.cc",
     "numerics/sample_counter.h",
     "onetimeevent.h",
-    "pathutils.cc",
-    "pathutils.h",
     "platform_file.cc",
     "platform_file.h",
     "race_checker.cc",
@@ -260,7 +261,6 @@
 rtc_source_set("rtc_event") {
   deps = [
     ":checks",
-    ":macromagic",
   ]
 
   if (build_with_chromium) {
@@ -282,6 +282,7 @@
   visibility = [ "*" ]
   libs = []
   deps = [
+    ":checks",
     ":criticalsection",
     ":macromagic",
     ":platform_thread_types",
@@ -367,6 +368,7 @@
   deps = [
     ":rtc_base_approved",
     "../system_wrappers",
+    "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
 
@@ -651,6 +653,8 @@
   sources = [
     "numerics/exp_filter.cc",
     "numerics/exp_filter.h",
+    "numerics/moving_average.cc",
+    "numerics/moving_average.h",
     "numerics/moving_median_filter.h",
     "numerics/percentile_filter.h",
     "numerics/sequence_number_util.h",
@@ -688,48 +692,23 @@
 
 rtc_static_library("rtc_base") {
   visibility = [ "*" ]
-  public_deps = []
-  if (!build_with_mozilla) {
-    public_deps += [ ":rtc_base_generic" ]
-  }
-  if (is_win) {
-    sources = [
-      "noop.cc",
-    ]
-  }
-  if (is_ios || is_mac) {
-    sources = [
-      "noop.mm",
-    ]
-    public_deps += [ ":rtc_base_objc" ]
-  }
-}
-
-if (is_ios || is_mac) {
-  rtc_source_set("rtc_base_objc") {
-    sources = [
-      "thread_darwin.mm",
-    ]
-    deps = [
-      ":rtc_base_generic",
-    ]
-    visibility = [ ":rtc_base" ]
-  }
-}
-
-rtc_static_library("rtc_base_generic") {
   cflags = []
   cflags_cc = []
   libs = []
   defines = []
   deps = [
     ":checks",
+
+    # For deprecation of rtc::PacketTime, in asyncpacketsocket.h.
+    ":deprecation",
     ":stringutils",
     "..:webrtc_common",
     "../api:array_view",
+    "network:sent_packet",
     "third_party/base64",
     "third_party/sigslot",
     "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
   public_deps = [
@@ -762,8 +741,6 @@
     "dscp.h",
     "filerotatingstream.cc",
     "filerotatingstream.h",
-    "fileutils.cc",
-    "fileutils.h",
     "gunit_prod.h",
     "helpers.cc",
     "helpers.h",
@@ -772,6 +749,8 @@
     "ipaddress.cc",
     "ipaddress.h",
     "keep_ref_until_done.h",
+    "key_derivation.cc",
+    "key_derivation.h",
     "mdns_responder_interface.h",
     "messagedigest.cc",
     "messagedigest.h",
@@ -792,6 +771,8 @@
     "nullsocketserver.cc",
     "nullsocketserver.h",
     "openssl.h",
+    "openssl_key_derivation_hkdf.cc",
+    "openssl_key_derivation_hkdf.h",
     "openssladapter.cc",
     "openssladapter.h",
     "opensslcertificate.cc",
@@ -827,8 +808,6 @@
     "socketaddresspair.h",
     "socketfactory.h",
     "socketserver.h",
-    "socketstream.cc",
-    "socketstream.h",
     "ssladapter.cc",
     "ssladapter.h",
     "sslcertificate.cc",
@@ -845,11 +824,6 @@
     "thread.h",
   ]
 
-  visibility = [
-    ":rtc_base",
-    ":rtc_base_objc",
-  ]
-
   if (build_with_chromium) {
     include_dirs = [ "../../boringssl/src/include" ]
     public_configs += [ ":rtc_base_chromium_config" ]
@@ -859,8 +833,6 @@
       "logsinks.cc",
       "logsinks.h",
       "numerics/mathutils.h",
-      "optionsfile.cc",
-      "optionsfile.h",
       "rollingaccumulator.h",
       "sslroots.h",
     ]
@@ -894,6 +866,7 @@
 
   if (is_ios || is_mac) {
     sources += [ "macifaddrs_converter.cc" ]
+    deps += [ "system:cocoa_threading" ]
   }
 
   if (rtc_use_x11) {
@@ -919,18 +892,12 @@
       "macutils.cc",
       "macutils.h",
     ]
-    libs += [
-      # For ProcessInformationCopyDictionary in unixfilesystem.cc.
-      "ApplicationServices.framework",
-    ]
   }
 
   if (is_win) {
     sources += [
       "win32.cc",
       "win32.h",
-      "win32filesystem.cc",
-      "win32filesystem.h",
       "win32window.cc",
       "win32window.h",
     ]
@@ -948,8 +915,6 @@
     sources += [
       "ifaddrs_converter.cc",
       "ifaddrs_converter.h",
-      "unixfilesystem.cc",
-      "unixfilesystem.h",
     ]
   }
 
@@ -984,6 +949,8 @@
     "firewallsocketserver.h",
     "gunit.cc",
     "gunit.h",
+    "memory_stream.cc",
+    "memory_stream.h",
     "memory_usage.cc",
     "memory_usage.h",
     "natserver.cc",
@@ -996,6 +963,8 @@
     "proxyserver.h",
     "sigslottester.h",
     "sigslottester.h.pump",
+    "socketstream.cc",
+    "socketstream.h",
     "testbase64.h",
     "testcertificateverifier.h",
     "testclient.cc",
@@ -1127,7 +1096,6 @@
       "numerics/safe_minmax_unittest.cc",
       "numerics/sample_counter_unittest.cc",
       "onetimeevent_unittest.cc",
-      "pathutils_unittest.cc",
       "platform_file_unittest.cc",
       "platform_thread_unittest.cc",
       "random_unittest.cc",
@@ -1231,6 +1199,7 @@
 
     sources = [
       "numerics/exp_filter_unittest.cc",
+      "numerics/moving_average_unittest.cc",
       "numerics/moving_median_filter_unittest.cc",
       "numerics/percentile_filter_unittest.cc",
       "numerics/sequence_number_util_unittest.cc",
@@ -1272,7 +1241,6 @@
       "messagequeue_unittest.cc",
       "nat_unittest.cc",
       "network_unittest.cc",
-      "optionsfile_unittest.cc",
       "proxy_unittest.cc",
       "rollingaccumulator_unittest.cc",
       "rtccertificate_unittest.cc",
@@ -1291,6 +1259,7 @@
     }
     if (is_posix || is_fuchsia) {
       sources += [
+        "openssl_key_derivation_hkdf_unittest.cc",
         "openssladapter_unittest.cc",
         "opensslsessioncache_unittest.cc",
         "opensslutility_unittest.cc",
diff --git a/rtc_base/Dummy.java b/rtc_base/Dummy.java
deleted file mode 100644
index d8f02c9..0000000
--- a/rtc_base/Dummy.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  Copyright 2017 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.
- */
-
-/**
- * This class only exists as glue in a transition.
- * TODO(kjellander): Remove.
- * See https://bugs.webrtc.org/7634 for more details.
- */
-class Dummy {
-  Dummy() {
-  }
-}
diff --git a/rtc_base/OWNERS b/rtc_base/OWNERS
index 69ce253..e67e834 100644
--- a/rtc_base/OWNERS
+++ b/rtc_base/OWNERS
@@ -2,7 +2,6 @@
 juberti@webrtc.org
 kwiberg@webrtc.org
 mflodman@webrtc.org
-perkj@webrtc.org
 pthatcher@webrtc.org
 qingsi@webrtc.org
 sergeyu@chromium.org
diff --git a/rtc_base/asyncinvoker.cc b/rtc_base/asyncinvoker.cc
index e255fb9..f0dd188 100644
--- a/rtc_base/asyncinvoker.cc
+++ b/rtc_base/asyncinvoker.cc
@@ -17,7 +17,7 @@
 
 AsyncInvoker::AsyncInvoker()
     : pending_invocations_(0),
-      invocation_complete_(new RefCountedObject<Event>(false, false)),
+      invocation_complete_(new RefCountedObject<Event>()),
       destroying_(false) {}
 
 AsyncInvoker::~AsyncInvoker() {
diff --git a/rtc_base/asyncpacketsocket.cc b/rtc_base/asyncpacketsocket.cc
index e1b1eae..7e0cc8f 100644
--- a/rtc_base/asyncpacketsocket.cc
+++ b/rtc_base/asyncpacketsocket.cc
@@ -9,6 +9,7 @@
  */
 
 #include "rtc_base/asyncpacketsocket.h"
+#include "rtc_base/nethelper.h"
 
 namespace rtc {
 
@@ -33,9 +34,11 @@
                                        bool is_connectionless,
                                        rtc::PacketInfo* info) {
   info->packet_size_bytes = packet_size_bytes;
-  info->local_socket_address = socket_from.GetLocalAddress();
-  if (!is_connectionless) {
-    info->remote_socket_address = socket_from.GetRemoteAddress();
+  // TODO(srte): Make sure that the family of the local socket is always set
+  // in the VirtualSocket implementation and remove this check.
+  int family = socket_from.GetLocalAddress().family();
+  if (family != 0) {
+    info->ip_overhead_bytes = cricket::GetIpOverhead(family);
   }
 }
 
diff --git a/rtc_base/asyncpacketsocket.h b/rtc_base/asyncpacketsocket.h
index bb0b3bc..44d6c67 100644
--- a/rtc_base/asyncpacketsocket.h
+++ b/rtc_base/asyncpacketsocket.h
@@ -12,6 +12,7 @@
 #define RTC_BASE_ASYNCPACKETSOCKET_H_
 
 #include "rtc_base/constructormagic.h"
+#include "rtc_base/deprecation.h"
 #include "rtc_base/dscp.h"
 #include "rtc_base/socket.h"
 #include "rtc_base/third_party/sigslot/sigslot.h"
@@ -50,25 +51,9 @@
   PacketInfo info_signaled_after_sent;
 };
 
-// This structure will have the information about when packet is actually
-// received by socket.
-struct PacketTime {
-  PacketTime() : timestamp(-1), not_before(-1) {}
-  PacketTime(int64_t timestamp, int64_t not_before)
-      : timestamp(timestamp), not_before(not_before) {}
-
-  int64_t timestamp;  // Receive time after socket delivers the data.
-
-  // Earliest possible time the data could have arrived, indicating the
-  // potential error in the |timestamp| value, in case the system, is busy. For
-  // example, the time of the last select() call.
-  // If unknown, this value will be set to zero.
-  int64_t not_before;
-};
-
-inline PacketTime CreatePacketTime(int64_t not_before) {
-  return PacketTime(TimeMicros(), not_before);
-}
+// TODO(bugs.webrtc.org/9584): Compatibility alias, delete as soon as downstream
+// code is updated.
+typedef int64_t PacketTime;
 
 // Provides the ability to receive packets asynchronously. Sends are not
 // buffered since it is acceptable to drop packets under high load.
@@ -120,7 +105,9 @@
                    const char*,
                    size_t,
                    const SocketAddress&,
-                   const PacketTime&>
+                   // TODO(bugs.webrtc.org/9584): Change to passing the int64_t
+                   // timestamp by value.
+                   const int64_t&>
       SignalReadPacket;
 
   // Emitted each time a packet is sent.
diff --git a/rtc_base/asyncresolverinterface.h b/rtc_base/asyncresolverinterface.h
index 5b2303f..f3df884 100644
--- a/rtc_base/asyncresolverinterface.h
+++ b/rtc_base/asyncresolverinterface.h
@@ -22,9 +22,12 @@
   AsyncResolverInterface();
   virtual ~AsyncResolverInterface();
 
-  // Start address resolve process.
+  // Start address resolution of the hostname in |addr|.
   virtual void Start(const SocketAddress& addr) = 0;
-  // Returns top most resolved address of |family|
+  // Returns true iff the address from |Start| was successfully resolved.
+  // If the address was successfully resolved, sets |addr| to a copy of the
+  // address from |Start| with the IP address set to the top most resolved
+  // address of |family| (|addr| will have both hostname and the resolved ip).
   virtual bool GetResolvedAddress(int family, SocketAddress* addr) const = 0;
   // Returns error from resolver.
   virtual int GetError() const = 0;
diff --git a/rtc_base/asynctcpsocket.cc b/rtc_base/asynctcpsocket.cc
index 087a98e..666b335 100644
--- a/rtc_base/asynctcpsocket.cc
+++ b/rtc_base/asynctcpsocket.cc
@@ -321,7 +321,7 @@
       return;
 
     SignalReadPacket(this, data + kPacketLenSize, pkt_len, remote_addr,
-                     CreatePacketTime(0));
+                     TimeMicros());
 
     *len -= kPacketLenSize + pkt_len;
     if (*len > 0) {
diff --git a/rtc_base/asynctcpsocket.h b/rtc_base/asynctcpsocket.h
index c145d6f..9567dd9 100644
--- a/rtc_base/asynctcpsocket.h
+++ b/rtc_base/asynctcpsocket.h
@@ -11,14 +11,15 @@
 #ifndef RTC_BASE_ASYNCTCPSOCKET_H_
 #define RTC_BASE_ASYNCTCPSOCKET_H_
 
+#include <stddef.h>
 #include <memory>
 
-#include "rtc_base/asyncpacketsocket.h"  // for PacketOptions, AsyncPacketSo...
-#include "rtc_base/asyncsocket.h"        // for AsyncSocket
-#include "rtc_base/buffer.h"             // for Buffer
-#include "rtc_base/constructormagic.h"   // for RTC_DISALLOW_COPY_AND_ASSIGN
-#include "rtc_base/socket.h"             // for Socket, Socket::Option
-#include "rtc_base/socketaddress.h"      // for SocketAddress
+#include "rtc_base/asyncpacketsocket.h"
+#include "rtc_base/asyncsocket.h"
+#include "rtc_base/buffer.h"
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/socket.h"
+#include "rtc_base/socketaddress.h"
 
 namespace rtc {
 
diff --git a/rtc_base/asyncudpsocket.cc b/rtc_base/asyncudpsocket.cc
index ba5fa88..2f9011c 100644
--- a/rtc_base/asyncudpsocket.cc
+++ b/rtc_base/asyncudpsocket.cc
@@ -74,7 +74,6 @@
   rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis(),
                               options.info_signaled_after_sent);
   CopySocketInformationToPacketInfo(cb, *this, true, &sent_packet.info);
-  sent_packet.info.remote_socket_address = addr;
   int ret = socket_->SendTo(pv, cb, addr);
   SignalSentPacket(this, sent_packet);
   return ret;
@@ -123,9 +122,8 @@
 
   // TODO: Make sure that we got all of the packet.
   // If we did not, then we should resize our buffer to be large enough.
-  SignalReadPacket(
-      this, buf_, static_cast<size_t>(len), remote_addr,
-      (timestamp > -1 ? PacketTime(timestamp, 0) : CreatePacketTime(0)));
+  SignalReadPacket(this, buf_, static_cast<size_t>(len), remote_addr,
+                   (timestamp > -1 ? timestamp : TimeMicros()));
 }
 
 void AsyncUDPSocket::OnWriteEvent(AsyncSocket* socket) {
diff --git a/rtc_base/asyncudpsocket.h b/rtc_base/asyncudpsocket.h
index d814b4b..030946d 100644
--- a/rtc_base/asyncudpsocket.h
+++ b/rtc_base/asyncudpsocket.h
@@ -11,9 +11,13 @@
 #ifndef RTC_BASE_ASYNCUDPSOCKET_H_
 #define RTC_BASE_ASYNCUDPSOCKET_H_
 
+#include <stddef.h>
 #include <memory>
 
 #include "rtc_base/asyncpacketsocket.h"
+#include "rtc_base/asyncsocket.h"
+#include "rtc_base/socket.h"
+#include "rtc_base/socketaddress.h"
 #include "rtc_base/socketfactory.h"
 
 namespace rtc {
diff --git a/rtc_base/base64_unittest.cc b/rtc_base/base64_unittest.cc
index 4b857f1..bdf8559 100644
--- a/rtc_base/base64_unittest.cc
+++ b/rtc_base/base64_unittest.cc
@@ -11,7 +11,6 @@
 #include "rtc_base/third_party/base64/base64.h"
 #include "rtc_base/gunit.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/stringutils.h"
 
 #include "rtc_base/testbase64.h"
 
@@ -430,10 +429,10 @@
 
       // try putting some extra stuff after the equals signs, or in between them
       if (equals == 2) {
-        sprintfn(first_equals, 6, " = = ");
+        snprintf(first_equals, 6, " = = ");
         len = first_equals - encode_buffer + 5;
       } else {
-        sprintfn(first_equals, 6, " = ");
+        snprintf(first_equals, 6, " = ");
         len = first_equals - encode_buffer + 3;
       }
       decoded2.assign("this junk should be ignored");
diff --git a/rtc_base/bitrateallocationstrategy.cc b/rtc_base/bitrateallocationstrategy.cc
index 7c65c12..46e6674 100644
--- a/rtc_base/bitrateallocationstrategy.cc
+++ b/rtc_base/bitrateallocationstrategy.cc
@@ -9,10 +9,31 @@
  */
 
 #include "rtc_base/bitrateallocationstrategy.h"
+
 #include <algorithm>
+#include <cstddef>
+#include <cstdint>
 #include <map>
 #include <utility>
 
+#include "rtc_base/numerics/safe_minmax.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+AudioPriorityConfig::AudioPriorityConfig()
+    : min_rate("min"), max_rate("max"), target_rate("target") {
+  std::string trial_string;
+// TODO(bugs.webrtc.org/9889): Remove this when Chromium build has been fixed.
+#if !defined(WEBRTC_CHROMIUM_BUILD)
+  trial_string = field_trial::FindFullName("WebRTC-Bwe-AudioPriority");
+#endif
+  ParseFieldTrial({&min_rate, &max_rate, &target_rate}, trial_string);
+}
+AudioPriorityConfig::AudioPriorityConfig(const AudioPriorityConfig&) = default;
+AudioPriorityConfig::~AudioPriorityConfig() = default;
+
+}  // namespace webrtc
+
 namespace rtc {
 
 // The purpose of this is to allow video streams to use extra bandwidth for FEC.
@@ -22,31 +43,31 @@
 const int kTransmissionMaxBitrateMultiplier = 2;
 
 std::vector<uint32_t> BitrateAllocationStrategy::SetAllBitratesToMinimum(
-    const ArrayView<const TrackConfig*> track_configs) {
+    const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs) {
   std::vector<uint32_t> track_allocations;
-  for (const auto* track_config : track_configs) {
-    track_allocations.push_back(track_config->min_bitrate_bps);
+  for (const auto& track_config : track_configs) {
+    track_allocations.push_back(track_config.min_bitrate_bps);
   }
   return track_allocations;
 }
 
 std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly(
-    const ArrayView<const TrackConfig*> track_configs,
+    const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs,
     uint32_t available_bitrate) {
   std::vector<uint32_t> track_allocations =
       SetAllBitratesToMinimum(track_configs);
   uint32_t sum_min_bitrates = 0;
   uint32_t sum_max_bitrates = 0;
-  for (const auto* track_config : track_configs) {
-    sum_min_bitrates += track_config->min_bitrate_bps;
-    sum_max_bitrates += track_config->max_bitrate_bps;
+  for (const auto& track_config : track_configs) {
+    sum_min_bitrates += track_config.min_bitrate_bps;
+    sum_max_bitrates += track_config.max_bitrate_bps;
   }
   if (sum_min_bitrates >= available_bitrate) {
     return track_allocations;
   } else if (available_bitrate >= sum_max_bitrates) {
     auto track_allocations_it = track_allocations.begin();
-    for (const auto* track_config : track_configs) {
-      *track_allocations_it++ = track_config->max_bitrate_bps;
+    for (const auto& track_config : track_configs) {
+      *track_allocations_it++ = track_config.max_bitrate_bps;
     }
     return track_allocations;
   } else {
@@ -55,11 +76,10 @@
     // lowest max_bitrate_bps. Remainder of available bitrate split evenly among
     // remaining tracks.
     std::multimap<uint32_t, size_t> max_bitrate_sorted_configs;
-    for (const TrackConfig** track_configs_it = track_configs.begin();
-         track_configs_it != track_configs.end(); ++track_configs_it) {
+    for (const auto& track_config : track_configs) {
       max_bitrate_sorted_configs.insert(
-          std::make_pair((*track_configs_it)->max_bitrate_bps,
-                         track_configs_it - track_configs.begin()));
+          std::make_pair(track_config.max_bitrate_bps,
+                         &track_config - &track_configs.front()));
     }
     uint32_t total_available_increase = available_bitrate - sum_min_bitrates;
     int processed_configs = 0;
@@ -68,8 +88,8 @@
           total_available_increase /
           (static_cast<uint32_t>(track_configs.size() - processed_configs));
       uint32_t consumed_increase =
-          std::min(track_configs[track_config_pair.second]->max_bitrate_bps -
-                       track_configs[track_config_pair.second]->min_bitrate_bps,
+          std::min(track_configs[track_config_pair.second].max_bitrate_bps -
+                       track_configs[track_config_pair.second].min_bitrate_bps,
                    available_increase);
       track_allocations[track_config_pair.second] += consumed_increase;
       total_available_increase -= consumed_increase;
@@ -78,53 +98,50 @@
     return track_allocations;
   }
 }
-
 AudioPriorityBitrateAllocationStrategy::AudioPriorityBitrateAllocationStrategy(
     std::string audio_track_id,
     uint32_t sufficient_audio_bitrate)
     : audio_track_id_(audio_track_id),
-      sufficient_audio_bitrate_(sufficient_audio_bitrate) {}
+      sufficient_audio_bitrate_(sufficient_audio_bitrate) {
+  if (config_.target_rate) {
+    sufficient_audio_bitrate_ = config_.target_rate->bps();
+  }
+}
 
 std::vector<uint32_t> AudioPriorityBitrateAllocationStrategy::AllocateBitrates(
     uint32_t available_bitrate,
-    const ArrayView<const TrackConfig*> track_configs) {
-  const TrackConfig* audio_track_config = NULL;
+    std::vector<BitrateAllocationStrategy::TrackConfig> track_configs) {
+  TrackConfig* audio_track_config = nullptr;
   size_t audio_config_index = 0;
   uint32_t sum_min_bitrates = 0;
   uint32_t sum_max_bitrates = 0;
 
-  for (const auto*& track_config : track_configs) {
-    sum_min_bitrates += track_config->min_bitrate_bps;
-    sum_max_bitrates += track_config->max_bitrate_bps;
-    if (track_config->track_id == audio_track_id_) {
-      audio_track_config = track_config;
+  for (auto& track_config : track_configs) {
+    if (track_config.track_id == audio_track_id_) {
       audio_config_index = &track_config - &track_configs[0];
+      audio_track_config = &track_config;
+      if (config_.min_rate)
+        audio_track_config->min_bitrate_bps = config_.min_rate->bps();
+      if (config_.max_rate)
+        audio_track_config->max_bitrate_bps = config_.max_rate->bps();
     }
+    sum_min_bitrates += track_config.min_bitrate_bps;
+    sum_max_bitrates += track_config.max_bitrate_bps;
   }
   if (sum_max_bitrates < available_bitrate) {
     // Allow non audio streams to go above max upto
     // kTransmissionMaxBitrateMultiplier * max_bitrate_bps
-    size_t track_configs_size = track_configs.size();
-    std::vector<TrackConfig> increased_track_configs(track_configs_size);
-    std::vector<const TrackConfig*> increased_track_configs_ptr(
-        track_configs_size);
-    for (unsigned long i = 0; i < track_configs_size; i++) {
-      increased_track_configs[i] = (*track_configs[i]);
-      increased_track_configs_ptr[i] = &increased_track_configs[i];
-      if (track_configs[i]->track_id != audio_track_id_) {
-        increased_track_configs[i].max_bitrate_bps =
-            track_configs[i]->max_bitrate_bps *
-            kTransmissionMaxBitrateMultiplier;
-      }
+    for (auto& track_config : track_configs) {
+      if (&track_config != audio_track_config)
+        track_config.max_bitrate_bps *= kTransmissionMaxBitrateMultiplier;
     }
-    return DistributeBitratesEvenly(increased_track_configs_ptr,
-                                    available_bitrate);
-  }
-  if (audio_track_config == nullptr) {
     return DistributeBitratesEvenly(track_configs, available_bitrate);
   }
-  auto safe_sufficient_audio_bitrate = std::min(
-      std::max(audio_track_config->min_bitrate_bps, sufficient_audio_bitrate_),
+  if (!audio_track_config) {
+    return DistributeBitratesEvenly(track_configs, available_bitrate);
+  }
+  auto safe_sufficient_audio_bitrate = rtc::SafeClamp(
+      sufficient_audio_bitrate_, audio_track_config->min_bitrate_bps,
       audio_track_config->max_bitrate_bps);
   if (available_bitrate <= sum_min_bitrates) {
     return SetAllBitratesToMinimum(track_configs);
@@ -140,9 +157,7 @@
       // Setting audio track minimum to safe_sufficient_audio_bitrate will
       // allow using DistributeBitratesEvenly to allocate at least sufficient
       // bitrate for audio and the rest evenly.
-      TrackConfig sufficient_track_config(*track_configs[audio_config_index]);
-      sufficient_track_config.min_bitrate_bps = safe_sufficient_audio_bitrate;
-      track_configs[audio_config_index] = &sufficient_track_config;
+      audio_track_config->min_bitrate_bps = safe_sufficient_audio_bitrate;
       std::vector<uint32_t> track_allocations =
           DistributeBitratesEvenly(track_configs, available_bitrate);
       return track_allocations;
diff --git a/rtc_base/bitrateallocationstrategy.h b/rtc_base/bitrateallocationstrategy.h
index a4a17f8..13a4eee 100644
--- a/rtc_base/bitrateallocationstrategy.h
+++ b/rtc_base/bitrateallocationstrategy.h
@@ -11,9 +11,13 @@
 #ifndef RTC_BASE_BITRATEALLOCATIONSTRATEGY_H_
 #define RTC_BASE_BITRATEALLOCATIONSTRATEGY_H_
 
+#include <stdint.h>
 #include <string>
 #include <vector>
+
 #include "api/array_view.h"
+#include "rtc_base/experiments/field_trial_parser.h"
+#include "rtc_base/experiments/field_trial_units.h"
 
 namespace rtc {
 
@@ -53,10 +57,12 @@
     std::string track_id;
   };
 
+  // These are only used by AudioPriorityBitrateAllocationStrategy. They are
+  // exposed here to they can be unit tested.
   static std::vector<uint32_t> SetAllBitratesToMinimum(
-      const ArrayView<const TrackConfig*> track_configs);
+      const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs);
   static std::vector<uint32_t> DistributeBitratesEvenly(
-      const ArrayView<const TrackConfig*> track_configs,
+      const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs,
       uint32_t available_bitrate);
 
   // Strategy is expected to allocate all available_bitrate up to the sum of
@@ -71,11 +77,25 @@
   // available_bitrate decrease.
   virtual std::vector<uint32_t> AllocateBitrates(
       uint32_t available_bitrate,
-      const ArrayView<const TrackConfig*> track_configs) = 0;
+      std::vector<BitrateAllocationStrategy::TrackConfig> track_configs) = 0;
 
   virtual ~BitrateAllocationStrategy() = default;
 };
+}  // namespace rtc
 
+namespace webrtc {
+struct AudioPriorityConfig {
+  FieldTrialOptional<DataRate> min_rate;
+  FieldTrialOptional<DataRate> max_rate;
+  FieldTrialOptional<DataRate> target_rate;
+  AudioPriorityConfig();
+  AudioPriorityConfig(const AudioPriorityConfig&);
+  AudioPriorityConfig& operator=(const AudioPriorityConfig&) = default;
+  ~AudioPriorityConfig();
+};
+}  // namespace webrtc
+
+namespace rtc {
 // Simple allocation strategy giving priority to audio until
 // sufficient_audio_bitrate is reached. Bitrate is distributed evenly between
 // the tracks after sufficient_audio_bitrate is reached. This implementation
@@ -87,9 +107,11 @@
                                          uint32_t sufficient_audio_bitrate);
   std::vector<uint32_t> AllocateBitrates(
       uint32_t available_bitrate,
-      const ArrayView<const TrackConfig*> track_configs) override;
+      std::vector<BitrateAllocationStrategy::TrackConfig> track_configs)
+      override;
 
  private:
+  webrtc::AudioPriorityConfig config_;
   std::string audio_track_id_;
   uint32_t sufficient_audio_bitrate_;
 };
diff --git a/rtc_base/bitrateallocationstrategy_unittest.cc b/rtc_base/bitrateallocationstrategy_unittest.cc
index bfc41f5..f4c7ee7 100644
--- a/rtc_base/bitrateallocationstrategy_unittest.cc
+++ b/rtc_base/bitrateallocationstrategy_unittest.cc
@@ -43,11 +43,8 @@
       BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
                                              max_other_bitrate, false, "")};
 
-  std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
-      track_config_ptrs = MakeTrackConfigPtrsVector(track_configs);
-
   std::vector<uint32_t> allocations =
-      BitrateAllocationStrategy::SetAllBitratesToMinimum(track_config_ptrs);
+      BitrateAllocationStrategy::SetAllBitratesToMinimum(track_configs);
   EXPECT_EQ(min_audio_bitrate, allocations[0]);
   EXPECT_EQ(min_video_bitrate, allocations[1]);
   EXPECT_EQ(min_other_bitrate, allocations[2]);
@@ -76,11 +73,8 @@
       BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
                                              max_other_bitrate, false, "")};
 
-  std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
-      track_config_ptrs = MakeTrackConfigPtrsVector(track_configs);
-
   std::vector<uint32_t> allocations =
-      BitrateAllocationStrategy::DistributeBitratesEvenly(track_config_ptrs,
+      BitrateAllocationStrategy::DistributeBitratesEvenly(track_configs,
                                                           available_bitrate);
   EXPECT_EQ(min_audio_bitrate + even_bitrate_increase, allocations[0]);
   EXPECT_EQ(min_video_bitrate + even_bitrate_increase, allocations[1]);
@@ -108,11 +102,7 @@
       BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
                                              max_other_bitrate, false, "")};
 
-  std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
-      track_config_ptrs = MakeTrackConfigPtrsVector(track_configs);
-
-  return allocation_strategy.AllocateBitrates(available_bitrate,
-                                              track_config_ptrs);
+  return allocation_strategy.AllocateBitrates(available_bitrate, track_configs);
 }
 
 // Test that when the available bitrate is less than the sum of the minimum
diff --git a/rtc_base/buffer.h b/rtc_base/buffer.h
index 9bf96cd..f9291b9 100644
--- a/rtc_base/buffer.h
+++ b/rtc_base/buffer.h
@@ -150,9 +150,12 @@
 
   BufferT& operator=(BufferT&& buf) {
     RTC_DCHECK(buf.IsConsistent());
+    MaybeZeroCompleteBuffer();
     size_ = buf.size_;
     capacity_ = buf.capacity_;
-    data_ = std::move(buf.data_);
+    using std::swap;
+    swap(data_, buf.data_);
+    buf.data_.reset();
     buf.OnMovedFrom();
     return *this;
   }
@@ -373,10 +376,10 @@
 
   // Zero the complete buffer if template argument "ZeroOnFree" is true.
   void MaybeZeroCompleteBuffer() {
-    if (ZeroOnFree && capacity_) {
+    if (ZeroOnFree && capacity_ > 0) {
       // It would be sufficient to only zero "size_" elements, as all other
       // methods already ensure that the unused capacity contains no sensitive
-      // data - but better safe than sorry.
+      // data---but better safe than sorry.
       ExplicitZeroMemory(data_.get(), capacity_ * sizeof(T));
     }
   }
@@ -399,6 +402,7 @@
   // Called when *this has been moved from. Conceptually it's a no-op, but we
   // can mutate the state slightly to help subsequent sanity checks catch bugs.
   void OnMovedFrom() {
+    RTC_DCHECK(!data_);  // Our heap block should have been stolen.
 #if RTC_DCHECK_IS_ON
     // Ensure that *this is always inconsistent, to provoke bugs.
     size_ = 1;
diff --git a/rtc_base/buffer_unittest.cc b/rtc_base/buffer_unittest.cc
index 1c3abfd..b2f47c1 100644
--- a/rtc_base/buffer_unittest.cc
+++ b/rtc_base/buffer_unittest.cc
@@ -185,6 +185,17 @@
   EXPECT_TRUE(buf1.empty());
 }
 
+TEST(BufferTest, TestMoveAssignSelf) {
+  // Move self-assignment isn't required to produce a meaningful state, but
+  // should not leave the object in an inconsistent state. (Such inconsistent
+  // state could be caught by the DCHECKs and/or by the leak checker.) We need
+  // to be sneaky when testing this; if we're doing a too-obvious
+  // move-assign-to-self, clang's -Wself-move triggers at compile time.
+  Buffer buf(kTestData, 3, 40);
+  Buffer* buf_ptr = &buf;
+  buf = std::move(*buf_ptr);
+}
+
 TEST(BufferTest, TestSwap) {
   Buffer buf1(kTestData, 3);
   Buffer buf2(kTestData, 6, 40);
diff --git a/rtc_base/bufferqueue.cc b/rtc_base/bufferqueue.cc
index 48ff2e6..74f7a50 100644
--- a/rtc_base/bufferqueue.cc
+++ b/rtc_base/bufferqueue.cc
@@ -10,6 +10,8 @@
 
 #include "rtc_base/bufferqueue.h"
 
+#include <stdint.h>
+#include <string.h>
 #include <algorithm>
 
 namespace rtc {
diff --git a/rtc_base/bufferqueue.h b/rtc_base/bufferqueue.h
index 94ab0ca..63f5182 100644
--- a/rtc_base/bufferqueue.h
+++ b/rtc_base/bufferqueue.h
@@ -11,12 +11,14 @@
 #ifndef RTC_BASE_BUFFERQUEUE_H_
 #define RTC_BASE_BUFFERQUEUE_H_
 
+#include <stddef.h>
 #include <deque>
 #include <vector>
 
 #include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace rtc {
 
diff --git a/rtc_base/bytebuffer.h b/rtc_base/bytebuffer.h
index 9e08f02..4d25c21 100644
--- a/rtc_base/bytebuffer.h
+++ b/rtc_base/bytebuffer.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_BYTEBUFFER_H_
 #define RTC_BASE_BYTEBUFFER_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <string>
 
 #include "rtc_base/buffer.h"
diff --git a/rtc_base/cancelable_periodic_task_unittest.cc b/rtc_base/cancelable_periodic_task_unittest.cc
index fe27ea7..badd623 100644
--- a/rtc_base/cancelable_periodic_task_unittest.cc
+++ b/rtc_base/cancelable_periodic_task_unittest.cc
@@ -68,7 +68,7 @@
 }
 
 TEST(CancelablePeriodicTaskTest, CancelTaskBeforeItRuns) {
-  rtc::Event done(false, false);
+  rtc::Event done;
   MockClosure mock;
   EXPECT_CALL(mock, Call).Times(0);
   EXPECT_CALL(mock, Delete).WillOnce(Invoke([&done] { done.Set(); }));
@@ -84,7 +84,7 @@
 }
 
 TEST(CancelablePeriodicTaskTest, CancelDelayedTaskBeforeItRuns) {
-  rtc::Event done(false, false);
+  rtc::Event done;
   MockClosure mock;
   EXPECT_CALL(mock, Call).Times(0);
   EXPECT_CALL(mock, Delete).WillOnce(Invoke([&done] { done.Set(); }));
@@ -100,7 +100,7 @@
 }
 
 TEST(CancelablePeriodicTaskTest, CancelTaskAfterItRuns) {
-  rtc::Event done(false, false);
+  rtc::Event done;
   MockClosure mock;
   EXPECT_CALL(mock, Call).WillOnce(Return(100));
   EXPECT_CALL(mock, Delete).WillOnce(Invoke([&done] { done.Set(); }));
@@ -117,7 +117,7 @@
 
 TEST(CancelablePeriodicTaskTest, ZeroReturnValueRepostsTheTask) {
   NiceMock<MockClosure> closure;
-  rtc::Event done(false, false);
+  rtc::Event done;
   EXPECT_CALL(closure, Call()).WillOnce(Return(0)).WillOnce(Invoke([&done] {
     done.Set();
     return kTimeoutMs;
@@ -130,7 +130,7 @@
 
 TEST(CancelablePeriodicTaskTest, StartPeriodicTask) {
   MockFunction<int()> closure;
-  rtc::Event done(false, false);
+  rtc::Event done;
   EXPECT_CALL(closure, Call())
       .WillOnce(Return(20))
       .WillOnce(Return(20))
@@ -146,7 +146,7 @@
 
 // Validates perfect forwarding doesn't keep reference to deleted copy.
 TEST(CancelablePeriodicTaskTest, CreateWithCopyOfAClosure) {
-  rtc::Event done(false, false);
+  rtc::Event done;
   MockClosure mock;
   EXPECT_CALL(mock, Call).WillOnce(Invoke([&done] {
     done.Set();
@@ -166,7 +166,7 @@
 }
 
 TEST(CancelablePeriodicTaskTest, DeletingHandleDoesntStopTheTask) {
-  rtc::Event run(false, false);
+  rtc::Event run;
   rtc::TaskQueue task_queue("queue");
   auto task = rtc::CreateCancelablePeriodicTask(([&] {
     run.Set();
diff --git a/rtc_base/copyonwritebuffer.cc b/rtc_base/copyonwritebuffer.cc
index 6c48d52..8f5126a 100644
--- a/rtc_base/copyonwritebuffer.cc
+++ b/rtc_base/copyonwritebuffer.cc
@@ -10,6 +10,8 @@
 
 #include "rtc_base/copyonwritebuffer.h"
 
+#include <stddef.h>
+
 namespace rtc {
 
 CopyOnWriteBuffer::CopyOnWriteBuffer() {
diff --git a/rtc_base/copyonwritebuffer.h b/rtc_base/copyonwritebuffer.h
index 177e38f..cc174df 100644
--- a/rtc_base/copyonwritebuffer.h
+++ b/rtc_base/copyonwritebuffer.h
@@ -11,7 +11,11 @@
 #ifndef RTC_BASE_COPYONWRITEBUFFER_H_
 #define RTC_BASE_COPYONWRITEBUFFER_H_
 
+#include <stdint.h>
 #include <algorithm>
+#include <cstring>
+#include <string>
+#include <type_traits>
 #include <utility>
 
 #include "rtc_base/buffer.h"
diff --git a/rtc_base/cpu_time.cc b/rtc_base/cpu_time.cc
index de4a6bd..ad91eca 100644
--- a/rtc_base/cpu_time.cc
+++ b/rtc_base/cpu_time.cc
@@ -65,6 +65,9 @@
   } else {
     RTC_LOG_ERR(LS_ERROR) << "GetProcessTimes() failed.";
   }
+#elif defined(WEBRTC_FUCHSIA)
+  RTC_LOG_ERR(LS_ERROR) << "GetProcessCpuTimeNanos() not implemented";
+  return 0;
 #else
   // Not implemented yet.
   static_assert(
@@ -107,10 +110,13 @@
   } else {
     RTC_LOG_ERR(LS_ERROR) << "GetThreadTimes() failed.";
   }
+#elif defined(WEBRTC_FUCHSIA)
+  RTC_LOG_ERR(LS_ERROR) << "GetThreadCpuTimeNanos() not implemented";
+  return 0;
 #else
   // Not implemented yet.
   static_assert(
-      false, "GetProcessCpuTimeNanos() platform support not yet implemented.");
+      false, "GetThreadCpuTimeNanos() platform support not yet implemented.");
 #endif
   return -1;
 }
diff --git a/rtc_base/criticalsection.cc b/rtc_base/criticalsection.cc
index d8a5b48..4e00be9 100644
--- a/rtc_base/criticalsection.cc
+++ b/rtc_base/criticalsection.cc
@@ -10,6 +10,8 @@
 
 #include "rtc_base/criticalsection.h"
 
+#include <time.h>
+
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/platform_thread_types.h"
diff --git a/rtc_base/criticalsection_unittest.cc b/rtc_base/criticalsection_unittest.cc
index db4f9e7..6016f85 100644
--- a/rtc_base/criticalsection_unittest.cc
+++ b/rtc_base/criticalsection_unittest.cc
@@ -389,7 +389,7 @@
 // The test is disabled by default to avoid unecessarily loading the bots.
 TEST(CriticalSectionTest, DISABLED_Performance) {
   PerfTestThread threads[8];
-  Event event(false, false);
+  Event event;
 
   static const int kThreadRepeats = 10000000;
   static const int kExpectedCount = kThreadRepeats * arraysize(threads);
diff --git a/rtc_base/event.cc b/rtc_base/event.cc
index 6c9639b..42c22a2 100644
--- a/rtc_base/event.cc
+++ b/rtc_base/event.cc
@@ -24,6 +24,8 @@
 
 namespace rtc {
 
+Event::Event() : Event(false, false) {}
+
 #if defined(WEBRTC_WIN)
 
 Event::Event(bool manual_reset, bool initially_signaled) {
diff --git a/rtc_base/event.h b/rtc_base/event.h
index 7e61c4c..2e11002 100644
--- a/rtc_base/event.h
+++ b/rtc_base/event.h
@@ -11,7 +11,6 @@
 #ifndef RTC_BASE_EVENT_H_
 #define RTC_BASE_EVENT_H_
 
-#include "rtc_base/constructormagic.h"
 #if defined(WEBRTC_WIN)
 #include <windows.h>
 #elif defined(WEBRTC_POSIX)
@@ -26,7 +25,10 @@
  public:
   static const int kForever = -1;
 
+  Event();
   Event(bool manual_reset, bool initially_signaled);
+  Event(const Event&) = delete;
+  Event& operator=(const Event&) = delete;
   ~Event();
 
   void Set();
@@ -45,8 +47,6 @@
   const bool is_manual_reset_;
   bool event_status_;
 #endif
-
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Event);
 };
 
 // This class is provided for compatibility with Chromium.
diff --git a/rtc_base/event_tracer.cc b/rtc_base/event_tracer.cc
index 31f4271..af88c9d 100644
--- a/rtc_base/event_tracer.cc
+++ b/rtc_base/event_tracer.cc
@@ -10,7 +10,9 @@
 #include "rtc_base/event_tracer.h"
 
 #include <inttypes.h>
-
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
 #include <string>
 #include <vector>
 
@@ -20,7 +22,9 @@
 #include "rtc_base/event.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/platform_thread.h"
-#include "rtc_base/stringutils.h"
+#include "rtc_base/platform_thread_types.h"
+#include "rtc_base/thread_annotations.h"
+#include "rtc_base/thread_checker.h"
 #include "rtc_base/timeutils.h"
 #include "rtc_base/trace_event.h"
 
@@ -86,8 +90,7 @@
       : logging_thread_(EventTracingThreadFunc,
                         this,
                         "EventTracingThread",
-                        kLowPriority),
-        shutdown_event_(false, false) {}
+                        kLowPriority) {}
   ~EventLogger() { RTC_DCHECK(thread_checker_.CalledOnValidThread()); }
 
   void AddTraceEvent(const char* name,
@@ -286,19 +289,19 @@
           }
           break;
         case TRACE_VALUE_TYPE_UINT:
-          print_length = sprintfn(&output[0], kTraceArgBufferLength, "%llu",
+          print_length = snprintf(&output[0], kTraceArgBufferLength, "%llu",
                                   arg.value.as_uint);
           break;
         case TRACE_VALUE_TYPE_INT:
-          print_length = sprintfn(&output[0], kTraceArgBufferLength, "%lld",
+          print_length = snprintf(&output[0], kTraceArgBufferLength, "%lld",
                                   arg.value.as_int);
           break;
         case TRACE_VALUE_TYPE_DOUBLE:
-          print_length = sprintfn(&output[0], kTraceArgBufferLength, "%f",
+          print_length = snprintf(&output[0], kTraceArgBufferLength, "%f",
                                   arg.value.as_double);
           break;
         case TRACE_VALUE_TYPE_POINTER:
-          print_length = sprintfn(&output[0], kTraceArgBufferLength, "\"%p\"",
+          print_length = snprintf(&output[0], kTraceArgBufferLength, "\"%p\"",
                                   arg.value.as_pointer);
           break;
       }
diff --git a/rtc_base/event_unittest.cc b/rtc_base/event_unittest.cc
index 050619e..a65111b 100644
--- a/rtc_base/event_unittest.cc
+++ b/rtc_base/event_unittest.cc
@@ -32,7 +32,7 @@
 }
 
 TEST(EventTest, AutoReset) {
-  Event event(false, false);
+  Event event;
   ASSERT_FALSE(event.Wait(0));
 
   event.Set();
@@ -59,7 +59,7 @@
       me->reader_->Wait(Event::kForever);
     }
   }
-  Event stop_event_{false, false};
+  Event stop_event_;
   Event* writer_;
   Event* reader_;
   PlatformThread thread_;
@@ -68,7 +68,7 @@
 // These tests are disabled by default and only intended to be run manually.
 TEST(EventTest, DISABLED_PerformanceSingleThread) {
   static const int kNumIterations = 10000000;
-  Event event(false, false);
+  Event event;
   for (int i = 0; i < kNumIterations; ++i) {
     event.Set();
     event.Wait(0);
@@ -77,8 +77,8 @@
 
 TEST(EventTest, DISABLED_PerformanceMultiThread) {
   static const int kNumIterations = 10000;
-  Event read(false, false);
-  Event write(false, false);
+  Event read;
+  Event write;
   SignalerThread thread;
   thread.Start(&read, &write);
 
diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn
index 044db80..b2e1302 100644
--- a/rtc_base/experiments/BUILD.gn
+++ b/rtc_base/experiments/BUILD.gn
@@ -28,11 +28,11 @@
     "field_trial_units.h",
   ]
   deps = [
-    "../:rtc_base_approved",
     "../../api/units:data_rate",
     "../../api/units:data_size",
     "../../api/units:time_delta",
     "../../rtc_base:checks",
+    "../../rtc_base:logging",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
 }
@@ -63,6 +63,30 @@
   ]
 }
 
+rtc_static_library("normalize_simulcast_size_experiment") {
+  sources = [
+    "normalize_simulcast_size_experiment.cc",
+    "normalize_simulcast_size_experiment.h",
+  ]
+  deps = [
+    "../:rtc_base_approved",
+    "../../system_wrappers:field_trial",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
+rtc_static_library("cpu_speed_experiment") {
+  sources = [
+    "cpu_speed_experiment.cc",
+    "cpu_speed_experiment.h",
+  ]
+  deps = [
+    "../:rtc_base_approved",
+    "../../system_wrappers:field_trial",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
 rtc_static_library("rtt_mult_experiment") {
   sources = [
     "rtt_mult_experiment.cc",
@@ -92,20 +116,25 @@
 
     sources = [
       "congestion_controller_experiment_unittest.cc",
+      "cpu_speed_experiment_unittest.cc",
       "field_trial_parser_unittest.cc",
       "field_trial_units_unittest.cc",
+      "normalize_simulcast_size_experiment_unittest.cc",
       "quality_scaling_experiment_unittest.cc",
       "rtt_mult_experiment_unittest.cc",
     ]
     deps = [
       ":congestion_controller_experiment",
+      ":cpu_speed_experiment",
       ":field_trial_parser",
+      ":normalize_simulcast_size_experiment",
       ":quality_scaling_experiment",
       ":rtt_mult_experiment",
       "../:rtc_base_tests_main",
       "../:rtc_base_tests_utils",
       "../../system_wrappers:field_trial",
       "../../test:field_trial",
+      "../../test:test_support",
     ]
   }
 }
diff --git a/rtc_base/experiments/alr_experiment.cc b/rtc_base/experiments/alr_experiment.cc
index dff5ace..25e948d 100644
--- a/rtc_base/experiments/alr_experiment.cc
+++ b/rtc_base/experiments/alr_experiment.cc
@@ -10,9 +10,10 @@
 
 #include "rtc_base/experiments/alr_experiment.h"
 
+#include <inttypes.h>
+#include <stdio.h>
 #include <string>
 
-#include "rtc_base/format_macros.h"
 #include "rtc_base/logging.h"
 #include "system_wrappers/include/field_trial.h"
 
diff --git a/rtc_base/experiments/alr_experiment.h b/rtc_base/experiments/alr_experiment.h
index 4d9fd00..876bd02 100644
--- a/rtc_base/experiments/alr_experiment.h
+++ b/rtc_base/experiments/alr_experiment.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_EXPERIMENTS_ALR_EXPERIMENT_H_
 #define RTC_BASE_EXPERIMENTS_ALR_EXPERIMENT_H_
 
+#include <stdint.h>
+
 #include "absl/types/optional.h"
 
 namespace webrtc {
diff --git a/rtc_base/experiments/cpu_speed_experiment.cc b/rtc_base/experiments/cpu_speed_experiment.cc
new file mode 100644
index 0000000..f39540c
--- /dev/null
+++ b/rtc_base/experiments/cpu_speed_experiment.cc
@@ -0,0 +1,70 @@
+/*
+ *  Copyright 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 "rtc_base/experiments/cpu_speed_experiment.h"
+
+#include <string>
+
+#include "rtc_base/logging.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+namespace {
+constexpr char kFieldTrial[] = "WebRTC-VP8-CpuSpeed-Arm";
+constexpr int kMinSetting = -16;
+constexpr int kMaxSetting = -1;
+}  // namespace
+
+absl::optional<std::vector<CpuSpeedExperiment::Config>>
+CpuSpeedExperiment::GetConfigs() {
+  if (!webrtc::field_trial::IsEnabled(kFieldTrial))
+    return absl::nullopt;
+
+  const std::string group = webrtc::field_trial::FindFullName(kFieldTrial);
+  if (group.empty())
+    return absl::nullopt;
+
+  std::vector<Config> configs(3);
+  if (sscanf(group.c_str(), "Enabled-%d,%d,%d,%d,%d,%d", &(configs[0].pixels),
+             &(configs[0].cpu_speed), &(configs[1].pixels),
+             &(configs[1].cpu_speed), &(configs[2].pixels),
+             &(configs[2].cpu_speed)) != 6) {
+    RTC_LOG(LS_WARNING) << "Too few parameters provided.";
+    return absl::nullopt;
+  }
+
+  for (const auto& config : configs) {
+    if (config.cpu_speed < kMinSetting || config.cpu_speed > kMaxSetting) {
+      RTC_LOG(LS_WARNING) << "Unsupported cpu speed setting, value ignored.";
+      return absl::nullopt;
+    }
+  }
+
+  for (size_t i = 1; i < configs.size(); ++i) {
+    if (configs[i].pixels < configs[i - 1].pixels ||
+        configs[i].cpu_speed > configs[i - 1].cpu_speed) {
+      RTC_LOG(LS_WARNING) << "Invalid parameter value provided.";
+      return absl::nullopt;
+    }
+  }
+
+  return absl::optional<std::vector<Config>>(configs);
+}
+
+int CpuSpeedExperiment::GetValue(int pixels,
+                                 const std::vector<Config>& configs) {
+  for (const auto& config : configs) {
+    if (pixels <= config.pixels)
+      return config.cpu_speed;
+  }
+  return kMinSetting;
+}
+
+}  // namespace webrtc
diff --git a/rtc_base/experiments/cpu_speed_experiment.h b/rtc_base/experiments/cpu_speed_experiment.h
new file mode 100644
index 0000000..e6c8340
--- /dev/null
+++ b/rtc_base/experiments/cpu_speed_experiment.h
@@ -0,0 +1,41 @@
+/*
+ *  Copyright 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 RTC_BASE_EXPERIMENTS_CPU_SPEED_EXPERIMENT_H_
+#define RTC_BASE_EXPERIMENTS_CPU_SPEED_EXPERIMENT_H_
+
+#include <vector>
+
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+class CpuSpeedExperiment {
+ public:
+  struct Config {
+    bool operator==(const Config& o) const {
+      return pixels == o.pixels && cpu_speed == o.cpu_speed;
+    }
+
+    int pixels;     // The video frame size.
+    int cpu_speed;  // The |cpu_speed| to be used if the frame size is less
+                    // than or equal to |pixels|.
+  };
+
+  // Returns the configurations from field trial on success.
+  static absl::optional<std::vector<Config>> GetConfigs();
+
+  // Gets the cpu speed from the |configs| based on |pixels|.
+  static int GetValue(int pixels, const std::vector<Config>& configs);
+};
+
+}  // namespace webrtc
+
+#endif  // RTC_BASE_EXPERIMENTS_CPU_SPEED_EXPERIMENT_H_
diff --git a/rtc_base/experiments/cpu_speed_experiment_unittest.cc b/rtc_base/experiments/cpu_speed_experiment_unittest.cc
new file mode 100644
index 0000000..edc782c
--- /dev/null
+++ b/rtc_base/experiments/cpu_speed_experiment_unittest.cc
@@ -0,0 +1,85 @@
+/*
+ *  Copyright 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 "rtc_base/experiments/cpu_speed_experiment.h"
+
+#include "rtc_base/gunit.h"
+#include "test/field_trial.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+TEST(CpuSpeedExperimentTest, GetConfigsFailsIfNotEnabled) {
+  EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
+}
+
+TEST(CpuSpeedExperimentTest, GetConfigsFailsForTooFewParameters) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-1,2000,-10,3000/");
+  EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
+}
+
+TEST(CpuSpeedExperimentTest, GetConfigs) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-1,2000,-10,3000,-16/");
+
+  const absl::optional<std::vector<CpuSpeedExperiment::Config>> kConfigs =
+      CpuSpeedExperiment::GetConfigs();
+  ASSERT_TRUE(kConfigs);
+  EXPECT_THAT(*kConfigs,
+              ::testing::ElementsAre(CpuSpeedExperiment::Config{1000, -1},
+                                     CpuSpeedExperiment::Config{2000, -10},
+                                     CpuSpeedExperiment::Config{3000, -16}));
+}
+
+TEST(CpuSpeedExperimentTest, GetValue) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-5,2000,-10,3000,-12/");
+
+  const absl::optional<std::vector<CpuSpeedExperiment::Config>> kConfigs =
+      CpuSpeedExperiment::GetConfigs();
+  ASSERT_TRUE(kConfigs);
+  ASSERT_EQ(3u, (*kConfigs).size());
+  EXPECT_EQ(-5, CpuSpeedExperiment::GetValue(1, *kConfigs));
+  EXPECT_EQ(-5, CpuSpeedExperiment::GetValue(1000, *kConfigs));
+  EXPECT_EQ(-10, CpuSpeedExperiment::GetValue(1000 + 1, *kConfigs));
+  EXPECT_EQ(-10, CpuSpeedExperiment::GetValue(2000, *kConfigs));
+  EXPECT_EQ(-12, CpuSpeedExperiment::GetValue(2000 + 1, *kConfigs));
+  EXPECT_EQ(-12, CpuSpeedExperiment::GetValue(3000, *kConfigs));
+  EXPECT_EQ(-16, CpuSpeedExperiment::GetValue(3000 + 1, *kConfigs));
+}
+
+TEST(CpuSpeedExperimentTest, GetConfigsFailsForTooSmallValue) {
+  // Supported range: [-16, -1].
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-1,2000,-10,3000,-17/");
+  EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
+}
+
+TEST(CpuSpeedExperimentTest, GetConfigsFailsForTooLargeValue) {
+  // Supported range: [-16, -1].
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,0,2000,-10,3000,-16/");
+  EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
+}
+
+TEST(CpuSpeedExperimentTest, GetConfigsFailsIfPixelsDecreasing) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-5,999,-10,3000,-16/");
+  EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
+}
+
+TEST(CpuSpeedExperimentTest, GetConfigsFailsIfCpuSpeedIncreasing) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-VP8-CpuSpeed-Arm/Enabled-1000,-5,2000,-4,3000,-16/");
+  EXPECT_FALSE(CpuSpeedExperiment::GetConfigs());
+}
+
+}  // namespace webrtc
diff --git a/rtc_base/experiments/field_trial_units.cc b/rtc_base/experiments/field_trial_units.cc
index f53978b..8c201a6 100644
--- a/rtc_base/experiments/field_trial_units.cc
+++ b/rtc_base/experiments/field_trial_units.cc
@@ -9,6 +9,7 @@
  */
 #include "rtc_base/experiments/field_trial_units.h"
 
+#include <stdio.h>
 #include <limits>
 #include <string>
 
diff --git a/rtc_base/experiments/normalize_simulcast_size_experiment.cc b/rtc_base/experiments/normalize_simulcast_size_experiment.cc
new file mode 100644
index 0000000..9ce5f57
--- /dev/null
+++ b/rtc_base/experiments/normalize_simulcast_size_experiment.cc
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 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 "rtc_base/experiments/normalize_simulcast_size_experiment.h"
+
+#include <string>
+
+#include "rtc_base/logging.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+namespace {
+constexpr char kFieldTrial[] = "WebRTC-NormalizeSimulcastResolution";
+constexpr int kMinSetting = 0;
+constexpr int kMaxSetting = 5;
+}  // namespace
+
+absl::optional<int> NormalizeSimulcastSizeExperiment::GetBase2Exponent() {
+  if (!webrtc::field_trial::IsEnabled(kFieldTrial))
+    return absl::nullopt;
+
+  const std::string group = webrtc::field_trial::FindFullName(kFieldTrial);
+  if (group.empty())
+    return absl::nullopt;
+
+  int exponent;
+  if (sscanf(group.c_str(), "Enabled-%d", &exponent) != 1) {
+    RTC_LOG(LS_WARNING) << "No parameter provided.";
+    return absl::nullopt;
+  }
+
+  if (exponent < kMinSetting || exponent > kMaxSetting) {
+    RTC_LOG(LS_WARNING) << "Unsupported exp value provided, value ignored.";
+    return absl::nullopt;
+  }
+
+  return absl::optional<int>(exponent);
+}
+
+}  // namespace webrtc
diff --git a/rtc_base/experiments/normalize_simulcast_size_experiment.h b/rtc_base/experiments/normalize_simulcast_size_experiment.h
new file mode 100644
index 0000000..6b35820
--- /dev/null
+++ b/rtc_base/experiments/normalize_simulcast_size_experiment.h
@@ -0,0 +1,25 @@
+/*
+ *  Copyright 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 RTC_BASE_EXPERIMENTS_NORMALIZE_SIMULCAST_SIZE_EXPERIMENT_H_
+#define RTC_BASE_EXPERIMENTS_NORMALIZE_SIMULCAST_SIZE_EXPERIMENT_H_
+
+#include "absl/types/optional.h"
+
+namespace webrtc {
+class NormalizeSimulcastSizeExperiment {
+ public:
+  // Returns the base two exponent from field trial.
+  static absl::optional<int> GetBase2Exponent();
+};
+
+}  // namespace webrtc
+
+#endif  // RTC_BASE_EXPERIMENTS_NORMALIZE_SIMULCAST_SIZE_EXPERIMENT_H_
diff --git a/rtc_base/experiments/normalize_simulcast_size_experiment_unittest.cc b/rtc_base/experiments/normalize_simulcast_size_experiment_unittest.cc
new file mode 100644
index 0000000..c37b809
--- /dev/null
+++ b/rtc_base/experiments/normalize_simulcast_size_experiment_unittest.cc
@@ -0,0 +1,59 @@
+/*
+ *  Copyright 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 "rtc_base/experiments/normalize_simulcast_size_experiment.h"
+
+#include "rtc_base/gunit.h"
+#include "test/field_trial.h"
+
+namespace webrtc {
+
+TEST(NormalizeSimulcastSizeExperimentTest, GetExponent) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-NormalizeSimulcastResolution/Enabled-2/");
+  EXPECT_EQ(2, NormalizeSimulcastSizeExperiment::GetBase2Exponent());
+}
+
+TEST(NormalizeSimulcastSizeExperimentTest, GetExponentWithTwoParameters) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-NormalizeSimulcastResolution/Enabled-3-4/");
+  EXPECT_EQ(3, NormalizeSimulcastSizeExperiment::GetBase2Exponent());
+}
+
+TEST(NormalizeSimulcastSizeExperimentTest, GetExponentFailsIfNotEnabled) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-NormalizeSimulcastResolution/Disabled/");
+  EXPECT_FALSE(NormalizeSimulcastSizeExperiment::GetBase2Exponent());
+}
+
+TEST(NormalizeSimulcastSizeExperimentTest,
+     GetExponentFailsForInvalidFieldTrial) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-NormalizeSimulcastResolution/Enabled-invalid/");
+  EXPECT_FALSE(NormalizeSimulcastSizeExperiment::GetBase2Exponent());
+}
+
+TEST(NormalizeSimulcastSizeExperimentTest,
+     GetExponentFailsForNegativeOutOfBoundValue) {
+  // Supported range: [0, 5].
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-NormalizeSimulcastResolution/Enabled--1/");
+  EXPECT_FALSE(NormalizeSimulcastSizeExperiment::GetBase2Exponent());
+}
+
+TEST(NormalizeSimulcastSizeExperimentTest,
+     GetExponentFailsForPositiveOutOfBoundValue) {
+  // Supported range: [0, 5].
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-NormalizeSimulcastResolution/Enabled-6/");
+  EXPECT_FALSE(NormalizeSimulcastSizeExperiment::GetBase2Exponent());
+}
+
+}  // namespace webrtc
diff --git a/rtc_base/fake_mdns_responder.h b/rtc_base/fake_mdns_responder.h
index 32d69ba..1e60a5d 100644
--- a/rtc_base/fake_mdns_responder.h
+++ b/rtc_base/fake_mdns_responder.h
@@ -21,10 +21,10 @@
 
 namespace webrtc {
 
-class FakeMDnsResponder : public MDnsResponderInterface {
+class FakeMdnsResponder : public MdnsResponderInterface {
  public:
-  FakeMDnsResponder() = default;
-  ~FakeMDnsResponder() = default;
+  explicit FakeMdnsResponder(rtc::Thread* thread) : thread_(thread) {}
+  ~FakeMdnsResponder() = default;
 
   void CreateNameForAddress(const rtc::IPAddress& addr,
                             NameCreatedCallback callback) override {
@@ -35,7 +35,9 @@
       name = std::to_string(next_available_id_++) + ".local";
       addr_name_map_[addr] = name;
     }
-    callback(addr, name);
+    invoker_.AsyncInvoke<void>(
+        RTC_FROM_HERE, thread_,
+        [callback, addr, name]() { callback(addr, name); });
   }
   void RemoveNameForAddress(const rtc::IPAddress& addr,
                             NameRemovedCallback callback) override {
@@ -43,12 +45,16 @@
     if (it != addr_name_map_.end()) {
       addr_name_map_.erase(it);
     }
-    callback(it != addr_name_map_.end());
+    bool result = it != addr_name_map_.end();
+    invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
+                               [callback, result]() { callback(result); });
   }
 
  private:
   uint32_t next_available_id_ = 0;
   std::map<rtc::IPAddress, std::string> addr_name_map_;
+  rtc::Thread* thread_;
+  rtc::AsyncInvoker invoker_;
 };
 
 }  // namespace webrtc
diff --git a/rtc_base/fakenetwork.h b/rtc_base/fakenetwork.h
index d5426a3..cb890ec 100644
--- a/rtc_base/fakenetwork.h
+++ b/rtc_base/fakenetwork.h
@@ -82,16 +82,17 @@
   // MessageHandler interface.
   virtual void OnMessage(Message* msg) { DoUpdateNetworks(); }
 
-  void CreateMDnsResponder() {
+  void CreateMdnsResponder() {
     if (mdns_responder_ == nullptr) {
-      mdns_responder_ = absl::make_unique<webrtc::FakeMDnsResponder>();
+      mdns_responder_ =
+          absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current());
     }
   }
 
   using NetworkManagerBase::set_enumeration_permission;
   using NetworkManagerBase::set_default_local_addresses;
 
-  webrtc::MDnsResponderInterface* GetMDnsResponder() const override {
+  webrtc::MdnsResponderInterface* GetMdnsResponder() const override {
     return mdns_responder_.get();
   }
 
@@ -131,7 +132,7 @@
   IPAddress default_local_ipv4_address_;
   IPAddress default_local_ipv6_address_;
 
-  std::unique_ptr<webrtc::FakeMDnsResponder> mdns_responder_;
+  std::unique_ptr<webrtc::FakeMdnsResponder> mdns_responder_;
 };
 
 }  // namespace rtc
diff --git a/rtc_base/fakesslidentity.cc b/rtc_base/fakesslidentity.cc
index 80a3e78..62ac9dd 100644
--- a/rtc_base/fakesslidentity.cc
+++ b/rtc_base/fakesslidentity.cc
@@ -29,8 +29,8 @@
 
 FakeSSLCertificate::~FakeSSLCertificate() = default;
 
-FakeSSLCertificate* FakeSSLCertificate::GetReference() const {
-  return new FakeSSLCertificate(*this);
+std::unique_ptr<SSLCertificate> FakeSSLCertificate::Clone() const {
+  return absl::make_unique<FakeSSLCertificate>(*this);
 }
 
 std::string FakeSSLCertificate::ToPEMString() const {
@@ -83,10 +83,10 @@
 }
 
 FakeSSLIdentity::FakeSSLIdentity(const FakeSSLCertificate& cert)
-    : cert_chain_(absl::make_unique<SSLCertChain>(&cert)) {}
+    : cert_chain_(absl::make_unique<SSLCertChain>(cert.Clone())) {}
 
 FakeSSLIdentity::FakeSSLIdentity(const FakeSSLIdentity& o)
-    : cert_chain_(o.cert_chain_->UniqueCopy()) {}
+    : cert_chain_(o.cert_chain_->Clone()) {}
 
 FakeSSLIdentity::~FakeSSLIdentity() = default;
 
diff --git a/rtc_base/fakesslidentity.h b/rtc_base/fakesslidentity.h
index 4494a52..b19cbfb 100644
--- a/rtc_base/fakesslidentity.h
+++ b/rtc_base/fakesslidentity.h
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "rtc_base/sslcertificate.h"
 #include "rtc_base/sslidentity.h"
 
 namespace rtc {
@@ -28,7 +29,7 @@
   ~FakeSSLCertificate() override;
 
   // SSLCertificate implementation.
-  FakeSSLCertificate* GetReference() const override;
+  std::unique_ptr<SSLCertificate> Clone() const override;
   std::string ToPEMString() const override;
   void ToDER(Buffer* der_buffer) const override;
   int64_t CertificateExpirationTime() const override;
diff --git a/rtc_base/file.h b/rtc_base/file.h
index 75fd93d..bc0974a 100644
--- a/rtc_base/file.h
+++ b/rtc_base/file.h
@@ -11,8 +11,8 @@
 #ifndef RTC_BASE_FILE_H_
 #define RTC_BASE_FILE_H_
 
+#include <stddef.h>
 #include <stdint.h>
-
 #include <string>
 
 #include "rtc_base/constructormagic.h"
diff --git a/rtc_base/file_posix.cc b/rtc_base/file_posix.cc
index b0fec9f..4920192 100644
--- a/rtc_base/file_posix.cc
+++ b/rtc_base/file_posix.cc
@@ -8,17 +8,16 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "rtc_base/file.h"
-
 #include <errno.h>
 #include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <unistd.h>
-
 #include <limits>
 
 #include "rtc_base/checks.h"
+#include "rtc_base/file.h"
+#include "rtc_base/platform_file.h"
 
 namespace rtc {
 
diff --git a/rtc_base/filerotatingstream.cc b/rtc_base/filerotatingstream.cc
index 31b0051..d03ab39 100644
--- a/rtc_base/filerotatingstream.cc
+++ b/rtc_base/filerotatingstream.cc
@@ -13,18 +13,158 @@
 #include <algorithm>
 #include <cstdio>
 #include <string>
+#include <utility>
 
+#if defined(WEBRTC_WIN)
+#include <windows.h>
+#include "rtc_base/stringutils.h"
+#else
+#include <dirent.h>
+#include <sys/stat.h>
+#endif  // WEBRTC_WIN
+
+#include "absl/strings/match.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/fileutils.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/pathutils.h"
-#include "rtc_base/strings/string_builder.h"
 
 // Note: We use fprintf for logging in the write paths of this stream to avoid
 // infinite loops when logging.
 
 namespace rtc {
 
+namespace {
+
+std::string AddTrailingPathDelimiterIfNeeded(std::string directory);
+
+// |dir| must have a trailing delimiter. |prefix| must not include wild card
+// characters.
+std::vector<std::string> GetFilesWithPrefix(const std::string& directory,
+                                            const std::string& prefix);
+bool DeleteFile(const std::string& file);
+bool MoveFile(const std::string& old_file, const std::string& new_file);
+bool IsFile(const std::string& file);
+bool IsFolder(const std::string& file);
+absl::optional<size_t> GetFileSize(const std::string& file);
+
+#if defined(WEBRTC_WIN)
+
+std::string AddTrailingPathDelimiterIfNeeded(std::string directory) {
+  if (absl::EndsWith(directory, "\\")) {
+    return directory;
+  }
+  return directory + "\\";
+}
+
+std::vector<std::string> GetFilesWithPrefix(const std::string& directory,
+                                            const std::string& prefix) {
+  RTC_DCHECK(absl::EndsWith(directory, "\\"));
+  WIN32_FIND_DATA data;
+  HANDLE handle;
+  handle = ::FindFirstFile(ToUtf16(directory + prefix + '*').c_str(), &data);
+  if (handle == INVALID_HANDLE_VALUE)
+    return {};
+
+  std::vector<std::string> file_list;
+  do {
+    file_list.emplace_back(directory + ToUtf8(data.cFileName));
+  } while (::FindNextFile(handle, &data) == TRUE);
+
+  ::FindClose(handle);
+  return file_list;
+}
+
+bool DeleteFile(const std::string& file) {
+  return ::DeleteFile(ToUtf16(file).c_str()) != 0;
+}
+
+bool MoveFile(const std::string& old_file, const std::string& new_file) {
+  return ::MoveFile(ToUtf16(old_file).c_str(), ToUtf16(new_file).c_str()) != 0;
+}
+
+bool IsFile(const std::string& file) {
+  WIN32_FILE_ATTRIBUTE_DATA data = {0};
+  if (0 == ::GetFileAttributesEx(ToUtf16(file).c_str(), GetFileExInfoStandard,
+                                 &data))
+    return false;
+  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
+}
+
+bool IsFolder(const std::string& file) {
+  WIN32_FILE_ATTRIBUTE_DATA data = {0};
+  if (0 == ::GetFileAttributesEx(ToUtf16(file).c_str(), GetFileExInfoStandard,
+                                 &data))
+    return false;
+  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
+         FILE_ATTRIBUTE_DIRECTORY;
+}
+
+absl::optional<size_t> GetFileSize(const std::string& file) {
+  WIN32_FILE_ATTRIBUTE_DATA data = {0};
+  if (::GetFileAttributesEx(ToUtf16(file).c_str(), GetFileExInfoStandard,
+                            &data) == 0)
+    return absl::nullopt;
+  return data.nFileSizeLow;
+}
+
+#else  // defined(WEBRTC_WIN)
+
+std::string AddTrailingPathDelimiterIfNeeded(std::string directory) {
+  if (absl::EndsWith(directory, "/")) {
+    return directory;
+  }
+  return directory + "/";
+}
+
+std::vector<std::string> GetFilesWithPrefix(const std::string& directory,
+                                            const std::string& prefix) {
+  RTC_DCHECK(absl::EndsWith(directory, "/"));
+  DIR* dir = ::opendir(directory.c_str());
+  if (dir == nullptr)
+    return {};
+  std::vector<std::string> file_list;
+  for (struct dirent* dirent = ::readdir(dir); dirent;
+       dirent = ::readdir(dir)) {
+    std::string name = dirent->d_name;
+    if (name.compare(0, prefix.size(), prefix) == 0) {
+      file_list.emplace_back(directory + name);
+    }
+  }
+  ::closedir(dir);
+  return file_list;
+}
+
+bool DeleteFile(const std::string& file) {
+  return ::unlink(file.c_str()) == 0;
+}
+
+bool MoveFile(const std::string& old_file, const std::string& new_file) {
+  return ::rename(old_file.c_str(), new_file.c_str()) == 0;
+}
+
+bool IsFile(const std::string& file) {
+  struct stat st;
+  int res = ::stat(file.c_str(), &st);
+  // Treat symlinks, named pipes, etc. all as files.
+  return res == 0 && !S_ISDIR(st.st_mode);
+}
+
+bool IsFolder(const std::string& file) {
+  struct stat st;
+  int res = ::stat(file.c_str(), &st);
+  return res == 0 && S_ISDIR(st.st_mode);
+}
+
+absl::optional<size_t> GetFileSize(const std::string& file) {
+  struct stat st;
+  if (::stat(file.c_str(), &st) != 0)
+    return absl::nullopt;
+  return st.st_size;
+}
+
+#endif
+
+}  // namespace
+
 FileRotatingStream::FileRotatingStream(const std::string& dir_path,
                                        const std::string& file_prefix)
     : FileRotatingStream(dir_path, file_prefix, 0, 0, kRead) {}
@@ -47,7 +187,7 @@
                                        size_t max_file_size,
                                        size_t num_files,
                                        Mode mode)
-    : dir_path_(dir_path),
+    : dir_path_(AddTrailingPathDelimiterIfNeeded(dir_path)),
       file_prefix_(file_prefix),
       mode_(mode),
       file_stream_(nullptr),
@@ -56,7 +196,7 @@
       rotation_index_(0),
       current_bytes_written_(0),
       disable_buffering_(false) {
-  RTC_DCHECK(Filesystem::IsFolder(dir_path));
+  RTC_DCHECK(IsFolder(dir_path));
   switch (mode) {
     case kWrite: {
       file_names_.clear();
@@ -67,7 +207,7 @@
       break;
     }
     case kRead: {
-      file_names_ = GetFilesWithPrefix();
+      file_names_ = GetFilesWithPrefix(dir_path_, file_prefix_);
       std::sort(file_names_.begin(), file_names_.end());
       if (file_names_.size() > 0) {
         // |file_names_| is sorted newest first, so read from the end.
@@ -188,11 +328,7 @@
   *size = 0;
   size_t total_size = 0;
   for (auto file_name : file_names_) {
-    Pathname pathname(file_name);
-    size_t file_size = 0;
-    if (Filesystem::GetFileSize(file_name, &file_size)) {
-      total_size += file_size;
-    }
+    total_size += GetFileSize(file_name).value_or(0);
   }
   *size = total_size;
   return true;
@@ -210,9 +346,10 @@
       return true;
     case kWrite: {
       // Delete existing files when opening for write.
-      std::vector<std::string> matching_files = GetFilesWithPrefix();
-      for (auto matching_file : matching_files) {
-        if (!Filesystem::DeleteFile(matching_file)) {
+      std::vector<std::string> matching_files =
+          GetFilesWithPrefix(dir_path_, file_prefix_);
+      for (const auto& matching_file : matching_files) {
+        if (!DeleteFile(matching_file)) {
           std::fprintf(stderr, "Failed to delete: %s\n", matching_file.c_str());
         }
       }
@@ -283,16 +420,16 @@
   // See header file comments for example.
   RTC_DCHECK_LT(rotation_index_, file_names_.size());
   std::string file_to_delete = file_names_[rotation_index_];
-  if (Filesystem::IsFile(file_to_delete)) {
-    if (!Filesystem::DeleteFile(file_to_delete)) {
+  if (IsFile(file_to_delete)) {
+    if (!DeleteFile(file_to_delete)) {
       std::fprintf(stderr, "Failed to delete: %s\n", file_to_delete.c_str());
     }
   }
   for (auto i = rotation_index_; i > 0; --i) {
     std::string rotated_name = file_names_[i];
     std::string unrotated_name = file_names_[i - 1];
-    if (Filesystem::IsFile(unrotated_name)) {
-      if (!Filesystem::MoveFile(unrotated_name, rotated_name)) {
+    if (IsFile(unrotated_name)) {
+      if (!MoveFile(unrotated_name, rotated_name)) {
         std::fprintf(stderr, "Failed to move: %s to %s\n",
                      unrotated_name.c_str(), rotated_name.c_str());
       }
@@ -303,26 +440,6 @@
   OnRotation();
 }
 
-std::vector<std::string> FileRotatingStream::GetFilesWithPrefix() const {
-  std::vector<std::string> files;
-  // Iterate over the files in the directory.
-  DirectoryIterator it;
-  Pathname dir_path;
-  dir_path.SetFolder(dir_path_);
-  if (!it.Iterate(dir_path)) {
-    return files;
-  }
-  do {
-    std::string current_name = it.Name();
-    if (current_name.size() && !it.IsDirectory() &&
-        current_name.compare(0, file_prefix_.size(), file_prefix_) == 0) {
-      Pathname path(dir_path_, current_name);
-      files.push_back(path.pathname());
-    }
-  } while (it.Next());
-  return files;
-}
-
 std::string FileRotatingStream::GetFilePath(size_t index,
                                             size_t num_files) const {
   RTC_DCHECK_LT(index, num_files);
@@ -334,8 +451,7 @@
   RTC_DCHECK_LT(1 + max_digits, buffer_size);
   std::snprintf(file_postfix, buffer_size, "_%0*zu", max_digits, index);
 
-  Pathname file_path(dir_path_, file_prefix_ + file_postfix);
-  return file_path.pathname();
+  return dir_path_ + file_prefix_ + file_postfix;
 }
 
 CallSessionFileRotatingStream::CallSessionFileRotatingStream(
diff --git a/rtc_base/filerotatingstream.h b/rtc_base/filerotatingstream.h
index 4dab345..c75ee15 100644
--- a/rtc_base/filerotatingstream.h
+++ b/rtc_base/filerotatingstream.h
@@ -11,6 +11,7 @@
 #ifndef RTC_BASE_FILEROTATINGSTREAM_H_
 #define RTC_BASE_FILEROTATINGSTREAM_H_
 
+#include <stddef.h>
 #include <memory>
 #include <string>
 #include <vector>
@@ -101,8 +102,6 @@
   // create new file_0
   void RotateFiles();
 
-  // Returns a list of file names in the directory beginning with the prefix.
-  std::vector<std::string> GetFilesWithPrefix() const;
   // Private version of GetFilePath.
   std::string GetFilePath(size_t index, size_t num_files) const;
 
diff --git a/rtc_base/filerotatingstream_unittest.cc b/rtc_base/filerotatingstream_unittest.cc
index 1905516..172be57 100644
--- a/rtc_base/filerotatingstream_unittest.cc
+++ b/rtc_base/filerotatingstream_unittest.cc
@@ -13,9 +13,7 @@
 #include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/filerotatingstream.h"
-#include "rtc_base/fileutils.h"
 #include "rtc_base/gunit.h"
-#include "rtc_base/pathutils.h"
 #include "test/testsupport/fileutils.h"
 
 namespace rtc {
@@ -46,12 +44,15 @@
   void Init(const std::string& dir_name,
             const std::string& file_prefix,
             size_t max_file_size,
-            size_t num_log_files) {
+            size_t num_log_files,
+            bool ensure_trailing_delimiter = true) {
     dir_path_ = webrtc::test::OutputPath();
 
     // Append per-test output path in order to run within gtest parallel.
     dir_path_.append(dir_name);
-    dir_path_.push_back(Pathname::DefaultFolderDelimiter());
+    if (ensure_trailing_delimiter) {
+      dir_path_.append(webrtc::test::kPathDelimiter);
+    }
     ASSERT_TRUE(webrtc::test::CreateDir(dir_path_));
     stream_.reset(new FileRotatingStream(dir_path_, file_prefix, max_file_size,
                                          num_log_files));
@@ -159,12 +160,12 @@
   }
   // Check that exactly three files exist.
   for (size_t i = 0; i < arraysize(messages); ++i) {
-    EXPECT_TRUE(Filesystem::IsFile(stream_->GetFilePath(i)));
+    EXPECT_TRUE(webrtc::test::FileExists(stream_->GetFilePath(i)));
   }
   std::string message("d");
   WriteAndFlush(message.c_str(), message.size());
   for (size_t i = 0; i < arraysize(messages); ++i) {
-    EXPECT_TRUE(Filesystem::IsFile(stream_->GetFilePath(i)));
+    EXPECT_TRUE(webrtc::test::FileExists(stream_->GetFilePath(i)));
   }
   // TODO(tkchin): Maybe check all the files in the dir.
 
@@ -174,6 +175,53 @@
                    dir_path_, kFilePrefix);
 }
 
+// Tests that a write operation (with dir name without delimiter) followed by a
+// read returns the expected data and writes to the expected files.
+TEST_F(MAYBE_FileRotatingStreamTest, WriteWithoutDelimiterAndRead) {
+  Init("FileRotatingStreamTestWriteWithoutDelimiterAndRead", kFilePrefix,
+       kMaxFileSize, 3,
+       /* ensure_trailing_delimiter*/ false);
+
+  ASSERT_TRUE(stream_->Open());
+  // The test is set up to create three log files of length 2. Write and check
+  // contents.
+  std::string messages[3] = {"aa", "bb", "cc"};
+  for (size_t i = 0; i < arraysize(messages); ++i) {
+    const std::string& message = messages[i];
+    WriteAndFlush(message.c_str(), message.size());
+  }
+  std::string message("d");
+  WriteAndFlush(message.c_str(), message.size());
+
+  // Reopen for read.
+  std::string expected_contents("bbccd");
+  VerifyStreamRead(expected_contents.c_str(), expected_contents.size(),
+                   dir_path_ + webrtc::test::kPathDelimiter, kFilePrefix);
+}
+
+// Tests that a write operation followed by a read (without trailing delimiter)
+// returns the expected data and writes to the expected files.
+TEST_F(MAYBE_FileRotatingStreamTest, WriteAndReadWithoutDelimiter) {
+  Init("FileRotatingStreamTestWriteAndReadWithoutDelimiter", kFilePrefix,
+       kMaxFileSize, 3);
+
+  ASSERT_TRUE(stream_->Open());
+  // The test is set up to create three log files of length 2. Write and check
+  // contents.
+  std::string messages[3] = {"aa", "bb", "cc"};
+  for (size_t i = 0; i < arraysize(messages); ++i) {
+    const std::string& message = messages[i];
+    WriteAndFlush(message.c_str(), message.size());
+  }
+  std::string message("d");
+  WriteAndFlush(message.c_str(), message.size());
+
+  // Reopen for read.
+  std::string expected_contents("bbccd");
+  VerifyStreamRead(expected_contents.c_str(), expected_contents.size(),
+                   dir_path_.substr(0, dir_path_.size() - 1), kFilePrefix);
+}
+
 // Tests that writing data greater than the total capacity of the files
 // overwrites the files correctly and is read correctly after.
 TEST_F(MAYBE_FileRotatingStreamTest, WriteOverflowAndRead) {
@@ -218,7 +266,7 @@
 
     // Append per-test output path in order to run within gtest parallel.
     dir_path_.append(dir_name);
-    dir_path_.push_back(Pathname::DefaultFolderDelimiter());
+    dir_path_.append(webrtc::test::kPathDelimiter);
     ASSERT_TRUE(webrtc::test::CreateDir(dir_path_));
     stream_.reset(
         new CallSessionFileRotatingStream(dir_path_, max_total_log_size));
diff --git a/rtc_base/fileutils.cc b/rtc_base/fileutils.cc
deleted file mode 100644
index 0adbbac..0000000
--- a/rtc_base/fileutils.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  Copyright 2004 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 "rtc_base/fileutils.h"
-
-#include "rtc_base/checks.h"
-#include "rtc_base/pathutils.h"
-
-#if defined(WEBRTC_WIN)
-#include "rtc_base/stringutils.h"  // for ToUtf16
-#include "rtc_base/win32filesystem.h"
-#else
-#include "rtc_base/unixfilesystem.h"
-#endif
-
-#if !defined(WEBRTC_WIN)
-#define MAX_PATH 260
-#endif
-
-namespace rtc {
-
-//////////////////////////
-// Directory Iterator   //
-//////////////////////////
-
-// A DirectoryIterator is created with a given directory. It originally points
-// to the first file in the directory, and can be advanecd with Next(). This
-// allows you to get information about each file.
-
-// Constructor
-DirectoryIterator::DirectoryIterator()
-#ifdef WEBRTC_WIN
-    : handle_(INVALID_HANDLE_VALUE) {
-#else
-    : dir_(nullptr),
-      dirent_(nullptr){
-#endif
-}
-
-// Destructor
-DirectoryIterator::~DirectoryIterator() {
-#if defined(WEBRTC_WIN)
-  if (handle_ != INVALID_HANDLE_VALUE)
-    ::FindClose(handle_);
-#else
-  if (dir_)
-    closedir(dir_);
-#endif
-}
-
-// Starts traversing a directory.
-// dir is the directory to traverse
-// returns true if the directory exists and is valid
-bool DirectoryIterator::Iterate(const Pathname& dir) {
-  directory_ = dir.pathname();
-#if defined(WEBRTC_WIN)
-  if (handle_ != INVALID_HANDLE_VALUE)
-    ::FindClose(handle_);
-  std::string d = dir.pathname() + '*';
-  handle_ = ::FindFirstFile(ToUtf16(d).c_str(), &data_);
-  if (handle_ == INVALID_HANDLE_VALUE)
-    return false;
-#else
-  if (dir_ != nullptr)
-    closedir(dir_);
-  dir_ = ::opendir(directory_.c_str());
-  if (dir_ == nullptr)
-    return false;
-  dirent_ = readdir(dir_);
-  if (dirent_ == nullptr)
-    return false;
-
-  if (::stat(std::string(directory_ + Name()).c_str(), &stat_) != 0)
-    return false;
-#endif
-  return true;
-}
-
-// Advances to the next file
-// returns true if there were more files in the directory.
-bool DirectoryIterator::Next() {
-#if defined(WEBRTC_WIN)
-  return ::FindNextFile(handle_, &data_) == TRUE;
-#else
-  dirent_ = ::readdir(dir_);
-  if (dirent_ == nullptr)
-    return false;
-
-  return ::stat(std::string(directory_ + Name()).c_str(), &stat_) == 0;
-#endif
-}
-
-// returns true if the file currently pointed to is a directory
-bool DirectoryIterator::IsDirectory() const {
-#if defined(WEBRTC_WIN)
-  return (data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FALSE;
-#else
-  return S_ISDIR(stat_.st_mode);
-#endif
-}
-
-// returns the name of the file currently pointed to
-std::string DirectoryIterator::Name() const {
-#if defined(WEBRTC_WIN)
-  return ToUtf8(data_.cFileName);
-#else
-  RTC_DCHECK(dirent_);
-  return dirent_->d_name;
-#endif
-}
-
-FilesystemInterface* Filesystem::GetFilesystem() {
-#if defined(WEBRTC_WIN)
-  static FilesystemInterface* const filesystem = new Win32Filesystem();
-#else
-  static FilesystemInterface* const filesystem = new UnixFilesystem();
-#endif
-
-  return filesystem;
-}
-
-}  // namespace rtc
diff --git a/rtc_base/fileutils.h b/rtc_base/fileutils.h
deleted file mode 100644
index f7afaf9..0000000
--- a/rtc_base/fileutils.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  Copyright 2004 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 RTC_BASE_FILEUTILS_H_
-#define RTC_BASE_FILEUTILS_H_
-
-#include <string>
-
-#if defined(WEBRTC_WIN)
-#include <windows.h>
-#else
-#include <dirent.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#endif  // WEBRTC_WIN
-
-#include "rtc_base/constructormagic.h"
-
-namespace rtc {
-
-class FileStream;
-class Pathname;
-
-//////////////////////////
-// Directory Iterator   //
-//////////////////////////
-
-// A DirectoryIterator is created with a given directory. It originally points
-// to the first file in the directory, and can be advanecd with Next(). This
-// allows you to get information about each file.
-
-class DirectoryIterator {
-  friend class Filesystem;
-
- public:
-  // Constructor
-  DirectoryIterator();
-  // Destructor
-  virtual ~DirectoryIterator();
-
-  // Starts traversing a directory
-  // dir is the directory to traverse
-  // returns true if the directory exists and is valid
-  // The iterator will point to the first entry in the directory
-  virtual bool Iterate(const Pathname& path);
-
-  // Advances to the next file
-  // returns true if there were more files in the directory.
-  virtual bool Next();
-
-  // returns true if the file currently pointed to is a directory
-  virtual bool IsDirectory() const;
-
-  // returns the name of the file currently pointed to
-  virtual std::string Name() const;
-
- private:
-  std::string directory_;
-#if defined(WEBRTC_WIN)
-  WIN32_FIND_DATA data_;
-  HANDLE handle_;
-#else
-  DIR* dir_;
-  struct dirent* dirent_;
-  struct stat stat_;
-#endif
-};
-
-class FilesystemInterface {
- public:
-  virtual ~FilesystemInterface() {}
-
-  // This will attempt to delete the path located at filename.
-  // It DCHECKs and returns false if the path points to a folder or a
-  // non-existent file.
-  virtual bool DeleteFile(const Pathname& filename) = 0;
-
-  // This moves a file from old_path to new_path, where "old_path" is a
-  // plain file. This DCHECKs and returns false if old_path points to a
-  // directory, and returns true if the function succeeds.
-  virtual bool MoveFile(const Pathname& old_path, const Pathname& new_path) = 0;
-
-  // Returns true if pathname refers to a directory
-  virtual bool IsFolder(const Pathname& pathname) = 0;
-
-  // Returns true if pathname refers to a file
-  virtual bool IsFile(const Pathname& pathname) = 0;
-
-  // Determines the size of the file indicated by path.
-  virtual bool GetFileSize(const Pathname& path, size_t* size) = 0;
-};
-
-class Filesystem {
- public:
-  static bool DeleteFile(const Pathname& filename) {
-    return GetFilesystem()->DeleteFile(filename);
-  }
-
-  static bool MoveFile(const Pathname& old_path, const Pathname& new_path) {
-    return GetFilesystem()->MoveFile(old_path, new_path);
-  }
-
-  static bool IsFolder(const Pathname& pathname) {
-    return GetFilesystem()->IsFolder(pathname);
-  }
-
-  static bool IsFile(const Pathname& pathname) {
-    return GetFilesystem()->IsFile(pathname);
-  }
-
-  static bool GetFileSize(const Pathname& path, size_t* size) {
-    return GetFilesystem()->GetFileSize(path, size);
-  }
-
- private:
-  static FilesystemInterface* GetFilesystem();
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem);
-};
-
-}  // namespace rtc
-
-#endif  // RTC_BASE_FILEUTILS_H_
diff --git a/rtc_base/flags.h b/rtc_base/flags.h
index 1c476d8..a08bfd2 100644
--- a/rtc_base/flags.h
+++ b/rtc_base/flags.h
@@ -36,7 +36,7 @@
   // bool values ('bool b = "false";' results in b == true!), we pass
   // and int argument to New_BOOL as this appears to be safer - sigh.
   // In particular, it prevents the (not uncommon!) bug where a bool
-  // flag is defined via: DEFINE_bool(flag, "false", "some comment");.
+  // flag is defined via: WEBRTC_DEFINE_bool(flag, "false", "some comment");.
   static FlagValue New_BOOL(int b) {
     FlagValue v;
     v.b = (b != 0);
@@ -155,7 +155,7 @@
 };
 
 // Internal use only.
-#define DEFINE_FLAG(type, c_type, name, default, comment)                   \
+#define WEBRTC_DEFINE_FLAG(type, c_type, name, default, comment)            \
   /* define and initialize the flag */                                      \
   c_type FLAG_##name = (default);                                           \
   /* register the flag */                                                   \
@@ -164,25 +164,25 @@
                                rtc::FlagValue::New_##type(default))
 
 // Internal use only.
-#define DECLARE_FLAG(c_type, name) \
-  /* declare the external flag */  \
+#define WEBRTC_DECLARE_FLAG(c_type, name) \
+  /* declare the external flag */         \
   extern c_type FLAG_##name
 
 // Use the following macros to define a new flag:
-#define DEFINE_bool(name, default, comment) \
-  DEFINE_FLAG(BOOL, bool, name, default, comment)
-#define DEFINE_int(name, default, comment) \
-  DEFINE_FLAG(INT, int, name, default, comment)
-#define DEFINE_float(name, default, comment) \
-  DEFINE_FLAG(FLOAT, double, name, default, comment)
-#define DEFINE_string(name, default, comment) \
-  DEFINE_FLAG(STRING, const char*, name, default, comment)
+#define WEBRTC_DEFINE_bool(name, default, comment) \
+  WEBRTC_DEFINE_FLAG(BOOL, bool, name, default, comment)
+#define WEBRTC_DEFINE_int(name, default, comment) \
+  WEBRTC_DEFINE_FLAG(INT, int, name, default, comment)
+#define WEBRTC_DEFINE_float(name, default, comment) \
+  WEBRTC_DEFINE_FLAG(FLOAT, double, name, default, comment)
+#define WEBRTC_DEFINE_string(name, default, comment) \
+  WEBRTC_DEFINE_FLAG(STRING, const char*, name, default, comment)
 
 // Use the following macros to declare a flag defined elsewhere:
-#define DECLARE_bool(name) DECLARE_FLAG(bool, name)
-#define DECLARE_int(name) DECLARE_FLAG(int, name)
-#define DECLARE_float(name) DECLARE_FLAG(double, name)
-#define DECLARE_string(name) DECLARE_FLAG(const char*, name)
+#define WEBRTC_DECLARE_bool(name) WEBRTC_DECLARE_FLAG(bool, name)
+#define WEBRTC_DECLARE_int(name) WEBRTC_DECLARE_FLAG(int, name)
+#define WEBRTC_DECLARE_float(name) WEBRTC_DECLARE_FLAG(double, name)
+#define WEBRTC_DECLARE_string(name) WEBRTC_DECLARE_FLAG(const char*, name)
 
 // The global list of all flags.
 class FlagList {
diff --git a/rtc_base/helpers.h b/rtc_base/helpers.h
index d3b09cf..a93b321 100644
--- a/rtc_base/helpers.h
+++ b/rtc_base/helpers.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_HELPERS_H_
 #define RTC_BASE_HELPERS_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <string>
 
 namespace rtc {
diff --git a/rtc_base/httpcommon.cc b/rtc_base/httpcommon.cc
index 43831b7..7926f88 100644
--- a/rtc_base/httpcommon.cc
+++ b/rtc_base/httpcommon.cc
@@ -24,6 +24,7 @@
 #include <utility>  // for pair
 #include <vector>
 
+#include "absl/strings/match.h"
 #include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/cryptstring.h"  // for CryptString
@@ -32,7 +33,6 @@
 #include "rtc_base/messagedigest.h"
 #include "rtc_base/socketaddress.h"
 #include "rtc_base/strings/string_builder.h"
-#include "rtc_base/stringutils.h"                // for strcpyn, _stricmp
 #include "rtc_base/third_party/base64/base64.h"  // for Base64
 #include "rtc_base/zero_memory.h"                // for ExplicitZeroMemory
 
@@ -266,7 +266,7 @@
     return HAR_IGNORE;
 
   // BASIC
-  if (_stricmp(auth_method.c_str(), "basic") == 0) {
+  if (absl::EqualsIgnoreCase(auth_method, "basic")) {
     if (context)
       return HAR_CREDENTIALS;  // Bad credentials
     if (username.empty())
@@ -294,7 +294,7 @@
   }
 
   // DIGEST
-  if (_stricmp(auth_method.c_str(), "digest") == 0) {
+  if (absl::EqualsIgnoreCase(auth_method, "digest")) {
     if (context)
       return HAR_CREDENTIALS;  // Bad credentials
     if (username.empty())
@@ -361,8 +361,8 @@
 
 #if defined(WEBRTC_WIN)
 #if 1
-  bool want_negotiate = (_stricmp(auth_method.c_str(), "negotiate") == 0);
-  bool want_ntlm = (_stricmp(auth_method.c_str(), "ntlm") == 0);
+  bool want_negotiate = absl::EqualsIgnoreCase(auth_method, "negotiate");
+  bool want_ntlm = absl::EqualsIgnoreCase(auth_method, "ntlm");
   // SPNEGO & NTLM
   if (want_negotiate || want_ntlm) {
     const size_t MAX_MESSAGE = 12000, MAX_SPN = 256;
@@ -377,7 +377,7 @@
       return HAR_IGNORE;
     }
 #else
-    sprintfn(spn, MAX_SPN, "HTTP/%s", server.ToString().c_str());
+    snprintf(spn, MAX_SPN, "HTTP/%s", server.ToString().c_str());
 #endif
 
     SecBuffer out_sec;
diff --git a/rtc_base/ipaddress.cc b/rtc_base/ipaddress.cc
index c52c9a4..027a7b2 100644
--- a/rtc_base/ipaddress.cc
+++ b/rtc_base/ipaddress.cc
@@ -11,24 +11,17 @@
 #if defined(WEBRTC_POSIX)
 #include <netinet/in.h>
 #include <sys/socket.h>
-#include <sys/types.h>
 #ifdef OPENBSD
 #include <netinet/in_systm.h>
 #endif
 #ifndef __native_client__
 #include <netinet/ip.h>
 #endif
-#include <arpa/inet.h>
 #include <netdb.h>
-#include <unistd.h>
 #endif
 
-#include <stdio.h>
-
 #include "rtc_base/byteorder.h"
-#include "rtc_base/checks.h"
 #include "rtc_base/ipaddress.h"
-#include "rtc_base/logging.h"
 #include "rtc_base/nethelpers.h"
 #include "rtc_base/stringutils.h"
 
@@ -162,11 +155,10 @@
       std::string result;
       result.resize(INET6_ADDRSTRLEN);
       in6_addr addr = ipv6_address();
-      size_t len =
-          rtc::sprintfn(&(result[0]), result.size(), "%x:%x:%x:x:x:x:x:x",
-                        (addr.s6_addr[0] << 8) + addr.s6_addr[1],
-                        (addr.s6_addr[2] << 8) + addr.s6_addr[3],
-                        (addr.s6_addr[4] << 8) + addr.s6_addr[5]);
+      size_t len = snprintf(&(result[0]), result.size(), "%x:%x:%x:x:x:x:x:x",
+                            (addr.s6_addr[0] << 8) + addr.s6_addr[1],
+                            (addr.s6_addr[2] << 8) + addr.s6_addr[3],
+                            (addr.s6_addr[4] << 8) + addr.s6_addr[5]);
       result.resize(len);
       return result;
     }
diff --git a/rtc_base/key_derivation.cc b/rtc_base/key_derivation.cc
new file mode 100644
index 0000000..288e407
--- /dev/null
+++ b/rtc_base/key_derivation.cc
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 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 "rtc_base/key_derivation.h"
+
+#include "absl/memory/memory.h"
+#include "rtc_base/openssl_key_derivation_hkdf.h"
+
+namespace rtc {
+
+KeyDerivation::KeyDerivation() = default;
+KeyDerivation::~KeyDerivation() = default;
+
+// static
+std::unique_ptr<KeyDerivation> KeyDerivation::Create(
+    KeyDerivationAlgorithm key_derivation_algorithm) {
+  switch (key_derivation_algorithm) {
+    case KeyDerivationAlgorithm::HKDF_SHA256:
+      return absl::make_unique<OpenSSLKeyDerivationHKDF>();
+  }
+  RTC_NOTREACHED();
+}
+
+}  // namespace rtc
diff --git a/rtc_base/key_derivation.h b/rtc_base/key_derivation.h
new file mode 100644
index 0000000..fa329ae
--- /dev/null
+++ b/rtc_base/key_derivation.h
@@ -0,0 +1,70 @@
+/*
+ *  Copyright 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 RTC_BASE_KEY_DERIVATION_H_
+#define RTC_BASE_KEY_DERIVATION_H_
+
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "rtc_base/buffer.h"
+#include "rtc_base/constructormagic.h"
+
+namespace rtc {
+
+// Defines the set of key derivation algorithms that are supported. It is ideal
+// to keep this list as small as possible.
+enum class KeyDerivationAlgorithm {
+  // This algorithm is not suitable to generate a key from a password. Please
+  // only use with a cryptographically random master secret.
+  HKDF_SHA256
+};
+
+// KeyDerivation provides a generic interface for deriving keys in WebRTC. This
+// class should be used over directly accessing openssl or boringssl primitives
+// so that we can maintain seperate implementations.
+// Example:
+//   auto kd = KeyDerivation::Create(KeyDerivationAlgorithm::HDKF_SHA526);
+//   if (kd == nullptr) return;
+//   auto derived_key_or = kd->DeriveKey(secret, salt, label);
+//   if (!derived_key_or.ok()) return;
+//   DoSomethingWithKey(derived_key_or.value());
+class KeyDerivation {
+ public:
+  KeyDerivation();
+  virtual ~KeyDerivation();
+
+  // Derives a new key from existing key material.
+  // secret - The random secret value you wish to derive a key from.
+  // salt - Optional but recommended (non secret) cryptographically random.
+  // label - A non secret but unique label value to determine the derivation.
+  // derived_key_byte_size - This must be at least 128 bits.
+  // return - An optional ZeroOnFreeBuffer containing the derived key or
+  // absl::nullopt. Nullopt indicates a failure in derivation.
+  virtual absl::optional<ZeroOnFreeBuffer<uint8_t>> DeriveKey(
+      rtc::ArrayView<const uint8_t> secret,
+      rtc::ArrayView<const uint8_t> salt,
+      rtc::ArrayView<const uint8_t> label,
+      size_t derived_key_byte_size) = 0;
+
+  // Static factory that will return an implementation that is capable of
+  // handling the key derivation with the requested algorithm. If no
+  // implementation is available nullptr will be returned.
+  static std::unique_ptr<KeyDerivation> Create(
+      KeyDerivationAlgorithm key_derivation_algorithm);
+
+ private:
+  RTC_DISALLOW_COPY_AND_ASSIGN(KeyDerivation);
+};
+
+}  // namespace rtc
+
+#endif  // RTC_BASE_KEY_DERIVATION_H_
diff --git a/rtc_base/location.cc b/rtc_base/location.cc
index 9c90d9e..c95ad9c 100644
--- a/rtc_base/location.cc
+++ b/rtc_base/location.cc
@@ -10,8 +10,6 @@
 
 #include "rtc_base/location.h"
 
-#include "rtc_base/stringutils.h"
-
 namespace rtc {
 
 Location::Location(const char* function_name, const char* file_and_line)
@@ -31,7 +29,7 @@
 
 std::string Location::ToString() const {
   char buf[256];
-  sprintfn(buf, sizeof(buf), "%s@%s", function_name_, file_and_line_);
+  snprintf(buf, sizeof(buf), "%s@%s", function_name_, file_and_line_);
   return buf;
 }
 
diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc
index 53a1ed8..bb4fbfa 100644
--- a/rtc_base/logging.cc
+++ b/rtc_base/logging.cc
@@ -20,24 +20,28 @@
 #include <CoreServices/CoreServices.h>
 #elif defined(WEBRTC_ANDROID)
 #include <android/log.h>
+
 // Android has a 1024 limit on log inputs. We use 60 chars as an
 // approx for the header/tag portion.
 // See android/system/core/liblog/logd_write.c
 static const int kMaxLogLineSize = 1024 - 60;
 #endif  // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID
 
+#include <stdio.h>
+#include <string.h>
 #include <time.h>
-
 #include <algorithm>
 #include <cstdarg>
 #include <vector>
 
+#include "rtc_base/checks.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/platform_thread_types.h"
 #include "rtc_base/stringencode.h"
 #include "rtc_base/strings/string_builder.h"
 #include "rtc_base/stringutils.h"
+#include "rtc_base/thread_annotations.h"
 #include "rtc_base/timeutils.h"
 
 namespace rtc {
@@ -69,7 +73,12 @@
 void LogSink::OnLogMessage(const std::string& msg,
                            LoggingSeverity severity,
                            const char* tag) {
-  OnLogMessage(tag + (": " + msg));
+  OnLogMessage(tag + (": " + msg), severity);
+}
+
+void LogSink::OnLogMessage(const std::string& msg,
+                           LoggingSeverity /* severity */) {
+  OnLogMessage(msg);
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -202,7 +211,7 @@
 #if defined(WEBRTC_ANDROID)
       kv.first->OnLogMessage(str, severity_, tag_);
 #else
-      kv.first->OnLogMessage(str);
+      kv.first->OnLogMessage(str, severity_);
 #endif
     }
   }
diff --git a/rtc_base/logging.h b/rtc_base/logging.h
index 4292971..c15c37a 100644
--- a/rtc_base/logging.h
+++ b/rtc_base/logging.h
@@ -115,6 +115,8 @@
   virtual void OnLogMessage(const std::string& msg,
                             LoggingSeverity severity,
                             const char* tag);
+  virtual void OnLogMessage(const std::string& message,
+                            LoggingSeverity severity);
   virtual void OnLogMessage(const std::string& message) = 0;
 };
 
diff --git a/rtc_base/logging_unittest.cc b/rtc_base/logging_unittest.cc
index a475e52..4de1cf2 100644
--- a/rtc_base/logging_unittest.cc
+++ b/rtc_base/logging_unittest.cc
@@ -292,7 +292,7 @@
   static void ThreadEntry(void* p) { static_cast<LogThread*>(p)->Run(); }
 
   PlatformThread thread_;
-  Event event_{false, false};
+  Event event_;
 };
 
 // Ensure we don't crash when adding/removing streams while threads are going.
diff --git a/rtc_base/logsinks.cc b/rtc_base/logsinks.cc
index 662b1f2..c01bafb 100644
--- a/rtc_base/logsinks.cc
+++ b/rtc_base/logsinks.cc
@@ -10,10 +10,12 @@
 
 #include "rtc_base/logsinks.h"
 
+#include <string.h>
 #include <cstdio>
 #include <string>
 
 #include "rtc_base/checks.h"
+#include "rtc_base/stream.h"
 
 namespace rtc {
 
diff --git a/rtc_base/logsinks.h b/rtc_base/logsinks.h
index caf4a5f..d0867a2 100644
--- a/rtc_base/logsinks.h
+++ b/rtc_base/logsinks.h
@@ -11,6 +11,7 @@
 #ifndef RTC_BASE_LOGSINKS_H_
 #define RTC_BASE_LOGSINKS_H_
 
+#include <stddef.h>
 #include <memory>
 #include <string>
 
diff --git a/rtc_base/mdns_responder_interface.h b/rtc_base/mdns_responder_interface.h
index 9dbaf56..71938b2 100644
--- a/rtc_base/mdns_responder_interface.h
+++ b/rtc_base/mdns_responder_interface.h
@@ -12,36 +12,35 @@
 #define RTC_BASE_MDNS_RESPONDER_INTERFACE_H_
 
 #include <functional>
-#include <map>
-#include <memory>
-#include <set>
 #include <string>
 
 #include "rtc_base/ipaddress.h"
-#include "rtc_base/socketaddress.h"
 
 namespace webrtc {
 
 // Defines an mDNS responder that can be used in ICE candidate gathering, where
-// the local IP addresses of host candidates are obfuscated by mDNS hostnames.
-class MDnsResponderInterface {
+// the local IP addresses of host candidates are replaced by mDNS hostnames.
+class MdnsResponderInterface {
  public:
   using NameCreatedCallback =
       std::function<void(const rtc::IPAddress&, const std::string&)>;
   using NameRemovedCallback = std::function<void(bool)>;
 
-  MDnsResponderInterface() = default;
-  virtual ~MDnsResponderInterface() = default;
+  MdnsResponderInterface() = default;
+  virtual ~MdnsResponderInterface() = default;
 
-  // Asynchronously creates a type-4 UUID hostname for an IP address. The
-  // created name should be given to |callback| with the address that it
-  // represents.
+  // Asynchronously creates and returns a new name via |callback| for |addr| if
+  // there is no name mapped to it by this responder, and initializes the
+  // reference count of this name to one. Otherwise the existing name mapped to
+  // |addr| is returned and its reference count is incremented by one.
   virtual void CreateNameForAddress(const rtc::IPAddress& addr,
                                     NameCreatedCallback callback) = 0;
-  // Removes the name mapped to the given address if there is such an
-  // name-address mapping previously created via CreateNameForAddress. The
-  // result of whether an associated name-address mapping is removed should be
-  // given to |callback|.
+  // Decrements the reference count of the mapped name of |addr|, if
+  // there is a map created previously via CreateNameForAddress; asynchronously
+  // removes the association between |addr| and its mapped name, and returns
+  // true via |callback| if the decremented reference count reaches zero.
+  // Otherwise no operation is done and false is returned via |callback|
+  // asynchronously.
   virtual void RemoveNameForAddress(const rtc::IPAddress& addr,
                                     NameRemovedCallback callback) = 0;
 };
diff --git a/rtc_base/memory_stream.cc b/rtc_base/memory_stream.cc
new file mode 100644
index 0000000..541de07
--- /dev/null
+++ b/rtc_base/memory_stream.cc
@@ -0,0 +1,143 @@
+/*
+ *  Copyright 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 <algorithm>
+
+#include "rtc_base/memory_stream.h"
+
+namespace rtc {
+
+StreamState MemoryStream::GetState() const {
+  return SS_OPEN;
+}
+
+StreamResult MemoryStream::Read(void* buffer,
+                                size_t bytes,
+                                size_t* bytes_read,
+                                int* error) {
+  if (seek_position_ >= data_length_) {
+    return SR_EOS;
+  }
+  size_t available = data_length_ - seek_position_;
+  if (bytes > available) {
+    // Read partial buffer
+    bytes = available;
+  }
+  memcpy(buffer, &buffer_[seek_position_], bytes);
+  seek_position_ += bytes;
+  if (bytes_read) {
+    *bytes_read = bytes;
+  }
+  return SR_SUCCESS;
+}
+
+StreamResult MemoryStream::Write(const void* buffer,
+                                 size_t bytes,
+                                 size_t* bytes_written,
+                                 int* error) {
+  size_t available = buffer_length_ - seek_position_;
+  if (0 == available) {
+    // Increase buffer size to the larger of:
+    // a) new position rounded up to next 256 bytes
+    // b) double the previous length
+    size_t new_buffer_length =
+        std::max(((seek_position_ + bytes) | 0xFF) + 1, buffer_length_ * 2);
+    StreamResult result = DoReserve(new_buffer_length, error);
+    if (SR_SUCCESS != result) {
+      return result;
+    }
+    RTC_DCHECK(buffer_length_ >= new_buffer_length);
+    available = buffer_length_ - seek_position_;
+  }
+
+  if (bytes > available) {
+    bytes = available;
+  }
+  memcpy(&buffer_[seek_position_], buffer, bytes);
+  seek_position_ += bytes;
+  if (data_length_ < seek_position_) {
+    data_length_ = seek_position_;
+  }
+  if (bytes_written) {
+    *bytes_written = bytes;
+  }
+  return SR_SUCCESS;
+}
+
+void MemoryStream::Close() {
+  // nothing to do
+}
+
+bool MemoryStream::SetPosition(size_t position) {
+  if (position > data_length_)
+    return false;
+  seek_position_ = position;
+  return true;
+}
+
+bool MemoryStream::GetPosition(size_t* position) const {
+  if (position)
+    *position = seek_position_;
+  return true;
+}
+
+bool MemoryStream::GetSize(size_t* size) const {
+  if (size)
+    *size = data_length_;
+  return true;
+}
+
+bool MemoryStream::ReserveSize(size_t size) {
+  return (SR_SUCCESS == DoReserve(size, nullptr));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+MemoryStream::MemoryStream() {}
+
+MemoryStream::MemoryStream(const char* data) {
+  SetData(data, strlen(data));
+}
+
+MemoryStream::MemoryStream(const void* data, size_t length) {
+  SetData(data, length);
+}
+
+MemoryStream::~MemoryStream() {
+  delete[] buffer_;
+}
+
+void MemoryStream::SetData(const void* data, size_t length) {
+  data_length_ = buffer_length_ = length;
+  delete[] buffer_;
+  buffer_ = new char[buffer_length_];
+  memcpy(buffer_, data, data_length_);
+  seek_position_ = 0;
+}
+
+StreamResult MemoryStream::DoReserve(size_t size, int* error) {
+  if (buffer_length_ >= size)
+    return SR_SUCCESS;
+
+  if (char* new_buffer = new char[size]) {
+    memcpy(new_buffer, buffer_, data_length_);
+    delete[] buffer_;
+    buffer_ = new_buffer;
+    buffer_length_ = size;
+    return SR_SUCCESS;
+  }
+
+  if (error) {
+    *error = ENOMEM;
+  }
+  return SR_ERROR;
+}
+
+}  // namespace rtc
diff --git a/rtc_base/memory_stream.h b/rtc_base/memory_stream.h
new file mode 100644
index 0000000..936f71b
--- /dev/null
+++ b/rtc_base/memory_stream.h
@@ -0,0 +1,59 @@
+/*
+ *  Copyright 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 RTC_BASE_MEMORY_STREAM_H_
+#define RTC_BASE_MEMORY_STREAM_H_
+
+#include "rtc_base/stream.h"
+
+namespace rtc {
+
+// MemoryStream dynamically resizes to accomodate written data.
+
+class MemoryStream final : public StreamInterface {
+ public:
+  MemoryStream();
+  explicit MemoryStream(const char* data);  // Calls SetData(data, strlen(data))
+  MemoryStream(const void* data, size_t length);  // Calls SetData(data, length)
+  ~MemoryStream() override;
+
+  StreamState GetState() const override;
+  StreamResult Read(void* buffer,
+                    size_t bytes,
+                    size_t* bytes_read,
+                    int* error) override;
+  StreamResult Write(const void* buffer,
+                     size_t bytes,
+                     size_t* bytes_written,
+                     int* error) override;
+  void Close() override;
+  bool SetPosition(size_t position) override;
+  bool GetPosition(size_t* position) const override;
+  bool GetSize(size_t* size) const override;
+  bool ReserveSize(size_t size) override;
+
+  char* GetBuffer() { return buffer_; }
+  const char* GetBuffer() const { return buffer_; }
+
+  void SetData(const void* data, size_t length);
+
+ private:
+  StreamResult DoReserve(size_t size, int* error);
+
+  // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_
+  char* buffer_ = nullptr;
+  size_t buffer_length_ = 0;
+  size_t data_length_ = 0;
+  size_t seek_position_ = 0;
+};
+
+}  // namespace rtc
+
+#endif  // RTC_BASE_MEMORY_STREAM_H_
diff --git a/rtc_base/memory_usage.cc b/rtc_base/memory_usage.cc
index a70c547..9cd36d3 100644
--- a/rtc_base/memory_usage.cc
+++ b/rtc_base/memory_usage.cc
@@ -61,6 +61,9 @@
     return -1;
   }
   return pmc.WorkingSetSize;
+#elif defined(WEBRTC_FUCHSIA)
+  RTC_LOG_ERR(LS_ERROR) << "GetProcessResidentSizeBytes() not implemented";
+  return 0;
 #else
   // Not implemented yet.
   static_assert(false,
diff --git a/rtc_base/messagedigest.cc b/rtc_base/messagedigest.cc
index 9c10bcd..5a0d16a 100644
--- a/rtc_base/messagedigest.cc
+++ b/rtc_base/messagedigest.cc
@@ -10,9 +10,9 @@
 
 #include "rtc_base/messagedigest.h"
 
-#include <memory>
-
 #include <string.h>
+#include <cstdint>
+#include <memory>
 
 #include "rtc_base/openssldigest.h"
 #include "rtc_base/stringencode.h"
diff --git a/rtc_base/messagedigest.h b/rtc_base/messagedigest.h
index fc82088..757f914 100644
--- a/rtc_base/messagedigest.h
+++ b/rtc_base/messagedigest.h
@@ -11,6 +11,7 @@
 #ifndef RTC_BASE_MESSAGEDIGEST_H_
 #define RTC_BASE_MESSAGEDIGEST_H_
 
+#include <stddef.h>
 #include <string>
 
 namespace rtc {
diff --git a/rtc_base/messagequeue.cc b/rtc_base/messagequeue.cc
index 84d3a96..204952a 100644
--- a/rtc_base/messagequeue.cc
+++ b/rtc_base/messagequeue.cc
@@ -8,14 +8,15 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 #include <algorithm>
-#include <utility>  // for move
+#include <string>
+#include <utility>
 
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/messagequeue.h"
 #include "rtc_base/thread.h"
-#include "rtc_base/timeutils.h"  // for TimeMillis, TimeDiff, TimeUntil
+#include "rtc_base/timeutils.h"
 #include "rtc_base/trace_event.h"
 
 namespace rtc {
@@ -349,8 +350,10 @@
                         uint32_t id,
                         MessageData* pdata,
                         bool time_sensitive) {
-  if (IsQuitting())
+  if (IsQuitting()) {
+    delete pdata;
     return;
+  }
 
   // Keep thread safe
   // Add the message to the end of the queue
@@ -406,6 +409,7 @@
                                uint32_t id,
                                MessageData* pdata) {
   if (IsQuitting()) {
+    delete pdata;
     return;
   }
 
diff --git a/rtc_base/module.mk b/rtc_base/module.mk
index 2a1b9f3..8364fe5 100644
--- a/rtc_base/module.mk
+++ b/rtc_base/module.mk
@@ -17,7 +17,6 @@
 	rtc_base/flags.o \
 	rtc_base/location.o \
 	rtc_base/numerics/histogram_percentile_counter.o \
-	rtc_base/pathutils.o \
 	rtc_base/platform_file.o \
 	rtc_base/platform_thread.o \
 	rtc_base/platform_thread_types.o \
diff --git a/rtc_base/natserver.cc b/rtc_base/natserver.cc
index 8119376..b005eca 100644
--- a/rtc_base/natserver.cc
+++ b/rtc_base/natserver.cc
@@ -158,7 +158,7 @@
                                     const char* buf,
                                     size_t size,
                                     const SocketAddress& addr,
-                                    const PacketTime& packet_time) {
+                                    const int64_t& /* packet_time_us */) {
   // Read the intended destination from the wire.
   SocketAddress dest_addr;
   size_t length = UnpackAddressFromNAT(buf, size, &dest_addr);
@@ -184,7 +184,7 @@
                                     const char* buf,
                                     size_t size,
                                     const SocketAddress& remote_addr,
-                                    const PacketTime& packet_time) {
+                                    const int64_t& /* packet_time_us */) {
   SocketAddress local_addr = socket->GetLocalAddress();
 
   // Find the translation for this addresses.
diff --git a/rtc_base/natserver.h b/rtc_base/natserver.h
index f4cabcf..d16b537 100644
--- a/rtc_base/natserver.h
+++ b/rtc_base/natserver.h
@@ -81,12 +81,12 @@
                            const char* buf,
                            size_t size,
                            const SocketAddress& addr,
-                           const PacketTime& packet_time);
+                           const int64_t& packet_time_us);
   void OnExternalUDPPacket(AsyncPacketSocket* socket,
                            const char* buf,
                            size_t size,
                            const SocketAddress& remote_addr,
-                           const PacketTime& packet_time);
+                           const int64_t& packet_time_us);
 
  private:
   typedef std::set<SocketAddress, AddrCmp> AddressSet;
diff --git a/rtc_base/nethelpers.h b/rtc_base/nethelpers.h
index 429f0c0..138f958 100644
--- a/rtc_base/nethelpers.h
+++ b/rtc_base/nethelpers.h
@@ -12,8 +12,7 @@
 #define RTC_BASE_NETHELPERS_H_
 
 #if defined(WEBRTC_POSIX)
-#include <netdb.h>
-#include <stddef.h>
+#include <sys/socket.h>
 #elif WEBRTC_WIN
 #include <winsock2.h>  // NOLINT
 #endif
@@ -21,7 +20,7 @@
 #include <vector>
 
 #include "rtc_base/asyncresolverinterface.h"
-#include "rtc_base/ipaddress.h"  // for IPAddress
+#include "rtc_base/ipaddress.h"
 #include "rtc_base/signalthread.h"
 #include "rtc_base/socketaddress.h"
 
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index 67888ed..5c7b019 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -38,7 +38,6 @@
 #include "rtc_base/logging.h"
 #include "rtc_base/networkmonitor.h"
 #include "rtc_base/socket.h"  // includes something that makes windows happy
-#include "rtc_base/stream.h"
 #include "rtc_base/stringencode.h"
 #include "rtc_base/strings/string_builder.h"
 #include "rtc_base/stringutils.h"
@@ -260,7 +259,7 @@
   return false;
 }
 
-webrtc::MDnsResponderInterface* NetworkManager::GetMDnsResponder() const {
+webrtc::MdnsResponderInterface* NetworkManager::GetMdnsResponder() const {
   return nullptr;
 }
 
@@ -286,7 +285,7 @@
         new rtc::Network("any", "any", ipv4_any_address, 0, ADAPTER_TYPE_ANY));
     ipv4_any_address_network_->set_default_local_address_provider(this);
     ipv4_any_address_network_->AddIP(ipv4_any_address);
-    ipv4_any_address_network_->SetMDnsResponder(GetMDnsResponder());
+    ipv4_any_address_network_->SetMdnsResponder(GetMdnsResponder());
   }
   networks->push_back(ipv4_any_address_network_.get());
 
@@ -297,7 +296,7 @@
           "any", "any", ipv6_any_address, 0, ADAPTER_TYPE_ANY));
       ipv6_any_address_network_->set_default_local_address_provider(this);
       ipv6_any_address_network_->AddIP(ipv6_any_address);
-      ipv6_any_address_network_->SetMDnsResponder(GetMDnsResponder());
+      ipv6_any_address_network_->SetMdnsResponder(GetMdnsResponder());
     }
     networks->push_back(ipv6_any_address_network_.get());
   }
@@ -387,7 +386,7 @@
         delete net;
       }
     }
-    networks_map_[key]->SetMDnsResponder(GetMDnsResponder());
+    networks_map_[key]->SetMdnsResponder(GetMdnsResponder());
   }
   // It may still happen that the merged list is a subset of |networks_|.
   // To detect this change, we compare their sizes.
@@ -775,26 +774,28 @@
 
 #if defined(WEBRTC_LINUX)
 bool IsDefaultRoute(const std::string& network_name) {
-  FileStream fs;
-  if (!fs.Open("/proc/net/route", "r", nullptr)) {
+  FILE* f = fopen("/proc/net/route", "r");
+  if (!f) {
     RTC_LOG(LS_WARNING)
         << "Couldn't read /proc/net/route, skipping default "
         << "route check (assuming everything is a default route).";
     return true;
-  } else {
-    std::string line;
-    while (fs.ReadLine(&line) == SR_SUCCESS) {
-      char iface_name[256];
-      unsigned int iface_ip, iface_gw, iface_mask, iface_flags;
-      if (sscanf(line.c_str(), "%255s %8X %8X %4X %*d %*u %*d %8X", iface_name,
-                 &iface_ip, &iface_gw, &iface_flags, &iface_mask) == 5 &&
-          network_name == iface_name && iface_mask == 0 &&
-          (iface_flags & (RTF_UP | RTF_HOST)) == RTF_UP) {
-        return true;
-      }
+  }
+  bool is_default_route = false;
+  char line[500];
+  while (fgets(line, sizeof(line), f)) {
+    char iface_name[256];
+    unsigned int iface_ip, iface_gw, iface_mask, iface_flags;
+    if (sscanf(line, "%255s %8X %8X %4X %*d %*u %*d %8X", iface_name, &iface_ip,
+               &iface_gw, &iface_flags, &iface_mask) == 5 &&
+        network_name == iface_name && iface_mask == 0 &&
+        (iface_flags & (RTF_UP | RTF_HOST)) == RTF_UP) {
+      is_default_route = true;
+      break;
     }
   }
-  return false;
+  fclose(f);
+  return is_default_route;
 }
 #endif
 
diff --git a/rtc_base/network.h b/rtc_base/network.h
index 601e39f..8b1a5fc 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -141,7 +141,7 @@
 
   // Returns the mDNS responder that can be used to obfuscate the local IP
   // addresses of ICE host candidates by mDNS hostnames.
-  virtual webrtc::MDnsResponderInterface* GetMDnsResponder() const;
+  virtual webrtc::MdnsResponderInterface* GetMdnsResponder() const;
 };
 
 // Base class for NetworkManager implementations.
@@ -367,11 +367,11 @@
   // created name will be resolved by the responder.
   //
   // The mDNS responder, if not null, should outlive this rtc::Network.
-  void SetMDnsResponder(webrtc::MDnsResponderInterface* mdns_responder) {
+  void SetMdnsResponder(webrtc::MdnsResponderInterface* mdns_responder) {
     mdns_responder_ = mdns_responder;
   }
   // Returns the mDNS responder, which is null by default.
-  webrtc::MDnsResponderInterface* GetMDnsResponder() const {
+  webrtc::MdnsResponderInterface* GetMdnsResponder() const {
     return mdns_responder_;
   }
 
@@ -446,7 +446,7 @@
   int prefix_length_;
   std::string key_;
   std::vector<InterfaceAddress> ips_;
-  webrtc::MDnsResponderInterface* mdns_responder_ = nullptr;
+  webrtc::MdnsResponderInterface* mdns_responder_ = nullptr;
   int scope_id_;
   bool ignored_;
   AdapterType type_;
diff --git a/rtc_base/network/BUILD.gn b/rtc_base/network/BUILD.gn
new file mode 100644
index 0000000..0fbdbb1
--- /dev/null
+++ b/rtc_base/network/BUILD.gn
@@ -0,0 +1,19 @@
+# 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.
+
+import("../../webrtc.gni")
+
+rtc_source_set("sent_packet") {
+  sources = [
+    "sent_packet.cc",
+    "sent_packet.h",
+  ]
+  deps = [
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
diff --git a/rtc_base/network/sent_packet.cc b/rtc_base/network/sent_packet.cc
new file mode 100644
index 0000000..8cc4973
--- /dev/null
+++ b/rtc_base/network/sent_packet.cc
@@ -0,0 +1,27 @@
+/*
+ *  Copyright 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 "rtc_base/network/sent_packet.h"
+
+namespace rtc {
+
+PacketInfo::PacketInfo() = default;
+PacketInfo::PacketInfo(const PacketInfo& info) = default;
+PacketInfo::~PacketInfo() = default;
+
+SentPacket::SentPacket() = default;
+SentPacket::SentPacket(int64_t packet_id, int64_t send_time_ms)
+    : packet_id(packet_id), send_time_ms(send_time_ms) {}
+SentPacket::SentPacket(int64_t packet_id,
+                       int64_t send_time_ms,
+                       const rtc::PacketInfo& info)
+    : packet_id(packet_id), send_time_ms(send_time_ms), info(info) {}
+
+}  // namespace rtc
diff --git a/rtc_base/network/sent_packet.h b/rtc_base/network/sent_packet.h
new file mode 100644
index 0000000..0cad31c
--- /dev/null
+++ b/rtc_base/network/sent_packet.h
@@ -0,0 +1,68 @@
+/*
+ *  Copyright 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 RTC_BASE_NETWORK_SENT_PACKET_H_
+#define RTC_BASE_NETWORK_SENT_PACKET_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+
+namespace rtc {
+
+enum class PacketType {
+  kUnknown,
+  kData,
+  kIceConnectivityCheck,
+  kIceConnectivityCheckResponse,
+  kStunMessage,
+  kTurnMessage,
+};
+
+enum class PacketInfoProtocolType {
+  kUnknown,
+  kUdp,
+  kTcp,
+  kSsltcp,
+  kTls,
+};
+
+struct PacketInfo {
+  PacketInfo();
+  PacketInfo(const PacketInfo& info);
+  ~PacketInfo();
+
+  bool included_in_feedback = false;
+  bool included_in_allocation = false;
+  PacketType packet_type = PacketType::kUnknown;
+  PacketInfoProtocolType protocol = PacketInfoProtocolType::kUnknown;
+  // A unique id assigned by the network manager, and absl::nullopt if not set.
+  absl::optional<uint16_t> network_id;
+  size_t packet_size_bytes = 0;
+  size_t turn_overhead_bytes = 0;
+  size_t ip_overhead_bytes = 0;
+};
+
+struct SentPacket {
+  SentPacket();
+  SentPacket(int64_t packet_id, int64_t send_time_ms);
+  SentPacket(int64_t packet_id,
+             int64_t send_time_ms,
+             const rtc::PacketInfo& info);
+
+  int64_t packet_id = -1;
+  int64_t send_time_ms = -1;
+  rtc::PacketInfo info;
+};
+
+}  // namespace rtc
+
+#endif  // RTC_BASE_NETWORK_SENT_PACKET_H_
diff --git a/rtc_base/networkmonitor.cc b/rtc_base/networkmonitor.cc
index e3b2efd..0185eab 100644
--- a/rtc_base/networkmonitor.cc
+++ b/rtc_base/networkmonitor.cc
@@ -10,7 +10,10 @@
 
 #include "rtc_base/networkmonitor.h"
 
+#include <stdint.h>
+
 #include "rtc_base/checks.h"
+#include "rtc_base/location.h"
 #include "rtc_base/logging.h"
 
 namespace {
diff --git a/rtc_base/noop.cc b/rtc_base/noop.cc
deleted file mode 100644
index 16a8e6d..0000000
--- a/rtc_base/noop.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- *  Copyright 2015 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.
- */
-
-// This file is only needed to make ninja happy on some platforms.
-// On some platforms it is not possible to link an rtc_static_library
-// without any source file listed in the GN target.
diff --git a/rtc_base/noop.mm b/rtc_base/noop.mm
deleted file mode 100644
index 16a8e6d..0000000
--- a/rtc_base/noop.mm
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- *  Copyright 2015 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.
- */
-
-// This file is only needed to make ninja happy on some platforms.
-// On some platforms it is not possible to link an rtc_static_library
-// without any source file listed in the GN target.
diff --git a/rtc_base/nullsocketserver.cc b/rtc_base/nullsocketserver.cc
index c890c6f..ec042dd 100644
--- a/rtc_base/nullsocketserver.cc
+++ b/rtc_base/nullsocketserver.cc
@@ -13,7 +13,7 @@
 
 namespace rtc {
 
-NullSocketServer::NullSocketServer() : event_(false, false) {}
+NullSocketServer::NullSocketServer() = default;
 NullSocketServer::~NullSocketServer() {}
 
 bool NullSocketServer::Wait(int cms, bool process_io) {
diff --git a/rtc_base/nullsocketserver.h b/rtc_base/nullsocketserver.h
index 408bcd1..47a7fa6 100644
--- a/rtc_base/nullsocketserver.h
+++ b/rtc_base/nullsocketserver.h
@@ -11,7 +11,9 @@
 #ifndef RTC_BASE_NULLSOCKETSERVER_H_
 #define RTC_BASE_NULLSOCKETSERVER_H_
 
+#include "rtc_base/asyncsocket.h"
 #include "rtc_base/event.h"
+#include "rtc_base/socket.h"
 #include "rtc_base/socketserver.h"
 
 namespace rtc {
diff --git a/rtc_base/numerics/moving_average.cc b/rtc_base/numerics/moving_average.cc
new file mode 100644
index 0000000..c825839
--- /dev/null
+++ b/rtc_base/numerics/moving_average.cc
@@ -0,0 +1,60 @@
+/*
+ *  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 "rtc_base/numerics/moving_average.h"
+
+#include <algorithm>
+
+#include "rtc_base/checks.h"
+
+namespace rtc {
+
+MovingAverage::MovingAverage(size_t window_size) : history_(window_size, 0) {
+  // Limit window size to avoid overflow.
+  RTC_DCHECK_LE(window_size, (int64_t{1} << 32) - 1);
+}
+MovingAverage::~MovingAverage() = default;
+
+void MovingAverage::AddSample(int sample) {
+  count_++;
+  size_t index = count_ % history_.size();
+  if (count_ > history_.size())
+    sum_ -= history_[index];
+  sum_ += sample;
+  history_[index] = sample;
+}
+
+absl::optional<int> MovingAverage::GetAverageRoundedDown() const {
+  if (count_ == 0)
+    return absl::nullopt;
+  return sum_ / Size();
+}
+
+absl::optional<int> MovingAverage::GetAverageRoundedToClosest() const {
+  if (count_ == 0)
+    return absl::nullopt;
+  return (sum_ + Size() / 2) / Size();
+}
+
+absl::optional<double> MovingAverage::GetUnroundedAverage() const {
+  if (count_ == 0)
+    return absl::nullopt;
+  return sum_ / static_cast<double>(Size());
+}
+
+void MovingAverage::Reset() {
+  count_ = 0;
+  sum_ = 0;
+}
+
+size_t MovingAverage::Size() const {
+  return std::min(count_, history_.size());
+}
+}  // namespace rtc
diff --git a/rtc_base/numerics/moving_average.h b/rtc_base/numerics/moving_average.h
new file mode 100644
index 0000000..770e47d
--- /dev/null
+++ b/rtc_base/numerics/moving_average.h
@@ -0,0 +1,63 @@
+/*
+ *  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 RTC_BASE_NUMERICS_MOVING_AVERAGE_H_
+#define RTC_BASE_NUMERICS_MOVING_AVERAGE_H_
+
+#include <vector>
+
+#include "absl/types/optional.h"
+
+namespace rtc {
+
+// Calculates average over fixed size window. If there are less than window
+// size elements, calculates average of all inserted so far elements.
+//
+class MovingAverage {
+ public:
+  // Maximum supported window size is 2^32 - 1.
+  explicit MovingAverage(size_t window_size);
+  ~MovingAverage();
+  // MovingAverage is neither copyable nor movable.
+  MovingAverage(const MovingAverage&) = delete;
+  MovingAverage& operator=(const MovingAverage&) = delete;
+
+  // Adds new sample. If the window is full, the oldest element is pushed out.
+  void AddSample(int sample);
+
+  // Returns rounded down average of last |window_size| elements or all
+  // elements if there are not enough of them. Returns nullopt if there were
+  // no elements added.
+  absl::optional<int> GetAverageRoundedDown() const;
+
+  // Same as above but rounded to the closest integer.
+  absl::optional<int> GetAverageRoundedToClosest() const;
+
+  // Returns unrounded average over the window.
+  absl::optional<double> GetUnroundedAverage() const;
+
+  // Resets to the initial state before any elements were added.
+  void Reset();
+
+  // Returns number of elements in the window.
+  size_t Size() const;
+
+ private:
+  // Total number of samples added to the class since last reset.
+  size_t count_ = 0;
+  // Sum of the samples in the moving window.
+  int64_t sum_ = 0;
+  // Circular buffer for all the samples in the moving window.
+  // Size is always |window_size|
+  std::vector<int> history_;
+};
+
+}  // namespace rtc
+#endif  // RTC_BASE_NUMERICS_MOVING_AVERAGE_H_
diff --git a/rtc_base/numerics/moving_average_unittest.cc b/rtc_base/numerics/moving_average_unittest.cc
new file mode 100644
index 0000000..9bc9a1a
--- /dev/null
+++ b/rtc_base/numerics/moving_average_unittest.cc
@@ -0,0 +1,87 @@
+/*
+ *  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 "rtc_base/numerics/moving_average.h"
+
+#include "test/gtest.h"
+
+namespace test {
+
+TEST(MovingAverageTest, EmptyAverage) {
+  rtc::MovingAverage moving_average(1);
+  EXPECT_EQ(0u, moving_average.Size());
+  EXPECT_EQ(absl::nullopt, moving_average.GetAverageRoundedDown());
+}
+
+// Test single value.
+TEST(MovingAverageTest, OneElement) {
+  rtc::MovingAverage moving_average(1);
+  moving_average.AddSample(3);
+  EXPECT_EQ(1u, moving_average.Size());
+  EXPECT_EQ(3, *moving_average.GetAverageRoundedDown());
+}
+
+TEST(MovingAverageTest, GetAverage) {
+  rtc::MovingAverage moving_average(1024);
+  moving_average.AddSample(1);
+  moving_average.AddSample(1);
+  moving_average.AddSample(3);
+  moving_average.AddSample(3);
+  EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 2);
+  EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 2);
+}
+
+TEST(MovingAverageTest, GetAverageRoundedDownRounds) {
+  rtc::MovingAverage moving_average(1024);
+  moving_average.AddSample(1);
+  moving_average.AddSample(2);
+  moving_average.AddSample(2);
+  moving_average.AddSample(2);
+  EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 1);
+}
+
+TEST(MovingAverageTest, GetAverageRoundedToClosestRounds) {
+  rtc::MovingAverage moving_average(1024);
+  moving_average.AddSample(1);
+  moving_average.AddSample(2);
+  moving_average.AddSample(2);
+  moving_average.AddSample(2);
+  EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 2);
+}
+
+TEST(MovingAverageTest, Reset) {
+  rtc::MovingAverage moving_average(5);
+  moving_average.AddSample(1);
+  EXPECT_EQ(1, *moving_average.GetAverageRoundedDown());
+  EXPECT_EQ(1, *moving_average.GetAverageRoundedToClosest());
+
+  moving_average.Reset();
+
+  EXPECT_FALSE(moving_average.GetAverageRoundedDown());
+  moving_average.AddSample(10);
+  EXPECT_EQ(10, *moving_average.GetAverageRoundedDown());
+  EXPECT_EQ(10, *moving_average.GetAverageRoundedToClosest());
+}
+
+TEST(MovingAverageTest, ManySamples) {
+  rtc::MovingAverage moving_average(10);
+  for (int i = 1; i < 11; i++) {
+    moving_average.AddSample(i);
+  }
+  EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 5);
+  EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 6);
+  for (int i = 1; i < 2001; i++) {
+    moving_average.AddSample(i);
+  }
+  EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 1995);
+  EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 1996);
+}
+
+}  // namespace test
diff --git a/rtc_base/numerics/sample_counter.h b/rtc_base/numerics/sample_counter.h
index 4fe71d1..18bd36b 100644
--- a/rtc_base/numerics/sample_counter.h
+++ b/rtc_base/numerics/sample_counter.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_NUMERICS_SAMPLE_COUNTER_H_
 #define RTC_BASE_NUMERICS_SAMPLE_COUNTER_H_
 
+#include <stdint.h>
+
 #include "absl/types/optional.h"
 
 namespace rtc {
diff --git a/rtc_base/openssl_key_derivation_hkdf.cc b/rtc_base/openssl_key_derivation_hkdf.cc
new file mode 100644
index 0000000..52af667
--- /dev/null
+++ b/rtc_base/openssl_key_derivation_hkdf.cc
@@ -0,0 +1,70 @@
+/*
+ *  Copyright 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 "rtc_base/openssl_key_derivation_hkdf.h"
+
+#include <openssl/digest.h>
+#include <openssl/err.h>
+#include <openssl/hkdf.h>
+#include <openssl/sha.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "rtc_base/buffer.h"
+#include "rtc_base/openssl.h"
+
+namespace rtc {
+
+OpenSSLKeyDerivationHKDF::OpenSSLKeyDerivationHKDF() = default;
+OpenSSLKeyDerivationHKDF::~OpenSSLKeyDerivationHKDF() = default;
+
+const size_t OpenSSLKeyDerivationHKDF::kMinKeyByteSize = 16;
+const size_t OpenSSLKeyDerivationHKDF::kMaxKeyByteSize =
+    255 * SHA256_DIGEST_LENGTH;
+const size_t OpenSSLKeyDerivationHKDF::kMinSecretByteSize = 16;
+
+absl::optional<ZeroOnFreeBuffer<uint8_t>> OpenSSLKeyDerivationHKDF::DeriveKey(
+    rtc::ArrayView<const uint8_t> secret,
+    rtc::ArrayView<const uint8_t> salt,
+    rtc::ArrayView<const uint8_t> label,
+    size_t derived_key_byte_size) {
+  // Prevent deriving less than 128 bits of key material or more than the max.
+  if (derived_key_byte_size < kMinKeyByteSize ||
+      derived_key_byte_size > kMaxKeyByteSize) {
+    return absl::nullopt;
+  }
+  // The secret must reach the minimum number of bits to be secure.
+  if (secret.data() == nullptr || secret.size() < kMinSecretByteSize) {
+    return absl::nullopt;
+  }
+  // Empty labels are always invalid in derivation.
+  if (label.data() == nullptr || label.size() == 0) {
+    return absl::nullopt;
+  }
+  // If a random salt is not provided use all zeros.
+  rtc::Buffer salt_buffer;
+  if (salt.data() == nullptr || salt.size() == 0) {
+    salt_buffer.SetSize(SHA256_DIGEST_LENGTH);
+    std::fill(salt_buffer.begin(), salt_buffer.end(), 0);
+    salt = salt_buffer;
+  }
+  // This buffer will erase itself on release.
+  ZeroOnFreeBuffer<uint8_t> derived_key_buffer(derived_key_byte_size, 0);
+  if (!HKDF(derived_key_buffer.data(), derived_key_buffer.size(), EVP_sha256(),
+            secret.data(), secret.size(), salt.data(), salt.size(),
+            label.data(), label.size())) {
+    return absl::nullopt;
+  }
+  return absl::optional<ZeroOnFreeBuffer<uint8_t>>(
+      std::move(derived_key_buffer));
+}
+
+}  // namespace rtc
diff --git a/rtc_base/openssl_key_derivation_hkdf.h b/rtc_base/openssl_key_derivation_hkdf.h
new file mode 100644
index 0000000..ebf43cf
--- /dev/null
+++ b/rtc_base/openssl_key_derivation_hkdf.h
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 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 RTC_BASE_OPENSSL_KEY_DERIVATION_HKDF_H_
+#define RTC_BASE_OPENSSL_KEY_DERIVATION_HKDF_H_
+
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/key_derivation.h"
+
+namespace rtc {
+
+// OpenSSLKeyDerivationHKDF provides a concrete implementation of the
+// KeyDerivation interface to support the HKDF algorithm using the
+// OpenSSL/BoringSSL internal implementation.
+class OpenSSLKeyDerivationHKDF final : public KeyDerivation {
+ public:
+  OpenSSLKeyDerivationHKDF();
+  ~OpenSSLKeyDerivationHKDF() override;
+
+  // General users shouldn't be generating keys smaller than 128 bits.
+  static const size_t kMinKeyByteSize;
+  // The maximum available derivation size 255*DIGEST_LENGTH
+  static const size_t kMaxKeyByteSize;
+  // The minimum acceptable secret size.
+  static const size_t kMinSecretByteSize;
+
+  // Derives a new key from existing key material using HKDF.
+  // secret - The random secret value you wish to derive a key from.
+  // salt - Optional (non secret) cryptographically random value.
+  // label - A non secret but unique label value to determine the derivation.
+  // derived_key_byte_size - The size of the derived key.
+  // return - A ZeroOnFreeBuffer containing the derived key or an error
+  // condition. Checking error codes is explicit in the API and error should
+  // never be ignored.
+  absl::optional<ZeroOnFreeBuffer<uint8_t>> DeriveKey(
+      rtc::ArrayView<const uint8_t> secret,
+      rtc::ArrayView<const uint8_t> salt,
+      rtc::ArrayView<const uint8_t> label,
+      size_t derived_key_byte_size) override;
+
+ private:
+  RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyDerivationHKDF);
+};
+
+}  // namespace rtc
+
+#endif  // RTC_BASE_OPENSSL_KEY_DERIVATION_HKDF_H_
diff --git a/rtc_base/openssl_key_derivation_hkdf_unittest.cc b/rtc_base/openssl_key_derivation_hkdf_unittest.cc
new file mode 100644
index 0000000..92df42f
--- /dev/null
+++ b/rtc_base/openssl_key_derivation_hkdf_unittest.cc
@@ -0,0 +1,107 @@
+/*
+ *  Copyright 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 "rtc_base/openssl_key_derivation_hkdf.h"
+
+#include <utility>
+
+#include "test/gmock.h"
+
+namespace rtc {
+namespace {
+
+// Validates that a basic valid call works correctly.
+TEST(OpenSSLKeyDerivationHKDF, DerivationBasicTest) {
+  rtc::Buffer secret(32);
+  rtc::Buffer salt(32);
+  rtc::Buffer label(32);
+  const size_t derived_key_byte_size = 16;
+
+  OpenSSLKeyDerivationHKDF hkdf;
+  auto key_or = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
+  EXPECT_TRUE(key_or.has_value());
+  ZeroOnFreeBuffer<uint8_t> key = std::move(key_or.value());
+  EXPECT_EQ(derived_key_byte_size, key.size());
+}
+
+// Derivation fails if output is too small.
+TEST(OpenSSLKeyDerivationHKDF, DerivationFailsIfOutputIsTooSmall) {
+  rtc::Buffer secret(32);
+  rtc::Buffer salt(32);
+  rtc::Buffer label(32);
+  const size_t derived_key_byte_size = 15;
+
+  OpenSSLKeyDerivationHKDF hkdf;
+  auto key_or = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
+  EXPECT_FALSE(key_or.has_value());
+}
+
+// Derivation fails if output is too large.
+TEST(OpenSSLKeyDerivationHKDF, DerivationFailsIfOutputIsTooLarge) {
+  rtc::Buffer secret(32);
+  rtc::Buffer salt(32);
+  rtc::Buffer label(32);
+  const size_t derived_key_byte_size = 256 * 32;
+
+  OpenSSLKeyDerivationHKDF hkdf;
+  auto key_or = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
+  EXPECT_FALSE(key_or.has_value());
+}
+
+// Validates that too little key material causes a failure.
+TEST(OpenSSLKeyDerivationHKDF, DerivationFailsWithInvalidSecret) {
+  rtc::Buffer secret(15);
+  rtc::Buffer salt(32);
+  rtc::Buffer label(32);
+  const size_t derived_key_byte_size = 16;
+
+  OpenSSLKeyDerivationHKDF hkdf;
+  auto key_or_0 = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
+  EXPECT_FALSE(key_or_0.has_value());
+
+  auto key_or_1 = hkdf.DeriveKey(nullptr, salt, label, derived_key_byte_size);
+  EXPECT_FALSE(key_or_1.has_value());
+
+  rtc::Buffer secret_empty;
+  auto key_or_2 =
+      hkdf.DeriveKey(secret_empty, salt, label, derived_key_byte_size);
+  EXPECT_FALSE(key_or_2.has_value());
+}
+
+// Validates that HKDF works without a salt being set.
+TEST(OpenSSLKeyDerivationHKDF, DerivationWorksWithNoSalt) {
+  rtc::Buffer secret(32);
+  rtc::Buffer label(32);
+  const size_t derived_key_byte_size = 16;
+
+  OpenSSLKeyDerivationHKDF hkdf;
+  auto key_or = hkdf.DeriveKey(secret, nullptr, label, derived_key_byte_size);
+  EXPECT_TRUE(key_or.has_value());
+}
+
+// Validates that a label is required to work correctly.
+TEST(OpenSSLKeyDerivationHKDF, DerivationRequiresLabel) {
+  rtc::Buffer secret(32);
+  rtc::Buffer salt(32);
+  rtc::Buffer label(1);
+  const size_t derived_key_byte_size = 16;
+
+  OpenSSLKeyDerivationHKDF hkdf;
+  auto key_or_0 = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
+  EXPECT_TRUE(key_or_0.has_value());
+  ZeroOnFreeBuffer<uint8_t> key = std::move(key_or_0.value());
+  EXPECT_EQ(key.size(), derived_key_byte_size);
+
+  auto key_or_1 = hkdf.DeriveKey(secret, salt, nullptr, derived_key_byte_size);
+  EXPECT_FALSE(key_or_1.has_value());
+}
+
+}  // namespace
+}  // namespace rtc
diff --git a/rtc_base/openssladapter.cc b/rtc_base/openssladapter.cc
index b589195..fcfa53b 100644
--- a/rtc_base/openssladapter.cc
+++ b/rtc_base/openssladapter.cc
@@ -10,26 +10,25 @@
 
 #include "rtc_base/openssladapter.h"
 
-#if defined(WEBRTC_POSIX)
-#include <unistd.h>
-#endif
+#include <errno.h>
 
 #include <openssl/bio.h>
-#include <openssl/crypto.h>
 #include <openssl/err.h>
-#include <openssl/opensslv.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
-#include <openssl/x509v3.h>
 #include "rtc_base/openssl.h"
 
-#include "absl/memory/memory.h"  // for make_unique
+#include <string.h>
+#include <time.h>
+
+#include "absl/memory/memory.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/location.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/opensslcertificate.h"
 #include "rtc_base/opensslutility.h"
 #include "rtc_base/stringencode.h"
-#include "rtc_base/stringutils.h"
 #include "rtc_base/thread.h"
 
 #ifndef OPENSSL_IS_BORINGSSL
@@ -393,15 +392,17 @@
 
   // Do the connect.
   err = ContinueSSL();
-  if (err != 0)
+  if (err != 0) {
     goto ssl_error;
+  }
 
   return err;
 
 ssl_error:
   Cleanup();
-  if (bio)
+  if (bio) {
     BIO_free(bio);
+  }
 
   return err;
 }
@@ -425,14 +426,13 @@
 
       state_ = SSL_CONNECTED;
       AsyncSocketAdapter::OnConnectEvent(this);
-#if 0  // TODO(benwright): worry about this
-    // Don't let ourselves go away during the callbacks
-    PRefPtr<OpenSSLAdapter> lock(this);
-    RTC_LOG(LS_INFO) << " -- onStreamReadable";
-    AsyncSocketAdapter::OnReadEvent(this);
-    RTC_LOG(LS_INFO) << " -- onStreamWriteable";
-    AsyncSocketAdapter::OnWriteEvent(this);
-#endif
+      // TODO(benwright): Refactor this code path.
+      // Don't let ourselves go away during the callbacks
+      // PRefPtr<OpenSSLAdapter> lock(this);
+      // RTC_LOG(LS_INFO) << " -- onStreamReadable";
+      // AsyncSocketAdapter::OnReadEvent(this);
+      // RTC_LOG(LS_INFO) << " -- onStreamWriteable";
+      // AsyncSocketAdapter::OnWriteEvent(this);
       break;
 
     case SSL_ERROR_WANT_READ:
@@ -463,8 +463,9 @@
                       << ")";
   state_ = SSL_ERROR;
   SetError(err);
-  if (signal)
+  if (signal) {
     AsyncSocketAdapter::OnCloseEvent(this, err);
+  }
 }
 
 void OpenSSLAdapter::Cleanup() {
@@ -529,23 +530,20 @@
   return SOCKET_ERROR;
 }
 
-//
+///////////////////////////////////////////////////////////////////////////////
 // AsyncSocket Implementation
-//
+///////////////////////////////////////////////////////////////////////////////
 
 int OpenSSLAdapter::Send(const void* pv, size_t cb) {
   switch (state_) {
     case SSL_NONE:
       return AsyncSocketAdapter::Send(pv, cb);
-
     case SSL_WAIT:
     case SSL_CONNECTING:
       SetError(ENOTCONN);
       return SOCKET_ERROR;
-
     case SSL_CONNECTED:
       break;
-
     case SSL_ERROR:
     default:
       return SOCKET_ERROR;
@@ -568,8 +566,9 @@
   }
 
   // OpenSSL will return an error if we try to write zero bytes
-  if (cb == 0)
+  if (cb == 0) {
     return 0;
+  }
 
   ret = DoSslWrite(pv, cb, &error);
 
@@ -596,7 +595,6 @@
     // size. The user of this class can consider it sent.
     return rtc::dchecked_cast<int>(cb);
   }
-
   return ret;
 }
 
@@ -609,7 +607,6 @@
   }
 
   SetError(ENOTCONN);
-
   return SOCKET_ERROR;
 }
 
@@ -617,28 +614,26 @@
   switch (state_) {
     case SSL_NONE:
       return AsyncSocketAdapter::Recv(pv, cb, timestamp);
-
     case SSL_WAIT:
     case SSL_CONNECTING:
       SetError(ENOTCONN);
       return SOCKET_ERROR;
-
     case SSL_CONNECTED:
       break;
-
     case SSL_ERROR:
     default:
       return SOCKET_ERROR;
   }
 
   // Don't trust OpenSSL with zero byte reads
-  if (cb == 0)
+  if (cb == 0) {
     return 0;
+  }
 
   ssl_read_needs_write_ = false;
-
   int code = SSL_read(ssl_, pv, checked_cast<int>(cb));
   int error = SSL_get_error(ssl_, code);
+
   switch (error) {
     case SSL_ERROR_NONE:
       return code;
@@ -661,7 +656,6 @@
       Error("SSL_read", (code ? code : -1), false);
       break;
   }
-
   return SOCKET_ERROR;
 }
 
@@ -671,14 +665,11 @@
                              int64_t* timestamp) {
   if (socket_->GetState() == Socket::CS_CONNECTED) {
     int ret = Recv(pv, cb, timestamp);
-
     *paddr = GetRemoteAddress();
-
     return ret;
   }
 
   SetError(ENOTCONN);
-
   return SOCKET_ERROR;
 }
 
@@ -689,12 +680,11 @@
 }
 
 Socket::ConnState OpenSSLAdapter::GetState() const {
-  // if (signal_close_)
-  //  return CS_CONNECTED;
   ConnState state = socket_->GetState();
   if ((state == CS_CONNECTED) &&
-      ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
+      ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING))) {
     state = CS_CONNECTING;
+  }
   return state;
 }
 
@@ -737,8 +727,9 @@
     return;
   }
 
-  if (state_ != SSL_CONNECTED)
+  if (state_ != SSL_CONNECTED) {
     return;
+  }
 
   // Don't let ourselves go away during the callbacks
   // PRefPtr<OpenSSLAdapter> lock(this); // TODO(benwright): fix this
@@ -762,8 +753,9 @@
     return;
   }
 
-  if (state_ != SSL_CONNECTED)
+  if (state_ != SSL_CONNECTED) {
     return;
+  }
 
   // Don't let ourselves go away during the callbacks
   // PRefPtr<OpenSSLAdapter> lock(this); // TODO(benwright): fix this
diff --git a/rtc_base/openssladapter.h b/rtc_base/openssladapter.h
index 45ffc6f..2e3a355 100644
--- a/rtc_base/openssladapter.h
+++ b/rtc_base/openssladapter.h
@@ -11,28 +11,28 @@
 #ifndef RTC_BASE_OPENSSLADAPTER_H_
 #define RTC_BASE_OPENSSLADAPTER_H_
 
-#include <openssl/ossl_typ.h>
-
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "rtc_base/asyncsocket.h"          // for AsyncSocket
-#include "rtc_base/buffer.h"               // for Buffer
-#include "rtc_base/messagehandler.h"       // for MessageHandler
-#include "rtc_base/messagequeue.h"         // for Message
-#include "rtc_base/opensslidentity.h"      // for SSL_CTX, OpenSSLIdentity
-#include "rtc_base/opensslsessioncache.h"  // for OpenSSLSessionCache
-#include "rtc_base/socket.h"               // for Socket::ConnState
-#include "rtc_base/socketaddress.h"        // for SocketAddress
-#include "rtc_base/ssladapter.h"           // for SSLAdapter, SSLAdapterFactory
-#include "rtc_base/sslcertificate.h"       // for SSLCertificateVerifier
-#include "rtc_base/sslidentity.h"          // for SSLIdentity
-#include "rtc_base/sslstreamadapter.h"     // for SSLMode, SSLRole, SSL_MODE...
+#include "rtc_base/asyncsocket.h"
+#include "rtc_base/buffer.h"
+#include "rtc_base/messagehandler.h"
+#include "rtc_base/messagequeue.h"
+#include "rtc_base/opensslidentity.h"
+#include "rtc_base/opensslsessioncache.h"
+#include "rtc_base/socket.h"
+#include "rtc_base/socketaddress.h"
+#include "rtc_base/ssladapter.h"
+#include "rtc_base/sslcertificate.h"
+#include "rtc_base/sslidentity.h"
+#include "rtc_base/sslstreamadapter.h"
 
 namespace rtc {
 
-class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
+class OpenSSLAdapter final : public SSLAdapter, public MessageHandler {
  public:
   static bool InitializeSSL();
   static bool CleanupSSL();
diff --git a/rtc_base/opensslcertificate.cc b/rtc_base/opensslcertificate.cc
index ed67a89..4e61b86 100644
--- a/rtc_base/opensslcertificate.cc
+++ b/rtc_base/opensslcertificate.cc
@@ -10,10 +10,6 @@
 
 #include "rtc_base/opensslcertificate.h"
 
-#include <memory>
-#include <utility>
-#include <vector>
-
 #if defined(WEBRTC_WIN)
 // Must be included first before openssl headers.
 #include "rtc_base/win32.h"  // NOLINT
@@ -21,97 +17,24 @@
 
 #include <openssl/bio.h>
 #include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
 #include <openssl/pem.h>
-#include <openssl/rsa.h>
+#include <time.h>
 
 #include "absl/memory/memory.h"
-#include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/helpers.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_conversions.h"
-#include "rtc_base/openssl.h"
+#include "rtc_base/messagedigest.h"
 #include "rtc_base/openssldigest.h"
 #include "rtc_base/opensslidentity.h"
 #include "rtc_base/opensslutility.h"
-#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
-#include "rtc_base/sslroots.h"
-#endif  // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
 
 namespace rtc {
-
-//////////////////////////////////////////////////////////////////////
-// OpenSSLCertificate
-//////////////////////////////////////////////////////////////////////
-
-// We could have exposed a myriad of parameters for the crypto stuff,
-// but keeping it simple seems best.
+namespace {
 
 // Random bits for certificate serial number
 static const int SERIAL_RAND_BITS = 64;
 
-// Generate a self-signed certificate, with the public key from the
-// given key pair. Caller is responsible for freeing the returned object.
-static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) {
-  RTC_LOG(LS_INFO) << "Making certificate for " << params.common_name;
-  X509* x509 = nullptr;
-  BIGNUM* serial_number = nullptr;
-  X509_NAME* name = nullptr;
-  time_t epoch_off = 0;  // Time offset since epoch.
-
-  if ((x509 = X509_new()) == nullptr)
-    goto error;
-
-  if (!X509_set_pubkey(x509, pkey))
-    goto error;
-
-  // serial number
-  // temporary reference to serial number inside x509 struct
-  ASN1_INTEGER* asn1_serial_number;
-  if ((serial_number = BN_new()) == nullptr ||
-      !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) ||
-      (asn1_serial_number = X509_get_serialNumber(x509)) == nullptr ||
-      !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number))
-    goto error;
-
-  if (!X509_set_version(x509, 2L))  // version 3
-    goto error;
-
-  // There are a lot of possible components for the name entries. In
-  // our P2P SSL mode however, the certificates are pre-exchanged
-  // (through the secure XMPP channel), and so the certificate
-  // identification is arbitrary. It can't be empty, so we set some
-  // arbitrary common_name. Note that this certificate goes out in
-  // clear during SSL negotiation, so there may be a privacy issue in
-  // putting anything recognizable here.
-  if ((name = X509_NAME_new()) == nullptr ||
-      !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
-                                  (unsigned char*)params.common_name.c_str(),
-                                  -1, -1, 0) ||
-      !X509_set_subject_name(x509, name) || !X509_set_issuer_name(x509, name))
-    goto error;
-
-  if (!X509_time_adj(X509_get_notBefore(x509), params.not_before, &epoch_off) ||
-      !X509_time_adj(X509_get_notAfter(x509), params.not_after, &epoch_off))
-    goto error;
-
-  if (!X509_sign(x509, pkey, EVP_sha256()))
-    goto error;
-
-  BN_free(serial_number);
-  X509_NAME_free(name);
-  RTC_LOG(LS_INFO) << "Returning certificate";
-  return x509;
-
-error:
-  BN_free(serial_number);
-  X509_NAME_free(name);
-  X509_free(x509);
-  return nullptr;
-}
-
 #if !defined(NDEBUG)
 // Print a certificate to the log, for debugging.
 static void PrintCert(X509* x509) {
@@ -129,11 +52,77 @@
 }
 #endif
 
-OpenSSLCertificate::OpenSSLCertificate(X509* x509) : x509_(x509) {
-  AddReference();
+// Generate a self-signed certificate, with the public key from the
+// given key pair. Caller is responsible for freeing the returned object.
+static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) {
+  RTC_LOG(LS_INFO) << "Making certificate for " << params.common_name;
+
+  ASN1_INTEGER* asn1_serial_number = nullptr;
+  BIGNUM* serial_number = nullptr;
+  X509* x509 = nullptr;
+  X509_NAME* name = nullptr;
+  time_t epoch_off = 0;  // Time offset since epoch.
+
+  if ((x509 = X509_new()) == nullptr) {
+    goto error;
+  }
+  if (!X509_set_pubkey(x509, pkey)) {
+    goto error;
+  }
+  // serial number - temporary reference to serial number inside x509 struct
+  if ((serial_number = BN_new()) == nullptr ||
+      !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) ||
+      (asn1_serial_number = X509_get_serialNumber(x509)) == nullptr ||
+      !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) {
+    goto error;
+  }
+  // Set version to X509.V3
+  if (!X509_set_version(x509, 2L)) {
+    goto error;
+  }
+
+  // There are a lot of possible components for the name entries. In
+  // our P2P SSL mode however, the certificates are pre-exchanged
+  // (through the secure XMPP channel), and so the certificate
+  // identification is arbitrary. It can't be empty, so we set some
+  // arbitrary common_name. Note that this certificate goes out in
+  // clear during SSL negotiation, so there may be a privacy issue in
+  // putting anything recognizable here.
+  if ((name = X509_NAME_new()) == nullptr ||
+      !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
+                                  (unsigned char*)params.common_name.c_str(),
+                                  -1, -1, 0) ||
+      !X509_set_subject_name(x509, name) || !X509_set_issuer_name(x509, name)) {
+    goto error;
+  }
+  if (!X509_time_adj(X509_get_notBefore(x509), params.not_before, &epoch_off) ||
+      !X509_time_adj(X509_get_notAfter(x509), params.not_after, &epoch_off)) {
+    goto error;
+  }
+  if (!X509_sign(x509, pkey, EVP_sha256())) {
+    goto error;
+  }
+
+  BN_free(serial_number);
+  X509_NAME_free(name);
+  RTC_LOG(LS_INFO) << "Returning certificate";
+  return x509;
+
+error:
+  BN_free(serial_number);
+  X509_NAME_free(name);
+  X509_free(x509);
+  return nullptr;
 }
 
-OpenSSLCertificate* OpenSSLCertificate::Generate(
+}  // namespace
+
+OpenSSLCertificate::OpenSSLCertificate(X509* x509) : x509_(x509) {
+  RTC_DCHECK(x509_ != nullptr);
+  X509_up_ref(x509_);
+}
+
+std::unique_ptr<OpenSSLCertificate> OpenSSLCertificate::Generate(
     OpenSSLKeyPair* key_pair,
     const SSLIdentityParams& params) {
   SSLIdentityParams actual_params(params);
@@ -149,25 +138,27 @@
 #if !defined(NDEBUG)
   PrintCert(x509);
 #endif
-  OpenSSLCertificate* ret = new OpenSSLCertificate(x509);
+  auto ret = absl::make_unique<OpenSSLCertificate>(x509);
   X509_free(x509);
   return ret;
 }
 
-OpenSSLCertificate* OpenSSLCertificate::FromPEMString(
+std::unique_ptr<OpenSSLCertificate> OpenSSLCertificate::FromPEMString(
     const std::string& pem_string) {
   BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1);
-  if (!bio)
+  if (!bio) {
     return nullptr;
+  }
+
   BIO_set_mem_eof_return(bio, 0);
   X509* x509 =
       PEM_read_bio_X509(bio, nullptr, nullptr, const_cast<char*>("\0"));
   BIO_free(bio);  // Frees the BIO, but not the pointed-to string.
 
-  if (!x509)
+  if (!x509) {
     return nullptr;
-
-  OpenSSLCertificate* ret = new OpenSSLCertificate(x509);
+  }
+  auto ret = absl::make_unique<OpenSSLCertificate>(x509);
   X509_free(x509);
   return ret;
 }
@@ -229,19 +220,16 @@
                                        unsigned char* digest,
                                        size_t size,
                                        size_t* length) {
-  const EVP_MD* md;
-  unsigned int n;
-
-  if (!OpenSSLDigest::GetDigestEVP(algorithm, &md))
+  const EVP_MD* md = nullptr;
+  unsigned int n = 0;
+  if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) {
     return false;
-
-  if (size < static_cast<size_t>(EVP_MD_size(md)))
+  }
+  if (size < static_cast<size_t>(EVP_MD_size(md))) {
     return false;
-
+  }
   X509_digest(x509, md, digest, &n);
-
   *length = n;
-
   return true;
 }
 
@@ -249,18 +237,18 @@
   X509_free(x509_);
 }
 
-OpenSSLCertificate* OpenSSLCertificate::GetReference() const {
-  return new OpenSSLCertificate(x509_);
+std::unique_ptr<SSLCertificate> OpenSSLCertificate::Clone() const {
+  return absl::make_unique<OpenSSLCertificate>(x509_);
 }
 
 std::string OpenSSLCertificate::ToPEMString() const {
   BIO* bio = BIO_new(BIO_s_mem());
   if (!bio) {
-    FATAL() << "unreachable code";
+    FATAL() << "Unreachable code.";
   }
   if (!PEM_write_bio_X509(bio, x509_)) {
     BIO_free(bio);
-    FATAL() << "unreachable code";
+    FATAL() << "Unreachable code.";
   }
   BIO_write(bio, "\0", 1);
   char* buffer;
@@ -273,27 +261,21 @@
 void OpenSSLCertificate::ToDER(Buffer* der_buffer) const {
   // In case of failure, make sure to leave the buffer empty.
   der_buffer->SetSize(0);
-
   // Calculates the DER representation of the certificate, from scratch.
   BIO* bio = BIO_new(BIO_s_mem());
   if (!bio) {
-    FATAL() << "unreachable code";
+    FATAL() << "Unreachable code.";
   }
   if (!i2d_X509_bio(bio, x509_)) {
     BIO_free(bio);
-    FATAL() << "unreachable code";
+    FATAL() << "Unreachable code.";
   }
-  char* data;
+  char* data = nullptr;
   size_t length = BIO_get_mem_data(bio, &data);
   der_buffer->SetData(data, length);
   BIO_free(bio);
 }
 
-void OpenSSLCertificate::AddReference() const {
-  RTC_DCHECK(x509_ != nullptr);
-  X509_up_ref(x509_);
-}
-
 bool OpenSSLCertificate::operator==(const OpenSSLCertificate& other) const {
   return X509_cmp(x509_, other.x509_) == 0;
 }
@@ -302,11 +284,9 @@
   return !(*this == other);
 }
 
-// Documented in sslidentity.h.
 int64_t OpenSSLCertificate::CertificateExpirationTime() const {
   ASN1_TIME* expire_time = X509_get_notAfter(x509_);
   bool long_format;
-
   if (expire_time->type == V_ASN1_UTCTIME) {
     long_format = false;
   } else if (expire_time->type == V_ASN1_GENERALIZEDTIME) {
@@ -314,7 +294,6 @@
   } else {
     return -1;
   }
-
   return ASN1TimeToSec(expire_time->data, expire_time->length, long_format);
 }
 
diff --git a/rtc_base/opensslcertificate.h b/rtc_base/opensslcertificate.h
index b7ecc3b..088725c 100644
--- a/rtc_base/opensslcertificate.h
+++ b/rtc_base/opensslcertificate.h
@@ -11,18 +11,16 @@
 #ifndef RTC_BASE_OPENSSLCERTIFICATE_H_
 #define RTC_BASE_OPENSSLCERTIFICATE_H_
 
-#include <openssl/base.h>  // for X509, ssl_ctx_st
+#include <openssl/ossl_typ.h>
 
-#include <stddef.h>  // for size_t
-#include <stdint.h>  // for int64_t
+#include <stddef.h>
+#include <stdint.h>
 #include <string>
 
-#include "rtc_base/buffer.h"            // for Buffer
-#include "rtc_base/constructormagic.h"  // for RTC_DISALLOW_COPY_AND_ASSIGN
-#include "rtc_base/sslcertificate.h"    // for SSLCertificate
-#include "rtc_base/sslidentity.h"       // for SSLIdentityParams
-
-typedef struct ssl_ctx_st SSL_CTX;
+#include "rtc_base/buffer.h"
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/sslcertificate.h"
+#include "rtc_base/sslidentity.h"
 
 namespace rtc {
 
@@ -30,19 +28,21 @@
 
 // OpenSSLCertificate encapsulates an OpenSSL X509* certificate object,
 // which is also reference counted inside the OpenSSL library.
-class OpenSSLCertificate : public SSLCertificate {
+class OpenSSLCertificate final : public SSLCertificate {
  public:
   // X509 object has its reference count incremented. So the caller and
   // OpenSSLCertificate share ownership.
   explicit OpenSSLCertificate(X509* x509);
 
-  static OpenSSLCertificate* Generate(OpenSSLKeyPair* key_pair,
-                                      const SSLIdentityParams& params);
-  static OpenSSLCertificate* FromPEMString(const std::string& pem_string);
+  static std::unique_ptr<OpenSSLCertificate> Generate(
+      OpenSSLKeyPair* key_pair,
+      const SSLIdentityParams& params);
+  static std::unique_ptr<OpenSSLCertificate> FromPEMString(
+      const std::string& pem_string);
 
   ~OpenSSLCertificate() override;
 
-  OpenSSLCertificate* GetReference() const override;
+  std::unique_ptr<SSLCertificate> Clone() const override;
 
   X509* x509() const { return x509_; }
 
@@ -69,8 +69,6 @@
   int64_t CertificateExpirationTime() const override;
 
  private:
-  void AddReference() const;
-
   X509* x509_;  // NOT OWNED
   RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLCertificate);
 };
diff --git a/rtc_base/openssldigest.cc b/rtc_base/openssldigest.cc
index 9b644c4..da90b65 100644
--- a/rtc_base/openssldigest.cc
+++ b/rtc_base/openssldigest.cc
@@ -10,7 +10,7 @@
 
 #include "rtc_base/openssldigest.h"
 
-#include "rtc_base/checks.h"
+#include "rtc_base/checks.h"  // RTC_DCHECK, RTC_CHECK
 #include "rtc_base/openssl.h"
 
 namespace rtc {
diff --git a/rtc_base/openssldigest.h b/rtc_base/openssldigest.h
index 1427a94..82dc9a9 100644
--- a/rtc_base/openssldigest.h
+++ b/rtc_base/openssldigest.h
@@ -11,7 +11,8 @@
 #ifndef RTC_BASE_OPENSSLDIGEST_H_
 #define RTC_BASE_OPENSSLDIGEST_H_
 
-#include <openssl/base.h>  // for EVP_MD, EVP_MD_CTX
+#include <openssl/base.h>
+#include <stddef.h>
 #include <string>
 
 #include "rtc_base/messagedigest.h"
@@ -19,7 +20,7 @@
 namespace rtc {
 
 // An implementation of the digest class that uses OpenSSL.
-class OpenSSLDigest : public MessageDigest {
+class OpenSSLDigest final : public MessageDigest {
  public:
   // Creates an OpenSSLDigest with |algorithm| as the hash algorithm.
   explicit OpenSSLDigest(const std::string& algorithm);
diff --git a/rtc_base/opensslidentity.cc b/rtc_base/opensslidentity.cc
index a8c6919..9850c85 100644
--- a/rtc_base/opensslidentity.cc
+++ b/rtc_base/opensslidentity.cc
@@ -21,18 +21,17 @@
 
 #include <openssl/bio.h>
 #include <openssl/bn.h>
-#include <openssl/crypto.h>
 #include <openssl/err.h>
 #include <openssl/pem.h>
 #include <openssl/rsa.h>
 
+#include <stdint.h>
+
 #include "absl/memory/memory.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/helpers.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/openssl.h"
-#include "rtc_base/openssldigest.h"
 #include "rtc_base/opensslutility.h"
 
 namespace rtc {
@@ -316,7 +315,7 @@
 
 OpenSSLIdentity* OpenSSLIdentity::GetReference() const {
   return new OpenSSLIdentity(absl::WrapUnique(key_pair_->GetReference()),
-                             absl::WrapUnique(cert_chain_->Copy()));
+                             cert_chain_->Clone());
 }
 
 bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
diff --git a/rtc_base/opensslidentity.h b/rtc_base/opensslidentity.h
index b72a4c2..fcf7deb 100644
--- a/rtc_base/opensslidentity.h
+++ b/rtc_base/opensslidentity.h
@@ -11,25 +11,23 @@
 #ifndef RTC_BASE_OPENSSLIDENTITY_H_
 #define RTC_BASE_OPENSSLIDENTITY_H_
 
-#include <openssl/base.h>  // for EVP_PKEY, ssl_ctx_st
+#include <openssl/ossl_typ.h>
 
-#include <ctime>   // for time_t
-#include <memory>  // for unique_ptr
+#include <ctime>
+#include <memory>
 #include <string>
 
-#include "rtc_base/checks.h"              // for RTC_DCHECK
-#include "rtc_base/constructormagic.h"    // for RTC_DISALLOW_COPY_AND_ASSIGN
-#include "rtc_base/opensslcertificate.h"  // for OpenSSLCertificate
-#include "rtc_base/sslcertificate.h"      // for SSLCertChain
-#include "rtc_base/sslidentity.h"         // for SSLIdentity, KeyParams, SSL...
-
-typedef struct ssl_ctx_st SSL_CTX;
+#include "rtc_base/checks.h"
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/opensslcertificate.h"
+#include "rtc_base/sslcertificate.h"
+#include "rtc_base/sslidentity.h"
 
 namespace rtc {
 
 // OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object,
 // which is reference counted inside the OpenSSL library.
-class OpenSSLKeyPair {
+class OpenSSLKeyPair final {
  public:
   explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) {
     RTC_DCHECK(pkey_ != nullptr);
@@ -60,7 +58,7 @@
 
 // Holds a keypair and certificate together, and a method to generate
 // them consistently.
-class OpenSSLIdentity : public SSLIdentity {
+class OpenSSLIdentity final : public SSLIdentity {
  public:
   static OpenSSLIdentity* GenerateWithExpiration(const std::string& common_name,
                                                  const KeyParams& key_params,
diff --git a/rtc_base/opensslstreamadapter.cc b/rtc_base/opensslstreamadapter.cc
index fd54a08..727cb84 100644
--- a/rtc_base/opensslstreamadapter.cc
+++ b/rtc_base/opensslstreamadapter.cc
@@ -22,6 +22,7 @@
 #endif
 
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "rtc_base/checks.h"
@@ -31,6 +32,7 @@
 #include "rtc_base/openssladapter.h"
 #include "rtc_base/openssldigest.h"
 #include "rtc_base/opensslidentity.h"
+#include "rtc_base/sslcertificate.h"
 #include "rtc_base/stream.h"
 #include "rtc_base/stringutils.h"
 #include "rtc_base/thread.h"
@@ -180,8 +182,9 @@
 
 static BIO* BIO_new_stream(StreamInterface* stream) {
   BIO* ret = BIO_new(BIO_stream_method());
-  if (ret == nullptr)
+  if (ret == nullptr) {
     return nullptr;
+  }
   BIO_set_data(ret, stream);
   return ret;
 }
@@ -196,14 +199,16 @@
 }
 
 static int stream_free(BIO* b) {
-  if (b == nullptr)
+  if (b == nullptr) {
     return 0;
+  }
   return 1;
 }
 
 static int stream_read(BIO* b, char* out, int outl) {
-  if (!out)
+  if (!out) {
     return -1;
+  }
   StreamInterface* stream = static_cast<StreamInterface*>(BIO_get_data(b));
   BIO_clear_retry_flags(b);
   size_t read;
@@ -218,8 +223,9 @@
 }
 
 static int stream_write(BIO* b, const char* in, int inl) {
-  if (!in)
+  if (!in) {
     return -1;
+  }
   StreamInterface* stream = static_cast<StreamInterface*>(BIO_get_data(b));
   BIO_clear_retry_flags(b);
   size_t written;
@@ -296,7 +302,7 @@
     size_t digest_len,
     SSLPeerCertificateDigestError* error) {
   RTC_DCHECK(!peer_certificate_verified_);
-  RTC_DCHECK(!has_peer_certificate_digest());
+  RTC_DCHECK(!HasPeerCertificateDigest());
   size_t expected_len;
   if (error) {
     *error = SSLPeerCertificateDigestError::NONE;
@@ -362,8 +368,9 @@
 }
 
 bool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
-  if (state_ != SSL_CONNECTED)
+  if (state_ != SSL_CONNECTED) {
     return false;
+  }
 
   const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
   if (current_cipher == nullptr) {
@@ -380,17 +387,19 @@
 
   int ssl_version = SSL_version(ssl_);
   if (ssl_mode_ == SSL_MODE_DTLS) {
-    if (ssl_version == DTLS1_VERSION)
+    if (ssl_version == DTLS1_VERSION) {
       return SSL_PROTOCOL_DTLS_10;
-    else if (ssl_version == DTLS1_2_VERSION)
+    } else if (ssl_version == DTLS1_2_VERSION) {
       return SSL_PROTOCOL_DTLS_12;
+    }
   } else {
-    if (ssl_version == TLS1_VERSION)
+    if (ssl_version == TLS1_VERSION) {
       return SSL_PROTOCOL_TLS_10;
-    else if (ssl_version == TLS1_1_VERSION)
+    } else if (ssl_version == TLS1_1_VERSION) {
       return SSL_PROTOCOL_TLS_11;
-    else if (ssl_version == TLS1_2_VERSION)
+    } else if (ssl_version == TLS1_2_VERSION) {
       return SSL_PROTOCOL_TLS_12;
+    }
   }
 
   return -1;
@@ -403,15 +412,11 @@
                                                 bool use_context,
                                                 uint8_t* result,
                                                 size_t result_len) {
-  int i;
-
-  i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
+  if (SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
                                  label.length(), const_cast<uint8_t*>(context),
-                                 context_len, use_context);
-
-  if (i != 1)
+                                 context_len, use_context) != 1) {
     return false;
-
+  }
   return true;
 }
 
@@ -419,8 +424,9 @@
     const std::vector<int>& ciphers) {
   std::string internal_ciphers;
 
-  if (state_ != SSL_NONE)
+  if (state_ != SSL_NONE) {
     return false;
+  }
 
   for (std::vector<int>::const_iterator cipher = ciphers.begin();
        cipher != ciphers.end(); ++cipher) {
@@ -429,8 +435,9 @@
          ++entry) {
       if (*cipher == entry->id) {
         found = true;
-        if (!internal_ciphers.empty())
+        if (!internal_ciphers.empty()) {
           internal_ciphers += ":";
+        }
         internal_ciphers += entry->internal_name;
         break;
       }
@@ -442,8 +449,9 @@
     }
   }
 
-  if (internal_ciphers.empty())
+  if (internal_ciphers.empty()) {
     return false;
+  }
 
   srtp_ciphers_ = internal_ciphers;
   return true;
@@ -451,14 +459,16 @@
 
 bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) {
   RTC_DCHECK(state_ == SSL_CONNECTED);
-  if (state_ != SSL_CONNECTED)
+  if (state_ != SSL_CONNECTED) {
     return false;
+  }
 
   const SRTP_PROTECTION_PROFILE* srtp_profile =
       SSL_get_selected_srtp_profile(ssl_);
 
-  if (!srtp_profile)
+  if (!srtp_profile) {
     return false;
+  }
 
   *crypto_suite = srtp_profile->id;
   RTC_DCHECK(!SrtpCryptoSuiteToName(*crypto_suite).empty());
@@ -470,8 +480,8 @@
 }
 
 int OpenSSLStreamAdapter::StartSSL() {
+  // Don't allow StartSSL to be called twice.
   if (state_ != SSL_NONE) {
-    // Don't allow StartSSL to be called twice.
     return -1;
   }
 
@@ -524,7 +534,7 @@
       return SR_BLOCK;
 
     case SSL_CONNECTED:
-      if (waiting_to_verify_peer_certificate()) {
+      if (WaitingToVerifyPeerCertificate()) {
         return SR_BLOCK;
       }
       break;
@@ -532,15 +542,17 @@
     case SSL_ERROR:
     case SSL_CLOSED:
     default:
-      if (error)
+      if (error) {
         *error = ssl_error_code_;
+      }
       return SR_ERROR;
   }
 
   // OpenSSL will return an error if we try to write zero bytes
   if (data_len == 0) {
-    if (written)
+    if (written) {
       *written = 0;
+    }
     return SR_SUCCESS;
   }
 
@@ -567,8 +579,9 @@
     case SSL_ERROR_ZERO_RETURN:
     default:
       Error("SSL_write", (ssl_error ? ssl_error : -1), 0, false);
-      if (error)
+      if (error) {
         *error = ssl_error_code_;
+      }
       return SR_ERROR;
   }
   // not reached
@@ -583,31 +596,29 @@
     case SSL_NONE:
       // pass-through in clear text
       return StreamAdapterInterface::Read(data, data_len, read, error);
-
     case SSL_WAIT:
     case SSL_CONNECTING:
       return SR_BLOCK;
-
     case SSL_CONNECTED:
-      if (waiting_to_verify_peer_certificate()) {
+      if (WaitingToVerifyPeerCertificate()) {
         return SR_BLOCK;
       }
       break;
-
     case SSL_CLOSED:
       return SR_EOS;
-
     case SSL_ERROR:
     default:
-      if (error)
+      if (error) {
         *error = ssl_error_code_;
+      }
       return SR_ERROR;
   }
 
   // Don't trust OpenSSL with zero byte reads
   if (data_len == 0) {
-    if (read)
+    if (read) {
       *read = 0;
+    }
     return SR_SUCCESS;
   }
 
@@ -620,8 +631,9 @@
       RTC_LOG(LS_VERBOSE) << " -- success";
       RTC_DCHECK_GT(code, 0);
       RTC_DCHECK_LE(code, data_len);
-      if (read)
+      if (read) {
         *read = code;
+      }
 
       if (ssl_mode_ == SSL_MODE_DTLS) {
         // Enforce atomic reads -- this is a short read
@@ -630,8 +642,9 @@
         if (pending) {
           RTC_LOG(LS_INFO) << " -- short DTLS read. flushing";
           FlushInput(pending);
-          if (error)
+          if (error) {
             *error = SSE_MSG_TRUNC;
+          }
           return SR_ERROR;
         }
       }
@@ -650,8 +663,9 @@
       break;
     default:
       Error("SSL_read", (ssl_error ? ssl_error : -1), 0, false);
-      if (error)
+      if (error) {
         *error = ssl_error_code_;
+      }
       return SR_ERROR;
   }
   // not reached
@@ -694,13 +708,13 @@
     case SSL_CONNECTING:
       return SS_OPENING;
     case SSL_CONNECTED:
-      if (waiting_to_verify_peer_certificate()) {
+      if (WaitingToVerifyPeerCertificate()) {
         return SS_OPENING;
       }
       return SS_OPEN;
     default:
       return SS_CLOSED;
-  };
+  }
   // not reached
 }
 
@@ -710,6 +724,7 @@
   int events_to_signal = 0;
   int signal_error = 0;
   RTC_DCHECK(stream == this->stream());
+
   if ((events & SE_OPEN)) {
     RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
     if (state_ != SSL_WAIT) {
@@ -723,6 +738,7 @@
       }
     }
   }
+
   if ((events & (SE_READ | SE_WRITE))) {
     RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
                         << ((events & SE_READ) ? " SE_READ" : "")
@@ -747,6 +763,7 @@
       }
     }
   }
+
   if ((events & SE_CLOSE)) {
     RTC_LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err
                         << ")";
@@ -756,8 +773,10 @@
     RTC_DCHECK(signal_error == 0);
     signal_error = err;
   }
-  if (events_to_signal)
+
+  if (events_to_signal) {
     StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
+  }
 }
 
 int OpenSSLStreamAdapter::BeginSSL() {
@@ -770,12 +789,14 @@
   // First set up the context.
   RTC_DCHECK(ssl_ctx_ == nullptr);
   ssl_ctx_ = SetupSSLContext();
-  if (!ssl_ctx_)
+  if (!ssl_ctx_) {
     return -1;
+  }
 
   bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
-  if (!bio)
+  if (!bio) {
     return -1;
+  }
 
   ssl_ = SSL_new(ssl_ctx_);
   if (!ssl_) {
@@ -805,8 +826,9 @@
   // commonly supported. BoringSSL doesn't need explicit configuration and has
   // a reasonable default set.
   EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-  if (ecdh == nullptr)
+  if (ecdh == nullptr) {
     return -1;
+  }
   SSL_set_options(ssl_, SSL_OP_SINGLE_ECDH_USE);
   SSL_set_tmp_ecdh(ssl_, ecdh);
   EC_KEY_free(ecdh);
@@ -830,10 +852,10 @@
       RTC_LOG(LS_VERBOSE) << " -- success";
       // By this point, OpenSSL should have given us a certificate, or errored
       // out if one was missing.
-      RTC_DCHECK(peer_cert_chain_ || !client_auth_enabled());
+      RTC_DCHECK(peer_cert_chain_ || !GetClientAuthEnabled());
 
       state_ = SSL_CONNECTED;
-      if (!waiting_to_verify_peer_certificate()) {
+      if (!WaitingToVerifyPeerCertificate()) {
         // We have everything we need to start the connection, so signal
         // SE_OPEN. If we need a client certificate fingerprint and don't have
         // it yet, we'll instead signal SE_OPEN in SetPeerCertificateDigest.
@@ -886,8 +908,9 @@
   state_ = SSL_ERROR;
   ssl_error_code_ = err;
   Cleanup(alert);
-  if (signal)
+  if (signal) {
     StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
+  }
 }
 
 void OpenSSLStreamAdapter::Cleanup(uint8_t alert) {
@@ -990,8 +1013,9 @@
   ctx = SSL_CTX_new(method);
 #endif  // OPENSSL_IS_BORINGSSL
 
-  if (ctx == nullptr)
+  if (ctx == nullptr) {
     return nullptr;
+  }
 
 #ifdef OPENSSL_IS_BORINGSSL
   SSL_CTX_set_min_proto_version(
@@ -1026,7 +1050,7 @@
 #endif
 
   int mode = SSL_VERIFY_PEER;
-  if (client_auth_enabled()) {
+  if (GetClientAuthEnabled()) {
     // Require a certificate from the client.
     // Note: Normally this is always true in production, but it may be disabled
     // for testing purposes (e.g. SSLAdapter unit tests).
@@ -1058,7 +1082,7 @@
 }
 
 bool OpenSSLStreamAdapter::VerifyPeerCertificate() {
-  if (!has_peer_certificate_digest() || !peer_cert_chain_ ||
+  if (!HasPeerCertificateDigest() || !peer_cert_chain_ ||
       !peer_cert_chain_->GetSize()) {
     RTC_LOG(LS_WARNING) << "Missing digest or peer certificate.";
     return false;
@@ -1091,7 +1115,7 @@
 
 std::unique_ptr<SSLCertChain> OpenSSLStreamAdapter::GetPeerSSLCertChain()
     const {
-  return peer_cert_chain_ ? peer_cert_chain_->UniqueCopy() : nullptr;
+  return peer_cert_chain_ ? peer_cert_chain_->Clone() : nullptr;
 }
 
 int OpenSSLStreamAdapter::SSLVerifyCallback(X509_STORE_CTX* store, void* arg) {
@@ -1176,15 +1200,17 @@
 bool OpenSSLStreamAdapter::IsAcceptableCipher(int cipher, KeyType key_type) {
   if (key_type == KT_RSA) {
     for (const cipher_list& c : OK_RSA_ciphers) {
-      if (cipher == c.cipher)
+      if (cipher == c.cipher) {
         return true;
+      }
     }
   }
 
   if (key_type == KT_ECDSA) {
     for (const cipher_list& c : OK_ECDSA_ciphers) {
-      if (cipher == c.cipher)
+      if (cipher == c.cipher) {
         return true;
+      }
     }
   }
 
@@ -1195,22 +1221,24 @@
                                               KeyType key_type) {
   if (key_type == KT_RSA) {
     for (const cipher_list& c : OK_RSA_ciphers) {
-      if (cipher == c.cipher_str)
+      if (cipher == c.cipher_str) {
         return true;
+      }
     }
   }
 
   if (key_type == KT_ECDSA) {
     for (const cipher_list& c : OK_ECDSA_ciphers) {
-      if (cipher == c.cipher_str)
+      if (cipher == c.cipher_str) {
         return true;
+      }
     }
   }
 
   return false;
 }
 
-void OpenSSLStreamAdapter::enable_time_callback_for_testing() {
+void OpenSSLStreamAdapter::EnableTimeCallbackForTesting() {
   g_use_time_callback_for_testing = true;
 }
 
diff --git a/rtc_base/opensslstreamadapter.h b/rtc_base/opensslstreamadapter.h
index 61ffc3d..e012d17 100644
--- a/rtc_base/opensslstreamadapter.h
+++ b/rtc_base/opensslstreamadapter.h
@@ -13,13 +13,18 @@
 
 #include <openssl/ossl_typ.h>
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "rtc_base/buffer.h"
+#include "rtc_base/messagequeue.h"
 #include "rtc_base/opensslidentity.h"
+#include "rtc_base/sslidentity.h"
 #include "rtc_base/sslstreamadapter.h"
+#include "rtc_base/stream.h"
 
 namespace rtc {
 
@@ -47,11 +52,11 @@
 
 // Look in sslstreamadapter.h for documentation of the methods.
 
-class OpenSSLIdentity;
+class SSLCertChain;
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class OpenSSLStreamAdapter : public SSLStreamAdapter {
+class OpenSSLStreamAdapter final : public SSLStreamAdapter {
  public:
   explicit OpenSSLStreamAdapter(StreamInterface* stream);
   ~OpenSSLStreamAdapter() override;
@@ -115,7 +120,7 @@
 
   // Use our timeutils.h source of timing in BoringSSL, allowing us to test
   // using a fake clock.
-  static void enable_time_callback_for_testing();
+  static void EnableTimeCallbackForTesting();
 
  protected:
   void OnEvent(StreamInterface* stream, int events, int err) override;
@@ -170,11 +175,11 @@
   // SSL_CTX_set_cert_verify_callback.
   static int SSLVerifyCallback(X509_STORE_CTX* store, void* arg);
 
-  bool waiting_to_verify_peer_certificate() const {
-    return client_auth_enabled() && !peer_certificate_verified_;
+  bool WaitingToVerifyPeerCertificate() const {
+    return GetClientAuthEnabled() && !peer_certificate_verified_;
   }
 
-  bool has_peer_certificate_digest() const {
+  bool HasPeerCertificateDigest() const {
     return !peer_certificate_digest_algorithm_.empty() &&
            !peer_certificate_digest_value_.empty();
   }
diff --git a/rtc_base/opensslutility.cc b/rtc_base/opensslutility.cc
index 46f4547..a3f3347 100644
--- a/rtc_base/opensslutility.cc
+++ b/rtc_base/opensslutility.cc
@@ -9,29 +9,21 @@
  */
 
 #include "rtc_base/opensslutility.h"
-
-#include <memory>
-
-#if defined(WEBRTC_POSIX)
-#include <unistd.h>
-#endif
-
 #if defined(WEBRTC_WIN)
 // Must be included first before openssl headers.
 #include "rtc_base/win32.h"  // NOLINT
 #endif                       // WEBRTC_WIN
 
-#include <openssl/bio.h>
-#include <openssl/crypto.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
+#include "rtc_base/openssl.h"
+
+#include <stddef.h>
 
 #include "rtc_base/arraysize.h"
-#include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
-#include "rtc_base/openssl.h"
 #include "rtc_base/opensslcertificate.h"
 #ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
 #include "rtc_base/sslroots.h"
diff --git a/rtc_base/optionsfile.cc b/rtc_base/optionsfile.cc
deleted file mode 100644
index 535859b..0000000
--- a/rtc_base/optionsfile.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- *  Copyright 2008 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 "rtc_base/optionsfile.h"
-
-#include <ctype.h>
-
-#include "rtc_base/logging.h"
-#include "rtc_base/stream.h"
-#include "rtc_base/stringencode.h"
-
-namespace rtc {
-
-OptionsFile::OptionsFile(const std::string& path) : path_(path) {}
-
-OptionsFile::~OptionsFile() = default;
-
-bool OptionsFile::Load() {
-  options_.clear();
-  // Open file.
-  FileStream stream;
-  int err;
-  if (!stream.Open(path_, "r", &err)) {
-    RTC_LOG_F(LS_WARNING) << "Could not open file, err=" << err;
-    // We do not consider this an error because we expect there to be no file
-    // until the user saves a setting.
-    return true;
-  }
-  // Read in all its data.
-  std::string line;
-  StreamResult res;
-  for (;;) {
-    res = stream.ReadLine(&line);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    size_t equals_pos = line.find('=');
-    if (equals_pos == std::string::npos) {
-      // We do not consider this an error. Instead we ignore the line and
-      // keep going.
-      RTC_LOG_F(LS_WARNING) << "Ignoring malformed line in " << path_;
-      continue;
-    }
-    std::string key(line, 0, equals_pos);
-    std::string value(line, equals_pos + 1, line.length() - (equals_pos + 1));
-    options_[key] = value;
-  }
-  if (res != SR_EOS) {
-    RTC_LOG_F(LS_ERROR) << "Error when reading from file";
-    return false;
-  } else {
-    return true;
-  }
-}
-
-bool OptionsFile::Save() {
-  // Open file.
-  FileStream stream;
-  int err;
-  if (!stream.Open(path_, "w", &err)) {
-    RTC_LOG_F(LS_ERROR) << "Could not open file, err=" << err;
-    return false;
-  }
-  // Write out all the data.
-  StreamResult res = SR_SUCCESS;
-  size_t written;
-  int error;
-  for (OptionsMap::const_iterator i = options_.begin(); i != options_.end();
-       ++i) {
-    res =
-        stream.WriteAll(i->first.c_str(), i->first.length(), &written, &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    res = stream.WriteAll("=", 1, &written, &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    res = stream.WriteAll(i->second.c_str(), i->second.length(), &written,
-                          &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    res = stream.WriteAll("\n", 1, &written, &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-  }
-  if (res != SR_SUCCESS) {
-    RTC_LOG_F(LS_ERROR) << "Unable to write to file";
-    return false;
-  } else {
-    return true;
-  }
-}
-
-bool OptionsFile::IsLegalName(const std::string& name) {
-  for (size_t pos = 0; pos < name.length(); ++pos) {
-    if (name[pos] == '\n' || name[pos] == '\\' || name[pos] == '=') {
-      // Illegal character.
-      RTC_LOG(LS_WARNING) << "Ignoring operation for illegal option " << name;
-      return false;
-    }
-  }
-  return true;
-}
-
-bool OptionsFile::IsLegalValue(const std::string& value) {
-  for (size_t pos = 0; pos < value.length(); ++pos) {
-    if (value[pos] == '\n' || value[pos] == '\\') {
-      // Illegal character.
-      RTC_LOG(LS_WARNING) << "Ignoring operation for illegal value " << value;
-      return false;
-    }
-  }
-  return true;
-}
-
-bool OptionsFile::GetStringValue(const std::string& option,
-                                 std::string* out_val) const {
-  RTC_LOG(LS_VERBOSE) << "OptionsFile::GetStringValue " << option;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  OptionsMap::const_iterator i = options_.find(option);
-  if (i == options_.end()) {
-    return false;
-  }
-  *out_val = i->second;
-  return true;
-}
-
-bool OptionsFile::GetIntValue(const std::string& option, int* out_val) const {
-  RTC_LOG(LS_VERBOSE) << "OptionsFile::GetIntValue " << option;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  OptionsMap::const_iterator i = options_.find(option);
-  if (i == options_.end()) {
-    return false;
-  }
-  return FromString(i->second, out_val);
-}
-
-bool OptionsFile::SetStringValue(const std::string& option,
-                                 const std::string& value) {
-  RTC_LOG(LS_VERBOSE) << "OptionsFile::SetStringValue " << option << ":"
-                      << value;
-  if (!IsLegalName(option) || !IsLegalValue(value)) {
-    return false;
-  }
-  options_[option] = value;
-  return true;
-}
-
-bool OptionsFile::SetIntValue(const std::string& option, int value) {
-  RTC_LOG(LS_VERBOSE) << "OptionsFile::SetIntValue " << option << ":" << value;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  options_[option] = ToString(value);
-  return true;
-}
-
-bool OptionsFile::RemoveValue(const std::string& option) {
-  RTC_LOG(LS_VERBOSE) << "OptionsFile::RemoveValue " << option;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  options_.erase(option);
-  return true;
-}
-
-}  // namespace rtc
diff --git a/rtc_base/optionsfile.h b/rtc_base/optionsfile.h
deleted file mode 100644
index 55660ff..0000000
--- a/rtc_base/optionsfile.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Copyright 2008 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 RTC_BASE_OPTIONSFILE_H_
-#define RTC_BASE_OPTIONSFILE_H_
-
-#include <map>
-#include <string>
-
-namespace rtc {
-
-// Implements storage of simple options in a text file on disk. This is
-// cross-platform, but it is intended mostly for Linux where there is no
-// first-class options storage system.
-class OptionsFile {
- public:
-  OptionsFile(const std::string& path);
-  ~OptionsFile();
-
-  // Loads the file from disk, overwriting the in-memory values.
-  bool Load();
-  // Saves the contents in memory, overwriting the on-disk values.
-  bool Save();
-
-  bool GetStringValue(const std::string& option, std::string* out_val) const;
-  bool GetIntValue(const std::string& option, int* out_val) const;
-  bool SetStringValue(const std::string& option, const std::string& val);
-  bool SetIntValue(const std::string& option, int val);
-  bool RemoveValue(const std::string& option);
-
- private:
-  typedef std::map<std::string, std::string> OptionsMap;
-
-  static bool IsLegalName(const std::string& name);
-  static bool IsLegalValue(const std::string& value);
-
-  std::string path_;
-  OptionsMap options_;
-};
-
-}  // namespace rtc
-
-#endif  // RTC_BASE_OPTIONSFILE_H_
diff --git a/rtc_base/optionsfile_unittest.cc b/rtc_base/optionsfile_unittest.cc
deleted file mode 100644
index fc5bc82..0000000
--- a/rtc_base/optionsfile_unittest.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  Copyright 2008 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 <memory>
-
-#include "rtc_base/checks.h"
-#include "rtc_base/gunit.h"
-#include "rtc_base/optionsfile.h"
-#include "test/testsupport/fileutils.h"
-
-namespace rtc {
-
-static const std::string kTestOptionA = "test-option-a";
-static const std::string kTestOptionB = "test-option-b";
-static const std::string kTestString1 = "a string";
-static const std::string kTestString2 = "different string";
-static const std::string kOptionWithEquals = "foo=bar";
-static const std::string kOptionWithNewline = "foo\nbar";
-static const std::string kValueWithEquals = "baz=quux";
-static const std::string kValueWithNewline = "baz\nquux";
-static const std::string kEmptyString = "";
-static const char kOptionWithUtf8[] = {'O',    'p', 't', '\302', '\256',
-                                       'i',    'o', 'n', '\342', '\204',
-                                       '\242', '\0'};  // Opt(R)io(TM).
-static const char kValueWithUtf8[] = {
-    'V', 'a',    'l',    '\302', '\256', 'v',
-    'e', '\342', '\204', '\242', '\0'};  // Val(R)ue(TM).
-static int kTestInt1 = 12345;
-static int kTestInt2 = 67890;
-static int kNegInt = -634;
-static int kZero = 0;
-
-#if defined(WEBRTC_ANDROID)
-// Fails on Android: https://bugs.chromium.org/p/webrtc/issues/detail?id=4364.
-#define MAYBE_OptionsFileTest DISABLED_OptionsFileTest
-#else
-#define MAYBE_OptionsFileTest OptionsFileTest
-#endif
-
-class MAYBE_OptionsFileTest : public testing::Test {
- public:
-  MAYBE_OptionsFileTest() {
-    test_file_ =
-        webrtc::test::TempFilename(webrtc::test::OutputPath(), ".testfile");
-    OpenStore();
-  }
-
-  ~MAYBE_OptionsFileTest() override { webrtc::test::RemoveFile(test_file_); }
-
- protected:
-  void OpenStore() { store_.reset(new OptionsFile(test_file_)); }
-
-  std::unique_ptr<OptionsFile> store_;
-
- private:
-  std::string test_file_;
-};
-
-TEST_F(MAYBE_OptionsFileTest, GetSetString) {
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store_->Save());
-  std::string out1, out2;
-  EXPECT_FALSE(store_->GetStringValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store_->GetStringValue(kTestOptionB, &out2));
-  EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kTestString1));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->SetStringValue(kTestOptionB, kTestString2));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out1));
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionB, &out2));
-  EXPECT_EQ(kTestString1, out1);
-  EXPECT_EQ(kTestString2, out2);
-  EXPECT_TRUE(store_->RemoveValue(kTestOptionA));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->RemoveValue(kTestOptionB));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_FALSE(store_->GetStringValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store_->GetStringValue(kTestOptionB, &out2));
-}
-
-TEST_F(MAYBE_OptionsFileTest, GetSetInt) {
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store_->Save());
-  int out1, out2;
-  EXPECT_FALSE(store_->GetIntValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store_->GetIntValue(kTestOptionB, &out2));
-  EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kTestInt1));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->SetIntValue(kTestOptionB, kTestInt2));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1));
-  EXPECT_TRUE(store_->GetIntValue(kTestOptionB, &out2));
-  EXPECT_EQ(kTestInt1, out1);
-  EXPECT_EQ(kTestInt2, out2);
-  EXPECT_TRUE(store_->RemoveValue(kTestOptionA));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->RemoveValue(kTestOptionB));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_FALSE(store_->GetIntValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store_->GetIntValue(kTestOptionB, &out2));
-  EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kNegInt));
-  EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1));
-  EXPECT_EQ(kNegInt, out1);
-  EXPECT_TRUE(store_->SetIntValue(kTestOptionA, kZero));
-  EXPECT_TRUE(store_->GetIntValue(kTestOptionA, &out1));
-  EXPECT_EQ(kZero, out1);
-}
-
-TEST_F(MAYBE_OptionsFileTest, Persist) {
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kTestString1));
-  EXPECT_TRUE(store_->SetIntValue(kTestOptionB, kNegInt));
-  EXPECT_TRUE(store_->Save());
-
-  // Load the saved contents from above.
-  OpenStore();
-  EXPECT_TRUE(store_->Load());
-  std::string out1;
-  int out2;
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out1));
-  EXPECT_TRUE(store_->GetIntValue(kTestOptionB, &out2));
-  EXPECT_EQ(kTestString1, out1);
-  EXPECT_EQ(kNegInt, out2);
-}
-
-TEST_F(MAYBE_OptionsFileTest, SpecialCharacters) {
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store_->Save());
-  std::string out;
-  EXPECT_FALSE(store_->SetStringValue(kOptionWithEquals, kTestString1));
-  EXPECT_FALSE(store_->GetStringValue(kOptionWithEquals, &out));
-  EXPECT_FALSE(store_->SetStringValue(kOptionWithNewline, kTestString1));
-  EXPECT_FALSE(store_->GetStringValue(kOptionWithNewline, &out));
-  EXPECT_TRUE(store_->SetStringValue(kOptionWithUtf8, kValueWithUtf8));
-  EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kTestString1));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out));
-  EXPECT_EQ(kTestString1, out);
-  EXPECT_TRUE(store_->GetStringValue(kOptionWithUtf8, &out));
-  EXPECT_EQ(kValueWithUtf8, out);
-  EXPECT_FALSE(store_->SetStringValue(kTestOptionA, kValueWithNewline));
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out));
-  EXPECT_EQ(kTestString1, out);
-  EXPECT_TRUE(store_->SetStringValue(kTestOptionA, kValueWithEquals));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionA, &out));
-  EXPECT_EQ(kValueWithEquals, out);
-  EXPECT_TRUE(store_->SetStringValue(kEmptyString, kTestString2));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->GetStringValue(kEmptyString, &out));
-  EXPECT_EQ(kTestString2, out);
-  EXPECT_TRUE(store_->SetStringValue(kTestOptionB, kEmptyString));
-  EXPECT_TRUE(store_->Save());
-  EXPECT_TRUE(store_->Load());
-  EXPECT_TRUE(store_->GetStringValue(kTestOptionB, &out));
-  EXPECT_EQ(kEmptyString, out);
-}
-
-}  // namespace rtc
diff --git a/rtc_base/pathutils.cc b/rtc_base/pathutils.cc
deleted file mode 100644
index 0764671..0000000
--- a/rtc_base/pathutils.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Copyright 2004 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.
- */
-
-#if defined(WEBRTC_WIN)
-#include <windows.h>
-#include <shellapi.h>
-#include <shlobj.h>
-#include <tchar.h>
-#endif  // WEBRTC_WIN
-
-#include <string.h>  // for strchr
-
-#include "rtc_base/pathutils.h"
-
-namespace rtc {
-
-static const char EMPTY_STR[] = "";
-
-// EXT_DELIM separates a file basename from extension
-const char EXT_DELIM = '.';
-
-// FOLDER_DELIMS separate folder segments and the filename
-const char* const FOLDER_DELIMS = "/\\";
-
-// DEFAULT_FOLDER_DELIM is the preferred delimiter for this platform
-#ifdef WEBRTC_WIN
-const char DEFAULT_FOLDER_DELIM = '\\';
-#else  // !WEBRTC_WIN
-const char DEFAULT_FOLDER_DELIM = '/';
-#endif  // !WEBRTC_WIN
-
-///////////////////////////////////////////////////////////////////////////////
-// Pathname - parsing of pathnames into components, and vice versa
-///////////////////////////////////////////////////////////////////////////////
-
-bool Pathname::IsFolderDelimiter(char ch) {
-  return (nullptr != ::strchr(FOLDER_DELIMS, ch));
-}
-
-char Pathname::DefaultFolderDelimiter() {
-  return DEFAULT_FOLDER_DELIM;
-}
-
-Pathname::Pathname()
-    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
-}
-
-Pathname::Pathname(const Pathname&) = default;
-Pathname::Pathname(Pathname&&) = default;
-
-Pathname::Pathname(const std::string& pathname)
-    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
-  SetPathname(pathname);
-}
-
-Pathname::Pathname(const std::string& folder, const std::string& filename)
-    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
-  SetPathname(folder, filename);
-}
-
-Pathname& Pathname::operator=(const Pathname&) = default;
-Pathname& Pathname::operator=(Pathname&&) = default;
-
-std::string Pathname::pathname() const {
-  std::string pathname(folder_);
-  pathname.append(basename_);
-  pathname.append(extension_);
-  if (pathname.empty()) {
-    // Instead of the empty pathname, return the current working directory.
-    pathname.push_back('.');
-    pathname.push_back(folder_delimiter_);
-  }
-  return pathname;
-}
-
-void Pathname::SetPathname(const std::string& pathname) {
-  std::string::size_type pos = pathname.find_last_of(FOLDER_DELIMS);
-  if (pos != std::string::npos) {
-    SetFolder(pathname.substr(0, pos + 1));
-    SetFilename(pathname.substr(pos + 1));
-  } else {
-    SetFolder(EMPTY_STR);
-    SetFilename(pathname);
-  }
-}
-
-void Pathname::SetPathname(const std::string& folder,
-                           const std::string& filename) {
-  SetFolder(folder);
-  SetFilename(filename);
-}
-
-void Pathname::SetFolder(const std::string& folder) {
-  folder_.assign(folder);
-  // Ensure folder ends in a path delimiter
-  if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) {
-    folder_.push_back(folder_delimiter_);
-  }
-}
-
-void Pathname::AppendFolder(const std::string& folder) {
-  folder_.append(folder);
-  // Ensure folder ends in a path delimiter
-  if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) {
-    folder_.push_back(folder_delimiter_);
-  }
-}
-
-bool Pathname::SetBasename(const std::string& basename) {
-  if(basename.find_first_of(FOLDER_DELIMS) != std::string::npos) {
-    return false;
-  }
-  basename_.assign(basename);
-  return true;
-}
-
-bool Pathname::SetExtension(const std::string& extension) {
-  if (extension.find_first_of(FOLDER_DELIMS) != std::string::npos ||
-    extension.find_first_of(EXT_DELIM, 1) != std::string::npos) {
-      return false;
-  }
-  extension_.assign(extension);
-  // Ensure extension begins with the extension delimiter
-  if (!extension_.empty() && (extension_[0] != EXT_DELIM)) {
-    extension_.insert(extension_.begin(), EXT_DELIM);
-  }
-  return true;
-}
-
-std::string Pathname::filename() const {
-  std::string filename(basename_);
-  filename.append(extension_);
-  return filename;
-}
-
-bool Pathname::SetFilename(const std::string& filename) {
-  std::string::size_type pos = filename.rfind(EXT_DELIM);
-  if ((pos == std::string::npos) || (pos == 0)) {
-    return SetExtension(EMPTY_STR) && SetBasename(filename);
-  } else {
-    return SetExtension(filename.substr(pos)) && SetBasename(filename.substr(0, pos));
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace rtc
diff --git a/rtc_base/pathutils.h b/rtc_base/pathutils.h
deleted file mode 100644
index 59f2a4a..0000000
--- a/rtc_base/pathutils.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Copyright 2004 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 RTC_BASE_PATHUTILS_H_
-#define RTC_BASE_PATHUTILS_H_
-
-#include <string>
-
-namespace rtc {
-
-///////////////////////////////////////////////////////////////////////////////
-// Pathname - parsing of pathnames into components, and vice versa.
-//
-// To establish consistent terminology, a filename never contains a folder
-// component.  A folder never contains a filename.  A pathname may include
-// a folder and/or filename component.  Here are some examples:
-//
-//   pathname()      /home/john/example.txt
-//   folder()        /home/john/
-//   filename()                 example.txt
-//   parent_folder() /home/
-//   folder_name()         john/
-//   basename()                 example
-//   extension()                       .txt
-//
-// Basename may begin, end, and/or include periods, but no folder delimiters.
-// If extension exists, it consists of a period followed by zero or more
-// non-period/non-delimiter characters, and basename is non-empty.
-///////////////////////////////////////////////////////////////////////////////
-
-class Pathname {
- public:
-  // Folder delimiters are slash and backslash
-  static bool IsFolderDelimiter(char ch);
-  static char DefaultFolderDelimiter();
-
-  Pathname();
-  Pathname(const Pathname&);
-  Pathname(Pathname&&);
-  Pathname(const std::string& pathname);
-  Pathname(const std::string& folder, const std::string& filename);
-
-  Pathname& operator=(const Pathname&);
-  Pathname& operator=(Pathname&&);
-
-  // Returns the folder and filename components.  If the pathname is empty,
-  // returns a string representing the current directory (as a relative path,
-  // i.e., ".").
-  std::string pathname() const;
-  void SetPathname(const std::string& pathname);
-  void SetPathname(const std::string& folder, const std::string& filename);
-
-  // SetFolder and AppendFolder will append a folder delimiter, if needed.
-  void SetFolder(const std::string& folder);
-  void AppendFolder(const std::string& folder);
-
-  bool SetBasename(const std::string& basename);
-
-  // SetExtension will prefix a period, if needed.
-  bool SetExtension(const std::string& extension);
-
-  std::string filename() const;
-  bool SetFilename(const std::string& filename);
-
- private:
-  std::string folder_, basename_, extension_;
-  char folder_delimiter_;
-};
-
-}  // namespace rtc
-
-#endif  // RTC_BASE_PATHUTILS_H_
diff --git a/rtc_base/pathutils_unittest.cc b/rtc_base/pathutils_unittest.cc
deleted file mode 100644
index fae4f0a..0000000
--- a/rtc_base/pathutils_unittest.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Copyright 2007 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 "rtc_base/pathutils.h"
-#include "rtc_base/gunit.h"
-
-TEST(Pathname, ReturnsDotForEmptyPathname) {
-  const std::string kCWD =
-      std::string(".") + rtc::Pathname::DefaultFolderDelimiter();
-
-  rtc::Pathname path("/", "");
-  EXPECT_TRUE (path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(std::string("/"), path.pathname());
-
-  path.SetPathname("", "foo");
-  EXPECT_FALSE(path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(std::string("foo"), path.pathname());
-
-  path.SetPathname("", "");
-  EXPECT_TRUE (path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(kCWD, path.pathname());
-
-  path.SetPathname(kCWD, "");
-  EXPECT_TRUE (path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(kCWD, path.pathname());
-}
diff --git a/rtc_base/physicalsocketserver_unittest.cc b/rtc_base/physicalsocketserver_unittest.cc
index 1e046c0..4b36cd5 100644
--- a/rtc_base/physicalsocketserver_unittest.cc
+++ b/rtc_base/physicalsocketserver_unittest.cc
@@ -547,7 +547,13 @@
 
 // Test receiving a synchronous signal while not in Wait() and then entering
 // Wait() afterwards.
-TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
+// TODO(webrtc:7864): Fails on real iOS devices
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM_FAMILY)
+#define MAYBE_RaiseThenWait DISABLED_RaiseThenWait
+#else
+#define MAYBE_RaiseThenWait RaiseThenWait
+#endif
+TEST_F(PosixSignalDeliveryTest, MAYBE_RaiseThenWait) {
   ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
   raise(SIGTERM);
   EXPECT_TRUE(ss_->Wait(0, true));
@@ -557,7 +563,13 @@
 
 // Test that we can handle getting tons of repeated signals and that we see all
 // the different ones.
-TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
+// TODO(webrtc:7864): Fails on real iOS devices
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM_FAMILY)
+#define MAYBE_InsanelyManySignals DISABLED_InsanelyManySignals
+#else
+#define MAYBE_InsanelyManySignals InsanelyManySignals
+#endif
+TEST_F(PosixSignalDeliveryTest, MAYBE_InsanelyManySignals) {
   ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
   ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
   for (int i = 0; i < 10000; ++i) {
@@ -597,7 +609,13 @@
 
 // Test that it works no matter what thread the kernel chooses to give the
 // signal to (since it's not guaranteed to be the one that Wait() runs on).
-TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
+// TODO(webrtc:7864): Fails on real iOS devices
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM_FAMILY)
+#define MAYBE_SignalOnDifferentThread DISABLED_SignalOnDifferentThread
+#else
+#define MAYBE_SignalOnDifferentThread SignalOnDifferentThread
+#endif
+TEST_F(PosixSignalDeliveryTest, DISABLED_SignalOnDifferentThread) {
   ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
   // Mask out SIGTERM so that it can't be delivered to this thread.
   sigset_t mask;
diff --git a/rtc_base/platform_file.cc b/rtc_base/platform_file.cc
index d74acdd..baefb22 100644
--- a/rtc_base/platform_file.cc
+++ b/rtc_base/platform_file.cc
@@ -12,11 +12,11 @@
 
 #if defined(WEBRTC_WIN)
 #include <io.h>
+
 #include "rtc_base/stringutils.h"  // For ToUtf16
 #else
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <unistd.h>
 #endif
 
diff --git a/rtc_base/platform_thread.cc b/rtc_base/platform_thread.cc
index 79d9d53..ba84b6a 100644
--- a/rtc_base/platform_thread.cc
+++ b/rtc_base/platform_thread.cc
@@ -10,15 +10,17 @@
 
 #include "rtc_base/platform_thread.h"
 
+#if !defined(WEBRTC_WIN)
+#include <sched.h>
+#endif
+#include <stdint.h>
+#include <time.h>
+#include <algorithm>
+
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/timeutils.h"
 
-#if defined(WEBRTC_LINUX)
-#include <sys/prctl.h>
-#include <sys/syscall.h>
-#endif
-
 namespace rtc {
 namespace {
 #if defined(WEBRTC_WIN)
diff --git a/rtc_base/platform_thread.h b/rtc_base/platform_thread.h
index ea67aca..47c23dc 100644
--- a/rtc_base/platform_thread.h
+++ b/rtc_base/platform_thread.h
@@ -11,6 +11,9 @@
 #ifndef RTC_BASE_PLATFORM_THREAD_H_
 #define RTC_BASE_PLATFORM_THREAD_H_
 
+#ifndef WEBRTC_WIN
+#include <pthread.h>
+#endif
 #include <string>
 
 #include "rtc_base/constructormagic.h"
diff --git a/rtc_base/race_checker.h b/rtc_base/race_checker.h
index d6eba08..4d57460 100644
--- a/rtc_base/race_checker.h
+++ b/rtc_base/race_checker.h
@@ -12,7 +12,7 @@
 #define RTC_BASE_RACE_CHECKER_H_
 
 #include "rtc_base/checks.h"
-#include "rtc_base/platform_thread_types.h"  // for PlatformThreadRef
+#include "rtc_base/platform_thread_types.h"
 #include "rtc_base/thread_annotations.h"
 
 namespace rtc {
diff --git a/rtc_base/random.h b/rtc_base/random.h
index 2faa985..e1c3bb7 100644
--- a/rtc_base/random.h
+++ b/rtc_base/random.h
@@ -11,6 +11,7 @@
 #ifndef RTC_BASE_RANDOM_H_
 #define RTC_BASE_RANDOM_H_
 
+#include <stdint.h>
 #include <limits>
 
 #include "rtc_base/checks.h"
diff --git a/rtc_base/rate_limiter.cc b/rtc_base/rate_limiter.cc
index 0343f25..5c7bdef 100644
--- a/rtc_base/rate_limiter.cc
+++ b/rtc_base/rate_limiter.cc
@@ -9,6 +9,10 @@
  */
 
 #include "rtc_base/rate_limiter.h"
+
+#include <limits>
+
+#include "absl/types/optional.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
diff --git a/rtc_base/rate_limiter.h b/rtc_base/rate_limiter.h
index 0bfde0d..43ef88d 100644
--- a/rtc_base/rate_limiter.h
+++ b/rtc_base/rate_limiter.h
@@ -11,11 +11,13 @@
 #ifndef RTC_BASE_RATE_LIMITER_H_
 #define RTC_BASE_RATE_LIMITER_H_
 
-#include <limits>
+#include <stddef.h>
+#include <stdint.h>
 
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/rate_statistics.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace webrtc {
 
diff --git a/rtc_base/rate_limiter_unittest.cc b/rtc_base/rate_limiter_unittest.cc
index 6efea54..ac0625f 100644
--- a/rtc_base/rate_limiter_unittest.cc
+++ b/rtc_base/rate_limiter_unittest.cc
@@ -112,9 +112,7 @@
 class ThreadTask {
  public:
   explicit ThreadTask(RateLimiter* rate_limiter)
-      : rate_limiter_(rate_limiter),
-        start_signal_(false, false),
-        end_signal_(false, false) {}
+      : rate_limiter_(rate_limiter) {}
   virtual ~ThreadTask() {}
 
   void Run() {
diff --git a/rtc_base/rate_statistics.h b/rtc_base/rate_statistics.h
index 68035c9..d4ccc59 100644
--- a/rtc_base/rate_statistics.h
+++ b/rtc_base/rate_statistics.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_RATE_STATISTICS_H_
 #define RTC_BASE_RATE_STATISTICS_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 
 #include "absl/types/optional.h"
diff --git a/rtc_base/rtccertificate.cc b/rtc_base/rtccertificate.cc
index 786333f..875068f 100644
--- a/rtc_base/rtccertificate.cc
+++ b/rtc_base/rtccertificate.cc
@@ -14,6 +14,8 @@
 
 #include "rtc_base/checks.h"
 #include "rtc_base/refcountedobject.h"
+#include "rtc_base/sslcertificate.h"
+#include "rtc_base/sslidentity.h"
 #include "rtc_base/timeutils.h"
 
 namespace rtc {
@@ -30,7 +32,7 @@
 RTCCertificate::~RTCCertificate() {}
 
 uint64_t RTCCertificate::Expires() const {
-  int64_t expires = ssl_certificate().CertificateExpirationTime();
+  int64_t expires = GetSSLCertificate().CertificateExpirationTime();
   if (expires != -1)
     return static_cast<uint64_t>(expires) * kNumMillisecsPerSec;
   // If the expiration time could not be retrieved return an expired timestamp.
@@ -41,17 +43,22 @@
   return Expires() <= now;
 }
 
+const SSLCertificate& RTCCertificate::GetSSLCertificate() const {
+  return identity_->certificate();
+}
+
+// Deprecated: TODO(benwright) - Remove once chromium is updated.
 const SSLCertificate& RTCCertificate::ssl_certificate() const {
   return identity_->certificate();
 }
 
-const SSLCertChain& RTCCertificate::ssl_cert_chain() const {
+const SSLCertChain& RTCCertificate::GetSSLCertificateChain() const {
   return identity_->cert_chain();
 }
 
 RTCCertificatePEM RTCCertificate::ToPEM() const {
   return RTCCertificatePEM(identity_->PrivateKeyToPEMString(),
-                           ssl_certificate().ToPEMString());
+                           GetSSLCertificate().ToPEMString());
 }
 
 scoped_refptr<RTCCertificate> RTCCertificate::FromPEM(
diff --git a/rtc_base/rtccertificate.h b/rtc_base/rtccertificate.h
index d5422f8..561ea0f 100644
--- a/rtc_base/rtccertificate.h
+++ b/rtc_base/rtccertificate.h
@@ -12,15 +12,18 @@
 #define RTC_BASE_RTCCERTIFICATE_H_
 
 #include <stdint.h>
-
 #include <memory>
+#include <string>
 
 #include "rtc_base/refcount.h"
 #include "rtc_base/scoped_ref_ptr.h"
-#include "rtc_base/sslidentity.h"
 
 namespace rtc {
 
+class SSLCertChain;
+class SSLCertificate;
+class SSLIdentity;
+
 // This class contains PEM strings of an RTCCertificate's private key and
 // certificate and acts as a text representation of RTCCertificate. Certificates
 // can be serialized and deserialized to and from this format, which allows for
@@ -55,11 +58,15 @@
   // Checks if the certificate has expired, where |now| is expressed in ms
   // relative to epoch, 1970-01-01T00:00:00Z.
   bool HasExpired(uint64_t now) const;
+
+  const SSLCertificate& GetSSLCertificate() const;
+  const SSLCertChain& GetSSLCertificateChain() const;
+
+  // Deprecated: TODO(benwright) - Remove once chromium is updated.
   const SSLCertificate& ssl_certificate() const;
-  const SSLCertChain& ssl_cert_chain() const;
 
   // TODO(hbos): If possible, remove once RTCCertificate and its
-  // ssl_certificate() is used in all relevant places. Should not pass around
+  // GetSSLCertificate() is used in all relevant places. Should not pass around
   // raw SSLIdentity* for the sake of accessing SSLIdentity::certificate().
   // However, some places might need SSLIdentity* for its public/private key...
   SSLIdentity* identity() const { return identity_.get(); }
@@ -77,7 +84,7 @@
 
  private:
   // The SSLIdentity is the owner of the SSLCertificate. To protect our
-  // ssl_certificate() we take ownership of |identity_|.
+  // GetSSLCertificate() we take ownership of |identity_|.
   std::unique_ptr<SSLIdentity> identity_;
 };
 
diff --git a/rtc_base/rtccertificategenerator.cc b/rtc_base/rtccertificategenerator.cc
index 0b51c61..114b35c 100644
--- a/rtc_base/rtccertificategenerator.cc
+++ b/rtc_base/rtccertificategenerator.cc
@@ -10,10 +10,15 @@
 
 #include "rtc_base/rtccertificategenerator.h"
 
+#include <time.h>
 #include <algorithm>
 #include <memory>
+#include <utility>
 
 #include "rtc_base/checks.h"
+#include "rtc_base/location.h"
+#include "rtc_base/messagehandler.h"
+#include "rtc_base/messagequeue.h"
 #include "rtc_base/refcountedobject.h"
 #include "rtc_base/sslidentity.h"
 
@@ -23,7 +28,6 @@
 
 // A certificates' subject and issuer name.
 const char kIdentityName[] = "WebRTC";
-
 const uint64_t kYearInSeconds = 365 * 24 * 60 * 60;
 
 enum {
@@ -60,11 +64,9 @@
     switch (msg->message_id) {
       case MSG_GENERATE:
         RTC_DCHECK(worker_thread_->IsCurrent());
-
         // Perform the certificate generation work here on the worker thread.
         certificate_ = RTCCertificateGenerator::GenerateCertificate(
             key_params_, expires_ms_);
-
         // Handle callbacks on signaling thread. Pass on the |msg->pdata|
         // (which references |this| with ref counting) to that thread.
         signaling_thread_->Post(RTC_FROM_HERE, this, MSG_GENERATE_DONE,
@@ -72,14 +74,12 @@
         break;
       case MSG_GENERATE_DONE:
         RTC_DCHECK(signaling_thread_->IsCurrent());
-
         // Perform callback with result here on the signaling thread.
         if (certificate_) {
           callback_->OnSuccess(certificate_);
         } else {
           callback_->OnFailure();
         }
-
         // Destroy |msg->pdata| which references |this| with ref counting. This
         // may result in |this| being deleted - do not touch member variables
         // after this line.
@@ -105,9 +105,11 @@
 scoped_refptr<RTCCertificate> RTCCertificateGenerator::GenerateCertificate(
     const KeyParams& key_params,
     const absl::optional<uint64_t>& expires_ms) {
-  if (!key_params.IsValid())
+  if (!key_params.IsValid()) {
     return nullptr;
-  SSLIdentity* identity;
+  }
+
+  SSLIdentity* identity = nullptr;
   if (!expires_ms) {
     identity = SSLIdentity::Generate(kIdentityName, key_params);
   } else {
@@ -124,8 +126,9 @@
     identity = SSLIdentity::GenerateWithExpiration(kIdentityName, key_params,
                                                    cert_lifetime_s);
   }
-  if (!identity)
+  if (!identity) {
     return nullptr;
+  }
   std::unique_ptr<SSLIdentity> identity_sptr(identity);
   return RTCCertificate::Create(std::move(identity_sptr));
 }
diff --git a/rtc_base/rtccertificategenerator.h b/rtc_base/rtccertificategenerator.h
index a6c503a..fed075e 100644
--- a/rtc_base/rtccertificategenerator.h
+++ b/rtc_base/rtccertificategenerator.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_RTCCERTIFICATEGENERATOR_H_
 #define RTC_BASE_RTCCERTIFICATEGENERATOR_H_
 
+#include <stdint.h>
+
 #include "absl/types/optional.h"
 #include "rtc_base/refcount.h"
 #include "rtc_base/rtccertificate.h"
diff --git a/rtc_base/sanitizer.h b/rtc_base/sanitizer.h
index 23a748f..a9eccfc 100644
--- a/rtc_base/sanitizer.h
+++ b/rtc_base/sanitizer.h
@@ -123,9 +123,11 @@
 
 template <typename T>
 inline T MsanUninitialized(T t) {
+#if RTC_HAS_MSAN
   // TODO(bugs.webrtc.org/8762): Switch to std::is_trivially_copyable when it
   // becomes available in downstream projects.
   static_assert(sanitizer_impl::IsTriviallyCopyable<T>(), "");
+#endif
   rtc_MsanMarkUninitialized(&t, sizeof(T), 1);
   return t;
 }
diff --git a/rtc_base/sequenced_task_checker_impl.cc b/rtc_base/sequenced_task_checker_impl.cc
index 16069c2..717cb95 100644
--- a/rtc_base/sequenced_task_checker_impl.cc
+++ b/rtc_base/sequenced_task_checker_impl.cc
@@ -14,6 +14,7 @@
 #include <dispatch/dispatch.h>
 #endif
 
+#include "rtc_base/checks.h"
 #include "rtc_base/sequenced_task_checker.h"
 #include "rtc_base/task_queue.h"
 
diff --git a/rtc_base/sequenced_task_checker_unittest.cc b/rtc_base/sequenced_task_checker_unittest.cc
index 83fb14f..7b7247c 100644
--- a/rtc_base/sequenced_task_checker_unittest.cc
+++ b/rtc_base/sequenced_task_checker_unittest.cc
@@ -44,7 +44,6 @@
   CallCalledSequentiallyOnThread(bool expect_true,
                                  SequencedTaskChecker* sequenced_task_checker)
       : expect_true_(expect_true),
-        thread_has_run_event_(false, false),
         thread_(&Run, this, "call_do_stuff_on_thread"),
         sequenced_task_checker_(sequenced_task_checker) {
     thread_.Start();
@@ -78,7 +77,6 @@
   explicit DeleteSequencedCheckerOnThread(
       std::unique_ptr<SequencedTaskChecker> sequenced_task_checker)
       : thread_(&Run, this, "delete_sequenced_task_checker_on_thread"),
-        thread_has_run_event_(false, false),
         sequenced_task_checker_(std::move(sequenced_task_checker)) {
     thread_.Start();
   }
@@ -119,7 +117,7 @@
 
   static const char kQueueName[] = "MethodNotAllowedOnDifferentTq";
   TaskQueue queue(kQueueName);
-  Event done_event(false, false);
+  Event done_event;
   queue.PostTask([&sequenced_task_checker, &done_event, expect_true] {
     if (expect_true)
       EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
@@ -136,7 +134,7 @@
 
   sequenced_task_checker->Detach();
 
-  Event done_event(false, false);
+  Event done_event;
   TaskQueue queue1("DetachThenCallFromDifferentTaskQueueImpl1");
   queue1.PostTask([&sequenced_task_checker, &done_event] {
     EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
@@ -194,7 +192,7 @@
   sequenced_task_checker->Detach();
   static const char kQueueName[] = "DetachFromThreadAndUseOnTaskQueue";
   TaskQueue queue(kQueueName);
-  Event done_event(false, false);
+  Event done_event;
   queue.PostTask([&sequenced_task_checker, &done_event] {
     EXPECT_TRUE(sequenced_task_checker->CalledSequentially());
     done_event.Set();
@@ -204,7 +202,7 @@
 
 TEST(SequencedTaskCheckerTest, DetachFromTaskQueueAndUseOnThread) {
   TaskQueue queue("DetachFromTaskQueueAndUseOnThread");
-  Event done_event(false, false);
+  Event done_event;
   queue.PostTask([&done_event] {
     std::unique_ptr<SequencedTaskChecker> sequenced_task_checker(
         new SequencedTaskChecker());
@@ -272,7 +270,7 @@
   TestAnnotations annotations;
   static const char kQueueName[] = "TestAnnotationsOnWrongQueueDebug";
   TaskQueue queue(kQueueName);
-  Event done_event(false, false);
+  Event done_event;
   queue.PostTask([&annotations, &done_event] {
     annotations.ModifyTestVar();
     done_event.Set();
diff --git a/rtc_base/signalthread.cc b/rtc_base/signalthread.cc
index 2e0fa0c..5dd9387 100644
--- a/rtc_base/signalthread.cc
+++ b/rtc_base/signalthread.cc
@@ -10,9 +10,13 @@
 
 #include "rtc_base/signalthread.h"
 
+#include <memory>
+
 #include "absl/memory/memory.h"
 #include "rtc_base/checks.h"
+#include "rtc_base/location.h"
 #include "rtc_base/nullsocketserver.h"
+#include "rtc_base/socketserver.h"
 
 namespace rtc {
 
diff --git a/rtc_base/signalthread.h b/rtc_base/signalthread.h
index 448b289..9208e2c 100644
--- a/rtc_base/signalthread.h
+++ b/rtc_base/signalthread.h
@@ -14,13 +14,13 @@
 #include <string>
 
 #include "rtc_base/checks.h"
-#include "rtc_base/constructormagic.h"             // for RTC_DISALLOW_IMPLI...
-#include "rtc_base/criticalsection.h"              // for CriticalSection
-#include "rtc_base/messagehandler.h"               // for MessageHandler
-#include "rtc_base/messagequeue.h"                 // for Message
-#include "rtc_base/third_party/sigslot/sigslot.h"  // for has_slots, signal_...
-#include "rtc_base/thread.h"                       // for Thread
-#include "rtc_base/thread_annotations.h"           // for RTC_EXCLUSIVE_LOCK...
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/criticalsection.h"
+#include "rtc_base/messagehandler.h"
+#include "rtc_base/messagequeue.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
+#include "rtc_base/thread.h"
+#include "rtc_base/thread_annotations.h"
 
 namespace rtc {
 
diff --git a/rtc_base/socket.cc b/rtc_base/socket.cc
index a9749a4..f19b344 100644
--- a/rtc_base/socket.cc
+++ b/rtc_base/socket.cc
@@ -12,16 +12,4 @@
 
 namespace rtc {
 
-PacketInfo::PacketInfo() = default;
-PacketInfo::PacketInfo(const PacketInfo& info) = default;
-PacketInfo::~PacketInfo() = default;
-
-SentPacket::SentPacket() = default;
-SentPacket::SentPacket(int64_t packet_id, int64_t send_time_ms)
-    : packet_id(packet_id), send_time_ms(send_time_ms) {}
-SentPacket::SentPacket(int64_t packet_id,
-                       int64_t send_time_ms,
-                       const rtc::PacketInfo& info)
-    : packet_id(packet_id), send_time_ms(send_time_ms), info(info) {}
-
 }  // namespace rtc
diff --git a/rtc_base/socket.h b/rtc_base/socket.h
index 2a3d61d..e7e8210 100644
--- a/rtc_base/socket.h
+++ b/rtc_base/socket.h
@@ -25,8 +25,8 @@
 #include "rtc_base/win32.h"
 #endif
 
-#include "absl/types/optional.h"
 #include "rtc_base/constructormagic.h"
+#include "rtc_base/network/sent_packet.h"
 #include "rtc_base/socketaddress.h"
 
 // Rather than converting errors into a private namespace,
@@ -123,52 +123,6 @@
   return (e == EWOULDBLOCK) || (e == EAGAIN) || (e == EINPROGRESS);
 }
 
-enum class PacketType {
-  kUnknown,
-  kData,
-  kIceConnectivityCheck,
-  kIceConnectivityCheckResponse,
-  kStunMessage,
-  kTurnMessage,
-};
-
-enum class PacketInfoProtocolType {
-  kUnknown,
-  kUdp,
-  kTcp,
-  kSsltcp,
-  kTls,
-};
-
-struct PacketInfo {
-  PacketInfo();
-  PacketInfo(const PacketInfo& info);
-  ~PacketInfo();
-
-  bool included_in_feedback;
-  bool included_in_allocation;
-  PacketType packet_type = PacketType::kUnknown;
-  PacketInfoProtocolType protocol = PacketInfoProtocolType::kUnknown;
-  // A unique id assigned by the network manager, and absl::nullopt if not set.
-  absl::optional<uint16_t> network_id;
-  size_t packet_size_bytes = 0;
-  size_t turn_overhead_bytes = 0;
-  SocketAddress local_socket_address;
-  SocketAddress remote_socket_address;
-};
-
-struct SentPacket {
-  SentPacket();
-  SentPacket(int64_t packet_id, int64_t send_time_ms);
-  SentPacket(int64_t packet_id,
-             int64_t send_time_ms,
-             const rtc::PacketInfo& info);
-
-  int64_t packet_id = -1;
-  int64_t send_time_ms = -1;
-  rtc::PacketInfo info;
-};
-
 // General interface for the socket implementations of various networks.  The
 // methods match those of normal UNIX sockets very closely.
 class Socket {
diff --git a/rtc_base/socketadapters.cc b/rtc_base/socketadapters.cc
index 98be868..9451928 100644
--- a/rtc_base/socketadapters.cc
+++ b/rtc_base/socketadapters.cc
@@ -13,18 +13,24 @@
 #endif
 
 #include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <time.h>
 
 #if defined(WEBRTC_WIN)
 #include <windows.h>
 #include <winsock2.h>
 #include <ws2tcpip.h>
+
 #define SECURITY_WIN32
 #include <security.h>
 #endif
 
 #include <algorithm>
 
+#include "absl/strings/match.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/bytebuffer.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/httpcommon.h"
@@ -456,7 +462,7 @@
         return;
     }
   } else if ((state_ == PS_AUTHENTICATE) &&
-             (_strnicmp(data, "Proxy-Authenticate:", 19) == 0)) {
+             absl::StartsWithIgnoreCase(data, "Proxy-Authenticate:")) {
     std::string response, auth_method;
     switch (HttpAuthenticate(data + 19, len - 19, proxy_, "CONNECT", "/", user_,
                              pass_, context_, response, auth_method)) {
@@ -484,12 +490,12 @@
         unknown_mechanisms_.clear();
         break;
     }
-  } else if (_strnicmp(data, "Content-Length:", 15) == 0) {
+  } else if (absl::StartsWithIgnoreCase(data, "Content-Length:")) {
     content_length_ = strtoul(data + 15, 0, 0);
-  } else if (_strnicmp(data, "Proxy-Connection: Keep-Alive", 28) == 0) {
+  } else if (absl::StartsWithIgnoreCase(data, "Proxy-Connection: Keep-Alive")) {
     expect_close_ = false;
     /*
-  } else if (_strnicmp(data, "Connection: close", 17) == 0) {
+  } else if (absl::StartsWithIgnoreCase(data, "Connection: close") {
     expect_close_ = true;
     */
   }
diff --git a/rtc_base/socketaddresspair.h b/rtc_base/socketaddresspair.h
index 5ff148a..6691386 100644
--- a/rtc_base/socketaddresspair.h
+++ b/rtc_base/socketaddresspair.h
@@ -11,6 +11,8 @@
 #ifndef RTC_BASE_SOCKETADDRESSPAIR_H_
 #define RTC_BASE_SOCKETADDRESSPAIR_H_
 
+#include <stddef.h>
+
 #include "rtc_base/socketaddress.h"
 
 namespace rtc {
diff --git a/rtc_base/socketstream.cc b/rtc_base/socketstream.cc
index 2ea1cec..8978404 100644
--- a/rtc_base/socketstream.cc
+++ b/rtc_base/socketstream.cc
@@ -11,6 +11,7 @@
 #include "rtc_base/socketstream.h"
 
 #include "rtc_base/checks.h"
+#include "rtc_base/socket.h"
 
 namespace rtc {
 
diff --git a/rtc_base/ssladapter.h b/rtc_base/ssladapter.h
index 4843d26..7ebedca 100644
--- a/rtc_base/ssladapter.h
+++ b/rtc_base/ssladapter.h
@@ -16,6 +16,7 @@
 
 #include "rtc_base/asyncsocket.h"
 #include "rtc_base/sslcertificate.h"
+#include "rtc_base/sslidentity.h"
 #include "rtc_base/sslstreamadapter.h"
 
 namespace rtc {
diff --git a/rtc_base/ssladapter_unittest.cc b/rtc_base/ssladapter_unittest.cc
index 8ed460f..c84c668 100644
--- a/rtc_base/ssladapter_unittest.cc
+++ b/rtc_base/ssladapter_unittest.cc
@@ -267,7 +267,7 @@
     // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
     // clients are not required to provide a certificate during handshake.
     // Accordingly, we must disable client authentication here.
-    ssl_stream_adapter_->set_client_auth_enabled(false);
+    ssl_stream_adapter_->SetClientAuthEnabledForTesting(false);
 
     ssl_stream_adapter_->SetIdentity(ssl_identity_->GetReference());
 
diff --git a/rtc_base/sslcertificate.cc b/rtc_base/sslcertificate.cc
index e40feec..934848f 100644
--- a/rtc_base/sslcertificate.cc
+++ b/rtc_base/sslcertificate.cc
@@ -10,15 +10,15 @@
 
 #include "rtc_base/sslcertificate.h"
 
-#include <algorithm>  // for transform
+#include <algorithm>
 #include <string>
 #include <utility>
 
-#include "absl/memory/memory.h"                  // for WrapUnique, make_unique
-#include "rtc_base/checks.h"                     // for FatalLogCall, RTC_DC...
-#include "rtc_base/opensslcertificate.h"         // for OpenSSLCertificate
-#include "rtc_base/sslfingerprint.h"             // for SSLFingerprint
-#include "rtc_base/third_party/base64/base64.h"  // for Base64
+#include "absl/memory/memory.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/opensslcertificate.h"
+#include "rtc_base/sslfingerprint.h"
+#include "rtc_base/third_party/base64/base64.h"
 
 namespace rtc {
 
@@ -30,7 +30,7 @@
     std::string&& fingerprint,
     std::string&& fingerprint_algorithm,
     std::string&& base64_certificate,
-    std::unique_ptr<SSLCertificateStats>&& issuer)
+    std::unique_ptr<SSLCertificateStats> issuer)
     : fingerprint(std::move(fingerprint)),
       fingerprint_algorithm(std::move(fingerprint_algorithm)),
       base64_certificate(std::move(base64_certificate)),
@@ -54,8 +54,8 @@
   // |SSLCertificate::GetSignatureDigestAlgorithm| is not supported by the
   // implementation of |SSLCertificate::ComputeDigest|. This currently happens
   // with MD5- and SHA-224-signed certificates when linked to libNSS.
-  std::unique_ptr<SSLFingerprint> ssl_fingerprint(
-      SSLFingerprint::Create(digest_algorithm, this));
+  std::unique_ptr<SSLFingerprint> ssl_fingerprint =
+      SSLFingerprint::Create(digest_algorithm, *this);
   if (!ssl_fingerprint)
     return nullptr;
   std::string fingerprint = ssl_fingerprint->GetRfc4572Fingerprint();
@@ -70,49 +70,30 @@
                                                 std::move(der_base64), nullptr);
 }
 
-std::unique_ptr<SSLCertificate> SSLCertificate::GetUniqueReference() const {
-  return absl::WrapUnique(GetReference());
-}
-
 //////////////////////////////////////////////////////////////////////
 // SSLCertChain
 //////////////////////////////////////////////////////////////////////
 
+SSLCertChain::SSLCertChain(std::unique_ptr<SSLCertificate> single_cert) {
+  certs_.push_back(std::move(single_cert));
+}
+
 SSLCertChain::SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>> certs)
     : certs_(std::move(certs)) {}
 
-SSLCertChain::SSLCertChain(const std::vector<SSLCertificate*>& certs) {
-  RTC_DCHECK(!certs.empty());
-  certs_.resize(certs.size());
-  std::transform(
-      certs.begin(), certs.end(), certs_.begin(),
-      [](const SSLCertificate* cert) -> std::unique_ptr<SSLCertificate> {
-        return cert->GetUniqueReference();
-      });
-}
-
-SSLCertChain::SSLCertChain(const SSLCertificate* cert) {
-  certs_.push_back(cert->GetUniqueReference());
-}
-
 SSLCertChain::SSLCertChain(SSLCertChain&& rhs) = default;
 
 SSLCertChain& SSLCertChain::operator=(SSLCertChain&&) = default;
 
-SSLCertChain::~SSLCertChain() {}
+SSLCertChain::~SSLCertChain() = default;
 
-SSLCertChain* SSLCertChain::Copy() const {
+std::unique_ptr<SSLCertChain> SSLCertChain::Clone() const {
   std::vector<std::unique_ptr<SSLCertificate>> new_certs(certs_.size());
-  std::transform(certs_.begin(), certs_.end(), new_certs.begin(),
-                 [](const std::unique_ptr<SSLCertificate>& cert)
-                     -> std::unique_ptr<SSLCertificate> {
-                   return cert->GetUniqueReference();
-                 });
-  return new SSLCertChain(std::move(new_certs));
-}
-
-std::unique_ptr<SSLCertChain> SSLCertChain::UniqueCopy() const {
-  return absl::WrapUnique(Copy());
+  std::transform(
+      certs_.begin(), certs_.end(), new_certs.begin(),
+      [](const std::unique_ptr<SSLCertificate>& cert)
+          -> std::unique_ptr<SSLCertificate> { return cert->Clone(); });
+  return absl::make_unique<SSLCertChain>(std::move(new_certs));
 }
 
 std::unique_ptr<SSLCertificateStats> SSLCertChain::GetStats() const {
@@ -134,7 +115,8 @@
 }
 
 // static
-SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) {
+std::unique_ptr<SSLCertificate> SSLCertificate::FromPEMString(
+    const std::string& pem_string) {
   return OpenSSLCertificate::FromPEMString(pem_string);
 }
 
diff --git a/rtc_base/sslcertificate.h b/rtc_base/sslcertificate.h
index 029404c..eb81c20 100644
--- a/rtc_base/sslcertificate.h
+++ b/rtc_base/sslcertificate.h
@@ -15,6 +15,8 @@
 #ifndef RTC_BASE_SSLCERTIFICATE_H_
 #define RTC_BASE_SSLCERTIFICATE_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <memory>
 #include <string>
 #include <vector>
@@ -28,7 +30,7 @@
   SSLCertificateStats(std::string&& fingerprint,
                       std::string&& fingerprint_algorithm,
                       std::string&& base64_certificate,
-                      std::unique_ptr<SSLCertificateStats>&& issuer);
+                      std::unique_ptr<SSLCertificateStats> issuer);
   ~SSLCertificateStats();
   std::string fingerprint;
   std::string fingerprint_algorithm;
@@ -51,17 +53,13 @@
   // The length of the string representation of the certificate is
   // stored in *pem_length if it is non-null, and only if
   // parsing was successful.
-  // Caller is responsible for freeing the returned object.
-  static SSLCertificate* FromPEMString(const std::string& pem_string);
-  virtual ~SSLCertificate() {}
+  static std::unique_ptr<SSLCertificate> FromPEMString(
+      const std::string& pem_string);
+  virtual ~SSLCertificate() = default;
 
   // Returns a new SSLCertificate object instance wrapping the same
-  // underlying certificate, including its chain if present.  Caller is
-  // responsible for freeing the returned object. Use GetUniqueReference
-  // instead.
-  virtual SSLCertificate* GetReference() const = 0;
-
-  std::unique_ptr<SSLCertificate> GetUniqueReference() const;
+  // underlying certificate, including its chain if present.
+  virtual std::unique_ptr<SSLCertificate> Clone() const = 0;
 
   // Returns a PEM encoded string representation of the certificate.
   virtual std::string ToPEMString() const = 0;
@@ -92,13 +90,10 @@
 // SSLCertChain is a simple wrapper for a vector of SSLCertificates. It serves
 // primarily to ensure proper memory management (especially deletion) of the
 // SSLCertificate pointers.
-class SSLCertChain {
+class SSLCertChain final {
  public:
+  explicit SSLCertChain(std::unique_ptr<SSLCertificate> single_cert);
   explicit SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>> certs);
-  // These constructors copy the provided SSLCertificate(s), so the caller
-  // retains ownership.
-  explicit SSLCertChain(const std::vector<SSLCertificate*>& certs);
-  explicit SSLCertChain(const SSLCertificate* cert);
   // Allow move semantics for the object.
   SSLCertChain(SSLCertChain&&);
   SSLCertChain& operator=(SSLCertChain&&);
@@ -112,10 +107,8 @@
   const SSLCertificate& Get(size_t pos) const { return *(certs_[pos]); }
 
   // Returns a new SSLCertChain object instance wrapping the same underlying
-  // certificate chain.  Caller is responsible for freeing the returned object.
-  SSLCertChain* Copy() const;
-  // Same as above, but returning a unique_ptr for convenience.
-  std::unique_ptr<SSLCertChain> UniqueCopy() const;
+  // certificate chain.
+  std::unique_ptr<SSLCertChain> Clone() const;
 
   // Gets information (fingerprint, etc.) about this certificate chain. This is
   // used for certificate stats, see
diff --git a/rtc_base/sslfingerprint.cc b/rtc_base/sslfingerprint.cc
index 4f1ae8f..b296d33 100644
--- a/rtc_base/sslfingerprint.cc
+++ b/rtc_base/sslfingerprint.cc
@@ -11,66 +11,82 @@
 #include "rtc_base/sslfingerprint.h"
 
 #include <ctype.h>
+#include <algorithm>
+#include <cstdint>
 #include <string>
 
+#include "absl/memory/memory.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/messagedigest.h"
+#include "rtc_base/rtccertificate.h"
+#include "rtc_base/sslcertificate.h"
+#include "rtc_base/sslidentity.h"
 #include "rtc_base/stringencode.h"
 
 namespace rtc {
 
 SSLFingerprint* SSLFingerprint::Create(const std::string& algorithm,
                                        const rtc::SSLIdentity* identity) {
-  if (!identity) {
-    return nullptr;
-  }
-
-  return Create(algorithm, &(identity->certificate()));
+  return CreateUnique(algorithm, *identity).release();
 }
 
-SSLFingerprint* SSLFingerprint::Create(const std::string& algorithm,
-                                       const rtc::SSLCertificate* cert) {
+std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateUnique(
+    const std::string& algorithm,
+    const rtc::SSLIdentity& identity) {
+  return Create(algorithm, identity.certificate());
+}
+
+std::unique_ptr<SSLFingerprint> SSLFingerprint::Create(
+    const std::string& algorithm,
+    const rtc::SSLCertificate& cert) {
   uint8_t digest_val[64];
   size_t digest_len;
-  bool ret = cert->ComputeDigest(algorithm, digest_val, sizeof(digest_val),
-                                 &digest_len);
+  bool ret = cert.ComputeDigest(algorithm, digest_val, sizeof(digest_val),
+                                &digest_len);
   if (!ret) {
     return nullptr;
   }
-
-  return new SSLFingerprint(algorithm, digest_val, digest_len);
+  return absl::make_unique<SSLFingerprint>(
+      algorithm, ArrayView<const uint8_t>(digest_val, digest_len));
 }
 
 SSLFingerprint* SSLFingerprint::CreateFromRfc4572(
     const std::string& algorithm,
     const std::string& fingerprint) {
+  return CreateUniqueFromRfc4572(algorithm, fingerprint).release();
+}
+
+std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateUniqueFromRfc4572(
+    const std::string& algorithm,
+    const std::string& fingerprint) {
   if (algorithm.empty() || !rtc::IsFips180DigestAlgorithm(algorithm))
     return nullptr;
 
   if (fingerprint.empty())
     return nullptr;
 
-  size_t value_len;
   char value[rtc::MessageDigest::kMaxSize];
-  value_len = rtc::hex_decode_with_delimiter(
+  size_t value_len = rtc::hex_decode_with_delimiter(
       value, sizeof(value), fingerprint.c_str(), fingerprint.length(), ':');
   if (!value_len)
     return nullptr;
 
-  return new SSLFingerprint(algorithm, reinterpret_cast<uint8_t*>(value),
-                            value_len);
+  return absl::make_unique<SSLFingerprint>(
+      algorithm,
+      ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(value), value_len));
 }
 
-SSLFingerprint* SSLFingerprint::CreateFromCertificate(
-    const RTCCertificate* cert) {
+std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateFromCertificate(
+    const RTCCertificate& cert) {
   std::string digest_alg;
-  if (!cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_alg)) {
+  if (!cert.GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)) {
     RTC_LOG(LS_ERROR)
         << "Failed to retrieve the certificate's digest algorithm";
     return nullptr;
   }
 
-  SSLFingerprint* fingerprint = Create(digest_alg, cert->identity());
+  std::unique_ptr<SSLFingerprint> fingerprint =
+      CreateUnique(digest_alg, *cert.identity());
   if (!fingerprint) {
     RTC_LOG(LS_ERROR) << "Failed to create identity fingerprint, alg="
                       << digest_alg;
@@ -79,11 +95,13 @@
 }
 
 SSLFingerprint::SSLFingerprint(const std::string& algorithm,
+                               ArrayView<const uint8_t> digest_view)
+    : algorithm(algorithm), digest(digest_view.data(), digest_view.size()) {}
+
+SSLFingerprint::SSLFingerprint(const std::string& algorithm,
                                const uint8_t* digest_in,
                                size_t digest_len)
-    : algorithm(algorithm) {
-  digest.SetData(digest_in, digest_len);
-}
+    : SSLFingerprint(algorithm, MakeArrayView(digest_in, digest_len)) {}
 
 SSLFingerprint::SSLFingerprint(const SSLFingerprint& from)
     : algorithm(from.algorithm), digest(from.digest) {}
diff --git a/rtc_base/sslfingerprint.h b/rtc_base/sslfingerprint.h
index b204bc7..ea10ede 100644
--- a/rtc_base/sslfingerprint.h
+++ b/rtc_base/sslfingerprint.h
@@ -11,31 +11,48 @@
 #ifndef RTC_BASE_SSLFINGERPRINT_H_
 #define RTC_BASE_SSLFINGERPRINT_H_
 
+#include <stddef.h>
+#include <stdint.h>
 #include <string>
 
 #include "rtc_base/copyonwritebuffer.h"
-#include "rtc_base/rtccertificate.h"
-#include "rtc_base/sslidentity.h"
 
 namespace rtc {
 
+class RTCCertificate;
 class SSLCertificate;
+class SSLIdentity;
 
 struct SSLFingerprint {
+  // TODO(steveanton): Remove once downstream projects have moved off of this.
   static SSLFingerprint* Create(const std::string& algorithm,
                                 const rtc::SSLIdentity* identity);
+  // TODO(steveanton): Rename to Create once projects have migrated.
+  static std::unique_ptr<SSLFingerprint> CreateUnique(
+      const std::string& algorithm,
+      const rtc::SSLIdentity& identity);
 
-  static SSLFingerprint* Create(const std::string& algorithm,
-                                const rtc::SSLCertificate* cert);
+  static std::unique_ptr<SSLFingerprint> Create(
+      const std::string& algorithm,
+      const rtc::SSLCertificate& cert);
 
+  // TODO(steveanton): Remove once downstream projects have moved off of this.
   static SSLFingerprint* CreateFromRfc4572(const std::string& algorithm,
                                            const std::string& fingerprint);
+  // TODO(steveanton): Rename to CreateFromRfc4572 once projects have migrated.
+  static std::unique_ptr<SSLFingerprint> CreateUniqueFromRfc4572(
+      const std::string& algorithm,
+      const std::string& fingerprint);
 
   // Creates a fingerprint from a certificate, using the same digest algorithm
   // as the certificate's signature.
-  static SSLFingerprint* CreateFromCertificate(const RTCCertificate* cert);
+  static std::unique_ptr<SSLFingerprint> CreateFromCertificate(
+      const RTCCertificate& cert);
 
   SSLFingerprint(const std::string& algorithm,
+                 ArrayView<const uint8_t> digest_view);
+  // TODO(steveanton): Remove once downstream projects have moved off of this.
+  SSLFingerprint(const std::string& algorithm,
                  const uint8_t* digest_in,
                  size_t digest_len);
 
diff --git a/rtc_base/sslidentity.cc b/rtc_base/sslidentity.cc
index 1d136d7..41eb35d 100644
--- a/rtc_base/sslidentity.cc
+++ b/rtc_base/sslidentity.cc
@@ -11,19 +11,96 @@
 // Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
 #include "rtc_base/sslidentity.h"
 
-#include <string.h>  // for strspn
-#include <ctime>
+#include <string.h>
+#include <time.h>
 #include <string>
 
-#include "rtc_base/checks.h"                     // for FatalLogCall, RTC_DC...
-#include "rtc_base/opensslidentity.h"            // for OpenSSLIdentity
-#include "rtc_base/strings/string_builder.h"     // for StringBuilder
-#include "rtc_base/third_party/base64/base64.h"  // for Base64, Base64::DO_P...
-#include "rtc_base/timeutils.h"                  // for TmToSeconds
+#include "rtc_base/checks.h"
+#include "rtc_base/opensslidentity.h"
+#include "rtc_base/sslcertificate.h"
+#include "rtc_base/strings/string_builder.h"
+#include "rtc_base/third_party/base64/base64.h"
+#include "rtc_base/timeutils.h"
 
 namespace rtc {
 
 //////////////////////////////////////////////////////////////////////
+// Helper Functions
+//////////////////////////////////////////////////////////////////////
+
+namespace {
+// Read |n| bytes from ASN1 number string at *|pp| and return the numeric value.
+// Update *|pp| and *|np| to reflect number of read bytes.
+// TODO(bugs.webrtc.org/9860) - Remove this code.
+inline int ASN1ReadInt(const unsigned char** pp, size_t* np, size_t n) {
+  const unsigned char* p = *pp;
+  int x = 0;
+  for (size_t i = 0; i < n; i++) {
+    x = 10 * x + p[i] - '0';
+  }
+  *pp = p + n;
+  *np = *np - n;
+  return x;
+}
+
+}  // namespace
+
+// TODO(bugs.webrtc.org/9860) - Remove this code.
+int64_t ASN1TimeToSec(const unsigned char* s, size_t length, bool long_format) {
+  size_t bytes_left = length;
+  // Make sure the string ends with Z.  Doing it here protects the strspn call
+  // from running off the end of the string in Z's absense.
+  if (length == 0 || s[length - 1] != 'Z') {
+    return -1;
+  }
+  // Make sure we only have ASCII digits so that we don't need to clutter the
+  // code below and ASN1ReadInt with error checking.
+  size_t n = strspn(reinterpret_cast<const char*>(s), "0123456789");
+  if (n + 1 != length) {
+    return -1;
+  }
+  // Read out ASN1 year, in either 2-char "UTCTIME" or 4-char "GENERALIZEDTIME"
+  // format.  Both format use UTC in this context.
+  int year = 0;
+  if (long_format) {
+    // ASN1 format: yyyymmddhh[mm[ss[.fff]]]Z where the Z is literal, but
+    // RFC 5280 requires us to only support exactly yyyymmddhhmmssZ.
+    if (bytes_left < 11) {
+      return -1;
+    }
+    year = ASN1ReadInt(&s, &bytes_left, 4);
+    year -= 1900;
+  } else {
+    // ASN1 format: yymmddhhmm[ss]Z where the Z is literal, but RFC 5280
+    // requires us to only support exactly yymmddhhmmssZ.
+    if (bytes_left < 9) {
+      return -1;
+    }
+    year = ASN1ReadInt(&s, &bytes_left, 2);
+    // Per RFC 5280 4.1.2.5.1
+    if (year < 50) {
+      year += 100;
+    }
+  }
+
+  // Read out remaining ASN1 time data and store it in |tm| in documented
+  // std::tm format.
+  tm tm;
+  tm.tm_year = year;
+  tm.tm_mon = ASN1ReadInt(&s, &bytes_left, 2) - 1;
+  tm.tm_mday = ASN1ReadInt(&s, &bytes_left, 2);
+  tm.tm_hour = ASN1ReadInt(&s, &bytes_left, 2);
+  tm.tm_min = ASN1ReadInt(&s, &bytes_left, 2);
+  tm.tm_sec = ASN1ReadInt(&s, &bytes_left, 2);
+
+  // Now just Z should remain.  Its existence was asserted above.
+  if (bytes_left != 1) {
+    return -1;
+  }
+  return TmToSeconds(tm);
+}
+
+//////////////////////////////////////////////////////////////////////
 // KeyParams
 //////////////////////////////////////////////////////////////////////
 
@@ -91,22 +168,21 @@
 bool SSLIdentity::PemToDer(const std::string& pem_type,
                            const std::string& pem_string,
                            std::string* der) {
-  // Find the inner body. We need this to fulfill the contract of
-  // returning pem_length.
+  // Find the inner body. We need this to fulfill the contract of returning
+  // pem_length.
   size_t header = pem_string.find("-----BEGIN " + pem_type + "-----");
-  if (header == std::string::npos)
+  if (header == std::string::npos) {
     return false;
-
+  }
   size_t body = pem_string.find("\n", header);
-  if (body == std::string::npos)
+  if (body == std::string::npos) {
     return false;
-
+  }
   size_t trailer = pem_string.find("-----END " + pem_type + "-----");
-  if (trailer == std::string::npos)
+  if (trailer == std::string::npos) {
     return false;
-
+  }
   std::string inner = pem_string.substr(body + 1, trailer - (body + 1));
-
   *der = Base64::Decode(inner, Base64::DO_PARSE_WHITE | Base64::DO_PAD_ANY |
                                    Base64::DO_TERM_BUFFER);
   return true;
@@ -116,14 +192,12 @@
                                   const unsigned char* data,
                                   size_t length) {
   rtc::StringBuilder result;
-
   result << "-----BEGIN " << pem_type << "-----\n";
 
   std::string b64_encoded;
   Base64::EncodeFromArray(data, length, &b64_encoded);
-
-  // Divide the Base-64 encoded data into 64-character chunks, as per
-  // 4.3.2.4 of RFC 1421.
+  // Divide the Base-64 encoded data into 64-character chunks, as per 4.3.2.4
+  // of RFC 1421.
   static const size_t kChunkSize = 64;
   size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize;
   for (size_t i = 0, chunk_offset = 0; i < chunks;
@@ -131,9 +205,7 @@
     result << b64_encoded.substr(chunk_offset, kChunkSize);
     result << "\n";
   }
-
   result << "-----END " << pem_type << "-----\n";
-
   return result.Release();
 }
 
@@ -184,78 +256,4 @@
   return !(a == b);
 }
 
-//////////////////////////////////////////////////////////////////////
-// Helper Functions
-//////////////////////////////////////////////////////////////////////
-
-// Read |n| bytes from ASN1 number string at *|pp| and return the numeric value.
-// Update *|pp| and *|np| to reflect number of read bytes.
-static inline int ASN1ReadInt(const unsigned char** pp, size_t* np, size_t n) {
-  const unsigned char* p = *pp;
-  int x = 0;
-  for (size_t i = 0; i < n; i++)
-    x = 10 * x + p[i] - '0';
-  *pp = p + n;
-  *np = *np - n;
-  return x;
-}
-
-int64_t ASN1TimeToSec(const unsigned char* s, size_t length, bool long_format) {
-  size_t bytes_left = length;
-
-  // Make sure the string ends with Z.  Doing it here protects the strspn call
-  // from running off the end of the string in Z's absense.
-  if (length == 0 || s[length - 1] != 'Z')
-    return -1;
-
-  // Make sure we only have ASCII digits so that we don't need to clutter the
-  // code below and ASN1ReadInt with error checking.
-  size_t n = strspn(reinterpret_cast<const char*>(s), "0123456789");
-  if (n + 1 != length)
-    return -1;
-
-  int year;
-
-  // Read out ASN1 year, in either 2-char "UTCTIME" or 4-char "GENERALIZEDTIME"
-  // format.  Both format use UTC in this context.
-  if (long_format) {
-    // ASN1 format: yyyymmddhh[mm[ss[.fff]]]Z where the Z is literal, but
-    // RFC 5280 requires us to only support exactly yyyymmddhhmmssZ.
-
-    if (bytes_left < 11)
-      return -1;
-
-    year = ASN1ReadInt(&s, &bytes_left, 4);
-    year -= 1900;
-  } else {
-    // ASN1 format: yymmddhhmm[ss]Z where the Z is literal, but RFC 5280
-    // requires us to only support exactly yymmddhhmmssZ.
-
-    if (bytes_left < 9)
-      return -1;
-
-    year = ASN1ReadInt(&s, &bytes_left, 2);
-    if (year < 50)  // Per RFC 5280 4.1.2.5.1
-      year += 100;
-  }
-
-  std::tm tm;
-  tm.tm_year = year;
-
-  // Read out remaining ASN1 time data and store it in |tm| in documented
-  // std::tm format.
-  tm.tm_mon = ASN1ReadInt(&s, &bytes_left, 2) - 1;
-  tm.tm_mday = ASN1ReadInt(&s, &bytes_left, 2);
-  tm.tm_hour = ASN1ReadInt(&s, &bytes_left, 2);
-  tm.tm_min = ASN1ReadInt(&s, &bytes_left, 2);
-  tm.tm_sec = ASN1ReadInt(&s, &bytes_left, 2);
-
-  if (bytes_left != 1) {
-    // Now just Z should remain.  Its existence was asserted above.
-    return -1;
-  }
-
-  return TmToSeconds(tm);
-}
-
 }  // namespace rtc
diff --git a/rtc_base/sslidentity.h b/rtc_base/sslidentity.h
index d17d38b..39feeab 100644
--- a/rtc_base/sslidentity.h
+++ b/rtc_base/sslidentity.h
@@ -13,13 +13,15 @@
 #ifndef RTC_BASE_SSLIDENTITY_H_
 #define RTC_BASE_SSLIDENTITY_H_
 
+#include <stdint.h>
 #include <ctime>
 #include <string>
 
-#include "rtc_base/sslcertificate.h"
-
 namespace rtc {
 
+class SSLCertChain;
+class SSLCertificate;
+
 // KT_LAST is intended for vector declarations and loops over all key types;
 // it does not represent any key type in itself.
 // KT_DEFAULT is used as the default KeyType for KeyParams.
diff --git a/rtc_base/sslidentity_unittest.cc b/rtc_base/sslidentity_unittest.cc
index 68b5828..ba53d17 100644
--- a/rtc_base/sslidentity_unittest.cc
+++ b/rtc_base/sslidentity_unittest.cc
@@ -180,7 +180,7 @@
   const rtc::SSLCertChain& chain = info.identity->cert_chain();
   std::unique_ptr<rtc::SSLFingerprint> fp;
   for (size_t i = 0; i < chain.GetSize(); i++) {
-    fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain.Get(i)));
+    fp = rtc::SSLFingerprint::Create("sha-1", chain.Get(i));
     EXPECT_TRUE(fp);
     info.fingerprints.push_back(fp->GetRfc4572Fingerprint());
   }
@@ -201,7 +201,7 @@
     ASSERT_TRUE(identity_ecdsa1_);
     ASSERT_TRUE(identity_ecdsa2_);
 
-    test_cert_.reset(rtc::SSLCertificate::FromPEMString(kTestCertificate));
+    test_cert_ = rtc::SSLCertificate::FromPEMString(kTestCertificate);
     ASSERT_TRUE(test_cert_);
   }
 
diff --git a/rtc_base/sslstreamadapter.cc b/rtc_base/sslstreamadapter.cc
index 746ebd5..9c33a9c 100644
--- a/rtc_base/sslstreamadapter.cc
+++ b/rtc_base/sslstreamadapter.cc
@@ -89,40 +89,12 @@
           crypto_suite == CS_AEAD_AES_128_GCM);
 }
 
-// static
-CryptoOptions CryptoOptions::NoGcm() {
-  CryptoOptions options;
-  options.enable_gcm_crypto_suites = false;
-  return options;
-}
-
-std::vector<int> GetSupportedDtlsSrtpCryptoSuites(
-    const rtc::CryptoOptions& crypto_options) {
-  std::vector<int> crypto_suites;
-  if (crypto_options.enable_gcm_crypto_suites) {
-    crypto_suites.push_back(rtc::SRTP_AEAD_AES_256_GCM);
-    crypto_suites.push_back(rtc::SRTP_AEAD_AES_128_GCM);
-  }
-  // Note: SRTP_AES128_CM_SHA1_80 is what is required to be supported (by
-  // draft-ietf-rtcweb-security-arch), but SRTP_AES128_CM_SHA1_32 is allowed as
-  // well, and saves a few bytes per packet if it ends up selected.
-  // As the cipher suite is potentially insecure, it will only be used if
-  // enabled by both peers.
-  if (crypto_options.enable_aes128_sha1_32_crypto_cipher) {
-    crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_32);
-  }
-  crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_80);
-  return crypto_suites;
-}
-
 SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
   return new OpenSSLStreamAdapter(stream);
 }
 
 SSLStreamAdapter::SSLStreamAdapter(StreamInterface* stream)
-    : StreamAdapterInterface(stream),
-      ignore_bad_cert_(false),
-      client_auth_enabled_(true) {}
+    : StreamAdapterInterface(stream) {}
 
 SSLStreamAdapter::~SSLStreamAdapter() {}
 
@@ -161,8 +133,13 @@
 std::string SSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
   return OpenSSLStreamAdapter::SslCipherSuiteToName(cipher_suite);
 }
-void SSLStreamAdapter::enable_time_callback_for_testing() {
-  OpenSSLStreamAdapter::enable_time_callback_for_testing();
+
+///////////////////////////////////////////////////////////////////////////////
+// Test only settings
+///////////////////////////////////////////////////////////////////////////////
+
+void SSLStreamAdapter::EnableTimeCallbackForTesting() {
+  OpenSSLStreamAdapter::EnableTimeCallbackForTesting();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/rtc_base/sslstreamadapter.h b/rtc_base/sslstreamadapter.h
index 2d4e19f..25f4f33 100644
--- a/rtc_base/sslstreamadapter.h
+++ b/rtc_base/sslstreamadapter.h
@@ -70,34 +70,6 @@
 // Returns true if the given crypto suite name uses a GCM cipher.
 bool IsGcmCryptoSuiteName(const std::string& crypto_suite);
 
-struct CryptoOptions {
-  CryptoOptions() {}
-
-  // Helper method to return an instance of the CryptoOptions with GCM crypto
-  // suites disabled. This method should be used instead of depending on current
-  // default values set by the constructor.
-  static CryptoOptions NoGcm();
-
-  // Enable GCM crypto suites from RFC 7714 for SRTP. GCM will only be used
-  // if both sides enable it.
-  bool enable_gcm_crypto_suites = false;
-
-  // If set to true, the (potentially insecure) crypto cipher
-  // SRTP_AES128_CM_SHA1_32 will be included in the list of supported ciphers
-  // during negotiation. It will only be used if both peers support it and no
-  // other ciphers get preferred.
-  bool enable_aes128_sha1_32_crypto_cipher = false;
-
-  // If set to true, encrypted RTP header extensions as defined in RFC 6904
-  // will be negotiated. They will only be used if both peers support them.
-  bool enable_encrypted_rtp_header_extensions = false;
-};
-
-// Returns supported crypto suites, given |crypto_options|.
-// CS_AES_CM_128_HMAC_SHA1_32 will be preferred by default.
-std::vector<int> GetSupportedDtlsSrtpCryptoSuites(
-    const rtc::CryptoOptions& crypto_options);
-
 // SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
 // After SSL has been started, the stream will only open on successful
 // SSL verification of certificates, and the communication is
@@ -144,12 +116,6 @@
   explicit SSLStreamAdapter(StreamInterface* stream);
   ~SSLStreamAdapter() override;
 
-  void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
-  bool ignore_bad_cert() const { return ignore_bad_cert_; }
-
-  void set_client_auth_enabled(bool enabled) { client_auth_enabled_ = enabled; }
-  bool client_auth_enabled() const { return client_auth_enabled_; }
-
   // Specify our SSL identity: key and certificate. SSLStream takes ownership
   // of the SSLIdentity object and will free it when appropriate. Should be
   // called no more than once on a given SSLStream instance.
@@ -263,22 +229,32 @@
   // depending on specific SSL implementation.
   static std::string SslCipherSuiteToName(int cipher_suite);
 
+  ////////////////////////////////////////////////////////////////////////////
+  // Testing only member functions
+  ////////////////////////////////////////////////////////////////////////////
+
   // Use our timeutils.h source of timing in BoringSSL, allowing us to test
   // using a fake clock.
-  static void enable_time_callback_for_testing();
+  static void EnableTimeCallbackForTesting();
+
+  // Deprecated. Do not use this API outside of testing.
+  // Do not set this to false outside of testing.
+  void SetClientAuthEnabledForTesting(bool enabled) {
+    client_auth_enabled_ = enabled;
+  }
+
+  // Deprecated. Do not use this API outside of testing.
+  // Returns true by default, else false if explicitly set to disable client
+  // authentication.
+  bool GetClientAuthEnabled() const { return client_auth_enabled_; }
 
   sigslot::signal1<SSLHandshakeError> SignalSSLHandshakeError;
 
  private:
-  // If true, the server certificate need not match the configured
-  // server_name, and in fact missing certificate authority and other
-  // verification errors are ignored.
-  bool ignore_bad_cert_;
-
   // If true (default), the client is required to provide a certificate during
   // handshake. If no certificate is given, handshake fails. This applies to
   // server mode only.
-  bool client_auth_enabled_;
+  bool client_auth_enabled_ = true;
 };
 
 }  // namespace rtc
diff --git a/rtc_base/sslstreamadapter_unittest.cc b/rtc_base/sslstreamadapter_unittest.cc
index 389b0ea..6fbb1d7 100644
--- a/rtc_base/sslstreamadapter_unittest.cc
+++ b/rtc_base/sslstreamadapter_unittest.cc
@@ -17,6 +17,7 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/gunit.h"
 #include "rtc_base/helpers.h"
+#include "rtc_base/memory_stream.h"
 #include "rtc_base/messagedigest.h"
 #include "rtc_base/ssladapter.h"
 #include "rtc_base/sslidentity.h"
@@ -588,8 +589,7 @@
       chain = client_ssl_->GetPeerSSLCertChain();
     else
       chain = server_ssl_->GetPeerSSLCertChain();
-    return (chain && chain->GetSize()) ? chain->Get(0).GetUniqueReference()
-                                       : nullptr;
+    return (chain && chain->GetSize()) ? chain->Get(0).Clone() : nullptr;
   }
 
   bool GetSslCipherSuite(bool client, int* retval) {
diff --git a/rtc_base/stream.cc b/rtc_base/stream.cc
index ea2e47a..783625c 100644
--- a/rtc_base/stream.cc
+++ b/rtc_base/stream.cc
@@ -7,28 +7,23 @@
  *  in the file PATENTS.  All contributing project authors may
  *  be found in the AUTHORS file in the root of the source tree.
  */
-
-#if defined(WEBRTC_POSIX)
-#include <sys/file.h>
-#endif  // WEBRTC_POSIX
 #include <errno.h>
+#include <string.h>
 #include <sys/stat.h>
-#include <sys/types.h>
-
-#include <string.h>  // for memcpy, memmove, strlen
 #include <algorithm>
 #include <string>
 
 #include "rtc_base/checks.h"
-#include "rtc_base/location.h"  // for RTC_FROM_HERE
+#include "rtc_base/location.h"
 #include "rtc_base/messagequeue.h"
 #include "rtc_base/stream.h"
 #include "rtc_base/thread.h"
 
 #if defined(WEBRTC_WIN)
 #include <windows.h>
+
 #define fileno _fileno
-#include "rtc_base/stringutils.h"  // for ToUtf16
+#include "rtc_base/stringutils.h"
 #endif
 
 namespace rtc {
@@ -74,26 +69,6 @@
   return result;
 }
 
-StreamResult StreamInterface::ReadLine(std::string* line) {
-  line->clear();
-  StreamResult result = SR_SUCCESS;
-  while (true) {
-    char ch;
-    result = Read(&ch, sizeof(ch), nullptr, nullptr);
-    if (result != SR_SUCCESS) {
-      break;
-    }
-    if (ch == '\n') {
-      break;
-    }
-    line->push_back(ch);
-  }
-  if (!line->empty()) {   // give back the line we've collected so far with
-    result = SR_SUCCESS;  // a success code.  Otherwise return the last code
-  }
-  return result;
-}
-
 void StreamInterface::PostEvent(Thread* t, int events, int err) {
   t->Post(RTC_FROM_HERE, this, MSG_POST_EVENT,
           new StreamEventData(events, err));
@@ -103,14 +78,6 @@
   PostEvent(Thread::Current(), events, err);
 }
 
-const void* StreamInterface::GetReadData(size_t* data_len) {
-  return nullptr;
-}
-
-void* StreamInterface::GetWriteBuffer(size_t* buf_len) {
-  return nullptr;
-}
-
 bool StreamInterface::SetPosition(size_t position) {
   return false;
 }
@@ -123,10 +90,6 @@
   return false;
 }
 
-bool StreamInterface::GetWriteRemaining(size_t* size) const {
-  return false;
-}
-
 bool StreamInterface::Flush() {
   return false;
 }
@@ -187,10 +150,6 @@
   return stream_->GetSize(size);
 }
 
-bool StreamAdapterInterface::GetWriteRemaining(size_t* size) const {
-  return stream_->GetWriteRemaining(size);
-}
-
 bool StreamAdapterInterface::ReserveSize(size_t size) {
   return stream_->ReserveSize(size);
 }
@@ -389,143 +348,6 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// MemoryStream
-///////////////////////////////////////////////////////////////////////////////
-
-MemoryStreamBase::MemoryStreamBase()
-    : buffer_(nullptr), buffer_length_(0), data_length_(0), seek_position_(0) {}
-
-StreamState MemoryStreamBase::GetState() const {
-  return SS_OPEN;
-}
-
-StreamResult MemoryStreamBase::Read(void* buffer,
-                                    size_t bytes,
-                                    size_t* bytes_read,
-                                    int* error) {
-  if (seek_position_ >= data_length_) {
-    return SR_EOS;
-  }
-  size_t available = data_length_ - seek_position_;
-  if (bytes > available) {
-    // Read partial buffer
-    bytes = available;
-  }
-  memcpy(buffer, &buffer_[seek_position_], bytes);
-  seek_position_ += bytes;
-  if (bytes_read) {
-    *bytes_read = bytes;
-  }
-  return SR_SUCCESS;
-}
-
-StreamResult MemoryStreamBase::Write(const void* buffer,
-                                     size_t bytes,
-                                     size_t* bytes_written,
-                                     int* error) {
-  size_t available = buffer_length_ - seek_position_;
-  if (0 == available) {
-    // Increase buffer size to the larger of:
-    // a) new position rounded up to next 256 bytes
-    // b) double the previous length
-    size_t new_buffer_length =
-        std::max(((seek_position_ + bytes) | 0xFF) + 1, buffer_length_ * 2);
-    StreamResult result = DoReserve(new_buffer_length, error);
-    if (SR_SUCCESS != result) {
-      return result;
-    }
-    RTC_DCHECK(buffer_length_ >= new_buffer_length);
-    available = buffer_length_ - seek_position_;
-  }
-
-  if (bytes > available) {
-    bytes = available;
-  }
-  memcpy(&buffer_[seek_position_], buffer, bytes);
-  seek_position_ += bytes;
-  if (data_length_ < seek_position_) {
-    data_length_ = seek_position_;
-  }
-  if (bytes_written) {
-    *bytes_written = bytes;
-  }
-  return SR_SUCCESS;
-}
-
-void MemoryStreamBase::Close() {
-  // nothing to do
-}
-
-bool MemoryStreamBase::SetPosition(size_t position) {
-  if (position > data_length_)
-    return false;
-  seek_position_ = position;
-  return true;
-}
-
-bool MemoryStreamBase::GetPosition(size_t* position) const {
-  if (position)
-    *position = seek_position_;
-  return true;
-}
-
-bool MemoryStreamBase::GetSize(size_t* size) const {
-  if (size)
-    *size = data_length_;
-  return true;
-}
-
-bool MemoryStreamBase::ReserveSize(size_t size) {
-  return (SR_SUCCESS == DoReserve(size, nullptr));
-}
-
-StreamResult MemoryStreamBase::DoReserve(size_t size, int* error) {
-  return (buffer_length_ >= size) ? SR_SUCCESS : SR_EOS;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MemoryStream::MemoryStream() {}
-
-MemoryStream::MemoryStream(const char* data) {
-  SetData(data, strlen(data));
-}
-
-MemoryStream::MemoryStream(const void* data, size_t length) {
-  SetData(data, length);
-}
-
-MemoryStream::~MemoryStream() {
-  delete[] buffer_;
-}
-
-void MemoryStream::SetData(const void* data, size_t length) {
-  data_length_ = buffer_length_ = length;
-  delete[] buffer_;
-  buffer_ = new char[buffer_length_];
-  memcpy(buffer_, data, data_length_);
-  seek_position_ = 0;
-}
-
-StreamResult MemoryStream::DoReserve(size_t size, int* error) {
-  if (buffer_length_ >= size)
-    return SR_SUCCESS;
-
-  if (char* new_buffer = new char[size]) {
-    memcpy(new_buffer, buffer_, data_length_);
-    delete[] buffer_;
-    buffer_ = new_buffer;
-    buffer_length_ = size;
-    return SR_SUCCESS;
-  }
-
-  if (error) {
-    *error = ENOMEM;
-  }
-  return SR_ERROR;
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // FifoBuffer
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -757,68 +579,4 @@
   return SR_SUCCESS;
 }
 
-
-///////////////////////////////////////////////////////////////////////////////
-
-StreamResult Flow(StreamInterface* source,
-                  char* buffer,
-                  size_t buffer_len,
-                  StreamInterface* sink,
-                  size_t* data_len /* = nullptr */) {
-  RTC_DCHECK(buffer_len > 0);
-
-  StreamResult result;
-  size_t count, read_pos, write_pos;
-  if (data_len) {
-    read_pos = *data_len;
-  } else {
-    read_pos = 0;
-  }
-
-  bool end_of_stream = false;
-  do {
-    // Read until buffer is full, end of stream, or error
-    while (!end_of_stream && (read_pos < buffer_len)) {
-      result = source->Read(buffer + read_pos, buffer_len - read_pos, &count,
-                            nullptr);
-      if (result == SR_EOS) {
-        end_of_stream = true;
-      } else if (result != SR_SUCCESS) {
-        if (data_len) {
-          *data_len = read_pos;
-        }
-        return result;
-      } else {
-        read_pos += count;
-      }
-    }
-
-    // Write until buffer is empty, or error (including end of stream)
-    write_pos = 0;
-    while (write_pos < read_pos) {
-      result = sink->Write(buffer + write_pos, read_pos - write_pos, &count,
-                           nullptr);
-      if (result != SR_SUCCESS) {
-        if (data_len) {
-          *data_len = read_pos - write_pos;
-          if (write_pos > 0) {
-            memmove(buffer, buffer + write_pos, *data_len);
-          }
-        }
-        return result;
-      }
-      write_pos += count;
-    }
-
-    read_pos = 0;
-  } while (!end_of_stream);
-
-  if (data_len) {
-    *data_len = 0;
-  }
-  return SR_SUCCESS;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 }  // namespace rtc
diff --git a/rtc_base/stream.h b/rtc_base/stream.h
index 7c6e618..43e7f58 100644
--- a/rtc_base/stream.h
+++ b/rtc_base/stream.h
@@ -107,59 +107,6 @@
   // Like the aforementioned method, but posts to the current thread.
   void PostEvent(int events, int err);
 
-  //
-  // OPTIONAL OPERATIONS
-  //
-  // Not all implementations will support the following operations.  In general,
-  // a stream will only support an operation if it reasonably efficient to do
-  // so.  For example, while a socket could buffer incoming data to support
-  // seeking, it will not do so.  Instead, a buffering stream adapter should
-  // be used.
-  //
-  // Even though several of these operations are related, you should
-  // always use whichever operation is most relevant.
-  //
-  // The following four methods are used to avoid copying data multiple times.
-
-  // GetReadData returns a pointer to a buffer which is owned by the stream.
-  // The buffer contains data_len bytes.  null is returned if no data is
-  // available, or if the method fails.  If the caller processes the data, it
-  // must call ConsumeReadData with the number of processed bytes.  GetReadData
-  // does not require a matching call to ConsumeReadData if the data is not
-  // processed.  Read and ConsumeReadData invalidate the buffer returned by
-  // GetReadData.
-  virtual const void* GetReadData(size_t* data_len);
-  virtual void ConsumeReadData(size_t used) {}
-
-  // GetWriteBuffer returns a pointer to a buffer which is owned by the stream.
-  // The buffer has a capacity of buf_len bytes.  null is returned if there is
-  // no buffer available, or if the method fails.  The call may write data to
-  // the buffer, and then call ConsumeWriteBuffer with the number of bytes
-  // written.  GetWriteBuffer does not require a matching call to
-  // ConsumeWriteData if no data is written.  Write, ForceWrite, and
-  // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer.
-  // TODO: Allow the caller to specify a minimum buffer size.  If the specified
-  // amount of buffer is not yet available, return null and Signal SE_WRITE
-  // when it is available.  If the requested amount is too large, return an
-  // error.
-  virtual void* GetWriteBuffer(size_t* buf_len);
-  virtual void ConsumeWriteBuffer(size_t used) {}
-
-  // Write data_len bytes found in data, circumventing any throttling which
-  // would could cause SR_BLOCK to be returned.  Returns true if all the data
-  // was written.  Otherwise, the method is unsupported, or an unrecoverable
-  // error occurred, and the error value is set.  This method should be used
-  // sparingly to write critical data which should not be throttled.  A stream
-  // which cannot circumvent its blocking constraints should not implement this
-  // method.
-  // NOTE: This interface is being considered experimentally at the moment.  It
-  // would be used by JUDP and BandwidthStream as a way to circumvent certain
-  // soft limits in writing.
-  // virtual bool ForceWrite(const void* data, size_t data_len, int* error) {
-  //  if (error) *error = -1;
-  //  return false;
-  //}
-
   // Seek to a byte offset from the beginning of the stream.  Returns false if
   // the stream does not support seeking, or cannot seek to the specified
   // position.
@@ -173,10 +120,6 @@
   // is not known.
   virtual bool GetSize(size_t* size) const;
 
-  // Return the number of Write()-able bytes remaining before end-of-stream.
-  // Returns false if not known.
-  virtual bool GetWriteRemaining(size_t* size) const;
-
   // Return true if flush is successful.
   virtual bool Flush();
 
@@ -213,12 +156,6 @@
                        size_t* read,
                        int* error);
 
-  // ReadLine is a helper function which repeatedly calls Read until it hits
-  // the end-of-line character, or something other than SR_SUCCESS.
-  // TODO: this is too inefficient to keep here.  Break this out into a buffered
-  // readline object or adapter
-  StreamResult ReadLine(std::string* line);
-
  protected:
   StreamInterface();
 
@@ -254,37 +191,9 @@
                      int* error) override;
   void Close() override;
 
-  // Optional Stream Interface
-  /*  Note: Many stream adapters were implemented prior to this Read/Write
-      interface.  Therefore, a simple pass through of data in those cases may
-      be broken.  At a later time, we should do a once-over pass of all
-      adapters, and make them compliant with these interfaces, after which this
-      code can be uncommented.
-  virtual const void* GetReadData(size_t* data_len) {
-    return stream_->GetReadData(data_len);
-  }
-  virtual void ConsumeReadData(size_t used) {
-    stream_->ConsumeReadData(used);
-  }
-
-  virtual void* GetWriteBuffer(size_t* buf_len) {
-    return stream_->GetWriteBuffer(buf_len);
-  }
-  virtual void ConsumeWriteBuffer(size_t used) {
-    stream_->ConsumeWriteBuffer(used);
-  }
-  */
-
-  /*  Note: This interface is currently undergoing evaluation.
-  virtual bool ForceWrite(const void* data, size_t data_len, int* error) {
-    return stream_->ForceWrite(data, data_len, error);
-  }
-  */
-
   bool SetPosition(size_t position) override;
   bool GetPosition(size_t* position) const override;
   bool GetSize(size_t* size) const override;
-  bool GetWriteRemaining(size_t* size) const override;
   bool ReserveSize(size_t size) override;
   bool Flush() override;
 
@@ -352,68 +261,11 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(FileStream);
 };
 
-///////////////////////////////////////////////////////////////////////////////
-// MemoryStream is a simple implementation of a StreamInterface over in-memory
-// data.  Data is read and written at the current seek position.  Reads return
-// end-of-stream when they reach the end of data.  Writes actually extend the
-// end of data mark.
-///////////////////////////////////////////////////////////////////////////////
-
-class MemoryStreamBase : public StreamInterface {
- public:
-  StreamState GetState() const override;
-  StreamResult Read(void* buffer,
-                    size_t bytes,
-                    size_t* bytes_read,
-                    int* error) override;
-  StreamResult Write(const void* buffer,
-                     size_t bytes,
-                     size_t* bytes_written,
-                     int* error) override;
-  void Close() override;
-  bool SetPosition(size_t position) override;
-  bool GetPosition(size_t* position) const override;
-  bool GetSize(size_t* size) const override;
-  bool ReserveSize(size_t size) override;
-
-  char* GetBuffer() { return buffer_; }
-  const char* GetBuffer() const { return buffer_; }
-
- protected:
-  MemoryStreamBase();
-
-  virtual StreamResult DoReserve(size_t size, int* error);
-
-  // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_
-  char* buffer_;
-  size_t buffer_length_;
-  size_t data_length_;
-  size_t seek_position_;
-
- private:
-  RTC_DISALLOW_COPY_AND_ASSIGN(MemoryStreamBase);
-};
-
-// MemoryStream dynamically resizes to accomodate written data.
-
-class MemoryStream : public MemoryStreamBase {
- public:
-  MemoryStream();
-  explicit MemoryStream(const char* data);  // Calls SetData(data, strlen(data))
-  MemoryStream(const void* data, size_t length);  // Calls SetData(data, length)
-  ~MemoryStream() override;
-
-  void SetData(const void* data, size_t length);
-
- protected:
-  StreamResult DoReserve(size_t size, int* error) override;
-};
-
 // FifoBuffer allows for efficient, thread-safe buffering of data between
 // writer and reader. As the data can wrap around the end of the buffer,
 // MemoryStreamBase can't help us here.
 
-class FifoBuffer : public StreamInterface {
+class FifoBuffer final : public StreamInterface {
  public:
   // Creates a FIFO buffer with the specified capacity.
   explicit FifoBuffer(size_t length);
@@ -454,11 +306,28 @@
                      size_t* bytes_written,
                      int* error) override;
   void Close() override;
-  const void* GetReadData(size_t* data_len) override;
-  void ConsumeReadData(size_t used) override;
-  void* GetWriteBuffer(size_t* buf_len) override;
-  void ConsumeWriteBuffer(size_t used) override;
-  bool GetWriteRemaining(size_t* size) const override;
+  // GetReadData returns a pointer to a buffer which is owned by the stream.
+  // The buffer contains data_len bytes.  null is returned if no data is
+  // available, or if the method fails.  If the caller processes the data, it
+  // must call ConsumeReadData with the number of processed bytes.  GetReadData
+  // does not require a matching call to ConsumeReadData if the data is not
+  // processed.  Read and ConsumeReadData invalidate the buffer returned by
+  // GetReadData.
+  const void* GetReadData(size_t* data_len);
+  void ConsumeReadData(size_t used);
+  // GetWriteBuffer returns a pointer to a buffer which is owned by the stream.
+  // The buffer has a capacity of buf_len bytes.  null is returned if there is
+  // no buffer available, or if the method fails.  The call may write data to
+  // the buffer, and then call ConsumeWriteBuffer with the number of bytes
+  // written.  GetWriteBuffer does not require a matching call to
+  // ConsumeWriteData if no data is written.  Write and
+  // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer.
+  void* GetWriteBuffer(size_t* buf_len);
+  void ConsumeWriteBuffer(size_t used);
+
+  // Return the number of Write()-able bytes remaining before end-of-stream.
+  // Returns false if not known.
+  bool GetWriteRemaining(size_t* size) const;
 
  private:
   // Helper method that implements ReadOffset. Caller must acquire a lock
@@ -494,25 +363,6 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(FifoBuffer);
 };
 
-///////////////////////////////////////////////////////////////////////////////
-
-// Flow attempts to move bytes from source to sink via buffer of size
-// buffer_len.  The function returns SR_SUCCESS when source reaches
-// end-of-stream (returns SR_EOS), and all the data has been written successful
-// to sink.  Alternately, if source returns SR_BLOCK or SR_ERROR, or if sink
-// returns SR_BLOCK, SR_ERROR, or SR_EOS, then the function immediately returns
-// with the unexpected StreamResult value.
-// data_len is the length of the valid data in buffer. in case of error
-// this is the data that read from source but can't move to destination.
-// as a pass in parameter, it indicates data in buffer that should move to sink
-StreamResult Flow(StreamInterface* source,
-                  char* buffer,
-                  size_t buffer_len,
-                  StreamInterface* sink,
-                  size_t* data_len = nullptr);
-
-///////////////////////////////////////////////////////////////////////////////
-
 }  // namespace rtc
 
 #endif  // RTC_BASE_STREAM_H_
diff --git a/rtc_base/stream_unittest.cc b/rtc_base/stream_unittest.cc
index 616783c..2ca2526 100644
--- a/rtc_base/stream_unittest.cc
+++ b/rtc_base/stream_unittest.cc
@@ -105,56 +105,52 @@
   const void* q;
   size_t bytes;
   FifoBuffer buf(kSize);
-  StreamInterface* stream = &buf;
 
   // Test assumptions about base state
-  EXPECT_EQ(SS_OPEN, stream->GetState());
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, nullptr));
-  EXPECT_TRUE(nullptr != stream->GetReadData(&bytes));
-  EXPECT_EQ((size_t)0, bytes);
-  stream->ConsumeReadData(0);
-  EXPECT_TRUE(nullptr != stream->GetWriteBuffer(&bytes));
+  EXPECT_EQ(SS_OPEN, buf.GetState());
+  EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
+  EXPECT_TRUE(nullptr != buf.GetWriteBuffer(&bytes));
   EXPECT_EQ(kSize, bytes);
-  stream->ConsumeWriteBuffer(0);
+  buf.ConsumeWriteBuffer(0);
 
   // Try a full write
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
 
   // Try a write that should block
-  EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_BLOCK, buf.Write(in, kSize, &bytes, nullptr));
 
   // Try a full read
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize));
 
   // Try a read that should block
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
 
   // Try a too-big write
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize * 2, &bytes, nullptr));
   EXPECT_EQ(bytes, kSize);
 
   // Try a too-big read
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 2, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize));
 
   // Try some small writes and reads
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
 
@@ -166,51 +162,51 @@
   // XXXXWWWWWWWWXXXX 4567012345670123
   // RRRRXXXXXXXXRRRR ....01234567....
   // ....RRRRRRRR.... ................
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize * 3 / 4, &bytes, nullptr));
   EXPECT_EQ(kSize * 3 / 4, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 4, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 4, &bytes, nullptr));
   EXPECT_EQ(kSize / 4, bytes);
   EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
 
   // Use GetWriteBuffer to reset the read_position for the next tests
-  stream->GetWriteBuffer(&bytes);
-  stream->ConsumeWriteBuffer(0);
+  buf.GetWriteBuffer(&bytes);
+  buf.ConsumeWriteBuffer(0);
 
   // Try using GetReadData to do a full read
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, nullptr));
-  q = stream->GetReadData(&bytes);
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
+  q = buf.GetReadData(&bytes);
   EXPECT_TRUE(nullptr != q);
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(q, in, kSize));
-  stream->ConsumeReadData(kSize);
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, nullptr));
+  buf.ConsumeReadData(kSize);
+  EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
 
   // Try using GetReadData to do some small reads
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, nullptr));
-  q = stream->GetReadData(&bytes);
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
+  q = buf.GetReadData(&bytes);
   EXPECT_TRUE(nullptr != q);
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(q, in, kSize / 2));
-  stream->ConsumeReadData(kSize / 2);
-  q = stream->GetReadData(&bytes);
+  buf.ConsumeReadData(kSize / 2);
+  q = buf.GetReadData(&bytes);
   EXPECT_TRUE(nullptr != q);
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2));
-  stream->ConsumeReadData(kSize / 2);
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, nullptr));
+  buf.ConsumeReadData(kSize / 2);
+  EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
 
   // Try using GetReadData in a wraparound case
   // WWWWWWWWWWWWWWWW 0123456789ABCDEF
@@ -218,46 +214,46 @@
   // WWWWWWWW....XXXX 01234567....CDEF
   // ............RRRR 01234567........
   // RRRRRRRR........ ................
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, nullptr));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, nullptr));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
-  q = stream->GetReadData(&bytes);
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 3 / 4, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
+  q = buf.GetReadData(&bytes);
   EXPECT_TRUE(nullptr != q);
   EXPECT_EQ(kSize / 4, bytes);
   EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4));
-  stream->ConsumeReadData(kSize / 4);
-  q = stream->GetReadData(&bytes);
+  buf.ConsumeReadData(kSize / 4);
+  q = buf.GetReadData(&bytes);
   EXPECT_TRUE(nullptr != q);
   EXPECT_EQ(kSize / 2, bytes);
   EXPECT_EQ(0, memcmp(q, in, kSize / 2));
-  stream->ConsumeReadData(kSize / 2);
+  buf.ConsumeReadData(kSize / 2);
 
   // Use GetWriteBuffer to reset the read_position for the next tests
-  stream->GetWriteBuffer(&bytes);
-  stream->ConsumeWriteBuffer(0);
+  buf.GetWriteBuffer(&bytes);
+  buf.ConsumeWriteBuffer(0);
 
   // Try using GetWriteBuffer to do a full write
-  p = stream->GetWriteBuffer(&bytes);
+  p = buf.GetWriteBuffer(&bytes);
   EXPECT_TRUE(nullptr != p);
   EXPECT_EQ(kSize, bytes);
   memcpy(p, in, kSize);
-  stream->ConsumeWriteBuffer(kSize);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, nullptr));
+  buf.ConsumeWriteBuffer(kSize);
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize));
 
   // Try using GetWriteBuffer to do some small writes
-  p = stream->GetWriteBuffer(&bytes);
+  p = buf.GetWriteBuffer(&bytes);
   EXPECT_TRUE(nullptr != p);
   EXPECT_EQ(kSize, bytes);
   memcpy(p, in, kSize / 2);
-  stream->ConsumeWriteBuffer(kSize / 2);
-  p = stream->GetWriteBuffer(&bytes);
+  buf.ConsumeWriteBuffer(kSize / 2);
+  p = buf.GetWriteBuffer(&bytes);
   EXPECT_TRUE(nullptr != p);
   EXPECT_EQ(kSize / 2, bytes);
   memcpy(p, in + kSize / 2, kSize / 2);
-  stream->ConsumeWriteBuffer(kSize / 2);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, nullptr));
+  buf.ConsumeWriteBuffer(kSize / 2);
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize));
 
@@ -267,53 +263,53 @@
   // ........XXXXWWWW ........89AB0123
   // WWWW....XXXXXXXX 4567....89AB0123
   // RRRR....RRRRRRRR ................
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, nullptr));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
-  p = stream->GetWriteBuffer(&bytes);
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize * 3 / 4, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
+  p = buf.GetWriteBuffer(&bytes);
   EXPECT_TRUE(nullptr != p);
   EXPECT_EQ(kSize / 4, bytes);
   memcpy(p, in, kSize / 4);
-  stream->ConsumeWriteBuffer(kSize / 4);
-  p = stream->GetWriteBuffer(&bytes);
+  buf.ConsumeWriteBuffer(kSize / 4);
+  p = buf.GetWriteBuffer(&bytes);
   EXPECT_TRUE(nullptr != p);
   EXPECT_EQ(kSize / 2, bytes);
   memcpy(p, in + kSize / 4, kSize / 4);
-  stream->ConsumeWriteBuffer(kSize / 4);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, nullptr));
+  buf.ConsumeWriteBuffer(kSize / 4);
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 3 / 4, &bytes, nullptr));
   EXPECT_EQ(kSize * 3 / 4, bytes);
   EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
   EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4));
 
   // Check that the stream is now empty
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
 
   // Try growing the buffer
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_TRUE(buf.SetCapacity(kSize * 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in + kSize, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in + kSize, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 2, &bytes, nullptr));
   EXPECT_EQ(kSize * 2, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize * 2));
 
   // Try shrinking the buffer
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_TRUE(buf.SetCapacity(kSize));
-  EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, nullptr));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_BLOCK, buf.Write(in, kSize, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
   EXPECT_EQ(kSize, bytes);
   EXPECT_EQ(0, memcmp(in, out, kSize));
 
   // Write to the stream, close it, read the remaining bytes
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, nullptr));
-  stream->Close();
-  EXPECT_EQ(SS_CLOSED, stream->GetState());
-  EXPECT_EQ(SR_EOS, stream->Write(in, kSize / 2, &bytes, nullptr));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
+  buf.Close();
+  EXPECT_EQ(SS_CLOSED, buf.GetState());
+  EXPECT_EQ(SR_EOS, buf.Write(in, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
   EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_EOS, stream->Read(out, kSize / 2, &bytes, nullptr));
+  EXPECT_EQ(SR_EOS, buf.Read(out, kSize / 2, &bytes, nullptr));
 }
 
 TEST(FifoBufferTest, FullBufferCheck) {
diff --git a/rtc_base/string_to_number.cc b/rtc_base/string_to_number.cc
index 9201242..634652b 100644
--- a/rtc_base/string_to_number.cc
+++ b/rtc_base/string_to_number.cc
@@ -10,6 +10,7 @@
 
 #include "rtc_base/string_to_number.h"
 
+#include <ctype.h>
 #include <cerrno>
 #include <cstdlib>
 
diff --git a/rtc_base/string_to_number.h b/rtc_base/string_to_number.h
index 7ea9f25..4cb5215 100644
--- a/rtc_base/string_to_number.h
+++ b/rtc_base/string_to_number.h
@@ -13,6 +13,7 @@
 
 #include <limits>
 #include <string>
+#include <type_traits>
 
 #include "absl/types/optional.h"
 
diff --git a/rtc_base/stringencode.cc b/rtc_base/stringencode.cc
index 6a065cb..fc4e3bc 100644
--- a/rtc_base/stringencode.cc
+++ b/rtc_base/stringencode.cc
@@ -10,6 +10,8 @@
 
 #include "rtc_base/stringencode.h"
 
+#include <cstdio>
+
 #include "rtc_base/arraysize.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/stringutils.h"
@@ -48,67 +50,6 @@
   return bufpos;
 }
 
-size_t utf8_decode(const char* source, size_t srclen, unsigned long* value) {
-  const unsigned char* s = reinterpret_cast<const unsigned char*>(source);
-  if ((s[0] & 0x80) == 0x00) {  // Check s[0] == 0xxxxxxx
-    *value = s[0];
-    return 1;
-  }
-  if ((srclen < 2) || ((s[1] & 0xC0) != 0x80)) {  // Check s[1] != 10xxxxxx
-    return 0;
-  }
-  // Accumulate the trailer byte values in value16, and combine it with the
-  // relevant bits from s[0], once we've determined the sequence length.
-  unsigned long value16 = (s[1] & 0x3F);
-  if ((s[0] & 0xE0) == 0xC0) {  // Check s[0] == 110xxxxx
-    *value = ((s[0] & 0x1F) << 6) | value16;
-    return 2;
-  }
-  if ((srclen < 3) || ((s[2] & 0xC0) != 0x80)) {  // Check s[2] != 10xxxxxx
-    return 0;
-  }
-  value16 = (value16 << 6) | (s[2] & 0x3F);
-  if ((s[0] & 0xF0) == 0xE0) {  // Check s[0] == 1110xxxx
-    *value = ((s[0] & 0x0F) << 12) | value16;
-    return 3;
-  }
-  if ((srclen < 4) || ((s[3] & 0xC0) != 0x80)) {  // Check s[3] != 10xxxxxx
-    return 0;
-  }
-  value16 = (value16 << 6) | (s[3] & 0x3F);
-  if ((s[0] & 0xF8) == 0xF0) {  // Check s[0] == 11110xxx
-    *value = ((s[0] & 0x07) << 18) | value16;
-    return 4;
-  }
-  return 0;
-}
-
-size_t utf8_encode(char* buffer, size_t buflen, unsigned long value) {
-  if ((value <= 0x7F) && (buflen >= 1)) {
-    buffer[0] = static_cast<unsigned char>(value);
-    return 1;
-  }
-  if ((value <= 0x7FF) && (buflen >= 2)) {
-    buffer[0] = 0xC0 | static_cast<unsigned char>(value >> 6);
-    buffer[1] = 0x80 | static_cast<unsigned char>(value & 0x3F);
-    return 2;
-  }
-  if ((value <= 0xFFFF) && (buflen >= 3)) {
-    buffer[0] = 0xE0 | static_cast<unsigned char>(value >> 12);
-    buffer[1] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F);
-    buffer[2] = 0x80 | static_cast<unsigned char>(value & 0x3F);
-    return 3;
-  }
-  if ((value <= 0x1FFFFF) && (buflen >= 4)) {
-    buffer[0] = 0xF0 | static_cast<unsigned char>(value >> 18);
-    buffer[1] = 0x80 | static_cast<unsigned char>((value >> 12) & 0x3F);
-    buffer[2] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F);
-    buffer[3] = 0x80 | static_cast<unsigned char>(value & 0x3F);
-    return 4;
-  }
-  return 0;
-}
-
 static const char HEX[] = "0123456789abcdef";
 
 char hex_encode(unsigned char val) {
@@ -119,9 +60,9 @@
 bool hex_decode(char ch, unsigned char* val) {
   if ((ch >= '0') && (ch <= '9')) {
     *val = ch - '0';
-  } else if ((ch >= 'A') && (ch <= 'Z')) {
+  } else if ((ch >= 'A') && (ch <= 'F')) {
     *val = (ch - 'A') + 10;
-  } else if ((ch >= 'a') && (ch <= 'z')) {
+  } else if ((ch >= 'a') && (ch <= 'f')) {
     *val = (ch - 'a') + 10;
   } else {
     return false;
diff --git a/rtc_base/stringencode.h b/rtc_base/stringencode.h
index 5d436df..09bf77f 100644
--- a/rtc_base/stringencode.h
+++ b/rtc_base/stringencode.h
@@ -11,9 +11,12 @@
 #ifndef RTC_BASE_STRINGENCODE_H_
 #define RTC_BASE_STRINGENCODE_H_
 
+#include <stddef.h>
 #include <string>
+#include <type_traits>
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/string_to_number.h"
 
diff --git a/rtc_base/stringencode_unittest.cc b/rtc_base/stringencode_unittest.cc
index 9bdc592..f21c4cb 100644
--- a/rtc_base/stringencode_unittest.cc
+++ b/rtc_base/stringencode_unittest.cc
@@ -141,7 +141,8 @@
 
 // Test that decoding non-hex data fails.
 TEST_F(HexEncodeTest, TestDecodeBogusData) {
-  dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "xyz", 3, 0);
+  dec_res_ =
+      hex_decode_with_delimiter(decoded_, sizeof(decoded_), "axyz", 4, 0);
   ASSERT_EQ(0U, dec_res_);
 }
 
diff --git a/rtc_base/strings/audio_format_to_string.cc b/rtc_base/strings/audio_format_to_string.cc
index a149344..7e91c3b 100644
--- a/rtc_base/strings/audio_format_to_string.cc
+++ b/rtc_base/strings/audio_format_to_string.cc
@@ -10,6 +10,8 @@
 
 #include "rtc_base/strings/audio_format_to_string.h"
 
+#include <utility>
+
 #include "rtc_base/strings/string_builder.h"
 
 namespace rtc {
diff --git a/rtc_base/strings/string_builder.cc b/rtc_base/strings/string_builder.cc
index 0dca938..adf4fa9 100644
--- a/rtc_base/strings/string_builder.cc
+++ b/rtc_base/strings/string_builder.cc
@@ -10,11 +10,11 @@
 
 #include "rtc_base/strings/string_builder.h"
 
-#include <stdarg.h>  // for va_end, va_list, va_start
-#include <cstring>   // for strlen
+#include <stdarg.h>
+#include <cstring>
 
-#include "rtc_base/checks.h"                // for FatalLogCall, RTC_DCHECK
-#include "rtc_base/numerics/safe_minmax.h"  // for SafeMin
+#include "rtc_base/checks.h"
+#include "rtc_base/numerics/safe_minmax.h"
 
 namespace rtc {
 
diff --git a/rtc_base/stringutils.cc b/rtc_base/stringutils.cc
index 35153ab..c808eb2 100644
--- a/rtc_base/stringutils.cc
+++ b/rtc_base/stringutils.cc
@@ -10,93 +10,26 @@
 
 #include "rtc_base/stringutils.h"
 
-#include "rtc_base/checks.h"
-
 namespace rtc {
 
-bool memory_check(const void* memory, int c, size_t count) {
-  const char* char_memory = static_cast<const char*>(memory);
-  char char_c = static_cast<char>(c);
-  for (size_t i = 0; i < count; ++i) {
-    if (char_memory[i] != char_c) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool string_match(const char* target, const char* pattern) {
-  while (*pattern) {
-    if (*pattern == '*') {
-      if (!*++pattern) {
-        return true;
-      }
-      while (*target) {
-        if ((toupper(*pattern) == toupper(*target)) &&
-            string_match(target + 1, pattern + 1)) {
-          return true;
-        }
-        ++target;
-      }
-      return false;
-    } else {
-      if (toupper(*pattern) != toupper(*target)) {
-        return false;
-      }
-      ++target;
-      ++pattern;
-    }
-  }
-  return !*target;
-}
-
-#if defined(WEBRTC_WIN)
-int ascii_string_compare(const wchar_t* s1,
-                         const char* s2,
-                         size_t n,
-                         CharacterTransformation transformation) {
-  wchar_t c1, c2;
-  while (true) {
-    if (n-- == 0)
-      return 0;
-    c1 = transformation(*s1);
-    // Double check that characters are not UTF-8
-    RTC_DCHECK_LT(*s2, 128);
-    // Note: *s2 gets implicitly promoted to wchar_t
-    c2 = transformation(*s2);
-    if (c1 != c2)
-      return (c1 < c2) ? -1 : 1;
-    if (!c1)
-      return 0;
-    ++s1;
-    ++s2;
-  }
-}
-
-size_t asccpyn(wchar_t* buffer,
+size_t strcpyn(char* buffer,
                size_t buflen,
                const char* source,
-               size_t srclen) {
+               size_t srclen /* = SIZE_UNKNOWN */) {
   if (buflen <= 0)
     return 0;
 
   if (srclen == SIZE_UNKNOWN) {
-    srclen = strlenn(source, buflen - 1);
-  } else if (srclen >= buflen) {
+    srclen = strlen(source);
+  }
+  if (srclen >= buflen) {
     srclen = buflen - 1;
   }
-#if RTC_DCHECK_IS_ON
-  // Double check that characters are not UTF-8
-  for (size_t pos = 0; pos < srclen; ++pos)
-    RTC_DCHECK_LT(source[pos], 128);
-#endif
-  std::copy(source, source + srclen, buffer);
+  memcpy(buffer, source, srclen);
   buffer[srclen] = 0;
   return srclen;
 }
 
-#endif  // WEBRTC_WIN
-
 void replace_substrs(const char* search,
                      size_t search_len,
                      const char* replace,
diff --git a/rtc_base/stringutils.h b/rtc_base/stringutils.h
index 5739d21..702bc67 100644
--- a/rtc_base/stringutils.h
+++ b/rtc_base/stringutils.h
@@ -20,6 +20,7 @@
 #include <malloc.h>
 #include <wchar.h>
 #include <windows.h>
+
 #define alloca _alloca
 #endif  // WEBRTC_WIN
 
@@ -29,6 +30,7 @@
 #else  // BSD
 #include <alloca.h>
 #endif  // !BSD
+#include <strings.h>
 #endif  // WEBRTC_POSIX
 
 #include <string>
@@ -40,47 +42,6 @@
 #define STACK_ARRAY(TYPE, LEN) \
   static_cast<TYPE*>(::alloca((LEN) * sizeof(TYPE)))
 
-namespace rtc {
-
-// Determines whether the simple wildcard pattern matches target.
-// Alpha characters in pattern match case-insensitively.
-// Asterisks in pattern match 0 or more characters.
-// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true
-bool string_match(const char* target, const char* pattern);
-
-}  // namespace rtc
-
-///////////////////////////////////////////////////////////////////////////////
-// Rename a few common string functions so they are consistent across platforms.
-// tolowercase is like tolower, but not compatible with end-of-file value
-//
-// It's not clear if we will ever use wchar_t strings on unix.  In theory,
-// all strings should be Utf8 all the time, except when interfacing with Win32
-// APIs that require Utf16.
-///////////////////////////////////////////////////////////////////////////////
-inline char tolowercase(char c) {
-  return static_cast<char>(tolower(c));
-}
-
-#if defined(WEBRTC_WIN)
-
-inline wchar_t tolowercase(wchar_t c) {
-  return static_cast<wchar_t>(towlower(c));
-}
-
-#endif  // WEBRTC_WIN
-
-#if defined(WEBRTC_POSIX)
-
-inline int _stricmp(const char* s1, const char* s2) {
-  return strcasecmp(s1, s2);
-}
-inline int _strnicmp(const char* s1, const char* s2, size_t n) {
-  return strncasecmp(s1, s2, n);
-}
-
-#endif  // WEBRTC_POSIX
-
 ///////////////////////////////////////////////////////////////////////////////
 // Traits simplifies porting string functions to be CTYPE-agnostic
 ///////////////////////////////////////////////////////////////////////////////
@@ -89,191 +50,12 @@
 
 const size_t SIZE_UNKNOWN = static_cast<size_t>(-1);
 
-template <class CTYPE>
-struct Traits {
-  // STL string type
-  // typedef XXX string;
-  // Null-terminated string
-  // inline static const CTYPE* empty_str();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// String utilities which work with char or wchar_t
-///////////////////////////////////////////////////////////////////////////////
-
-template <class CTYPE>
-inline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = nullptr) {
-  return str ? str : (def_str ? def_str : Traits<CTYPE>::empty_str());
-}
-
-template <class CTYPE>
-const CTYPE* strchr(const CTYPE* str, const CTYPE* chs) {
-  for (size_t i = 0; str[i]; ++i) {
-    for (size_t j = 0; chs[j]; ++j) {
-      if (str[i] == chs[j]) {
-        return str + i;
-      }
-    }
-  }
-  return 0;
-}
-
-template <class CTYPE>
-const CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) {
-  for (size_t i = 0; i < slen && str[i]; ++i) {
-    if (str[i] == ch) {
-      return str + i;
-    }
-  }
-  return 0;
-}
-
-template <class CTYPE>
-size_t strlenn(const CTYPE* buffer, size_t buflen) {
-  size_t bufpos = 0;
-  while (buffer[bufpos] && (bufpos < buflen)) {
-    ++bufpos;
-  }
-  return bufpos;
-}
-
-// Safe versions of strncpy, strncat, snprintf and vsnprintf that always
-// null-terminate.
-
-template <class CTYPE>
-size_t strcpyn(CTYPE* buffer,
-               size_t buflen,
-               const CTYPE* source,
-               size_t srclen = SIZE_UNKNOWN) {
-  if (buflen <= 0)
-    return 0;
-
-  if (srclen == SIZE_UNKNOWN) {
-    srclen = strlenn(source, buflen - 1);
-  } else if (srclen >= buflen) {
-    srclen = buflen - 1;
-  }
-  memcpy(buffer, source, srclen * sizeof(CTYPE));
-  buffer[srclen] = 0;
-  return srclen;
-}
-
-template <class CTYPE>
-size_t strcatn(CTYPE* buffer,
-               size_t buflen,
-               const CTYPE* source,
-               size_t srclen = SIZE_UNKNOWN) {
-  if (buflen <= 0)
-    return 0;
-
-  size_t bufpos = strlenn(buffer, buflen - 1);
-  return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen);
-}
-
-// Some compilers (clang specifically) require vsprintfn be defined before
-// sprintfn.
-template <class CTYPE>
-__attribute__ ((__format__ (__printf__, 3, 0)))
-size_t vsprintfn(CTYPE* buffer,
-                 size_t buflen,
-                 const char* format,
-                 va_list args) {
-  int len = vsnprintf(buffer, buflen, format, args);
-  if ((len < 0) || (static_cast<size_t>(len) >= buflen)) {
-    len = static_cast<int>(buflen - 1);
-    buffer[len] = 0;
-  }
-  return len;
-}
-
-template <class CTYPE>
-__attribute__ ((__format__ (__printf__, 3, 0)))
-size_t sprintfn(CTYPE* buffer, size_t buflen, const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  size_t len = vsprintfn(buffer, buflen, format, args);
-  va_end(args);
-  return len;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Allow safe comparing and copying ascii (not UTF-8) with both wide and
-// non-wide character strings.
-///////////////////////////////////////////////////////////////////////////////
-
-inline int asccmp(const char* s1, const char* s2) {
-  return strcmp(s1, s2);
-}
-inline int ascicmp(const char* s1, const char* s2) {
-  return _stricmp(s1, s2);
-}
-inline int ascncmp(const char* s1, const char* s2, size_t n) {
-  return strncmp(s1, s2, n);
-}
-inline int ascnicmp(const char* s1, const char* s2, size_t n) {
-  return _strnicmp(s1, s2, n);
-}
-inline size_t asccpyn(char* buffer,
-                      size_t buflen,
-                      const char* source,
-                      size_t srclen = SIZE_UNKNOWN) {
-  return strcpyn(buffer, buflen, source, srclen);
-}
-
-#if defined(WEBRTC_WIN)
-
-typedef wchar_t (*CharacterTransformation)(wchar_t);
-inline wchar_t identity(wchar_t c) {
-  return c;
-}
-int ascii_string_compare(const wchar_t* s1,
-                         const char* s2,
-                         size_t n,
-                         CharacterTransformation transformation);
-
-inline int asccmp(const wchar_t* s1, const char* s2) {
-  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), identity);
-}
-inline int ascicmp(const wchar_t* s1, const char* s2) {
-  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), tolowercase);
-}
-inline int ascncmp(const wchar_t* s1, const char* s2, size_t n) {
-  return ascii_string_compare(s1, s2, n, identity);
-}
-inline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) {
-  return ascii_string_compare(s1, s2, n, tolowercase);
-}
-size_t asccpyn(wchar_t* buffer,
+// Safe version of strncpy that always nul-terminate.
+size_t strcpyn(char* buffer,
                size_t buflen,
                const char* source,
                size_t srclen = SIZE_UNKNOWN);
 
-#endif  // WEBRTC_WIN
-
-///////////////////////////////////////////////////////////////////////////////
-// Traits<char> specializations
-///////////////////////////////////////////////////////////////////////////////
-
-template <>
-struct Traits<char> {
-  typedef std::string string;
-  inline static const char* empty_str() { return ""; }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Traits<wchar_t> specializations (Windows only, currently)
-///////////////////////////////////////////////////////////////////////////////
-
-#if defined(WEBRTC_WIN)
-
-template <>
-struct Traits<wchar_t> {
-  typedef std::wstring string;
-  inline static const wchar_t* empty_str() { return L""; }
-};
-
-#endif  // WEBRTC_WIN
-
 ///////////////////////////////////////////////////////////////////////////////
 // UTF helpers (Windows only)
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/rtc_base/stringutils_unittest.cc b/rtc_base/stringutils_unittest.cc
index a6e6468..663e976 100644
--- a/rtc_base/stringutils_unittest.cc
+++ b/rtc_base/stringutils_unittest.cc
@@ -13,70 +13,6 @@
 
 namespace rtc {
 
-// Tests for string_match().
-
-TEST(string_matchTest, Matches) {
-  EXPECT_TRUE(string_match("A.B.C.D", "a.b.c.d"));
-  EXPECT_TRUE(string_match("www.TEST.GOOGLE.COM", "www.*.com"));
-  EXPECT_TRUE(string_match("127.0.0.1", "12*.0.*1"));
-  EXPECT_TRUE(string_match("127.1.0.21", "12*.0.*1"));
-  EXPECT_FALSE(string_match("127.0.0.0", "12*.0.*1"));
-  EXPECT_FALSE(string_match("127.0.0.0", "12*.0.*1"));
-  EXPECT_FALSE(string_match("127.1.1.21", "12*.0.*1"));
-}
-
-// It's not clear if we will ever use wchar_t strings on unix.  In theory,
-// all strings should be Utf8 all the time, except when interfacing with Win32
-// APIs that require Utf16.
-
-#if defined(WEBRTC_WIN)
-
-// Tests for ascii_string_compare().
-
-// Tests null input.
-TEST(ascii_string_compareTest, NullInput) {
-  // The following results in an access violation in
-  // ascii_string_compare.  Is this a bug or by design?  stringutils.h
-  // should document the expected behavior in this case.
-
-  // EXPECT_EQ(0, ascii_string_compare(nullptr, nullptr, 1, identity));
-}
-
-// Tests comparing two strings of different lengths.
-TEST(ascii_string_compareTest, DifferentLengths) {
-  EXPECT_EQ(-1, ascii_string_compare(L"Test", "Test1", 5, identity));
-}
-
-// Tests the case where the buffer size is smaller than the string
-// lengths.
-TEST(ascii_string_compareTest, SmallBuffer) {
-  EXPECT_EQ(0, ascii_string_compare(L"Test", "Test1", 3, identity));
-}
-
-// Tests the case where the buffer is not full.
-TEST(ascii_string_compareTest, LargeBuffer) {
-  EXPECT_EQ(0, ascii_string_compare(L"Test", "Test", 10, identity));
-}
-
-// Tests comparing two eqaul strings.
-TEST(ascii_string_compareTest, Equal) {
-  EXPECT_EQ(0, ascii_string_compare(L"Test", "Test", 5, identity));
-  EXPECT_EQ(0, ascii_string_compare(L"TeSt", "tEsT", 5, tolowercase));
-}
-
-// Tests comparing a smller string to a larger one.
-TEST(ascii_string_compareTest, LessThan) {
-  EXPECT_EQ(-1, ascii_string_compare(L"abc", "abd", 4, identity));
-  EXPECT_EQ(-1, ascii_string_compare(L"ABC", "abD", 5, tolowercase));
-}
-
-// Tests comparing a larger string to a smaller one.
-TEST(ascii_string_compareTest, GreaterThan) {
-  EXPECT_EQ(1, ascii_string_compare(L"xyz", "xy", 5, identity));
-  EXPECT_EQ(1, ascii_string_compare(L"abc", "ABB", 5, tolowercase));
-}
-#endif  // WEBRTC_WIN
-
 TEST(string_trim_Test, Trimming) {
   EXPECT_EQ("temp", string_trim("\n\r\t temp \n\r\t"));
   EXPECT_EQ("temp\n\r\t temp", string_trim(" temp\n\r\t temp "));
diff --git a/rtc_base/synchronization/rw_lock_posix.cc b/rtc_base/synchronization/rw_lock_posix.cc
index 7e37dc9..15ef3d7 100644
--- a/rtc_base/synchronization/rw_lock_posix.cc
+++ b/rtc_base/synchronization/rw_lock_posix.cc
@@ -10,6 +10,8 @@
 
 #include "rtc_base/synchronization/rw_lock_posix.h"
 
+#include <stddef.h>
+
 namespace webrtc {
 
 RWLockPosix::RWLockPosix() : lock_() {}
diff --git a/rtc_base/system/BUILD.gn b/rtc_base/system/BUILD.gn
index f22efe1..e5aa32b 100644
--- a/rtc_base/system/BUILD.gn
+++ b/rtc_base/system/BUILD.gn
@@ -65,3 +65,15 @@
     "rtc_export.h",
   ]
 }
+
+if (is_mac || is_ios) {
+  rtc_source_set("cocoa_threading") {
+    sources = [
+      "cocoa_threading.h",
+      "cocoa_threading.mm",
+    ]
+    deps = [
+      "..:checks",
+    ]
+  }
+}
diff --git a/rtc_base/system/cocoa_threading.h b/rtc_base/system/cocoa_threading.h
new file mode 100644
index 0000000..518cb71
--- /dev/null
+++ b/rtc_base/system/cocoa_threading.h
@@ -0,0 +1,24 @@
+/*
+ *  Copyright 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 RTC_BASE_SYSTEM_COCOA_THREADING_H_
+#define RTC_BASE_SYSTEM_COCOA_THREADING_H_
+
+// If Cocoa is to be used on more than one thread, it must know that the
+// application is multithreaded.  Since it's possible to enter Cocoa code
+// from threads created by pthread_thread_create, Cocoa won't necessarily
+// be aware that the application is multithreaded.  Spawning an NSThread is
+// enough to get Cocoa to set up for multithreaded operation, so this is done
+// if necessary before pthread_thread_create spawns any threads.
+//
+// http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_4.html
+void InitCocoaMultiThreading();
+
+#endif  // RTC_BASE_SYSTEM_COCOA_THREADING_H_
diff --git a/rtc_base/system/cocoa_threading.mm b/rtc_base/system/cocoa_threading.mm
new file mode 100644
index 0000000..c09862e
--- /dev/null
+++ b/rtc_base/system/cocoa_threading.mm
@@ -0,0 +1,24 @@
+/*
+ *  Copyright 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 "rtc_base/system/cocoa_threading.h"
+
+#import <Foundation/Foundation.h>
+
+#include "rtc_base/checks.h"
+
+void InitCocoaMultiThreading() {
+  static BOOL is_cocoa_multithreaded = [NSThread isMultiThreaded];
+  if (!is_cocoa_multithreaded) {
+    // +[NSObject class] is idempotent.
+    [NSThread detachNewThreadSelector:@selector(class) toTarget:[NSObject class] withObject:nil];
+    is_cocoa_multithreaded = YES;
+    RTC_DCHECK([NSThread isMultiThreaded]);
+  }
+}
diff --git a/rtc_base/system/file_wrapper.cc b/rtc_base/system/file_wrapper.cc
index 72f5f25..c033a79 100644
--- a/rtc_base/system/file_wrapper.cc
+++ b/rtc_base/system/file_wrapper.cc
@@ -13,14 +13,11 @@
 #ifdef _WIN32
 #include <Windows.h>
 #else
-#include <stdarg.h>
 #include <string.h>
 #endif
 
 #include <utility>
 
-#include "rtc_base/checks.h"
-
 namespace webrtc {
 namespace {
 FILE* FileOpen(const char* file_name_utf8, bool read_only) {
diff --git a/rtc_base/system/file_wrapper.h b/rtc_base/system/file_wrapper.h
index 5411b04..0bb86a3 100644
--- a/rtc_base/system/file_wrapper.h
+++ b/rtc_base/system/file_wrapper.h
@@ -14,7 +14,6 @@
 #include <stddef.h>
 #include <stdio.h>
 
-#include "common_types.h"  // NOLINT(build/include)
 #include "rtc_base/criticalsection.h"
 
 // Implementation that can read (exclusive) or write from/to a file.
diff --git a/rtc_base/task_queue_for_test.h b/rtc_base/task_queue_for_test.h
index 70c58fb..9162e81 100644
--- a/rtc_base/task_queue_for_test.h
+++ b/rtc_base/task_queue_for_test.h
@@ -33,7 +33,7 @@
   template <class Closure>
   void SendTask(Closure* task) {
     RTC_DCHECK(!IsCurrent());
-    rtc::Event event(false, false);
+    rtc::Event event;
     PostTask(rtc::NewClosure(
         [&task]() {
           RTC_CHECK_EQ(false, static_cast<QueuedTask*>(task)->Run());
@@ -47,7 +47,7 @@
   template <class Closure>
   void SendTask(Closure&& task) {
     RTC_DCHECK(!IsCurrent());
-    rtc::Event event(false, false);
+    rtc::Event event;
     PostTask(rtc::NewClosure(std::move(task), [&event]() { event.Set(); }));
     event.Wait(rtc::Event::kForever);
   }
diff --git a/rtc_base/task_queue_libevent.cc b/rtc_base/task_queue_libevent.cc
index 000f463..7588569 100644
--- a/rtc_base/task_queue_libevent.cc
+++ b/rtc_base/task_queue_libevent.cc
@@ -10,17 +10,17 @@
 
 #include "rtc_base/task_queue.h"
 
-#include <errno.h>  // for EAGAIN, errno
+#include <errno.h>
 #include <fcntl.h>
-#include <pthread.h>  // for pthread_getspecific
+#include <pthread.h>
 #include <signal.h>
-#include <stdint.h>  // for uint32_t
-#include <time.h>    // for nanosleep, timespec
+#include <stdint.h>
+#include <time.h>
 #include <unistd.h>
 #include <list>
-#include <memory>       // for unique_ptr, allocator
-#include <type_traits>  // for remove_reference<>::...
-#include <utility>      // for move
+#include <memory>
+#include <type_traits>
+#include <utility>
 
 #include <event.h>
 #include "rtc_base/checks.h"
@@ -28,13 +28,13 @@
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/platform_thread.h"
-#include "rtc_base/platform_thread_types.h"  // for CurrentThreadRef
+#include "rtc_base/platform_thread_types.h"
 #include "rtc_base/refcount.h"
 #include "rtc_base/refcountedobject.h"
-#include "rtc_base/scoped_ref_ptr.h"  // for scoped_refptr
+#include "rtc_base/scoped_ref_ptr.h"
 #include "rtc_base/system/unused.h"
 #include "rtc_base/task_queue_posix.h"
-#include "rtc_base/thread_annotations.h"  // for RTC_GUARDED_BY
+#include "rtc_base/thread_annotations.h"
 #include "rtc_base/timeutils.h"
 
 namespace rtc {
diff --git a/rtc_base/task_queue_unittest.cc b/rtc_base/task_queue_unittest.cc
index cedf68e..0af39a5 100644
--- a/rtc_base/task_queue_unittest.cc
+++ b/rtc_base/task_queue_unittest.cc
@@ -64,7 +64,7 @@
 
 TEST(TaskQueueTest, PostAndCheckCurrent) {
   static const char kQueueName[] = "PostAndCheckCurrent";
-  Event event(false, false);
+  Event event;
   TaskQueue queue(kQueueName);
 
   // We're not running a task, so there shouldn't be a current queue.
@@ -106,7 +106,7 @@
 
 TEST(TaskQueueTest, PostDelayedZero) {
   static const char kQueueName[] = "PostDelayedZero";
-  Event event(false, false);
+  Event event;
   TaskQueue queue(kQueueName);
 
   queue.PostDelayedTask([&event]() { event.Set(); }, 0);
@@ -115,7 +115,7 @@
 
 TEST(TaskQueueTest, PostFromQueue) {
   static const char kQueueName[] = "PostFromQueue";
-  Event event(false, false);
+  Event event;
   TaskQueue queue(kQueueName);
 
   queue.PostTask(
@@ -125,7 +125,7 @@
 
 TEST(TaskQueueTest, PostDelayed) {
   static const char kQueueName[] = "PostDelayed";
-  Event event(false, false);
+  Event event;
   TaskQueue queue(kQueueName, TaskQueue::Priority::HIGH);
 
   uint32_t start = Time();
@@ -145,7 +145,7 @@
   EnableHighResTimers high_res_scope;
 
   static const char kQueueName[] = "PostDelayedHighRes";
-  Event event(false, false);
+  Event event;
   TaskQueue queue(kQueueName, TaskQueue::Priority::HIGH);
 
   uint32_t start = Time();
@@ -165,7 +165,7 @@
 
   std::vector<std::unique_ptr<Event>> events;
   for (int i = 0; i < 100; ++i) {
-    events.push_back(std::unique_ptr<Event>(new Event(false, false)));
+    events.push_back(absl::make_unique<Event>());
     queue.PostDelayedTask(Bind(&CheckCurrent, events.back().get(), &queue), i);
   }
 
@@ -175,8 +175,8 @@
 
 TEST(TaskQueueTest, PostDelayedAfterDestruct) {
   static const char kQueueName[] = "PostDelayedAfterDestruct";
-  Event run(false, false);
-  Event deleted(false, false);
+  Event run;
+  Event deleted;
   {
     TaskQueue queue(kQueueName);
     queue.PostDelayedTask(
@@ -191,7 +191,7 @@
 TEST(TaskQueueTest, PostAndReply) {
   static const char kPostQueue[] = "PostQueue";
   static const char kReplyQueue[] = "ReplyQueue";
-  Event event(false, false);
+  Event event;
   TaskQueue post_queue(kPostQueue);
   TaskQueue reply_queue(kReplyQueue);
 
@@ -204,7 +204,7 @@
 TEST(TaskQueueTest, PostAndReuse) {
   static const char kPostQueue[] = "PostQueue";
   static const char kReplyQueue[] = "ReplyQueue";
-  Event event(false, false);
+  Event event;
   TaskQueue post_queue(kPostQueue);
   TaskQueue reply_queue(kReplyQueue);
 
@@ -251,7 +251,7 @@
 TEST(TaskQueueTest, PostAndReplyLambda) {
   static const char kPostQueue[] = "PostQueue";
   static const char kReplyQueue[] = "ReplyQueue";
-  Event event(false, false);
+  Event event;
   TaskQueue post_queue(kPostQueue);
   TaskQueue reply_queue(kReplyQueue);
 
@@ -287,7 +287,7 @@
 
   int num_copies = 0;
   int num_moves = 0;
-  Event event(false, false);
+  Event event;
 
   static const char kPostQueue[] = "PostCopyableClosure";
   TaskQueue post_queue(kPostQueue);
@@ -323,7 +323,7 @@
   };
 
   int num_moves = 0;
-  Event event(false, false);
+  Event event;
   std::unique_ptr<SomeState> state(new SomeState(&event));
 
   static const char kPostQueue[] = "PostMoveOnlyClosure";
@@ -346,8 +346,8 @@
     std::unique_ptr<SomeState> state;
   };
 
-  Event event_run(false, false);
-  Event event_cleanup(false, false);
+  Event event_run;
+  Event event_cleanup;
   std::unique_ptr<SomeState> state_run(new SomeState(&event_run));
   std::unique_ptr<SomeState> state_cleanup(new SomeState(&event_cleanup));
 
@@ -367,7 +367,7 @@
 // written in a way that makes it likely and by running with --gtest_repeat=1000
 // the bug would occur. Alas, now it should be fixed.
 TEST(TaskQueueTest, PostAndReplyDeadlock) {
-  Event event(false, false);
+  Event event;
   TaskQueue post_queue("PostQueue");
   TaskQueue reply_queue("ReplyQueue");
 
@@ -384,8 +384,8 @@
 #define MAYBE_DeleteTaskQueueAfterPostAndReply DeleteTaskQueueAfterPostAndReply
 #endif
 TEST(TaskQueueTest, MAYBE_DeleteTaskQueueAfterPostAndReply) {
-  Event task_deleted(false, false);
-  Event reply_deleted(false, false);
+  Event task_deleted;
+  Event reply_deleted;
   auto* task_queue = new TaskQueue("Queue");
 
   task_queue->PostTaskAndReply(
@@ -413,7 +413,7 @@
 TEST(TaskQueueTest, PostAndReply2) {
   static const char kQueueName[] = "PostAndReply2";
   static const char kWorkQueueName[] = "PostAndReply2_Worker";
-  Event event(false, false);
+  Event event;
   TaskQueue queue(kQueueName);
   TaskQueue work_queue(kWorkQueueName);
 
@@ -425,7 +425,7 @@
 // In situations like that, tasks will get dropped.
 TEST(TaskQueueTest, PostALot) {
   // To destruct the event after the queue has gone out of scope.
-  Event event(false, false);
+  Event event;
 
   int tasks_executed = 0;
   int tasks_cleaned_up = 0;
diff --git a/rtc_base/testclient.cc b/rtc_base/testclient.cc
index 7c151c7..a5b90dd 100644
--- a/rtc_base/testclient.cc
+++ b/rtc_base/testclient.cc
@@ -97,7 +97,7 @@
   std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs);
   if (packet) {
     res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 &&
-           CheckTimestamp(packet->packet_time.timestamp));
+           CheckTimestamp(packet->packet_time_us));
     if (addr)
       *addr = packet->addr;
   }
@@ -144,10 +144,10 @@
                           const char* buf,
                           size_t size,
                           const SocketAddress& remote_addr,
-                          const PacketTime& packet_time) {
+                          const int64_t& packet_time_us) {
   CritScope cs(&crit_);
   packets_.push_back(
-      absl::make_unique<Packet>(remote_addr, buf, size, packet_time));
+      absl::make_unique<Packet>(remote_addr, buf, size, packet_time_us));
 }
 
 void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
@@ -157,14 +157,14 @@
 TestClient::Packet::Packet(const SocketAddress& a,
                            const char* b,
                            size_t s,
-                           const PacketTime& packet_time)
-    : addr(a), buf(0), size(s), packet_time(packet_time) {
+                           int64_t packet_time_us)
+    : addr(a), buf(0), size(s), packet_time_us(packet_time_us) {
   buf = new char[size];
   memcpy(buf, b, size);
 }
 
 TestClient::Packet::Packet(const Packet& p)
-    : addr(p.addr), buf(0), size(p.size), packet_time(p.packet_time) {
+    : addr(p.addr), buf(0), size(p.size), packet_time_us(p.packet_time_us) {
   buf = new char[size];
   memcpy(buf, p.buf, size);
 }
diff --git a/rtc_base/testclient.h b/rtc_base/testclient.h
index a0d98b3..16fb6ba 100644
--- a/rtc_base/testclient.h
+++ b/rtc_base/testclient.h
@@ -29,14 +29,14 @@
     Packet(const SocketAddress& a,
            const char* b,
            size_t s,
-           const PacketTime& packet_time);
+           int64_t packet_time_us);
     Packet(const Packet& p);
     virtual ~Packet();
 
     SocketAddress addr;
     char* buf;
     size_t size;
-    PacketTime packet_time;
+    int64_t packet_time_us;
   };
 
   // Default timeout for NextPacket reads.
@@ -97,7 +97,7 @@
                 const char* buf,
                 size_t len,
                 const SocketAddress& remote_addr,
-                const PacketTime& packet_time);
+                const int64_t& packet_time_us);
   void OnReadyToSend(AsyncPacketSocket* socket);
   bool CheckTimestamp(int64_t packet_timestamp);
   void AdvanceTime(int ms);
diff --git a/rtc_base/testechoserver.h b/rtc_base/testechoserver.h
index 5e714eb..9ffd786 100644
--- a/rtc_base/testechoserver.h
+++ b/rtc_base/testechoserver.h
@@ -44,7 +44,7 @@
                 const char* buf,
                 size_t size,
                 const SocketAddress& remote_addr,
-                const PacketTime& packet_time) {
+                const int64_t& /* packet_time_us */) {
     rtc::PacketOptions options;
     socket->Send(buf, size, options);
   }
diff --git a/rtc_base/testutils.cc b/rtc_base/testutils.cc
index b4a7433..f3292fd 100644
--- a/rtc_base/testutils.cc
+++ b/rtc_base/testutils.cc
@@ -14,75 +14,7 @@
 namespace testing {
 
 StreamSink::StreamSink() = default;
-
 StreamSink::~StreamSink() = default;
 
-StreamSource::StreamSource() {
-  Clear();
-}
-
-StreamSource::~StreamSource() = default;
-
-StreamState StreamSource::GetState() const {
-  return state_;
-}
-
-StreamResult StreamSource::Read(void* buffer,
-                                size_t buffer_len,
-                                size_t* read,
-                                int* error) {
-  if (SS_CLOSED == state_) {
-    if (error)
-      *error = -1;
-    return SR_ERROR;
-  }
-  if ((SS_OPENING == state_) || (readable_data_.size() <= read_block_)) {
-    return SR_BLOCK;
-  }
-  size_t count = std::min(buffer_len, readable_data_.size() - read_block_);
-  memcpy(buffer, &readable_data_[0], count);
-  size_t new_size = readable_data_.size() - count;
-  // Avoid undefined access beyond the last element of the vector.
-  // This only happens when new_size is 0.
-  if (count < readable_data_.size()) {
-    memmove(&readable_data_[0], &readable_data_[count], new_size);
-  }
-  readable_data_.resize(new_size);
-  if (read)
-    *read = count;
-  return SR_SUCCESS;
-}
-
-StreamResult StreamSource::Write(const void* data,
-                                 size_t data_len,
-                                 size_t* written,
-                                 int* error) {
-  if (SS_CLOSED == state_) {
-    if (error)
-      *error = -1;
-    return SR_ERROR;
-  }
-  if (SS_OPENING == state_) {
-    return SR_BLOCK;
-  }
-  if (SIZE_UNKNOWN != write_block_) {
-    if (written_data_.size() >= write_block_) {
-      return SR_BLOCK;
-    }
-    if (data_len > (write_block_ - written_data_.size())) {
-      data_len = write_block_ - written_data_.size();
-    }
-  }
-  if (written)
-    *written = data_len;
-  const char* cdata = static_cast<const char*>(data);
-  written_data_.insert(written_data_.end(), cdata, cdata + data_len);
-  return SR_SUCCESS;
-}
-
-void StreamSource::Close() {
-  state_ = SS_CLOSED;
-}
-
 }  // namespace testing
 }  // namespace webrtc
diff --git a/rtc_base/testutils.h b/rtc_base/testutils.h
index 2ab4a35..6b3733f 100644
--- a/rtc_base/testutils.h
+++ b/rtc_base/testutils.h
@@ -21,7 +21,6 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/gunit.h"
 #include "rtc_base/stream.h"
-#include "rtc_base/stringutils.h"
 
 namespace webrtc {
 namespace testing {
@@ -137,91 +136,6 @@
   EventMap events_;
 };
 
-///////////////////////////////////////////////////////////////////////////////
-// StreamSource - Implements stream interface and simulates asynchronous
-// events on the stream, without a network.  Also buffers written data.
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamSource : public StreamInterface {
- public:
-  StreamSource();
-  ~StreamSource() override;
-
-  void Clear() {
-    readable_data_.clear();
-    written_data_.clear();
-    state_ = SS_CLOSED;
-    read_block_ = 0;
-    write_block_ = SIZE_UNKNOWN;
-  }
-  void QueueString(const char* data) { QueueData(data, strlen(data)); }
-#if defined(__GNUC__)
-  // Note: Implicit |this| argument counts as the first argument.
-  __attribute__((__format__(__printf__, 2, 3)))
-#endif
-  void
-  QueueStringF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char buffer[1024];
-    size_t len = vsprintfn(buffer, sizeof(buffer), format, args);
-    RTC_CHECK(len < sizeof(buffer) - 1);
-    va_end(args);
-    QueueData(buffer, len);
-  }
-  void QueueData(const char* data, size_t len) {
-    readable_data_.insert(readable_data_.end(), data, data + len);
-    if ((SS_OPEN == state_) && (readable_data_.size() == len)) {
-      SignalEvent(this, SE_READ, 0);
-    }
-  }
-  std::string ReadData() {
-    std::string data;
-    // avoid accessing written_data_[0] if it is undefined
-    if (written_data_.size() > 0) {
-      data.insert(0, &written_data_[0], written_data_.size());
-    }
-    written_data_.clear();
-    return data;
-  }
-  void SetState(StreamState state) {
-    int events = 0;
-    if ((SS_OPENING == state_) && (SS_OPEN == state)) {
-      events |= SE_OPEN;
-      if (!readable_data_.empty()) {
-        events |= SE_READ;
-      }
-    } else if ((SS_CLOSED != state_) && (SS_CLOSED == state)) {
-      events |= SE_CLOSE;
-    }
-    state_ = state;
-    if (events) {
-      SignalEvent(this, events, 0);
-    }
-  }
-  // Will cause Read to block when there are pos bytes in the read queue.
-  void SetReadBlock(size_t pos) { read_block_ = pos; }
-  // Will cause Write to block when there are pos bytes in the write queue.
-  void SetWriteBlock(size_t pos) { write_block_ = pos; }
-
-  StreamState GetState() const override;
-  StreamResult Read(void* buffer,
-                    size_t buffer_len,
-                    size_t* read,
-                    int* error) override;
-  StreamResult Write(const void* data,
-                     size_t data_len,
-                     size_t* written,
-                     int* error) override;
-  void Close() override;
-
- private:
-  typedef std::vector<char> Buffer;
-  Buffer readable_data_, written_data_;
-  StreamState state_;
-  size_t read_block_, write_block_;
-};
-
 }  // namespace testing
 }  // namespace webrtc
 
diff --git a/rtc_base/thread.cc b/rtc_base/thread.cc
index 911ac16..4dd5fd2 100644
--- a/rtc_base/thread.cc
+++ b/rtc_base/thread.cc
@@ -24,15 +24,43 @@
 #pragma warning(disable : 4722)
 #endif
 
-#include <utility>  // for move
+#include <stdio.h>
+#include <utility>
 
 #include "rtc_base/checks.h"
+#include "rtc_base/criticalsection.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/nullsocketserver.h"
-#include "rtc_base/stringutils.h"
 #include "rtc_base/timeutils.h"
 #include "rtc_base/trace_event.h"
 
+#if defined(WEBRTC_MAC)
+#include "rtc_base/system/cocoa_threading.h"
+
+/*
+ * These are forward-declarations for methods that are part of the
+ * ObjC runtime. They are declared in the private header objc-internal.h.
+ * These calls are what clang inserts when using @autoreleasepool in ObjC,
+ * but here they are used directly in order to keep this file C++.
+ * https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support
+ */
+extern "C" {
+void* objc_autoreleasePoolPush(void);
+void objc_autoreleasePoolPop(void* pool);
+}
+
+namespace {
+class ScopedAutoReleasePool {
+ public:
+  ScopedAutoReleasePool() : pool_(objc_autoreleasePoolPush()) {}
+  ~ScopedAutoReleasePool() { objc_autoreleasePoolPop(pool_); }
+
+ private:
+  void* const pool_;
+};
+}  // namespace
+#endif
+
 namespace rtc {
 
 ThreadManager* ThreadManager::Instance() {
@@ -62,11 +90,12 @@
 }
 
 #if defined(WEBRTC_POSIX)
-#if !defined(WEBRTC_MAC)
 ThreadManager::ThreadManager() : main_thread_ref_(CurrentThreadRef()) {
+#if defined(WEBRTC_MAC)
+  InitCocoaMultiThreading();
+#endif
   pthread_key_create(&key_, nullptr);
 }
-#endif
 
 Thread* ThreadManager::CurrentThread() {
   return static_cast<Thread*>(pthread_getspecific(key_));
@@ -194,8 +223,10 @@
 
   name_ = name;
   if (obj) {
-    char buf[16];
-    sprintfn(buf, sizeof(buf), " 0x%p", obj);
+    // The %p specifier typically produce at most 16 hex digits, possibly with a
+    // 0x prefix. But format is implementation defined, so add some margin.
+    char buf[30];
+    snprintf(buf, sizeof(buf), " 0x%p", obj);
     name_ += buf;
   }
   return true;
@@ -301,7 +332,6 @@
 }
 
 // static
-#if !defined(WEBRTC_MAC)
 #if defined(WEBRTC_WIN)
 DWORD WINAPI Thread::PreRun(LPVOID pv) {
 #else
@@ -310,6 +340,9 @@
   ThreadInit* init = static_cast<ThreadInit*>(pv);
   ThreadManager::Instance()->SetCurrentThread(init->thread);
   rtc::SetCurrentThreadName(init->thread->name_.c_str());
+#if defined(WEBRTC_MAC)
+  ScopedAutoReleasePool pool;
+#endif
   if (init->runnable) {
     init->runnable->Run(init->thread);
   } else {
@@ -323,7 +356,6 @@
   return nullptr;
 #endif
 }
-#endif
 
 void Thread::Run() {
   ProcessMessages(kForever);
@@ -486,9 +518,6 @@
   ClearInternal(phandler, id, removed);
 }
 
-#if !defined(WEBRTC_MAC)
-// Note that these methods have a separate implementation for mac and ios
-// defined in webrtc/rtc_base/thread_darwin.mm.
 bool Thread::ProcessMessages(int cmsLoop) {
   // Using ProcessMessages with a custom clock for testing and a time greater
   // than 0 doesn't work, since it's not guaranteed to advance the custom
@@ -499,6 +528,9 @@
   int cmsNext = cmsLoop;
 
   while (true) {
+#if defined(WEBRTC_MAC)
+    ScopedAutoReleasePool pool;
+#endif
     Message msg;
     if (!Get(&msg, cmsNext))
       return !IsQuitting();
@@ -511,7 +543,6 @@
     }
   }
 }
-#endif
 
 bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager,
                                           bool need_synchronize_access) {
diff --git a/rtc_base/thread.h b/rtc_base/thread.h
index fde5e8b..039192c 100644
--- a/rtc_base/thread.h
+++ b/rtc_base/thread.h
@@ -11,16 +11,22 @@
 #ifndef RTC_BASE_THREAD_H_
 #define RTC_BASE_THREAD_H_
 
+#include <stdint.h>
 #include <list>
 #include <memory>
 #include <string>
+#include <type_traits>
 
 #if defined(WEBRTC_POSIX)
 #include <pthread.h>
 #endif
 #include "rtc_base/constructormagic.h"
+#include "rtc_base/location.h"
+#include "rtc_base/messagehandler.h"
 #include "rtc_base/messagequeue.h"
 #include "rtc_base/platform_thread_types.h"
+#include "rtc_base/socketserver.h"
+#include "rtc_base/thread_annotations.h"
 
 #if defined(WEBRTC_WIN)
 #include "rtc_base/win32.h"
diff --git a/rtc_base/thread_darwin.mm b/rtc_base/thread_darwin.mm
deleted file mode 100644
index e64d6eb..0000000
--- a/rtc_base/thread_darwin.mm
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Copyright 2017 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 "rtc_base/thread.h"
-
-#import <Foundation/Foundation.h>
-
-#include "rtc_base/platform_thread.h"
-#include "rtc_base/timeutils.h"  // for TimeAfter, TimeUntil
-
-/*
- * This file contains platform-specific implementations for several
- * methods in rtc::Thread.
- */
-
-namespace {
-void InitCocoaMultiThreading() {
-  if ([NSThread isMultiThreaded] == NO) {
-    // The sole purpose of this autorelease pool is to avoid a console
-    // message on Leopard that tells us we're autoreleasing the thread
-    // with no autorelease pool in place.
-    @autoreleasepool {
-      [NSThread detachNewThreadSelector:@selector(class)
-                               toTarget:[NSObject class]
-                             withObject:nil];
-    }
-  }
-
-  RTC_DCHECK([NSThread isMultiThreaded]);
-}
-}
-
-namespace rtc {
-
-ThreadManager::ThreadManager() : main_thread_ref_(CurrentThreadRef()) {
-  pthread_key_create(&key_, nullptr);
-  // This is necessary to alert the cocoa runtime of the fact that
-  // we are running in a multithreaded environment.
-  InitCocoaMultiThreading();
-}
-
-// static
-void* Thread::PreRun(void* pv) {
-  ThreadInit* init = static_cast<ThreadInit*>(pv);
-  ThreadManager::Instance()->SetCurrentThread(init->thread);
-  rtc::SetCurrentThreadName(init->thread->name_.c_str());
-  @autoreleasepool {
-    if (init->runnable) {
-      init->runnable->Run(init->thread);
-    } else {
-      init->thread->Run();
-    }
-  }
-  ThreadManager::Instance()->SetCurrentThread(nullptr);
-  delete init;
-  return nullptr;
-}
-
-bool Thread::ProcessMessages(int cmsLoop) {
-  int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop);
-  int cmsNext = cmsLoop;
-
-  while (true) {
-    @autoreleasepool {
-      Message msg;
-      if (!Get(&msg, cmsNext))
-        return !IsQuitting();
-      Dispatch(&msg);
-
-      if (cmsLoop != kForever) {
-        cmsNext = static_cast<int>(TimeUntil(msEnd));
-        if (cmsNext < 0)
-          return true;
-      }
-    }
-  }
-}
-}  // namespace rtc
diff --git a/rtc_base/thread_unittest.cc b/rtc_base/thread_unittest.cc
index d5c53f8..7e392af 100644
--- a/rtc_base/thread_unittest.cc
+++ b/rtc_base/thread_unittest.cc
@@ -69,7 +69,7 @@
                 const char* buf,
                 size_t size,
                 const SocketAddress& remote_addr,
-                const PacketTime& packet_time) {
+                const int64_t& packet_time_us) {
     EXPECT_EQ(size, sizeof(uint32_t));
     uint32_t prev = reinterpret_cast<const uint32_t*>(buf)[0];
     uint32_t result = Next(prev);
@@ -470,9 +470,9 @@
   // Use these events to get in a state where the functor is in the middle of
   // executing, and then to wait for it to finish, ensuring the "EXPECT_FALSE"
   // is run.
-  Event functor_started(false, false);
-  Event functor_continue(false, false);
-  Event functor_finished(false, false);
+  Event functor_started;
+  Event functor_continue;
+  Event functor_finished;
 
   auto thread = Thread::CreateWithSocketServer();
   thread->Start();
@@ -507,7 +507,7 @@
 // destroyed. This shouldn't deadlock or crash; this second invocation should
 // just be ignored.
 TEST_F(AsyncInvokeTest, KillInvokerDuringExecuteWithReentrantInvoke) {
-  Event functor_started(false, false);
+  Event functor_started;
   // Flag used to verify that the recursively invoked task never actually runs.
   bool reentrant_functor_run = false;
 
diff --git a/rtc_base/timestampaligner.cc b/rtc_base/timestampaligner.cc
index a9bcafb..f2da101 100644
--- a/rtc_base/timestampaligner.cc
+++ b/rtc_base/timestampaligner.cc
@@ -8,6 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <cstdlib>
 #include <limits>
 
 #include "rtc_base/checks.h"
diff --git a/rtc_base/timeutils.cc b/rtc_base/timeutils.cc
index de8fc32..dc5b611 100644
--- a/rtc_base/timeutils.cc
+++ b/rtc_base/timeutils.cc
@@ -14,6 +14,7 @@
 #include <sys/time.h>
 #if defined(WEBRTC_MAC)
 #include <mach/mach_time.h>
+#include "rtc_base/numerics/safe_conversions.h"
 #endif
 #endif
 
@@ -28,7 +29,6 @@
 #endif
 
 #include "rtc_base/checks.h"
-#include "rtc_base/numerics/safe_conversions.h"
 #include "rtc_base/timeutils.h"
 
 namespace rtc {
@@ -154,7 +154,7 @@
   return ts + (num_wrap_ << 32);
 }
 
-int64_t TmToSeconds(const std::tm& tm) {
+int64_t TmToSeconds(const tm& tm) {
   static short int mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
   static short int cumul_mdays[12] = {0,   31,  59,  90,  120, 151,
                                       181, 212, 243, 273, 304, 334};
diff --git a/rtc_base/timeutils.h b/rtc_base/timeutils.h
index 3a412a4..4e38a03 100644
--- a/rtc_base/timeutils.h
+++ b/rtc_base/timeutils.h
@@ -13,8 +13,6 @@
 
 #include <stdint.h>
 #include <time.h>
-
-#include <ctime>
 #include <string>
 
 #include "rtc_base/checks.h"
@@ -110,10 +108,10 @@
   int64_t num_wrap_;
 };
 
-// Convert from std::tm, which is relative to 1900-01-01 00:00 to number of
-// seconds from 1970-01-01 00:00 ("epoch").  Don't return time_t since that
+// Convert from tm, which is relative to 1900-01-01 00:00 to number of
+// seconds from 1970-01-01 00:00 ("epoch"). Don't return time_t since that
 // is still 32 bits on many systems.
-int64_t TmToSeconds(const std::tm& tm);
+int64_t TmToSeconds(const tm& tm);
 
 // Return the number of microseconds since January 1, 1970, UTC.
 // Useful mainly when producing logs to be correlated with other
diff --git a/rtc_base/timeutils_unittest.cc b/rtc_base/timeutils_unittest.cc
index 0e1949a..577efda 100644
--- a/rtc_base/timeutils_unittest.cc
+++ b/rtc_base/timeutils_unittest.cc
@@ -262,7 +262,7 @@
   worker->Start();
 
   // Post an event that won't be executed for 10 seconds.
-  Event message_handler_dispatched(false, false);
+  Event message_handler_dispatched;
   auto functor = [&message_handler_dispatched] {
     message_handler_dispatched.Set();
   };
diff --git a/rtc_base/unittest_main.cc b/rtc_base/unittest_main.cc
index 12543a3..5fd3a99 100644
--- a/rtc_base/unittest_main.cc
+++ b/rtc_base/unittest_main.cc
@@ -31,19 +31,20 @@
 #include "test/ios/test_support.h"
 #endif
 
-DEFINE_bool(help, false, "prints this message");
-DEFINE_string(log, "", "logging options to use");
-DEFINE_string(
+WEBRTC_DEFINE_bool(help, false, "prints this message");
+WEBRTC_DEFINE_string(log, "", "logging options to use");
+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.");
 #if defined(WEBRTC_WIN)
-DEFINE_int(crt_break_alloc, -1, "memory allocation to break on");
-DEFINE_bool(default_error_handlers,
-            false,
-            "leave the default exception/dbg handler functions in place");
+WEBRTC_DEFINE_int(crt_break_alloc, -1, "memory allocation to break on");
+WEBRTC_DEFINE_bool(
+    default_error_handlers,
+    false,
+    "leave the default exception/dbg handler functions in place");
 
 void TestInvalidParameterHandler(const wchar_t* expression,
                                  const wchar_t* function,
@@ -116,7 +117,7 @@
 
   // Initialize SSL which are used by several tests.
   rtc::InitializeSSL();
-  rtc::SSLStreamAdapter::enable_time_callback_for_testing();
+  rtc::SSLStreamAdapter::EnableTimeCallbackForTesting();
 
 #if defined(WEBRTC_IOS)
   rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv, false);
@@ -136,5 +137,13 @@
     _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestCrtReportHandler);
 #endif
 
+#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) ||  \
+    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
+    defined(UNDEFINED_SANITIZER)
+  // We want the test flagged as failed only for sanitizer defects,
+  // in which case the sanitizer will override exit code with 66.
+  return 0;
+#endif
+
   return res;
 }
diff --git a/rtc_base/unixfilesystem.cc b/rtc_base/unixfilesystem.cc
deleted file mode 100644
index 818cb8a..0000000
--- a/rtc_base/unixfilesystem.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  Copyright 2004 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 "rtc_base/unixfilesystem.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
-#include <CoreServices/CoreServices.h>
-#include <IOKit/IOCFBundle.h>
-#include <sys/statvfs.h>
-#include "rtc_base/macutils.h"
-#endif  // WEBRTC_MAC && !defined(WEBRTC_IOS)
-
-#if defined(WEBRTC_POSIX) && !defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
-#include <sys/types.h>
-#if defined(WEBRTC_ANDROID)
-#include <sys/statfs.h>
-#elif !defined(__native_client__)
-#include <sys/statvfs.h>
-#endif  //  !defined(__native_client__)
-#include <limits.h>
-#include <pwd.h>
-#include <stdio.h>
-#endif  // WEBRTC_POSIX && !WEBRTC_MAC || WEBRTC_IOS
-
-#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
-#include <ctype.h>
-#include <algorithm>
-#endif
-
-#if defined(__native_client__) && !defined(__GLIBC__)
-#include <sys/syslimits.h>
-#endif
-
-#include "rtc_base/arraysize.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/fileutils.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/pathutils.h"
-#include "rtc_base/stream.h"
-#include "rtc_base/stringutils.h"
-
-namespace rtc {
-
-UnixFilesystem::UnixFilesystem() {}
-
-UnixFilesystem::~UnixFilesystem() {}
-
-bool UnixFilesystem::DeleteFile(const Pathname& filename) {
-  RTC_LOG(LS_INFO) << "Deleting file:" << filename.pathname();
-
-  if (!IsFile(filename)) {
-    RTC_DCHECK(IsFile(filename));
-    return false;
-  }
-  return ::unlink(filename.pathname().c_str()) == 0;
-}
-
-bool UnixFilesystem::MoveFile(const Pathname& old_path,
-                              const Pathname& new_path) {
-  if (!IsFile(old_path)) {
-    RTC_DCHECK(IsFile(old_path));
-    return false;
-  }
-  RTC_LOG(LS_VERBOSE) << "Moving " << old_path.pathname() << " to "
-                      << new_path.pathname();
-  if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) {
-    return false;
-  }
-  return true;
-}
-
-bool UnixFilesystem::IsFolder(const Pathname& path) {
-  struct stat st;
-  if (stat(path.pathname().c_str(), &st) < 0)
-    return false;
-  return S_ISDIR(st.st_mode);
-}
-
-bool UnixFilesystem::IsFile(const Pathname& pathname) {
-  struct stat st;
-  int res = ::stat(pathname.pathname().c_str(), &st);
-  // Treat symlinks, named pipes, etc. all as files.
-  return res == 0 && !S_ISDIR(st.st_mode);
-}
-
-bool UnixFilesystem::GetFileSize(const Pathname& pathname, size_t* size) {
-  struct stat st;
-  if (::stat(pathname.pathname().c_str(), &st) != 0)
-    return false;
-  *size = st.st_size;
-  return true;
-}
-
-}  // namespace rtc
-
-#if defined(__native_client__)
-extern "C" int __attribute__((weak))
-link(const char* oldpath, const char* newpath) {
-  errno = EACCES;
-  return -1;
-}
-#endif
diff --git a/rtc_base/unixfilesystem.h b/rtc_base/unixfilesystem.h
deleted file mode 100644
index 711d7b3..0000000
--- a/rtc_base/unixfilesystem.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Copyright 2004 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 RTC_BASE_UNIXFILESYSTEM_H_
-#define RTC_BASE_UNIXFILESYSTEM_H_
-
-#include <sys/types.h>
-
-#include "rtc_base/fileutils.h"
-
-namespace rtc {
-
-class UnixFilesystem : public FilesystemInterface {
- public:
-  UnixFilesystem();
-  ~UnixFilesystem() override;
-
-  // This will attempt to delete the file located at filename.
-  // It will fail with VERIY if you pass it a non-existant file, or a directory.
-  bool DeleteFile(const Pathname& filename) override;
-
-  // This moves a file from old_path to new_path, where "file" can be a plain
-  // file or directory, which will be moved recursively.
-  // Returns true if function succeeds.
-  bool MoveFile(const Pathname& old_path, const Pathname& new_path) override;
-
-  // Returns true if a pathname is a directory
-  bool IsFolder(const Pathname& pathname) override;
-
-  // Returns true of pathname represents an existing file
-  bool IsFile(const Pathname& pathname) override;
-
-  bool GetFileSize(const Pathname& path, size_t* size) override;
-};
-
-}  // namespace rtc
-
-#endif  // RTC_BASE_UNIXFILESYSTEM_H_
diff --git a/rtc_base/virtualsocket_unittest.cc b/rtc_base/virtualsocket_unittest.cc
index d2bff54..d44f46a 100644
--- a/rtc_base/virtualsocket_unittest.cc
+++ b/rtc_base/virtualsocket_unittest.cc
@@ -104,7 +104,7 @@
                     const char* data,
                     size_t size,
                     const SocketAddress& remote_addr,
-                    const PacketTime& packet_time) {
+                    const int64_t& /* packet_time_us */) {
     ASSERT_EQ(socket.get(), s);
     ASSERT_GE(size, 4U);
 
diff --git a/rtc_base/virtualsocketserver.cc b/rtc_base/virtualsocketserver.cc
index 53dad46..7969411 100644
--- a/rtc_base/virtualsocketserver.cc
+++ b/rtc_base/virtualsocketserver.cc
@@ -525,7 +525,6 @@
 
 VirtualSocketServer::VirtualSocketServer(FakeClock* fake_clock)
     : fake_clock_(fake_clock),
-      wakeup_(/*manual_reset=*/false, /*initially_signaled=*/false),
       msg_queue_(nullptr),
       stop_on_idle_(false),
       next_ipv4_(kInitialNextIPv4),
diff --git a/rtc_base/weak_ptr_unittest.cc b/rtc_base/weak_ptr_unittest.cc
index 9541718..66f2b4d 100644
--- a/rtc_base/weak_ptr_unittest.cc
+++ b/rtc_base/weak_ptr_unittest.cc
@@ -202,7 +202,7 @@
 std::unique_ptr<T> NewObjectCreatedOnTaskQueue() {
   std::unique_ptr<T> obj;
   TaskQueue queue("NewObjectCreatedOnTaskQueue");
-  Event event(false, false);
+  Event event;
   queue.PostTask([&event, &obj] {
     obj.reset(new T());
     event.Set();
@@ -229,7 +229,7 @@
   // Create weak ptr on main thread
   WeakPtr<Target> weak_ptr = target->factory.GetWeakPtr();
   rtc::TaskQueue queue("queue");
-  rtc::Event done(false, false);
+  rtc::Event done;
   queue.PostTask([&] {
     // Dereference and invalide weak_ptr on another thread.
     EXPECT_EQ(weak_ptr.get(), target.get());
diff --git a/rtc_base/win32.cc b/rtc_base/win32.cc
index d81d685..e3482e3 100644
--- a/rtc_base/win32.cc
+++ b/rtc_base/win32.cc
@@ -72,9 +72,9 @@
   }
   const struct in_addr* as_in_addr =
       reinterpret_cast<const struct in_addr*>(src);
-  rtc::sprintfn(dst, size, "%d.%d.%d.%d", as_in_addr->S_un.S_un_b.s_b1,
-                as_in_addr->S_un.S_un_b.s_b2, as_in_addr->S_un.S_un_b.s_b3,
-                as_in_addr->S_un.S_un_b.s_b4);
+  snprintf(dst, size, "%d.%d.%d.%d", as_in_addr->S_un.S_un_b.s_b1,
+           as_in_addr->S_un.S_un_b.s_b2, as_in_addr->S_un.S_un_b.s_b3,
+           as_in_addr->S_un.S_un_b.s_b4);
   return dst;
 }
 
@@ -127,7 +127,7 @@
     *cursor++ = ':';
     *cursor++ = ':';
     if (maxpos == 4) {
-      cursor += rtc::sprintfn(cursor, INET6_ADDRSTRLEN - 2, "ffff:");
+      cursor += snprintf(cursor, INET6_ADDRSTRLEN - 2, "ffff:");
     }
     const struct in_addr* as_v4 =
         reinterpret_cast<const struct in_addr*>(&(as_shorts[6]));
@@ -136,8 +136,8 @@
   } else {
     for (int i = 0; i < run_array_size; ++i) {
       if (runpos[i] == -1) {
-        cursor += rtc::sprintfn(cursor, INET6_ADDRSTRLEN - (cursor - dst), "%x",
-                                NetworkToHost16(as_shorts[i]));
+        cursor += snprintf(cursor, INET6_ADDRSTRLEN - (cursor - dst), "%x",
+                           NetworkToHost16(as_shorts[i]));
         if (i != 7 && runpos[i + 1] != 1) {
           *cursor++ = ':';
         }
@@ -224,8 +224,8 @@
       *(readcursor + 2) != 0) {
     // Check for periods, which we'll take as a sign of v4 addresses.
     const char* addrstart = readcursor + 2;
-    if (rtc::strchr(addrstart, ".")) {
-      const char* colon = rtc::strchr(addrstart, "::");
+    if (strchr(addrstart, '.')) {
+      const char* colon = strchr(addrstart, ':');
       if (colon) {
         uint16_t a_short;
         int bytesread = 0;
diff --git a/rtc_base/win32filesystem.cc b/rtc_base/win32filesystem.cc
deleted file mode 100644
index cd43966..0000000
--- a/rtc_base/win32filesystem.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  Copyright 2004 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 "rtc_base/win32filesystem.h"
-
-#include <shellapi.h>
-#include <shlobj.h>
-#include <tchar.h>
-#include "rtc_base/win32.h"
-
-#include <memory>
-
-#include "rtc_base/arraysize.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/fileutils.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/pathutils.h"
-#include "rtc_base/stream.h"
-#include "rtc_base/stringutils.h"
-
-// In several places in this file, we test the integrity level of the process
-// before calling GetLongPathName. We do this because calling GetLongPathName
-// when running under protected mode IE (a low integrity process) can result in
-// a virtualized path being returned, which is wrong if you only plan to read.
-// TODO: Waiting to hear back from IE team on whether this is the
-// best approach; IEIsProtectedModeProcess is another possible solution.
-
-namespace rtc {
-
-bool Win32Filesystem::DeleteFile(const Pathname& filename) {
-  RTC_LOG(LS_INFO) << "Deleting file " << filename.pathname();
-  if (!IsFile(filename)) {
-    RTC_DCHECK(IsFile(filename));
-    return false;
-  }
-  return ::DeleteFile(ToUtf16(filename.pathname()).c_str()) != 0;
-}
-
-bool Win32Filesystem::MoveFile(const Pathname& old_path,
-                               const Pathname& new_path) {
-  if (!IsFile(old_path)) {
-    RTC_DCHECK(IsFile(old_path));
-    return false;
-  }
-  RTC_LOG(LS_INFO) << "Moving " << old_path.pathname() << " to "
-                   << new_path.pathname();
-  return ::MoveFile(ToUtf16(old_path.pathname()).c_str(),
-                    ToUtf16(new_path.pathname()).c_str()) != 0;
-}
-
-bool Win32Filesystem::IsFolder(const Pathname& path) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(),
-                                 GetFileExInfoStandard, &data))
-    return false;
-  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
-         FILE_ATTRIBUTE_DIRECTORY;
-}
-
-bool Win32Filesystem::IsFile(const Pathname& path) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(),
-                                 GetFileExInfoStandard, &data))
-    return false;
-  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
-}
-
-bool Win32Filesystem::GetFileSize(const Pathname& pathname, size_t* size) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (::GetFileAttributesEx(ToUtf16(pathname.pathname()).c_str(),
-                            GetFileExInfoStandard, &data) == 0)
-    return false;
-  *size = data.nFileSizeLow;
-  return true;
-}
-
-}  // namespace rtc
diff --git a/rtc_base/win32filesystem.h b/rtc_base/win32filesystem.h
deleted file mode 100644
index d26741e..0000000
--- a/rtc_base/win32filesystem.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Copyright 2004 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 RTC_BASE_WIN32FILESYSTEM_H_
-#define RTC_BASE_WIN32FILESYSTEM_H_
-
-#include "fileutils.h"
-
-namespace rtc {
-
-class Win32Filesystem : public FilesystemInterface {
- public:
-  // This will attempt to delete the path located at filename.
-  // If the path points to a folder, it will fail with VERIFY
-  bool DeleteFile(const Pathname& filename) override;
-
-  // This moves a file from old_path to new_path. If the new path is on a
-  // different volume than the old, it will attempt to copy and then delete
-  // the folder
-  // Returns true if the file is successfully moved
-  bool MoveFile(const Pathname& old_path, const Pathname& new_path) override;
-
-  // Returns true if a pathname is a directory
-  bool IsFolder(const Pathname& pathname) override;
-
-  // Returns true if a file exists at path
-  bool IsFile(const Pathname& path) override;
-
-  bool GetFileSize(const Pathname& path, size_t* size) override;
-};
-
-}  // namespace rtc
-
-#endif  // RTC_BASE_WIN32FILESYSTEM_H_
diff --git a/rtc_base/zero_memory.h b/rtc_base/zero_memory.h
index cb4646c..f697bcb 100644
--- a/rtc_base/zero_memory.h
+++ b/rtc_base/zero_memory.h
@@ -11,6 +11,7 @@
 #ifndef RTC_BASE_ZERO_MEMORY_H_
 #define RTC_BASE_ZERO_MEMORY_H_
 
+#include <stddef.h>
 #include <type_traits>
 
 #include "api/array_view.h"
diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn
index eb60052..143a347 100644
--- a/system_wrappers/BUILD.gn
+++ b/system_wrappers/BUILD.gn
@@ -105,6 +105,16 @@
   if (rtc_exclude_field_trial_default) {
     defines = [ "WEBRTC_EXCLUDE_FIELD_TRIAL_DEFAULT" ]
   }
+  if (build_with_chromium) {
+    # When WebRTC is built as part of Chromium it should exclude the default
+    # implementation of field_trial unless it is building for NACL or
+    # Chromecast.
+    if (!is_nacl && !is_chromecast) {
+      deps = [
+        "../../webrtc_overrides:field_trial",
+      ]
+    }
+  }
 }
 
 rtc_source_set("metrics") {
@@ -123,6 +133,9 @@
     "../rtc_base:checks",
     "../rtc_base:rtc_base_approved",
   ]
+  if (build_with_chromium) {
+    deps += [ "../../webrtc_overrides:metrics" ]
+  }
 }
 
 if (is_android && !build_with_mozilla) {
@@ -166,6 +179,7 @@
       "..:webrtc_common",
       "../rtc_base:rtc_base_approved",
       "../test:test_main",
+      "../test:test_support",
       "//testing/gtest",
     ]
 
diff --git a/system_wrappers/OWNERS b/system_wrappers/OWNERS
index 13b08a3..a08f611 100644
--- a/system_wrappers/OWNERS
+++ b/system_wrappers/OWNERS
@@ -2,7 +2,6 @@
 mflodman@webrtc.org
 niklas.enbom@webrtc.org
 nisse@webrtc.org
-perkj@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/system_wrappers/include/clock.h b/system_wrappers/include/clock.h
index 4b6eab8..f1fc11f 100644
--- a/system_wrappers/include/clock.h
+++ b/system_wrappers/include/clock.h
@@ -11,6 +11,7 @@
 #ifndef SYSTEM_WRAPPERS_INCLUDE_CLOCK_H_
 #define SYSTEM_WRAPPERS_INCLUDE_CLOCK_H_
 
+#include <stdint.h>
 #include <memory>
 
 #include "rtc_base/synchronization/rw_lock_wrapper.h"
diff --git a/system_wrappers/include/event_wrapper.h b/system_wrappers/include/event_wrapper.h
index 0531ddb..989e792 100644
--- a/system_wrappers/include/event_wrapper.h
+++ b/system_wrappers/include/event_wrapper.h
@@ -12,11 +12,7 @@
 #define SYSTEM_WRAPPERS_INCLUDE_EVENT_WRAPPER_H_
 
 namespace webrtc {
-enum EventTypeWrapper {
-  kEventSignaled = 1,
-  kEventError = 2,
-  kEventTimeout = 3
-};
+enum EventTypeWrapper { kEventSignaled = 1, kEventTimeout = 2 };
 
 #define WEBRTC_EVENT_INFINITE 0xffffffff
 
diff --git a/system_wrappers/include/rtp_to_ntp_estimator.h b/system_wrappers/include/rtp_to_ntp_estimator.h
index d7009d8..51da4d2 100644
--- a/system_wrappers/include/rtp_to_ntp_estimator.h
+++ b/system_wrappers/include/rtp_to_ntp_estimator.h
@@ -11,10 +11,12 @@
 #ifndef SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_
 #define SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_
 
+#include <stdint.h>
 #include <list>
 
 #include "absl/types/optional.h"
 #include "modules/include/module_common_types_public.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/numerics/moving_median_filter.h"
 #include "system_wrappers/include/ntp_time.h"
 
diff --git a/system_wrappers/source/clock.cc b/system_wrappers/source/clock.cc
index 35ab5f0..4f5d9cf 100644
--- a/system_wrappers/source/clock.cc
+++ b/system_wrappers/source/clock.cc
@@ -17,6 +17,8 @@
 
 #include <mmsystem.h>
 
+#include "rtc_base/criticalsection.h"
+
 #elif defined(WEBRTC_POSIX)
 
 #include <sys/time.h>
@@ -24,7 +26,6 @@
 
 #endif  // defined(WEBRTC_POSIX)
 
-#include "rtc_base/criticalsection.h"
 #include "rtc_base/synchronization/rw_lock_wrapper.h"
 #include "rtc_base/timeutils.h"
 
diff --git a/system_wrappers/source/event.cc b/system_wrappers/source/event.cc
index d1d2cda..0c4ce10 100644
--- a/system_wrappers/source/event.cc
+++ b/system_wrappers/source/event.cc
@@ -14,9 +14,6 @@
 #include <windows.h>
 #elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
 #include <ApplicationServices/ApplicationServices.h>
-#include <pthread.h>
-#else
-#include <pthread.h>
 #endif
 
 #include "rtc_base/event.h"
@@ -25,7 +22,6 @@
 
 class EventWrapperImpl : public EventWrapper {
  public:
-  EventWrapperImpl() : event_(false, false) {}
   ~EventWrapperImpl() override {}
 
   bool Set() override {
diff --git a/system_wrappers/source/field_trial.cc b/system_wrappers/source/field_trial.cc
index 60158f4..ac71311 100644
--- a/system_wrappers/source/field_trial.cc
+++ b/system_wrappers/source/field_trial.cc
@@ -9,6 +9,7 @@
 
 #include "system_wrappers/include/field_trial.h"
 
+#include <stddef.h>
 #include <string>
 
 // Simple field trial implementation, which allows client to
diff --git a/system_wrappers/source/rtp_to_ntp_estimator.cc b/system_wrappers/source/rtp_to_ntp_estimator.cc
index 730c4f6..aaef4b1 100644
--- a/system_wrappers/source/rtp_to_ntp_estimator.cc
+++ b/system_wrappers/source/rtp_to_ntp_estimator.cc
@@ -10,9 +10,10 @@
 
 #include "system_wrappers/include/rtp_to_ntp_estimator.h"
 
+#include <stddef.h>
+
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
-#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 namespace {