Move NetEq headers to api/

This CL also introduces NetEqFactory and NetEqControllerFactory
interfaces, as well as several convenience classes for working with
them: DefaultNetEqFactory, DefaultNetEqControllerFactory and
CustomNetEqFactory.

Bug: webrtc:11005
Change-Id: I1e8fc5154636ac2aad1a856828f80a2a758ad392
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156945
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29671}
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 2cad71c..50d847d 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -48,6 +48,9 @@
     "../../api:function_view",
     "../../api/audio:audio_frame_api",
     "../../api/audio_codecs:audio_codecs_api",
+    "../../api/neteq:custom_neteq_factory",
+    "../../api/neteq:default_neteq_controller_factory",
+    "../../api/neteq:neteq_api",
     "../../common_audio",
     "../../common_audio:common_audio_c",
     "../../rtc_base:audio_format_to_string",
@@ -944,7 +947,6 @@
     "neteq/decision_logic.h",
     "neteq/decoder_database.cc",
     "neteq/decoder_database.h",
-    "neteq/defines.h",
     "neteq/delay_manager.cc",
     "neteq/delay_manager.h",
     "neteq/delay_peak_detector.cc",
@@ -961,13 +963,10 @@
     "neteq/expand_uma_logger.h",
     "neteq/histogram.cc",
     "neteq/histogram.h",
-    "neteq/include/neteq.h",
     "neteq/merge.cc",
     "neteq/merge.h",
     "neteq/nack_tracker.cc",
     "neteq/nack_tracker.h",
-    "neteq/neteq.cc",
-    "neteq/neteq_controller.h",
     "neteq/neteq_impl.cc",
     "neteq/neteq_impl.h",
     "neteq/normal.cc",
@@ -988,8 +987,6 @@
     "neteq/statistics_calculator.h",
     "neteq/sync_buffer.cc",
     "neteq/sync_buffer.h",
-    "neteq/tick_timer.cc",
-    "neteq/tick_timer.h",
     "neteq/time_stretch.cc",
     "neteq/time_stretch.h",
     "neteq/timestamp_scaler.cc",
@@ -1007,6 +1004,9 @@
     "../../api:scoped_refptr",
     "../../api/audio:audio_frame_api",
     "../../api/audio_codecs:audio_codecs_api",
+    "../../api/neteq:neteq_api",
+    "../../api/neteq:neteq_controller_api",
+    "../../api/neteq:tick_timer",
     "../../common_audio",
     "../../common_audio:common_audio_c",
     "../../rtc_base:audio_format_to_string",
@@ -1052,6 +1052,9 @@
     "../../api:rtp_headers",
     "../../api/audio:audio_frame_api",
     "../../api/audio_codecs:audio_codecs_api",
+    "../../api/neteq:custom_neteq_factory",
+    "../../api/neteq:default_neteq_controller_factory",
+    "../../api/neteq:neteq_api",
     "../../rtc_base:checks",
     "../../rtc_base:rtc_base_approved",
     "../../system_wrappers",
@@ -1467,6 +1470,7 @@
         ":neteq",
         ":neteq_test_tools",
         "../../api/audio_codecs:builtin_audio_decoder_factory",
+        "../../api/neteq:neteq_api",
         "../../rtc_base:rtc_base_approved",
         "../../test:audio_codec_mocks",
         "../../test:field_trial",
@@ -1558,9 +1562,11 @@
       ":neteq",
       ":neteq_test_tools",
       ":pcm16b",
+      "../../api:neteq_factory_with_codecs",
       "../../api/audio:audio_frame_api",
       "../../api/audio_codecs:audio_codecs_api",
       "../../api/audio_codecs:builtin_audio_decoder_factory",
+      "../../api/neteq:neteq_api",
       "../../rtc_base:checks",
       "../../rtc_base:rtc_base_approved",
       "../../system_wrappers",
@@ -1581,6 +1587,9 @@
       ":neteq",
       ":neteq_test_tools",
       "../../api/audio_codecs:builtin_audio_decoder_factory",
+      "../../api/neteq:custom_neteq_factory",
+      "../../api/neteq:default_neteq_controller_factory",
+      "../../api/neteq:neteq_api",
       "../../rtc_base:checks",
       "../../system_wrappers",
       "../../test:fileutils",
@@ -1976,7 +1985,6 @@
       "neteq/red_payload_splitter_unittest.cc",
       "neteq/statistics_calculator_unittest.cc",
       "neteq/sync_buffer_unittest.cc",
-      "neteq/tick_timer_unittest.cc",
       "neteq/time_stretch_unittest.cc",
       "neteq/timestamp_scaler_unittest.cc",
       "neteq/tools/input_audio_file_unittest.cc",
@@ -2007,6 +2015,7 @@
       ":webrtc_opus",
       "..:module_api",
       "..:module_api_public",
+      "../../api:neteq_factory_with_codecs",
       "../../api/audio:audio_frame_api",
       "../../api/audio_codecs:audio_codecs_api",
       "../../api/audio_codecs:builtin_audio_decoder_factory",
@@ -2015,6 +2024,12 @@
       "../../api/audio_codecs/opus:audio_decoder_opus",
       "../../api/audio_codecs/opus:audio_encoder_multiopus",
       "../../api/audio_codecs/opus:audio_encoder_opus",
+      "../../api/neteq:custom_neteq_factory",
+      "../../api/neteq:default_neteq_controller_factory",
+      "../../api/neteq:neteq_api",
+      "../../api/neteq:neteq_controller_api",
+      "../../api/neteq:tick_timer",
+      "../../api/neteq:tick_timer_unittest",
       "../../api/rtc_event_log",
       "../../common_audio",
       "../../common_audio:common_audio_c",
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index 4019615..2723937 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -19,9 +19,11 @@
 #include "absl/strings/match.h"
 #include "api/audio/audio_frame.h"
 #include "api/audio_codecs/audio_decoder.h"
+#include "api/neteq/custom_neteq_factory.h"
+#include "api/neteq/default_neteq_controller_factory.h"
+#include "api/neteq/neteq.h"
 #include "modules/audio_coding/acm2/acm_resampler.h"
 #include "modules/audio_coding/acm2/call_statistics.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
@@ -32,11 +34,24 @@
 
 namespace acm2 {
 
+namespace {
+
+std::unique_ptr<NetEq> CreateNetEq(
+    const NetEq::Config& config,
+    Clock* clock,
+    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
+  CustomNetEqFactory neteq_factory(
+      decoder_factory, std::make_unique<DefaultNetEqControllerFactory>());
+  return neteq_factory.CreateNetEq(config, clock);
+}
+
+}  // namespace
+
 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config)
     : last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
-      neteq_(NetEq::Create(config.neteq_config,
-                           config.clock,
-                           config.decoder_factory)),
+      neteq_(CreateNetEq(config.neteq_config,
+                         config.clock,
+                         config.decoder_factory)),
       clock_(config.clock),
       resampled_last_output_frame_(true) {
   RTC_DCHECK(clock_);
diff --git a/modules/audio_coding/include/audio_coding_module.h b/modules/audio_coding/include/audio_coding_module.h
index da8ffb5..05d9380 100644
--- a/modules/audio_coding/include/audio_coding_module.h
+++ b/modules/audio_coding/include/audio_coding_module.h
@@ -20,8 +20,8 @@
 #include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/audio_codecs/audio_encoder.h"
 #include "api/function_view.h"
+#include "api/neteq/neteq.h"
 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "system_wrappers/include/clock.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc
index 1c887b1..5c746ad 100644
--- a/modules/audio_coding/neteq/decision_logic.cc
+++ b/modules/audio_coding/neteq/decision_logic.cc
@@ -91,42 +91,43 @@
   output_size_samples_ = output_size_samples;
 }
 
-Operations DecisionLogic::GetDecision(const NetEqStatus& status,
-                                      bool* reset_decoder) {
+NetEq::Operation DecisionLogic::GetDecision(const NetEqStatus& status,
+                                            bool* reset_decoder) {
   // If last mode was CNG (or Expand, since this could be covering up for
   // a lost CNG packet), remember that CNG is on. This is needed if comfort
   // noise is interrupted by DTMF.
-  if (status.last_mode == kModeRfc3389Cng) {
+  if (status.last_mode == NetEq::Mode::kRfc3389Cng) {
     cng_state_ = kCngRfc3389On;
-  } else if (status.last_mode == kModeCodecInternalCng) {
+  } else if (status.last_mode == NetEq::Mode::kCodecInternalCng) {
     cng_state_ = kCngInternalOn;
   }
 
   size_t cur_size_samples = estimate_dtx_delay_
                                 ? status.packet_buffer_info.span_samples
                                 : status.packet_buffer_info.num_samples;
-
   prev_time_scale_ =
-      prev_time_scale_ && (status.last_mode == kModeAccelerateSuccess ||
-                           status.last_mode == kModeAccelerateLowEnergy ||
-                           status.last_mode == kModePreemptiveExpandSuccess ||
-                           status.last_mode == kModePreemptiveExpandLowEnergy);
+      prev_time_scale_ &&
+      (status.last_mode == NetEq::Mode::kAccelerateSuccess ||
+       status.last_mode == NetEq::Mode::kAccelerateLowEnergy ||
+       status.last_mode == NetEq::Mode::kPreemptiveExpandSuccess ||
+       status.last_mode == NetEq::Mode::kPreemptiveExpandLowEnergy);
 
   // Do not update buffer history if currently playing CNG since it will bias
   // the filtered buffer level.
-  if (status.last_mode != kModeRfc3389Cng &&
-      status.last_mode != kModeCodecInternalCng &&
+  if (status.last_mode != NetEq::Mode::kRfc3389Cng &&
+      status.last_mode != NetEq::Mode::kCodecInternalCng &&
       !(status.next_packet && status.next_packet->is_dtx &&
         !estimate_dtx_delay_)) {
     FilterBufferLevel(cur_size_samples);
   }
 
   // Guard for errors, to avoid getting stuck in error mode.
-  if (status.last_mode == kModeError) {
+  if (status.last_mode == NetEq::Mode::kError) {
     if (!status.next_packet) {
-      return kExpand;
+      return NetEq::Operation::kExpand;
     } else {
-      return kUndefined;  // Use kUndefined to flag for a reset.
+      // Use kUndefined to flag for a reset.
+      return NetEq::Operation::kUndefined;
     }
   }
 
@@ -145,7 +146,7 @@
   // sender was restarted.
   if (num_consecutive_expands_ > kReinitAfterExpands) {
     *reset_decoder = true;
-    return kNormal;
+    return NetEq::Operation::kNormal;
   }
 
   // Make sure we don't restart audio too soon after an expansion to avoid
@@ -158,13 +159,14 @@
   const size_t current_span =
       estimate_dtx_delay_ ? status.packet_buffer_info.span_samples
                           : status.packet_buffer_info.span_samples_no_dtx;
-  if ((status.last_mode == kModeExpand || status.last_mode == kModeCodecPlc) &&
+  if ((status.last_mode == NetEq::Mode::kExpand ||
+       status.last_mode == NetEq::Mode::kCodecPlc) &&
       status.expand_mutefactor < 16384 / 2 &&
       current_span<static_cast<size_t>(delay_manager_->TargetLevel() *
                                        packet_length_samples_ *
                                        kPostponeDecodingLevel / 100)>> 8 &&
       !status.packet_buffer_info.dtx_or_cng) {
-    return kExpand;
+    return NetEq::Operation::kExpand;
   }
 
   const uint32_t five_seconds_samples = static_cast<uint32_t>(5 * sample_rate_);
@@ -182,12 +184,12 @@
   } else {
     // This implies that available_timestamp < target_timestamp, which can
     // happen when a new stream or codec is received. Signal for a reset.
-    return kUndefined;
+    return NetEq::Operation::kUndefined;
   }
 }
 
-void DecisionLogic::ExpandDecision(Operations operation) {
-  if (operation == kExpand) {
+void DecisionLogic::ExpandDecision(NetEq::Operation operation) {
+  if (operation == NetEq::Operation::kExpand) {
     num_consecutive_expands_++;
   } else {
     num_consecutive_expands_ = 0;
@@ -241,10 +243,10 @@
   time_stretched_cn_samples_ = 0;
 }
 
-Operations DecisionLogic::CngOperation(Modes prev_mode,
-                                       uint32_t target_timestamp,
-                                       uint32_t available_timestamp,
-                                       size_t generated_noise_samples) {
+NetEq::Operation DecisionLogic::CngOperation(NetEq::Mode prev_mode,
+                                             uint32_t target_timestamp,
+                                             uint32_t available_timestamp,
+                                             size_t generated_noise_samples) {
   // Signed difference between target and available timestamp.
   int32_t timestamp_diff = static_cast<int32_t>(
       static_cast<uint32_t>(generated_noise_samples + target_timestamp) -
@@ -264,35 +266,36 @@
         rtc::saturated_cast<int32_t>(timestamp_diff + excess_waiting_time_samp);
   }
 
-  if (timestamp_diff < 0 && prev_mode == kModeRfc3389Cng) {
+  if (timestamp_diff < 0 && prev_mode == NetEq::Mode::kRfc3389Cng) {
     // Not time to play this packet yet. Wait another round before using this
     // packet. Keep on playing CNG from previous CNG parameters.
-    return kRfc3389CngNoPacket;
+    return NetEq::Operation::kRfc3389CngNoPacket;
   } else {
     // Otherwise, go for the CNG packet now.
     noise_fast_forward_ = 0;
-    return kRfc3389Cng;
+    return NetEq::Operation::kRfc3389Cng;
   }
 }
 
-Operations DecisionLogic::NoPacket(bool play_dtmf) {
+NetEq::Operation DecisionLogic::NoPacket(bool play_dtmf) {
   if (cng_state_ == kCngRfc3389On) {
     // Keep on playing comfort noise.
-    return kRfc3389CngNoPacket;
+    return NetEq::Operation::kRfc3389CngNoPacket;
   } else if (cng_state_ == kCngInternalOn) {
     // Keep on playing codec internal comfort noise.
-    return kCodecInternalCng;
+    return NetEq::Operation::kCodecInternalCng;
   } else if (play_dtmf) {
-    return kDtmf;
+    return NetEq::Operation::kDtmf;
   } else {
     // Nothing to play, do expand.
-    return kExpand;
+    return NetEq::Operation::kExpand;
   }
 }
 
-Operations DecisionLogic::ExpectedPacketAvailable(Modes prev_mode,
-                                                  bool play_dtmf) {
-  if (!disallow_time_stretching_ && prev_mode != kModeExpand && !play_dtmf) {
+NetEq::Operation DecisionLogic::ExpectedPacketAvailable(NetEq::Mode prev_mode,
+                                                        bool play_dtmf) {
+  if (!disallow_time_stretching_ && prev_mode != NetEq::Mode::kExpand &&
+      !play_dtmf) {
     // Check criterion for time-stretching. The values are in number of packets
     // in Q8.
     int low_limit, high_limit;
@@ -304,20 +307,20 @@
           packet_length_samples_;
     }
     if (buffer_level_packets >= high_limit << 2)
-      return kFastAccelerate;
+      return NetEq::Operation::kFastAccelerate;
     if (TimescaleAllowed()) {
       if (buffer_level_packets >= high_limit)
-        return kAccelerate;
+        return NetEq::Operation::kAccelerate;
       if (buffer_level_packets < low_limit)
-        return kPreemptiveExpand;
+        return NetEq::Operation::kPreemptiveExpand;
     }
   }
-  return kNormal;
+  return NetEq::Operation::kNormal;
 }
 
-Operations DecisionLogic::FuturePacketAvailable(
+NetEq::Operation DecisionLogic::FuturePacketAvailable(
     size_t decoder_frame_length,
-    Modes prev_mode,
+    NetEq::Mode prev_mode,
     uint32_t target_timestamp,
     uint32_t available_timestamp,
     bool play_dtmf,
@@ -328,24 +331,26 @@
   // Check if we should continue with an ongoing expand because the new packet
   // is too far into the future.
   uint32_t timestamp_leap = available_timestamp - target_timestamp;
-  if ((prev_mode == kModeExpand || prev_mode == kModeCodecPlc) &&
+  if ((prev_mode == NetEq::Mode::kExpand ||
+       prev_mode == NetEq::Mode::kCodecPlc) &&
       !ReinitAfterExpands(timestamp_leap) && !MaxWaitForPacket() &&
       PacketTooEarly(timestamp_leap) && UnderTargetLevel()) {
     if (play_dtmf) {
       // Still have DTMF to play, so do not do expand.
-      return kDtmf;
+      return NetEq::Operation::kDtmf;
     } else {
       // Nothing to play.
-      return kExpand;
+      return NetEq::Operation::kExpand;
     }
   }
 
-  if (prev_mode == kModeCodecPlc) {
-    return kNormal;
+  if (prev_mode == NetEq::Mode::kCodecPlc) {
+    return NetEq::Operation::kNormal;
   }
 
   // If previous was comfort noise, then no merge is needed.
-  if (prev_mode == kModeRfc3389Cng || prev_mode == kModeCodecInternalCng) {
+  if (prev_mode == NetEq::Mode::kRfc3389Cng ||
+      prev_mode == NetEq::Mode::kCodecInternalCng) {
     size_t cur_size_samples =
         estimate_dtx_delay_
             ? cur_size_samples = span_samples_in_packet_buffer
@@ -370,7 +375,7 @@
       if ((generated_enough_noise && !below_target_window) ||
           above_target_window) {
         time_stretched_cn_samples_ = timestamp_leap - generated_noise_samples;
-        return kNormal;
+        return NetEq::Operation::kNormal;
       }
     } else {
       // Keep the same delay as before the CNG, but make sure that the number of
@@ -378,26 +383,26 @@
       if (generated_enough_noise ||
           cur_size_samples > target_level_samples * 4) {
         // Time to play this new packet.
-        return kNormal;
+        return NetEq::Operation::kNormal;
       }
     }
 
     // Too early to play this new packet; keep on playing comfort noise.
-    if (prev_mode == kModeRfc3389Cng) {
-      return kRfc3389CngNoPacket;
+    if (prev_mode == NetEq::Mode::kRfc3389Cng) {
+      return NetEq::Operation::kRfc3389CngNoPacket;
     }
     // prevPlayMode == kModeCodecInternalCng.
-    return kCodecInternalCng;
+    return NetEq::Operation::kCodecInternalCng;
   }
 
   // Do not merge unless we have done an expand before.
-  if (prev_mode == kModeExpand) {
-    return kMerge;
+  if (prev_mode == NetEq::Mode::kExpand) {
+    return NetEq::Operation::kMerge;
   } else if (play_dtmf) {
     // Play DTMF instead of expand.
-    return kDtmf;
+    return NetEq::Operation::kDtmf;
   } else {
-    return kExpand;
+    return NetEq::Operation::kExpand;
   }
 }
 
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index f0d7a93..b8dbefe 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -11,12 +11,12 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
 #define MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
 
+#include "api/neteq/neteq.h"
+#include "api/neteq/neteq_controller.h"
+#include "api/neteq/tick_timer.h"
 #include "modules/audio_coding/neteq/buffer_level_filter.h"
-#include "modules/audio_coding/neteq/defines.h"
 #include "modules/audio_coding/neteq/delay_manager.h"
 #include "modules/audio_coding/neteq/delay_peak_detector.h"
-#include "modules/audio_coding/neteq/neteq_controller.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
 #include "rtc_base/constructor_magic.h"
 #include "rtc_base/experiments/field_trial_parser.h"
 
@@ -52,8 +52,8 @@
   // true. The output variable |reset_decoder| will be set to true if a reset is
   // required; otherwise it is left unchanged (i.e., it can remain true if it
   // was true before the call).
-  Operations GetDecision(const NetEqStatus& status,
-                         bool* reset_decoder) override;
+  NetEq::Operation GetDecision(const NetEqController::NetEqStatus& status,
+                               bool* reset_decoder) override;
 
   // These methods test the |cng_state_| for different conditions.
   bool CngRfc3389On() const override { return cng_state_ == kCngRfc3389On; }
@@ -66,7 +66,7 @@
   // not. Note that this is necessary, since an expand decision can be changed
   // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
   // sync buffer.
-  void ExpandDecision(Operations operation) override;
+  void ExpandDecision(NetEq::Operation operation) override;
 
   // Adds |value| to |sample_memory_|.
   void AddSampleMemory(int32_t value) override { sample_memory_ += value; }
@@ -126,28 +126,29 @@
 
   // Returns the operation given that the next available packet is a comfort
   // noise payload (RFC 3389 only, not codec-internal).
-  Operations CngOperation(Modes prev_mode,
-                          uint32_t target_timestamp,
-                          uint32_t available_timestamp,
-                          size_t generated_noise_samples);
+  NetEq::Operation CngOperation(NetEq::Mode prev_mode,
+                                uint32_t target_timestamp,
+                                uint32_t available_timestamp,
+                                size_t generated_noise_samples);
 
   // Returns the operation given that no packets are available (except maybe
   // a DTMF event, flagged by setting |play_dtmf| true).
-  Operations NoPacket(bool play_dtmf);
+  NetEq::Operation NoPacket(bool play_dtmf);
 
   // Returns the operation to do given that the expected packet is available.
-  Operations ExpectedPacketAvailable(Modes prev_mode, bool play_dtmf);
+  NetEq::Operation ExpectedPacketAvailable(NetEq::Mode prev_mode,
+                                           bool play_dtmf);
 
   // Returns the operation to do given that the expected packet is not
   // available, but a packet further into the future is at hand.
-  Operations FuturePacketAvailable(size_t decoder_frame_length,
-                                   Modes prev_mode,
-                                   uint32_t target_timestamp,
-                                   uint32_t available_timestamp,
-                                   bool play_dtmf,
-                                   size_t generated_noise_samples,
-                                   size_t span_samples_in_packet_buffer,
-                                   size_t num_packets_in_packet_buffer);
+  NetEq::Operation FuturePacketAvailable(size_t decoder_frame_length,
+                                         NetEq::Mode prev_mode,
+                                         uint32_t target_timestamp,
+                                         uint32_t available_timestamp,
+                                         bool play_dtmf,
+                                         size_t generated_noise_samples,
+                                         size_t span_samples_in_packet_buffer,
+                                         size_t num_packets_in_packet_buffer);
 
   // Checks if enough time has elapsed since the last successful timescale
   // operation was done (i.e., accelerate or preemptive expand).
diff --git a/modules/audio_coding/neteq/decision_logic_unittest.cc b/modules/audio_coding/neteq/decision_logic_unittest.cc
index 9ba3b9d..d1dd123 100644
--- a/modules/audio_coding/neteq/decision_logic_unittest.cc
+++ b/modules/audio_coding/neteq/decision_logic_unittest.cc
@@ -12,14 +12,14 @@
 
 #include "modules/audio_coding/neteq/decision_logic.h"
 
+#include "api/neteq/neteq_controller.h"
+#include "api/neteq/tick_timer.h"
 #include "modules/audio_coding/neteq/buffer_level_filter.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
 #include "modules/audio_coding/neteq/delay_manager.h"
 #include "modules/audio_coding/neteq/delay_peak_detector.h"
-#include "modules/audio_coding/neteq/neteq_controller.h"
 #include "modules/audio_coding/neteq/packet_buffer.h"
 #include "modules/audio_coding/neteq/statistics_calculator.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
 #include "test/gtest.h"
 #include "test/mock_audio_decoder_factory.h"
 
diff --git a/modules/audio_coding/neteq/defines.h b/modules/audio_coding/neteq/defines.h
deleted file mode 100644
index 46926fa..0000000
--- a/modules/audio_coding/neteq/defines.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Copyright (c) 2012 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_CODING_NETEQ_DEFINES_H_
-#define MODULES_AUDIO_CODING_NETEQ_DEFINES_H_
-
-namespace webrtc {
-
-enum Operations {
-  kNormal = 0,
-  kMerge,
-  kExpand,
-  kAccelerate,
-  kFastAccelerate,
-  kPreemptiveExpand,
-  kRfc3389Cng,
-  kRfc3389CngNoPacket,
-  kCodecInternalCng,
-  kDtmf,
-  kUndefined = -1
-};
-
-enum Modes {
-  kModeNormal = 0,
-  kModeExpand,
-  kModeMerge,
-  kModeAccelerateSuccess,
-  kModeAccelerateLowEnergy,
-  kModeAccelerateFail,
-  kModePreemptiveExpandSuccess,
-  kModePreemptiveExpandLowEnergy,
-  kModePreemptiveExpandFail,
-  kModeRfc3389Cng,
-  kModeCodecInternalCng,
-  kModeCodecPlc,
-  kModeDtmf,
-  kModeError,
-  kModeUndefined = -1
-};
-
-}  // namespace webrtc
-#endif  // MODULES_AUDIO_CODING_NETEQ_DEFINES_H_
diff --git a/modules/audio_coding/neteq/delay_manager.h b/modules/audio_coding/neteq/delay_manager.h
index f1f24ac..c440447 100644
--- a/modules/audio_coding/neteq/delay_manager.h
+++ b/modules/audio_coding/neteq/delay_manager.h
@@ -17,8 +17,8 @@
 #include <memory>
 
 #include "absl/types/optional.h"
+#include "api/neteq/tick_timer.h"
 #include "modules/audio_coding/neteq/histogram.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
 #include "rtc_base/constructor_magic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/delay_peak_detector.h b/modules/audio_coding/neteq/delay_peak_detector.h
index 15db189..dce8bb4 100644
--- a/modules/audio_coding/neteq/delay_peak_detector.h
+++ b/modules/audio_coding/neteq/delay_peak_detector.h
@@ -17,7 +17,7 @@
 #include <list>
 #include <memory>
 
-#include "modules/audio_coding/neteq/tick_timer.h"
+#include "api/neteq/tick_timer.h"
 #include "rtc_base/constructor_magic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/expand_uma_logger.h b/modules/audio_coding/neteq/expand_uma_logger.h
index 1139bb6..246aaff 100644
--- a/modules/audio_coding/neteq/expand_uma_logger.h
+++ b/modules/audio_coding/neteq/expand_uma_logger.h
@@ -16,7 +16,7 @@
 #include <string>
 
 #include "absl/types/optional.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
+#include "api/neteq/tick_timer.h"
 #include "rtc_base/constructor_magic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/include/neteq.h b/modules/audio_coding/neteq/include/neteq.h
deleted file mode 100644
index b53b5ad..0000000
--- a/modules/audio_coding/neteq/include/neteq.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- *  Copyright (c) 2012 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_CODING_NETEQ_INCLUDE_NETEQ_H_
-#define MODULES_AUDIO_CODING_NETEQ_INCLUDE_NETEQ_H_
-
-#include <string.h>  // Provide access to size_t.
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "absl/types/optional.h"
-#include "api/audio_codecs/audio_codec_pair_id.h"
-#include "api/audio_codecs/audio_decoder.h"
-#include "api/audio_codecs/audio_format.h"
-#include "api/rtp_headers.h"
-#include "api/scoped_refptr.h"
-#include "modules/audio_coding/neteq/defines.h"
-#include "rtc_base/constructor_magic.h"
-
-namespace webrtc {
-
-// Forward declarations.
-class AudioFrame;
-class AudioDecoderFactory;
-class Clock;
-
-struct NetEqNetworkStatistics {
-  uint16_t current_buffer_size_ms;    // Current jitter buffer size in ms.
-  uint16_t preferred_buffer_size_ms;  // Target buffer size in ms.
-  uint16_t jitter_peaks_found;        // 1 if adding extra delay due to peaky
-                                      // jitter; 0 otherwise.
-  uint16_t packet_loss_rate;          // Loss rate (network + late) in Q14.
-  uint16_t expand_rate;         // Fraction (of original stream) of synthesized
-                                // audio inserted through expansion (in Q14).
-  uint16_t speech_expand_rate;  // Fraction (of original stream) of synthesized
-                                // speech inserted through expansion (in Q14).
-  uint16_t preemptive_rate;     // Fraction of data inserted through pre-emptive
-                                // expansion (in Q14).
-  uint16_t accelerate_rate;     // Fraction of data removed through acceleration
-                                // (in Q14).
-  uint16_t secondary_decoded_rate;    // Fraction of data coming from FEC/RED
-                                      // decoding (in Q14).
-  uint16_t secondary_discarded_rate;  // Fraction of discarded FEC/RED data (in
-                                      // Q14).
-  size_t added_zero_samples;  // Number of zero samples added in "off" mode.
-  // Statistics for packet waiting times, i.e., the time between a packet
-  // arrives until it is decoded.
-  int mean_waiting_time_ms;
-  int median_waiting_time_ms;
-  int min_waiting_time_ms;
-  int max_waiting_time_ms;
-};
-
-// NetEq statistics that persist over the lifetime of the class.
-// These metrics are never reset.
-struct NetEqLifetimeStatistics {
-  // Stats below correspond to similarly-named fields in the WebRTC stats spec.
-  // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats
-  uint64_t total_samples_received = 0;
-  uint64_t concealed_samples = 0;
-  uint64_t concealment_events = 0;
-  uint64_t jitter_buffer_delay_ms = 0;
-  uint64_t jitter_buffer_emitted_count = 0;
-  uint64_t inserted_samples_for_deceleration = 0;
-  uint64_t removed_samples_for_acceleration = 0;
-  uint64_t silent_concealed_samples = 0;
-  uint64_t fec_packets_received = 0;
-  uint64_t fec_packets_discarded = 0;
-  // Below stats are not part of the spec.
-  uint64_t delayed_packet_outage_samples = 0;
-  // This is sum of relative packet arrival delays of received packets so far.
-  // Since end-to-end delay of a packet is difficult to measure and is not
-  // necessarily useful for measuring jitter buffer performance, we report a
-  // relative packet arrival delay. The relative packet arrival delay of a
-  // packet is defined as the arrival delay compared to the first packet
-  // received, given that it had zero delay. To avoid clock drift, the "first"
-  // packet can be made dynamic.
-  uint64_t relative_packet_arrival_delay_ms = 0;
-  uint64_t jitter_buffer_packets_received = 0;
-  // An interruption is a loss-concealment event lasting at least 150 ms. The
-  // two stats below count the number os such events and the total duration of
-  // these events.
-  int32_t interruption_count = 0;
-  int32_t total_interruption_duration_ms = 0;
-};
-
-// Metrics that describe the operations performed in NetEq, and the internal
-// state.
-struct NetEqOperationsAndState {
-  // These sample counters are cumulative, and don't reset. As a reference, the
-  // total number of output samples can be found in
-  // NetEqLifetimeStatistics::total_samples_received.
-  uint64_t preemptive_samples = 0;
-  uint64_t accelerate_samples = 0;
-  // Count of the number of buffer flushes.
-  uint64_t packet_buffer_flushes = 0;
-  // The number of primary packets that were discarded.
-  uint64_t discarded_primary_packets = 0;
-  // The statistics below are not cumulative.
-  // The waiting time of the last decoded packet.
-  uint64_t last_waiting_time_ms = 0;
-  // The sum of the packet and jitter buffer size in ms.
-  uint64_t current_buffer_size_ms = 0;
-  // The current frame size in ms.
-  uint64_t current_frame_size_ms = 0;
-  // Flag to indicate that the next packet is available.
-  bool next_packet_available = false;
-};
-
-// This is the interface class for NetEq.
-class NetEq {
- public:
-  struct Config {
-    Config();
-    Config(const Config&);
-    Config(Config&&);
-    ~Config();
-    Config& operator=(const Config&);
-    Config& operator=(Config&&);
-
-    std::string ToString() const;
-
-    int sample_rate_hz = 16000;  // Initial value. Will change with input data.
-    bool enable_post_decode_vad = false;
-    size_t max_packets_in_buffer = 200;
-    int max_delay_ms = 0;
-    int min_delay_ms = 0;
-    bool enable_fast_accelerate = false;
-    bool enable_muted_state = false;
-    bool enable_rtx_handling = false;
-    absl::optional<AudioCodecPairId> codec_pair_id;
-    bool for_test_no_time_stretching = false;  // Use only for testing.
-  };
-
-  enum ReturnCodes { kOK = 0, kFail = -1 };
-
-  // Return type for GetDecoderFormat.
-  struct DecoderFormat {
-    int sample_rate_hz;
-    int num_channels;
-    SdpAudioFormat sdp_format;
-  };
-
-  // Creates a new NetEq object, with parameters set in |config|. The |config|
-  // object will only have to be valid for the duration of the call to this
-  // method.
-  static NetEq* Create(
-      const NetEq::Config& config,
-      Clock* clock,
-      const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory);
-
-  virtual ~NetEq() {}
-
-  // Inserts a new packet into NetEq.
-  // Returns 0 on success, -1 on failure.
-  virtual int InsertPacket(const RTPHeader& rtp_header,
-                           rtc::ArrayView<const uint8_t> payload) = 0;
-
-  // Deprecated. Use the version without the `receive_timestamp` argument.
-  int InsertPacket(const RTPHeader& rtp_header,
-                   rtc::ArrayView<const uint8_t> payload,
-                   uint32_t /*receive_timestamp*/) {
-    return InsertPacket(rtp_header, payload);
-  }
-
-  // Lets NetEq know that a packet arrived with an empty payload. This typically
-  // happens when empty packets are used for probing the network channel, and
-  // these packets use RTP sequence numbers from the same series as the actual
-  // audio packets.
-  virtual void InsertEmptyPacket(const RTPHeader& rtp_header) = 0;
-
-  // Instructs NetEq to deliver 10 ms of audio data. The data is written to
-  // |audio_frame|. All data in |audio_frame| is wiped; |data_|, |speech_type_|,
-  // |num_channels_|, |sample_rate_hz_|, |samples_per_channel_|, and
-  // |vad_activity_| are updated upon success. If an error is returned, some
-  // fields may not have been updated, or may contain inconsistent values.
-  // If muted state is enabled (through Config::enable_muted_state), |muted|
-  // may be set to true after a prolonged expand period. When this happens, the
-  // |data_| in |audio_frame| is not written, but should be interpreted as being
-  // all zeros. For testing purposes, an override can be supplied in the
-  // |action_override| argument, which will cause NetEq to take this action
-  // next, instead of the action it would normally choose.
-  // Returns kOK on success, or kFail in case of an error.
-  virtual int GetAudio(
-      AudioFrame* audio_frame,
-      bool* muted,
-      absl::optional<Operations> action_override = absl::nullopt) = 0;
-
-  // Replaces the current set of decoders with the given one.
-  virtual void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) = 0;
-
-  // Associates |rtp_payload_type| with the given codec, which NetEq will
-  // instantiate when it needs it. Returns true iff successful.
-  virtual bool RegisterPayloadType(int rtp_payload_type,
-                                   const SdpAudioFormat& audio_format) = 0;
-
-  // Removes |rtp_payload_type| from the codec database. Returns 0 on success,
-  // -1 on failure. Removing a payload type that is not registered is ok and
-  // will not result in an error.
-  virtual int RemovePayloadType(uint8_t rtp_payload_type) = 0;
-
-  // Removes all payload types from the codec database.
-  virtual void RemoveAllPayloadTypes() = 0;
-
-  // Sets a minimum delay in millisecond for packet buffer. The minimum is
-  // maintained unless a higher latency is dictated by channel condition.
-  // Returns true if the minimum is successfully applied, otherwise false is
-  // returned.
-  virtual bool SetMinimumDelay(int delay_ms) = 0;
-
-  // Sets a maximum delay in milliseconds for packet buffer. The latency will
-  // not exceed the given value, even required delay (given the channel
-  // conditions) is higher. Calling this method has the same effect as setting
-  // the |max_delay_ms| value in the NetEq::Config struct.
-  virtual bool SetMaximumDelay(int delay_ms) = 0;
-
-  // Sets a base minimum delay in milliseconds for packet buffer. The minimum
-  // delay which is set via |SetMinimumDelay| can't be lower than base minimum
-  // delay. Calling this method is similar to setting the |min_delay_ms| value
-  // in the NetEq::Config struct. Returns true if the base minimum is
-  // successfully applied, otherwise false is returned.
-  virtual bool SetBaseMinimumDelayMs(int delay_ms) = 0;
-
-  // Returns current value of base minimum delay in milliseconds.
-  virtual int GetBaseMinimumDelayMs() const = 0;
-
-  // Returns the current target delay in ms. This includes any extra delay
-  // requested through SetMinimumDelay.
-  virtual int TargetDelayMs() const = 0;
-
-  // Returns the current total delay (packet buffer and sync buffer) in ms,
-  // with smoothing applied to even out short-time fluctuations due to jitter.
-  // The packet buffer part of the delay is not updated during DTX/CNG periods.
-  virtual int FilteredCurrentDelayMs() const = 0;
-
-  // Writes the current network statistics to |stats|. The statistics are reset
-  // after the call.
-  virtual int NetworkStatistics(NetEqNetworkStatistics* stats) = 0;
-
-  // Returns a copy of this class's lifetime statistics. These statistics are
-  // never reset.
-  virtual NetEqLifetimeStatistics GetLifetimeStatistics() const = 0;
-
-  // Returns statistics about the performed operations and internal state. These
-  // statistics are never reset.
-  virtual NetEqOperationsAndState GetOperationsAndState() const = 0;
-
-  // Enables post-decode VAD. When enabled, GetAudio() will return
-  // kOutputVADPassive when the signal contains no speech.
-  virtual void EnableVad() = 0;
-
-  // Disables post-decode VAD.
-  virtual void DisableVad() = 0;
-
-  // Returns the RTP timestamp for the last sample delivered by GetAudio().
-  // The return value will be empty if no valid timestamp is available.
-  virtual absl::optional<uint32_t> GetPlayoutTimestamp() const = 0;
-
-  // Returns the sample rate in Hz of the audio produced in the last GetAudio
-  // call. If GetAudio has not been called yet, the configured sample rate
-  // (Config::sample_rate_hz) is returned.
-  virtual int last_output_sample_rate_hz() const = 0;
-
-  // Returns the decoder info for the given payload type. Returns empty if no
-  // such payload type was registered.
-  virtual absl::optional<DecoderFormat> GetDecoderFormat(
-      int payload_type) const = 0;
-
-  // Flushes both the packet buffer and the sync buffer.
-  virtual void FlushBuffers() = 0;
-
-  // Enables NACK and sets the maximum size of the NACK list, which should be
-  // positive and no larger than Nack::kNackListSizeLimit. If NACK is already
-  // enabled then the maximum NACK list size is modified accordingly.
-  virtual void EnableNack(size_t max_nack_list_size) = 0;
-
-  virtual void DisableNack() = 0;
-
-  // Returns a list of RTP sequence numbers corresponding to packets to be
-  // retransmitted, given an estimate of the round-trip time in milliseconds.
-  virtual std::vector<uint16_t> GetNackList(
-      int64_t round_trip_time_ms) const = 0;
-
-  // Returns a vector containing the timestamps of the packets that were decoded
-  // in the last GetAudio call. If no packets were decoded in the last call, the
-  // vector is empty.
-  // Mainly intended for testing.
-  virtual std::vector<uint32_t> LastDecodedTimestamps() const = 0;
-
-  // Returns the length of the audio yet to play in the sync buffer.
-  // Mainly intended for testing.
-  virtual int SyncBufferSizeMs() const = 0;
-
- protected:
-  NetEq() {}
-
- private:
-  RTC_DISALLOW_COPY_AND_ASSIGN(NetEq);
-};
-
-}  // namespace webrtc
-#endif  // MODULES_AUDIO_CODING_NETEQ_INCLUDE_NETEQ_H_
diff --git a/modules/audio_coding/neteq/mock/mock_neteq_controller.h b/modules/audio_coding/neteq/mock/mock_neteq_controller.h
index 38aa3e7..d1008c8 100644
--- a/modules/audio_coding/neteq/mock/mock_neteq_controller.h
+++ b/modules/audio_coding/neteq/mock/mock_neteq_controller.h
@@ -11,7 +11,7 @@
 #ifndef MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_NETEQ_CONTROLLER_H_
 #define MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_NETEQ_CONTROLLER_H_
 
-#include "modules/audio_coding/neteq/neteq_controller.h"
+#include "api/neteq/neteq_controller.h"
 #include "test/gmock.h"
 
 namespace webrtc {
@@ -24,8 +24,8 @@
   MOCK_METHOD0(Reset, void());
   MOCK_METHOD0(SoftReset, void());
   MOCK_METHOD2(GetDecision,
-               Operations(const NetEqStatus& neteq_status,
-                          bool* reset_decoder));
+               NetEq::Operation(const NetEqStatus& neteq_status,
+                                bool* reset_decoder));
   MOCK_METHOD6(Update,
                void(uint16_t sequence_number,
                     uint32_t timestamp,
@@ -42,7 +42,7 @@
   MOCK_CONST_METHOD0(CngRfc3389On, bool());
   MOCK_CONST_METHOD0(CngOff, bool());
   MOCK_METHOD0(SetCngOff, void());
-  MOCK_METHOD1(ExpandDecision, void(Operations operation));
+  MOCK_METHOD1(ExpandDecision, void(NetEq::Operation operation));
   MOCK_METHOD1(AddSampleMemory, void(int32_t value));
   MOCK_METHOD0(TargetLevelMs, int());
   MOCK_METHOD6(PacketArrived,
diff --git a/modules/audio_coding/neteq/neteq.cc b/modules/audio_coding/neteq/neteq.cc
deleted file mode 100644
index 0a36cb2..0000000
--- a/modules/audio_coding/neteq/neteq.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Copyright (c) 2012 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_coding/neteq/include/neteq.h"
-
-#include "modules/audio_coding/neteq/neteq_impl.h"
-#include "rtc_base/strings/string_builder.h"
-
-namespace webrtc {
-
-NetEq::Config::Config() = default;
-NetEq::Config::Config(const Config&) = default;
-NetEq::Config::Config(Config&&) = default;
-NetEq::Config::~Config() = default;
-NetEq::Config& NetEq::Config::operator=(const Config&) = default;
-NetEq::Config& NetEq::Config::operator=(Config&&) = default;
-
-std::string NetEq::Config::ToString() const {
-  char buf[1024];
-  rtc::SimpleStringBuilder ss(buf);
-  ss << "sample_rate_hz=" << sample_rate_hz << ", enable_post_decode_vad="
-     << (enable_post_decode_vad ? "true" : "false")
-     << ", max_packets_in_buffer=" << max_packets_in_buffer
-     << ", min_delay_ms=" << min_delay_ms << ", enable_fast_accelerate="
-     << (enable_fast_accelerate ? "true" : "false")
-     << ", enable_muted_state=" << (enable_muted_state ? "true" : "false")
-     << ", enable_rtx_handling=" << (enable_rtx_handling ? "true" : "false");
-  return ss.str();
-}
-
-// Creates all classes needed and inject them into a new NetEqImpl object.
-// Return the new object.
-NetEq* NetEq::Create(
-    const NetEq::Config& config,
-    Clock* clock,
-    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
-  return new NetEqImpl(config,
-                       NetEqImpl::Dependencies(config, clock, decoder_factory));
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_coding/neteq/neteq_controller.h b/modules/audio_coding/neteq/neteq_controller.h
deleted file mode 100644
index 16e3a8e..0000000
--- a/modules/audio_coding/neteq/neteq_controller.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  Copyright (c) 2019 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_CODING_NETEQ_NETEQ_CONTROLLER_H_
-#define MODULES_AUDIO_CODING_NETEQ_NETEQ_CONTROLLER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include <functional>
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "modules/audio_coding/neteq/defines.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
-
-namespace webrtc {
-
-// Decides the actions that NetEq should take. This affects the behavior of the
-// jitter buffer, and how it reacts to network conditions.
-// This class will undergo substantial refactoring in the near future, and the
-// API is expected to undergo significant changes. A target API is given below:
-//
-// class NetEqController {
-//  public:
-//   // Resets object to a clean state.
-//   void Reset();
-//   // Given NetEq status, make a decision.
-//   Operation GetDecision(NetEqStatus neteq_status);
-//   // Register every packet received.
-//   void RegisterPacket(PacketInfo packet_info);
-//   // Register empty packet.
-//   void RegisterEmptyPacket();
-//   // Register a codec switching.
-//   void CodecSwithed();
-//   // Sets the sample rate.
-//   void SetSampleRate(int fs_hz);
-//   // Sets the packet length in samples.
-//   void SetPacketLengthSamples();
-//   // Sets maximum delay.
-//   void SetMaximumDelay(int delay_ms);
-//   // Sets mininum delay.
-//   void SetMinimumDelay(int delay_ms);
-//   // Sets base mininum delay.
-//   void SetBaseMinimumDelay(int delay_ms);
-//   // Gets target buffer level.
-//   int GetTargetBufferLevelMs() const;
-//   // Gets filtered buffer level.
-//   int GetFilteredBufferLevel() const;
-//   // Gets base minimum delay.
-//   int GetBaseMinimumDelay() const;
-// }
-
-class NetEqController {
- public:
-  // This struct is used to create a NetEqController.
-  struct Config {
-    bool allow_time_stretching;
-    bool enable_rtx_handling;
-    int max_packets_in_buffer;
-    int base_min_delay_ms;
-    TickTimer* tick_timer;
-  };
-
-  struct PacketInfo {
-    uint32_t timestamp;
-    bool is_dtx;
-    bool is_cng;
-  };
-
-  struct PacketBufferInfo {
-    bool dtx_or_cng;
-    size_t num_samples;
-    size_t span_samples;
-    size_t span_samples_no_dtx;
-    size_t num_packets;
-  };
-
-  struct NetEqStatus {
-    uint32_t target_timestamp;
-    int16_t expand_mutefactor;
-    size_t last_packet_samples;
-    absl::optional<PacketInfo> next_packet;
-    Modes last_mode;
-    bool play_dtmf;
-    size_t generated_noise_samples;
-    PacketBufferInfo packet_buffer_info;
-  };
-
-  virtual ~NetEqController() = default;
-
-  // Resets object to a clean state.
-  virtual void Reset() = 0;
-
-  // Resets parts of the state. Typically done when switching codecs.
-  virtual void SoftReset() = 0;
-
-  // Given info about the latest received packet, and current jitter buffer
-  // status, returns the operation. |target_timestamp| and |expand_mutefactor|
-  // are provided for reference. |last_packet_samples| is the number of samples
-  // obtained from the last decoded frame. If there is a packet available, it
-  // should be supplied in |packet|. The mode resulting from the last call to
-  // NetEqImpl::GetAudio is supplied in |last_mode|. If there is a DTMF event to
-  // play, |play_dtmf| should be set to true. The output variable
-  // |reset_decoder| will be set to true if a reset is required; otherwise it is
-  // left unchanged (i.e., it can remain true if it was true before the call).
-  virtual Operations GetDecision(const NetEqStatus& status,
-                                 bool* reset_decoder) = 0;
-
-  // Inform NetEqController that an empty packet has arrived.
-  virtual void RegisterEmptyPacket() = 0;
-
-  // Sets the sample rate and the output block size.
-  virtual void SetSampleRate(int fs_hz, size_t output_size_samples) = 0;
-
-  // Sets a minimum or maximum delay in millisecond.
-  // Returns true if the delay bound is successfully applied, otherwise false.
-  virtual bool SetMaximumDelay(int delay_ms) = 0;
-  virtual bool SetMinimumDelay(int delay_ms) = 0;
-
-  // Sets a base minimum delay in milliseconds for packet buffer. The effective
-  // minimum delay can't be lower than base minimum delay, even if a lower value
-  // is set using SetMinimumDelay.
-  // Returns true if the base minimum is successfully applied, otherwise false.
-  virtual bool SetBaseMinimumDelay(int delay_ms) = 0;
-  virtual int GetBaseMinimumDelay() const = 0;
-
-  // These methods test the |cng_state_| for different conditions.
-  virtual bool CngRfc3389On() const = 0;
-  virtual bool CngOff() const = 0;
-
-  // Resets the |cng_state_| to kCngOff.
-  virtual void SetCngOff() = 0;
-
-  // Reports back to DecisionLogic whether the decision to do expand remains or
-  // not. Note that this is necessary, since an expand decision can be changed
-  // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
-  // sync buffer.
-  virtual void ExpandDecision(Operations operation) = 0;
-
-  // Adds |value| to |sample_memory_|.
-  virtual void AddSampleMemory(int32_t value) = 0;
-
-  // Returns the target buffer level in ms.
-  virtual int TargetLevelMs() = 0;
-
-  // Notify the NetEqController that a packet has arrived. Returns the relative
-  // arrival delay, if it can be computed.
-  virtual absl::optional<int> PacketArrived(bool last_cng_or_dtmf,
-                                            size_t packet_length_samples,
-                                            bool should_update_stats,
-                                            uint16_t main_sequence_number,
-                                            uint32_t main_timestamp,
-                                            int fs_hz) = 0;
-
-  // Returns true if a peak was found.
-  virtual bool PeakFound() const = 0;
-
-  // Get the filtered buffer level in samples.
-  virtual int GetFilteredBufferLevel() const = 0;
-
-  // Accessors and mutators.
-  virtual void set_sample_memory(int32_t value) = 0;
-  virtual size_t noise_fast_forward() const = 0;
-  virtual size_t packet_length_samples() const = 0;
-  virtual void set_packet_length_samples(size_t value) = 0;
-  virtual void set_prev_time_scale(bool value) = 0;
-};
-
-}  // namespace webrtc
-#endif  // MODULES_AUDIO_CODING_NETEQ_NETEQ_CONTROLLER_H_
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index 7290e93..b6f5971 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include "api/audio_codecs/audio_decoder.h"
+#include "api/neteq/tick_timer.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"
@@ -28,7 +29,6 @@
 #include "modules/audio_coding/neteq/comfort_noise.h"
 #include "modules/audio_coding/neteq/decision_logic.h"
 #include "modules/audio_coding/neteq/decoder_database.h"
-#include "modules/audio_coding/neteq/defines.h"
 #include "modules/audio_coding/neteq/dtmf_buffer.h"
 #include "modules/audio_coding/neteq/dtmf_tone_generator.h"
 #include "modules/audio_coding/neteq/expand.h"
@@ -42,7 +42,6 @@
 #include "modules/audio_coding/neteq/red_payload_splitter.h"
 #include "modules/audio_coding/neteq/statistics_calculator.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"
@@ -57,6 +56,7 @@
 namespace {
 
 std::unique_ptr<NetEqController> CreateNetEqController(
+    const NetEqControllerFactory& controller_factory,
     int base_min_delay,
     int max_packets_in_buffer,
     bool enable_rtx_handling,
@@ -68,7 +68,7 @@
   config.enable_rtx_handling = enable_rtx_handling;
   config.allow_time_stretching = allow_time_stretching;
   config.tick_timer = tick_timer;
-  return std::make_unique<DecisionLogic>(std::move(config));
+  return controller_factory.CreateNetEqController(config);
 }
 
 }  // namespace
@@ -76,7 +76,8 @@
 NetEqImpl::Dependencies::Dependencies(
     const NetEq::Config& config,
     Clock* clock,
-    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory)
+    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
+    const NetEqControllerFactory& controller_factory)
     : clock(clock),
       tick_timer(new TickTimer),
       stats(new StatisticsCalculator),
@@ -87,7 +88,8 @@
       packet_buffer(
           new PacketBuffer(config.max_packets_in_buffer, tick_timer.get())),
       neteq_controller(
-          CreateNetEqController(config.min_delay_ms,
+          CreateNetEqController(controller_factory,
+                                config.min_delay_ms,
                                 config.max_packets_in_buffer,
                                 config.enable_rtx_handling,
                                 !config.for_test_no_time_stretching,
@@ -117,7 +119,7 @@
       preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)),
       stats_(std::move(deps.stats)),
       controller_(std::move(deps.neteq_controller)),
-      last_mode_(kModeNormal),
+      last_mode_(Mode::kNormal),
       decoded_buffer_length_(kMaxFrameSize),
       decoded_buffer_(new int16_t[decoded_buffer_length_]),
       playout_timestamp_(0),
@@ -230,7 +232,7 @@
 
 int NetEqImpl::GetAudio(AudioFrame* audio_frame,
                         bool* muted,
-                        absl::optional<Operations> action_override) {
+                        absl::optional<Operation> action_override) {
   TRACE_EVENT0("webrtc", "NetEqImpl::GetAudio");
   rtc::CritScope lock(&crit_sect_);
   if (GetAudioInternal(audio_frame, muted, action_override) != 0) {
@@ -381,8 +383,8 @@
 
 absl::optional<uint32_t> NetEqImpl::GetPlayoutTimestamp() const {
   rtc::CritScope lock(&crit_sect_);
-  if (first_packet_ || last_mode_ == kModeRfc3389Cng ||
-      last_mode_ == kModeCodecInternalCng) {
+  if (first_packet_ || last_mode_ == Mode::kRfc3389Cng ||
+      last_mode_ == Mode::kCodecInternalCng) {
     // We don't have a valid RTP timestamp until we have decoded our first
     // RTP packet. Also, the RTP timestamp is not accurate while playing CNG,
     // which is indicated by returning an empty value.
@@ -470,7 +472,7 @@
   return sync_buffer_.get();
 }
 
-Operations NetEqImpl::last_operation_for_test() const {
+NetEq::Operation NetEqImpl::last_operation_for_test() const {
   rtc::CritScope lock(&crit_sect_);
   return last_operation_;
 }
@@ -743,10 +745,10 @@
 
 int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame,
                                 bool* muted,
-                                absl::optional<Operations> action_override) {
+                                absl::optional<Operation> action_override) {
   PacketList packet_list;
   DtmfEvent dtmf_event;
-  Operations operation;
+  Operation operation;
   bool play_dtmf;
   *muted = false;
   last_decoded_timestamps_.clear();
@@ -763,7 +765,7 @@
 
   // Check for muted state.
   if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) {
-    RTC_DCHECK_EQ(last_mode_, kModeExpand);
+    RTC_DCHECK_EQ(last_mode_, Mode::kExpand);
     audio_frame->Reset();
     RTC_DCHECK(audio_frame->muted());  // Reset() should mute the frame.
     playout_timestamp_ += static_cast<uint32_t>(output_size_samples_);
@@ -782,7 +784,7 @@
   int return_value = GetDecision(&operation, &packet_list, &dtmf_event,
                                  &play_dtmf, action_override);
   if (return_value != 0) {
-    last_mode_ = kModeError;
+    last_mode_ = Mode::kError;
     return return_value;
   }
 
@@ -793,7 +795,8 @@
       Decode(&packet_list, &operation, &length, &speech_type);
 
   assert(vad_.get());
-  bool sid_frame_available = (operation == kRfc3389Cng && !packet_list.empty());
+  bool sid_frame_available =
+      (operation == Operation::kRfc3389Cng && !packet_list.empty());
   vad_->Update(decoded_buffer_.get(), static_cast<size_t>(length), speech_type,
                sid_frame_available, fs_hz_);
 
@@ -810,18 +813,18 @@
 
   algorithm_buffer_->Clear();
   switch (operation) {
-    case kNormal: {
+    case Operation::kNormal: {
       DoNormal(decoded_buffer_.get(), length, speech_type, play_dtmf);
       if (length > 0) {
         stats_->DecodedOutputPlayed();
       }
       break;
     }
-    case kMerge: {
+    case Operation::kMerge: {
       DoMerge(decoded_buffer_.get(), length, speech_type, play_dtmf);
       break;
     }
-    case kExpand: {
+    case Operation::kExpand: {
       RTC_DCHECK_EQ(return_value, 0);
       if (!current_rtp_payload_type_ || !DoCodecPlc()) {
         return_value = DoExpand(play_dtmf);
@@ -830,40 +833,40 @@
                     output_size_samples_);
       break;
     }
-    case kAccelerate:
-    case kFastAccelerate: {
+    case Operation::kAccelerate:
+    case Operation::kFastAccelerate: {
       const bool fast_accelerate =
-          enable_fast_accelerate_ && (operation == kFastAccelerate);
+          enable_fast_accelerate_ && (operation == Operation::kFastAccelerate);
       return_value = DoAccelerate(decoded_buffer_.get(), length, speech_type,
                                   play_dtmf, fast_accelerate);
       break;
     }
-    case kPreemptiveExpand: {
+    case Operation::kPreemptiveExpand: {
       return_value = DoPreemptiveExpand(decoded_buffer_.get(), length,
                                         speech_type, play_dtmf);
       break;
     }
-    case kRfc3389Cng:
-    case kRfc3389CngNoPacket: {
+    case Operation::kRfc3389Cng:
+    case Operation::kRfc3389CngNoPacket: {
       return_value = DoRfc3389Cng(&packet_list, play_dtmf);
       break;
     }
-    case kCodecInternalCng: {
+    case Operation::kCodecInternalCng: {
       // This handles the case when there is no transmission and the decoder
       // should produce internal comfort noise.
       // TODO(hlundin): Write test for codec-internal CNG.
       DoCodecInternalCng(decoded_buffer_.get(), length);
       break;
     }
-    case kDtmf: {
+    case Operation::kDtmf: {
       // TODO(hlundin): Write test for this.
       return_value = DoDtmf(dtmf_event, &play_dtmf);
       break;
     }
-    case kUndefined: {
+    case Operation::kUndefined: {
       RTC_LOG(LS_ERROR) << "Invalid operation kUndefined.";
       assert(false);  // This should not happen.
-      last_mode_ = kModeError;
+      last_mode_ = Mode::kError;
       return kInvalidOperation;
     }
   }  // End of switch.
@@ -872,7 +875,7 @@
     return return_value;
   }
 
-  if (last_mode_ != kModeRfc3389Cng) {
+  if (last_mode_ != Mode::kRfc3389Cng) {
     comfort_noise_->Reset();
   }
 
@@ -941,20 +944,20 @@
   // Update the background noise parameters if last operation wrote data
   // straight from the decoder to the |sync_buffer_|. That is, none of the
   // operations that modify the signal can be followed by a parameter update.
-  if ((last_mode_ == kModeNormal) || (last_mode_ == kModeAccelerateFail) ||
-      (last_mode_ == kModePreemptiveExpandFail) ||
-      (last_mode_ == kModeRfc3389Cng) ||
-      (last_mode_ == kModeCodecInternalCng)) {
+  if ((last_mode_ == Mode::kNormal) || (last_mode_ == Mode::kAccelerateFail) ||
+      (last_mode_ == Mode::kPreemptiveExpandFail) ||
+      (last_mode_ == Mode::kRfc3389Cng) ||
+      (last_mode_ == Mode::kCodecInternalCng)) {
     background_noise_->Update(*sync_buffer_, *vad_.get());
   }
 
-  if (operation == kDtmf) {
+  if (operation == Operation::kDtmf) {
     // DTMF data was written the end of |sync_buffer_|.
     // Update index to end of DTMF data in |sync_buffer_|.
     sync_buffer_->set_dtmf_index(sync_buffer_->Size());
   }
 
-  if (last_mode_ != kModeExpand && last_mode_ != kModeCodecPlc) {
+  if (last_mode_ != Mode::kExpand && last_mode_ != Mode::kCodecPlc) {
     // If last operation was not expand, calculate the |playout_timestamp_| from
     // the |sync_buffer_|. However, do not update the |playout_timestamp_| if it
     // would be moved "backwards".
@@ -978,8 +981,9 @@
           : timestamp_scaler_->ToExternal(playout_timestamp_) -
                 static_cast<uint32_t>(audio_frame->samples_per_channel_);
 
-  if (!(last_mode_ == kModeRfc3389Cng || last_mode_ == kModeCodecInternalCng ||
-        last_mode_ == kModeExpand || last_mode_ == kModeCodecPlc)) {
+  if (!(last_mode_ == Mode::kRfc3389Cng ||
+        last_mode_ == Mode::kCodecInternalCng || last_mode_ == Mode::kExpand ||
+        last_mode_ == Mode::kCodecPlc)) {
     generated_noise_stopwatch_.reset();
   }
 
@@ -988,14 +992,14 @@
   return return_value;
 }
 
-int NetEqImpl::GetDecision(Operations* operation,
+int NetEqImpl::GetDecision(Operation* operation,
                            PacketList* packet_list,
                            DtmfEvent* dtmf_event,
                            bool* play_dtmf,
-                           absl::optional<Operations> action_override) {
+                           absl::optional<Operation> action_override) {
   // Initialize output variables.
   *play_dtmf = false;
-  *operation = kUndefined;
+  *operation = Operation::kUndefined;
 
   assert(sync_buffer_.get());
   uint32_t end_timestamp = sync_buffer_->end_timestamp();
@@ -1014,7 +1018,7 @@
                                        controller_->noise_fast_forward()
                                  : 0;
 
-  if (controller_->CngRfc3389On() || last_mode_ == kModeRfc3389Cng) {
+  if (controller_->CngRfc3389On() || last_mode_ == Mode::kRfc3389Cng) {
     // Because of timestamp peculiarities, we have to "manually" disallow using
     // a CNG packet with the same timestamp as the one that was last played.
     // This can happen when using redundancy and will cause the timing to shift.
@@ -1038,10 +1042,10 @@
   assert(expand_.get());
   const int samples_left = static_cast<int>(sync_buffer_->FutureLength() -
                                             expand_->overlap_length());
-  if (last_mode_ == kModeAccelerateSuccess ||
-      last_mode_ == kModeAccelerateLowEnergy ||
-      last_mode_ == kModePreemptiveExpandSuccess ||
-      last_mode_ == kModePreemptiveExpandLowEnergy) {
+  if (last_mode_ == Mode::kAccelerateSuccess ||
+      last_mode_ == Mode::kAccelerateLowEnergy ||
+      last_mode_ == Mode::kPreemptiveExpandSuccess ||
+      last_mode_ == Mode::kPreemptiveExpandLowEnergy) {
     // Subtract (samples_left + output_size_samples_) from sampleMemory.
     controller_->AddSampleMemory(
         -(samples_left + rtc::dchecked_cast<int>(output_size_samples_)));
@@ -1091,9 +1095,11 @@
   // during DTX. When we have a better way to update buffer level during DTX,
   // this can be discarded.
   if (packet && packet->frame && packet->frame->IsDtxPacket() &&
-      (*operation == kMerge || *operation == kAccelerate ||
-       *operation == kFastAccelerate || *operation == kPreemptiveExpand)) {
-    *operation = kNormal;
+      (*operation == Operation::kMerge ||
+       *operation == Operation::kAccelerate ||
+       *operation == Operation::kFastAccelerate ||
+       *operation == Operation::kPreemptiveExpand)) {
+    *operation = Operation::kNormal;
   }
 
   if (action_override) {
@@ -1104,16 +1110,17 @@
   // change decision to normal, unless the decision was merge, accelerate, or
   // preemptive expand.
   if (samples_left >= rtc::dchecked_cast<int>(output_size_samples_) &&
-      *operation != kMerge && *operation != kAccelerate &&
-      *operation != kFastAccelerate && *operation != kPreemptiveExpand) {
-    *operation = kNormal;
+      *operation != Operation::kMerge && *operation != Operation::kAccelerate &&
+      *operation != Operation::kFastAccelerate &&
+      *operation != Operation::kPreemptiveExpand) {
+    *operation = Operation::kNormal;
     return 0;
   }
 
   controller_->ExpandDecision(*operation);
 
   // Check conditions for reset.
-  if (new_codec_ || *operation == kUndefined) {
+  if (new_codec_ || *operation == Operation::kUndefined) {
     // The only valid reason to get kUndefined is that new_codec_ is set.
     assert(new_codec_);
     if (*play_dtmf && !packet) {
@@ -1124,13 +1131,13 @@
         return -1;
       }
       timestamp_ = packet->timestamp;
-      if (*operation == kRfc3389CngNoPacket &&
+      if (*operation == Operation::kRfc3389CngNoPacket &&
           decoder_database_->IsComfortNoise(packet->payload_type)) {
         // Change decision to CNG packet, since we do have a CNG packet, but it
         // was considered too early to use. Now, use it anyway.
-        *operation = kRfc3389Cng;
-      } else if (*operation != kRfc3389Cng) {
-        *operation = kNormal;
+        *operation = Operation::kRfc3389Cng;
+      } else if (*operation != Operation::kRfc3389Cng) {
+        *operation = Operation::kNormal;
       }
     }
     // Adjust |sync_buffer_| timestamp before setting |end_timestamp| to the
@@ -1148,15 +1155,15 @@
   const size_t samples_30_ms = 3 * samples_10_ms;
 
   switch (*operation) {
-    case kExpand: {
+    case Operation::kExpand: {
       timestamp_ = end_timestamp;
       return 0;
     }
-    case kRfc3389CngNoPacket:
-    case kCodecInternalCng: {
+    case Operation::kRfc3389CngNoPacket:
+    case Operation::kCodecInternalCng: {
       return 0;
     }
-    case kDtmf: {
+    case Operation::kDtmf: {
       // TODO(hlundin): Write test for this.
       // Update timestamp.
       timestamp_ = end_timestamp;
@@ -1166,7 +1173,7 @@
                         output_size_samples_ +
                     controller_->noise_fast_forward()
               : 0;
-      if (generated_noise_samples > 0 && last_mode_ != kModeDtmf) {
+      if (generated_noise_samples > 0 && last_mode_ != Mode::kDtmf) {
         // Make a jump in timestamp due to the recently played comfort noise.
         uint32_t timestamp_jump =
             static_cast<uint32_t>(generated_noise_samples);
@@ -1175,8 +1182,8 @@
       }
       return 0;
     }
-    case kAccelerate:
-    case kFastAccelerate: {
+    case Operation::kAccelerate:
+    case Operation::kFastAccelerate: {
       // In order to do an accelerate we need at least 30 ms of audio data.
       if (samples_left >= static_cast<int>(samples_30_ms)) {
         // Already have enough data, so we do not need to extract any more.
@@ -1186,7 +1193,7 @@
       } else if (samples_left >= static_cast<int>(samples_10_ms) &&
                  decoder_frame_length_ >= samples_30_ms) {
         // Avoid decoding more data as it might overflow the playout buffer.
-        *operation = kNormal;
+        *operation = Operation::kNormal;
         return 0;
       } else if (samples_left < static_cast<int>(samples_20_ms) &&
                  decoder_frame_length_ < samples_30_ms) {
@@ -1194,7 +1201,7 @@
         // not perform accelerate yet, but wait until we only need to do one
         // decoding.
         required_samples = 2 * output_size_samples_;
-        *operation = kNormal;
+        *operation = Operation::kNormal;
       }
       // If none of the above is true, we have one of two possible situations:
       // (1) 20 ms <= samples_left < 30 ms and decoder_frame_length_ < 30 ms; or
@@ -1203,7 +1210,7 @@
       // frame now.
       break;
     }
-    case kPreemptiveExpand: {
+    case Operation::kPreemptiveExpand: {
       // In order to do a preemptive expand we need at least 30 ms of decoded
       // audio data.
       if ((samples_left >= static_cast<int>(samples_30_ms)) ||
@@ -1225,7 +1232,7 @@
       // Move on with the preemptive expand decision.
       break;
     }
-    case kMerge: {
+    case Operation::kMerge: {
       required_samples =
           std::max(merge_->RequiredFutureSamples(), required_samples);
       break;
@@ -1247,7 +1254,7 @@
       stats_->LostSamples(packet->timestamp - end_timestamp);
     }
 
-    if (*operation != kRfc3389Cng) {
+    if (*operation != Operation::kRfc3389Cng) {
       // We are about to decode and use a non-CNG packet.
       controller_->SetCngOff();
     }
@@ -1258,18 +1265,20 @@
     }
   }
 
-  if (*operation == kAccelerate || *operation == kFastAccelerate ||
-      *operation == kPreemptiveExpand) {
+  if (*operation == Operation::kAccelerate ||
+      *operation == Operation::kFastAccelerate ||
+      *operation == Operation::kPreemptiveExpand) {
     controller_->set_sample_memory(samples_left + extracted_samples);
     controller_->set_prev_time_scale(true);
   }
 
-  if (*operation == kAccelerate || *operation == kFastAccelerate) {
+  if (*operation == Operation::kAccelerate ||
+      *operation == Operation::kFastAccelerate) {
     // Check that we have enough data (30ms) to do accelerate.
     if (extracted_samples + samples_left < static_cast<int>(samples_30_ms)) {
       // TODO(hlundin): Write test for this.
       // Not enough, do normal operation instead.
-      *operation = kNormal;
+      *operation = Operation::kNormal;
     }
   }
 
@@ -1278,7 +1287,7 @@
 }
 
 int NetEqImpl::Decode(PacketList* packet_list,
-                      Operations* operation,
+                      Operation* operation,
                       int* decoded_length,
                       AudioDecoder::SpeechType* speech_type) {
   *speech_type = AudioDecoder::kSpeech;
@@ -1341,12 +1350,12 @@
 
   *decoded_length = 0;
   // Update codec-internal PLC state.
-  if ((*operation == kMerge) && decoder && decoder->HasDecodePlc()) {
+  if ((*operation == Operation::kMerge) && decoder && decoder->HasDecodePlc()) {
     decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]);
   }
 
   int return_value;
-  if (*operation == kCodecInternalCng) {
+  if (*operation == Operation::kCodecInternalCng) {
     RTC_DCHECK(packet_list->empty());
     return_value = DecodeCng(decoder, decoded_length, speech_type);
   } else {
@@ -1371,7 +1380,7 @@
       return_value = kOtherDecoderError;
       RTC_LOG(LS_WARNING) << "Decoder error (no error code)";
     }
-    *operation = kExpand;  // Do expansion to get data instead.
+    *operation = Operation::kExpand;  // Do expansion to get data instead.
   }
   if (*speech_type != AudioDecoder::kComfortNoise) {
     // Don't increment timestamp if codec returned CNG speech type
@@ -1417,7 +1426,7 @@
 }
 
 int NetEqImpl::DecodeLoop(PacketList* packet_list,
-                          const Operations& operation,
+                          const Operation& operation,
                           AudioDecoder* decoder,
                           int* decoded_length,
                           AudioDecoder::SpeechType* speech_type) {
@@ -1432,9 +1441,11 @@
     // number decoder channels.
     assert(sync_buffer_->Channels() == decoder->Channels());
     assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->Channels());
-    assert(operation == kNormal || operation == kAccelerate ||
-           operation == kFastAccelerate || operation == kMerge ||
-           operation == kPreemptiveExpand);
+    assert(operation == Operation::kNormal ||
+           operation == Operation::kAccelerate ||
+           operation == Operation::kFastAccelerate ||
+           operation == Operation::kMerge ||
+           operation == Operation::kPreemptiveExpand);
 
     auto opt_result = packet_list->front().frame->Decode(
         rtc::ArrayView<int16_t>(&decoded_buffer_[*decoded_length],
@@ -1485,14 +1496,14 @@
   normal_->Process(decoded_buffer, decoded_length, last_mode_,
                    algorithm_buffer_.get());
   if (decoded_length != 0) {
-    last_mode_ = kModeNormal;
+    last_mode_ = Mode::kNormal;
   }
 
   // If last packet was decoded as an inband CNG, set mode to CNG instead.
   if ((speech_type == AudioDecoder::kComfortNoise) ||
-      ((last_mode_ == kModeCodecInternalCng) && (decoded_length == 0))) {
+      ((last_mode_ == Mode::kCodecInternalCng) && (decoded_length == 0))) {
     // TODO(hlundin): Remove second part of || statement above.
-    last_mode_ = kModeCodecInternalCng;
+    last_mode_ = Mode::kCodecInternalCng;
   }
 
   if (!play_dtmf) {
@@ -1521,10 +1532,10 @@
     stats_->ExpandedVoiceSamplesCorrection(expand_length_correction);
   }
 
-  last_mode_ = kModeMerge;
+  last_mode_ = Mode::kMerge;
   // If last packet was decoded as an inband CNG, set mode to CNG instead.
   if (speech_type == AudioDecoder::kComfortNoise) {
-    last_mode_ = kModeCodecInternalCng;
+    last_mode_ = Mode::kCodecInternalCng;
   }
   expand_->Reset();
   if (!play_dtmf) {
@@ -1555,7 +1566,7 @@
       concealment_audio_.size() / channels;
 
   // Update in-call and post-call statistics.
-  const bool is_new_concealment_event = (last_mode_ != kModeCodecPlc);
+  const bool is_new_concealment_event = (last_mode_ != Mode::kCodecPlc);
   if (std::all_of(concealment_audio_.cbegin(), concealment_audio_.cend(),
                   [](int16_t i) { return i == 0; })) {
     // Expand operation generates only noise.
@@ -1566,7 +1577,7 @@
     stats_->ExpandedVoiceSamples(concealed_samples_per_channel,
                                  is_new_concealment_event);
   }
-  last_mode_ = kModeCodecPlc;
+  last_mode_ = Mode::kCodecPlc;
   if (!generated_noise_stopwatch_) {
     // Start a new stopwatch since we may be covering for a lost CNG packet.
     generated_noise_stopwatch_ = tick_timer_->GetNewStopwatch();
@@ -1580,7 +1591,7 @@
     algorithm_buffer_->Clear();
     int return_value = expand_->Process(algorithm_buffer_.get());
     size_t length = algorithm_buffer_->Size();
-    bool is_new_concealment_event = (last_mode_ != kModeExpand);
+    bool is_new_concealment_event = (last_mode_ != Mode::kExpand);
 
     // Update in-call and post-call statistics.
     if (expand_->MuteFactor(0) == 0) {
@@ -1591,7 +1602,7 @@
       stats_->ExpandedVoiceSamples(length, is_new_concealment_event);
     }
 
-    last_mode_ = kModeExpand;
+    last_mode_ = Mode::kExpand;
 
     if (return_value < 0) {
       return return_value;
@@ -1640,17 +1651,17 @@
   stats_->AcceleratedSamples(samples_removed);
   switch (return_code) {
     case Accelerate::kSuccess:
-      last_mode_ = kModeAccelerateSuccess;
+      last_mode_ = Mode::kAccelerateSuccess;
       break;
     case Accelerate::kSuccessLowEnergy:
-      last_mode_ = kModeAccelerateLowEnergy;
+      last_mode_ = Mode::kAccelerateLowEnergy;
       break;
     case Accelerate::kNoStretch:
-      last_mode_ = kModeAccelerateFail;
+      last_mode_ = Mode::kAccelerateFail;
       break;
     case Accelerate::kError:
-      // TODO(hlundin): Map to kModeError instead?
-      last_mode_ = kModeAccelerateFail;
+      // TODO(hlundin): Map to Modes::kError instead?
+      last_mode_ = Mode::kAccelerateFail;
       return kAccelerateError;
   }
 
@@ -1676,7 +1687,7 @@
 
   // If last packet was decoded as an inband CNG, set mode to CNG instead.
   if (speech_type == AudioDecoder::kComfortNoise) {
-    last_mode_ = kModeCodecInternalCng;
+    last_mode_ = Mode::kCodecInternalCng;
   }
   if (!play_dtmf) {
     dtmf_tone_generator_->Reset();
@@ -1718,17 +1729,17 @@
   stats_->PreemptiveExpandedSamples(samples_added);
   switch (return_code) {
     case PreemptiveExpand::kSuccess:
-      last_mode_ = kModePreemptiveExpandSuccess;
+      last_mode_ = Mode::kPreemptiveExpandSuccess;
       break;
     case PreemptiveExpand::kSuccessLowEnergy:
-      last_mode_ = kModePreemptiveExpandLowEnergy;
+      last_mode_ = Mode::kPreemptiveExpandLowEnergy;
       break;
     case PreemptiveExpand::kNoStretch:
-      last_mode_ = kModePreemptiveExpandFail;
+      last_mode_ = Mode::kPreemptiveExpandFail;
       break;
     case PreemptiveExpand::kError:
-      // TODO(hlundin): Map to kModeError instead?
-      last_mode_ = kModePreemptiveExpandFail;
+      // TODO(hlundin): Map to Modes::kError instead?
+      last_mode_ = Mode::kPreemptiveExpandFail;
       return kPreemptiveExpandError;
   }
 
@@ -1742,7 +1753,7 @@
 
   // If last packet was decoded as an inband CNG, set mode to CNG instead.
   if (speech_type == AudioDecoder::kComfortNoise) {
-    last_mode_ = kModeCodecInternalCng;
+    last_mode_ = Mode::kCodecInternalCng;
   }
   if (!play_dtmf) {
     dtmf_tone_generator_->Reset();
@@ -1769,7 +1780,7 @@
   int cn_return =
       comfort_noise_->Generate(output_size_samples_, algorithm_buffer_.get());
   expand_->Reset();
-  last_mode_ = kModeRfc3389Cng;
+  last_mode_ = Mode::kRfc3389Cng;
   if (!play_dtmf) {
     dtmf_tone_generator_->Reset();
   }
@@ -1788,7 +1799,7 @@
   RTC_DCHECK(normal_.get());
   normal_->Process(decoded_buffer, decoded_length, last_mode_,
                    algorithm_buffer_.get());
-  last_mode_ = kModeCodecInternalCng;
+  last_mode_ = Mode::kCodecInternalCng;
   expand_->Reset();
 }
 
@@ -1803,7 +1814,8 @@
   // switch from audio to DTMF. Issue 1545 is filed to track this.
   //
   //  bool dtmf_switch = false;
-  //  if ((last_mode_ != kModeDtmf) && dtmf_tone_generator_->initialized()) {
+  //  if ((last_mode_ != Modes::kDtmf) &&
+  //      dtmf_tone_generator_->initialized()) {
   //    // Special case; see below.
   //    // We must catch this before calling Generate, since |initialized| is
   //    // modified in that call.
@@ -1865,7 +1877,7 @@
   sync_buffer_->IncreaseEndTimestamp(
       static_cast<uint32_t>(output_size_samples_));
   expand_->Reset();
-  last_mode_ = kModeDtmf;
+  last_mode_ = Mode::kDtmf;
 
   // Set to false because the DTMF is already in the algorithm buffer.
   *play_dtmf = false;
@@ -2024,7 +2036,7 @@
   output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_);
   decoder_frame_length_ = 3 * output_size_samples_;  // Initialize to 30ms.
 
-  last_mode_ = kModeNormal;
+  last_mode_ = Mode::kNormal;
 
   ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
   if (cng_decoder)
@@ -2076,16 +2088,17 @@
 NetEqImpl::OutputType NetEqImpl::LastOutputType() {
   assert(vad_.get());
   assert(expand_.get());
-  if (last_mode_ == kModeCodecInternalCng || last_mode_ == kModeRfc3389Cng) {
+  if (last_mode_ == Mode::kCodecInternalCng ||
+      last_mode_ == Mode::kRfc3389Cng) {
     return OutputType::kCNG;
-  } else if (last_mode_ == kModeExpand && expand_->MuteFactor(0) == 0) {
+  } else if (last_mode_ == Mode::kExpand && expand_->MuteFactor(0) == 0) {
     // Expand mode has faded down to background noise only (very long expand).
     return OutputType::kPLCCNG;
-  } else if (last_mode_ == kModeExpand) {
+  } else if (last_mode_ == Mode::kExpand) {
     return OutputType::kPLC;
   } else if (vad_->running() && !vad_->active_speech()) {
     return OutputType::kVadPassive;
-  } else if (last_mode_ == kModeCodecPlc) {
+  } else if (last_mode_ == Mode::kCodecPlc) {
     return OutputType::kCodecPLC;
   } else {
     return OutputType::kNormalSpeech;
diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h
index aa7eba1..956cb6e 100644
--- a/modules/audio_coding/neteq/neteq_impl.h
+++ b/modules/audio_coding/neteq/neteq_impl.h
@@ -19,16 +19,16 @@
 
 #include "absl/types/optional.h"
 #include "api/audio/audio_frame.h"
+#include "api/neteq/neteq.h"
+#include "api/neteq/neteq_controller.h"
+#include "api/neteq/neteq_controller_factory.h"
+#include "api/neteq/tick_timer.h"
 #include "api/rtp_packet_info.h"
 #include "modules/audio_coding/neteq/audio_multi_vector.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/neteq_controller.h"
 #include "modules/audio_coding/neteq/packet.h"
 #include "modules/audio_coding/neteq/random_vector.h"
 #include "modules/audio_coding/neteq/statistics_calculator.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
 #include "rtc_base/constructor_magic.h"
 #include "rtc_base/critical_section.h"
 #include "rtc_base/thread_annotations.h"
@@ -96,10 +96,10 @@
     // before sending the struct to the NetEqImpl constructor. However, there
     // are dependencies between some of the classes inside the struct, so
     // swapping out one may make it necessary to re-create another one.
-    Dependencies(
-        const NetEq::Config& config,
-        Clock* clock,
-        const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory);
+    Dependencies(const NetEq::Config& config,
+                 Clock* clock,
+                 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
+                 const NetEqControllerFactory& controller_factory);
     ~Dependencies();
 
     Clock* const clock;
@@ -133,7 +133,7 @@
   int GetAudio(
       AudioFrame* audio_frame,
       bool* muted,
-      absl::optional<Operations> action_override = absl::nullopt) override;
+      absl::optional<Operation> action_override = absl::nullopt) override;
 
   void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
 
@@ -195,7 +195,7 @@
 
   // This accessor method is only intended for testing purposes.
   const SyncBuffer* sync_buffer_for_test() const;
-  Operations last_operation_for_test() const;
+  Operation last_operation_for_test() const;
 
  protected:
   static const int kOutputSizeMs = 10;
@@ -216,7 +216,7 @@
   // Returns 0 on success, otherwise an error code.
   int GetAudioInternal(AudioFrame* audio_frame,
                        bool* muted,
-                       absl::optional<Operations> action_override)
+                       absl::optional<Operation> action_override)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
 
   // Provides a decision to the GetAudioInternal method. The decision what to
@@ -224,11 +224,11 @@
   // |packet_list|, and a DTMF event to play is written to |dtmf_event|. When
   // DTMF should be played, |play_dtmf| is set to true by the method.
   // Returns 0 on success, otherwise an error code.
-  int GetDecision(Operations* operation,
+  int GetDecision(Operation* operation,
                   PacketList* packet_list,
                   DtmfEvent* dtmf_event,
                   bool* play_dtmf,
-                  absl::optional<Operations> action_override)
+                  absl::optional<Operation> action_override)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
 
   // Decodes the speech packets in |packet_list|, and writes the results to
@@ -238,7 +238,7 @@
   // to |speech_type|. If |packet_list| contains any SID frames for RFC 3389
   // comfort noise, those are not decoded.
   int Decode(PacketList* packet_list,
-             Operations* operation,
+             Operation* operation,
              int* decoded_length,
              AudioDecoder::SpeechType* speech_type)
       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
@@ -251,7 +251,7 @@
 
   // Sub-method to Decode(). Performs the actual decoding.
   int DecodeLoop(PacketList* packet_list,
-                 const Operations& operation,
+                 const Operation& operation,
                  AudioDecoder* decoder,
                  int* decoded_length,
                  AudioDecoder::SpeechType* speech_type)
@@ -374,8 +374,8 @@
   int last_output_sample_rate_hz_ RTC_GUARDED_BY(crit_sect_);
   size_t output_size_samples_ RTC_GUARDED_BY(crit_sect_);
   size_t decoder_frame_length_ RTC_GUARDED_BY(crit_sect_);
-  Modes last_mode_ RTC_GUARDED_BY(crit_sect_);
-  Operations last_operation_ RTC_GUARDED_BY(crit_sect_);
+  Mode last_mode_ RTC_GUARDED_BY(crit_sect_);
+  Operation last_operation_ RTC_GUARDED_BY(crit_sect_);
   size_t decoded_buffer_length_ RTC_GUARDED_BY(crit_sect_);
   std::unique_ptr<int16_t[]> decoded_buffer_ RTC_GUARDED_BY(crit_sect_);
   uint32_t playout_timestamp_ RTC_GUARDED_BY(crit_sect_);
diff --git a/modules/audio_coding/neteq/neteq_impl_unittest.cc b/modules/audio_coding/neteq/neteq_impl_unittest.cc
index 4a47a4d..8599807 100644
--- a/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -15,18 +15,20 @@
 #include <vector>
 
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/neteq/default_neteq_controller_factory.h"
+#include "api/neteq/neteq.h"
+#include "api/neteq/neteq_controller.h"
+#include "api/test/neteq_factory_with_codecs.h"
 #include "modules/audio_coding/neteq/accelerate.h"
 #include "modules/audio_coding/neteq/decision_logic.h"
 #include "modules/audio_coding/neteq/expand.h"
 #include "modules/audio_coding/neteq/histogram.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
 #include "modules/audio_coding/neteq/mock/mock_dtmf_buffer.h"
 #include "modules/audio_coding/neteq/mock/mock_dtmf_tone_generator.h"
 #include "modules/audio_coding/neteq/mock/mock_neteq_controller.h"
 #include "modules/audio_coding/neteq/mock/mock_packet_buffer.h"
 #include "modules/audio_coding/neteq/mock/mock_red_payload_splitter.h"
-#include "modules/audio_coding/neteq/neteq_controller.h"
 #include "modules/audio_coding/neteq/preemptive_expand.h"
 #include "modules/audio_coding/neteq/statistics_calculator.h"
 #include "modules/audio_coding/neteq/sync_buffer.h"
@@ -73,7 +75,8 @@
   void CreateInstance(
       const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
     ASSERT_TRUE(decoder_factory);
-    NetEqImpl::Dependencies deps(config_, &clock_, decoder_factory);
+    NetEqImpl::Dependencies deps(config_, &clock_, decoder_factory,
+                                 DefaultNetEqControllerFactory());
 
     // Get a local pointer to NetEq's TickTimer object.
     tick_timer_ = deps.tick_timer.get();
@@ -249,9 +252,8 @@
 TEST(NetEq, CreateAndDestroy) {
   NetEq::Config config;
   SimulatedClock clock(0);
-  NetEq* neteq =
-      NetEq::Create(config, &clock, CreateBuiltinAudioDecoderFactory());
-  delete neteq;
+  std::unique_ptr<NetEqFactory> neteq_factory = CreateNetEqFactoryWithCodecs();
+  std::unique_ptr<NetEq> neteq = neteq_factory->CreateNetEq(config, &clock);
 }
 
 TEST_F(NetEqImplTest, RegisterPayloadType) {
@@ -1378,7 +1380,7 @@
   CreateInstance();
   EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
       .Times(1)
-      .WillOnce(Return(kNormal));
+      .WillOnce(Return(NetEq::Operation::kNormal));
 
   const int kPayloadLengthSamples = 80;
   const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;  // PCM 16-bit.
@@ -1518,7 +1520,8 @@
 
   bool muted;
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
-  EXPECT_EQ(kCodecInternalCng, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kCodecInternalCng,
+            neteq_->last_operation_for_test());
 }
 
 TEST_F(NetEqImplTest120ms, Normal) {
@@ -1528,7 +1531,7 @@
   InsertPacket(first_timestamp());
   GetFirstPacket();
 
-  EXPECT_EQ(kNormal, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kNormal, neteq_->last_operation_for_test());
 }
 
 TEST_F(NetEqImplTest120ms, Merge) {
@@ -1541,16 +1544,16 @@
   GetFirstPacket();
   bool muted;
   EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
-      .WillOnce(Return(kExpand));
+      .WillOnce(Return(NetEq::Operation::kExpand));
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
 
   InsertPacket(first_timestamp() + 2 * timestamp_diff_between_packets());
 
   EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
-      .WillOnce(Return(kMerge));
+      .WillOnce(Return(NetEq::Operation::kMerge));
 
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
-  EXPECT_EQ(kMerge, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kMerge, neteq_->last_operation_for_test());
 }
 
 TEST_F(NetEqImplTest120ms, Expand) {
@@ -1562,7 +1565,7 @@
 
   bool muted;
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
-  EXPECT_EQ(kExpand, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kExpand, neteq_->last_operation_for_test());
 }
 
 TEST_F(NetEqImplTest120ms, FastAccelerate) {
@@ -1575,11 +1578,12 @@
 
   EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
       .Times(1)
-      .WillOnce(Return(kFastAccelerate));
+      .WillOnce(Return(NetEq::Operation::kFastAccelerate));
 
   bool muted;
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
-  EXPECT_EQ(kFastAccelerate, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kFastAccelerate,
+            neteq_->last_operation_for_test());
 }
 
 TEST_F(NetEqImplTest120ms, PreemptiveExpand) {
@@ -1593,11 +1597,12 @@
 
   EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
       .Times(1)
-      .WillOnce(Return(kPreemptiveExpand));
+      .WillOnce(Return(NetEq::Operation::kPreemptiveExpand));
 
   bool muted;
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
-  EXPECT_EQ(kPreemptiveExpand, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kPreemptiveExpand,
+            neteq_->last_operation_for_test());
 }
 
 TEST_F(NetEqImplTest120ms, Accelerate) {
@@ -1611,11 +1616,11 @@
 
   EXPECT_CALL(*mock_neteq_controller_, GetDecision(_, _))
       .Times(1)
-      .WillOnce(Return(kAccelerate));
+      .WillOnce(Return(NetEq::Operation::kAccelerate));
 
   bool muted;
   EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output_, &muted));
-  EXPECT_EQ(kAccelerate, neteq_->last_operation_for_test());
+  EXPECT_EQ(NetEq::Operation::kAccelerate, neteq_->last_operation_for_test());
 }
 
 }  // namespace webrtc
diff --git a/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
index aa61d65..0e24f68 100644
--- a/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
@@ -13,7 +13,9 @@
 #include "absl/memory/memory.h"
 #include "api/audio/audio_frame.h"
 #include "api/audio_codecs/audio_decoder.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
+#include "api/neteq/custom_neteq_factory.h"
+#include "api/neteq/default_neteq_controller_factory.h"
+#include "api/neteq/neteq.h"
 #include "modules/audio_coding/neteq/tools/rtp_generator.h"
 #include "rtc_base/ref_counted_object.h"
 #include "system_wrappers/include/clock.h"
@@ -23,6 +25,19 @@
 namespace webrtc {
 namespace test {
 
+namespace {
+
+std::unique_ptr<NetEq> CreateNetEq(
+    const NetEq::Config& config,
+    Clock* clock,
+    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
+  CustomNetEqFactory neteq_factory(
+      decoder_factory, std::make_unique<DefaultNetEqControllerFactory>());
+  return neteq_factory.CreateNetEq(config, clock);
+}
+
+}  // namespace
+
 using ::testing::_;
 using ::testing::Return;
 using ::testing::SetArgPointee;
@@ -162,8 +177,7 @@
         packet_loss_interval_(0xffffffff) {
     NetEq::Config config;
     config.sample_rate_hz = format.clockrate_hz;
-    neteq_ = absl::WrapUnique(
-        NetEq::Create(config, Clock::GetRealTimeClock(), decoder_factory_));
+    neteq_ = CreateNetEq(config, Clock::GetRealTimeClock(), decoder_factory_);
     neteq_->RegisterPayloadType(kPayloadType, format);
   }
 
diff --git a/modules/audio_coding/neteq/neteq_stereo_unittest.cc b/modules/audio_coding/neteq/neteq_stereo_unittest.cc
index e59637b..14979ae 100644
--- a/modules/audio_coding/neteq/neteq_stereo_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_stereo_unittest.cc
@@ -17,8 +17,9 @@
 
 #include "api/audio/audio_frame.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/neteq/neteq.h"
+#include "api/test/neteq_factory_with_codecs.h"
 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "modules/audio_coding/neteq/tools/input_audio_file.h"
 #include "modules/audio_coding/neteq/tools/rtp_generator.h"
 #include "rtc_base/strings/string_builder.h"
@@ -67,10 +68,10 @@
         last_arrival_time_(0) {
     NetEq::Config config;
     config.sample_rate_hz = sample_rate_hz_;
-    rtc::scoped_refptr<AudioDecoderFactory> factory =
-        CreateBuiltinAudioDecoderFactory();
-    neteq_mono_ = NetEq::Create(config, &clock_, factory);
-    neteq_ = NetEq::Create(config, &clock_, factory);
+    std::unique_ptr<NetEqFactory> neteq_factory =
+        CreateNetEqFactoryWithCodecs();
+    neteq_mono_ = neteq_factory->CreateNetEq(config, &clock_);
+    neteq_ = neteq_factory->CreateNetEq(config, &clock_);
     input_ = new int16_t[frame_size_samples_];
     encoded_ = new uint8_t[2 * frame_size_samples_];
     input_multi_channel_ = new int16_t[frame_size_samples_ * num_channels_];
@@ -79,8 +80,6 @@
   }
 
   ~NetEqStereoTest() {
-    delete neteq_mono_;
-    delete neteq_;
     delete[] input_;
     delete[] encoded_;
     delete[] input_multi_channel_;
@@ -206,8 +205,8 @@
   const size_t frame_size_samples_;
   const size_t output_size_samples_;
   SimulatedClock clock_;
-  NetEq* neteq_mono_;
-  NetEq* neteq_;
+  std::unique_ptr<NetEq> neteq_mono_;
+  std::unique_ptr<NetEq> neteq_;
   test::RtpGenerator rtp_generator_mono_;
   test::RtpGenerator rtp_generator_;
   int16_t* input_;
diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc
index 443c1a0..a192611 100644
--- a/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_unittest.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/audio_coding/neteq/include/neteq.h"
+#include "api/neteq/neteq.h"
 
 #include <math.h>
 #include <stdlib.h>
@@ -23,6 +23,7 @@
 #include "absl/flags/flag.h"
 #include "api/audio/audio_frame.h"
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/test/neteq_factory_with_codecs.h"
 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
 #include "modules/audio_coding/neteq/tools/audio_loop.h"
 #include "modules/audio_coding/neteq/tools/neteq_packet_source_input.h"
@@ -287,7 +288,7 @@
   void DuplicateCng();
 
   SimulatedClock clock_;
-  NetEq* neteq_;
+  std::unique_ptr<NetEq> neteq_;
   NetEq::Config config_;
   std::unique_ptr<test::RtpFileSource> rtp_source_;
   std::unique_ptr<test::Packet> packet_;
@@ -305,7 +306,6 @@
 
 NetEqDecodingTest::NetEqDecodingTest()
     : clock_(0),
-      neteq_(NULL),
       config_(),
       output_sample_rate_(kInitSampleRateHz),
       algorithmic_delay_ms_(0) {
@@ -313,17 +313,16 @@
 }
 
 void NetEqDecodingTest::SetUp() {
-  neteq_ = NetEq::Create(config_, &clock_, CreateBuiltinAudioDecoderFactory());
+  std::unique_ptr<NetEqFactory> neteq_factory = CreateNetEqFactoryWithCodecs();
+  neteq_ = neteq_factory->CreateNetEq(config_, &clock_);
   NetEqNetworkStatistics stat;
   ASSERT_EQ(0, neteq_->NetworkStatistics(&stat));
   algorithmic_delay_ms_ = stat.current_buffer_size_ms;
   ASSERT_TRUE(neteq_);
-  LoadDecoders(neteq_);
+  LoadDecoders(neteq_.get());
 }
 
-void NetEqDecodingTest::TearDown() {
-  delete neteq_;
-}
+void NetEqDecodingTest::TearDown() {}
 
 void NetEqDecodingTest::OpenInputFile(const std::string& rtp_file) {
   rtp_source_.reset(test::RtpFileSource::Create(rtp_file));
@@ -1366,8 +1365,9 @@
   }
 
   void CreateSecondInstance() {
-    neteq2_.reset(
-        NetEq::Create(config2_, &clock_, CreateBuiltinAudioDecoderFactory()));
+    std::unique_ptr<NetEqFactory> neteq_factory =
+        CreateNetEqFactoryWithCodecs();
+    neteq2_ = neteq_factory->CreateNetEq(config2_, &clock_);
     ASSERT_TRUE(neteq2_);
     LoadDecoders(neteq2_.get());
   }
@@ -1658,7 +1658,7 @@
 
   // We have two packets in the buffer and kAccelerate operation will
   // extract 20 ms of data.
-  neteq_->GetAudio(&out_frame_, &muted, Operations::kAccelerate);
+  neteq_->GetAudio(&out_frame_, &muted, NetEq::Operation::kAccelerate);
 
   // Check jitter buffer delay.
   NetEqLifetimeStatistics stats = neteq_->GetLifetimeStatistics();
diff --git a/modules/audio_coding/neteq/normal.cc b/modules/audio_coding/neteq/normal.cc
index 713bfb6..967deea 100644
--- a/modules/audio_coding/neteq/normal.cc
+++ b/modules/audio_coding/neteq/normal.cc
@@ -26,7 +26,7 @@
 
 int Normal::Process(const int16_t* input,
                     size_t length,
-                    Modes last_mode,
+                    NetEq::Mode last_mode,
                     AudioMultiVector* output) {
   if (length == 0) {
     // Nothing to process.
@@ -52,7 +52,7 @@
 
   // Check if last RecOut call resulted in an Expand. If so, we have to take
   // care of some cross-fading and unmuting.
-  if (last_mode == kModeExpand) {
+  if (last_mode == NetEq::Mode::kExpand) {
     // Generate interpolation data using Expand.
     // First, set Expand parameters to appropriate values.
     expand_->SetParametersForNormalAfterExpand();
@@ -144,7 +144,7 @@
       RTC_DCHECK_GT(win_up_Q14,
                     (1 << 14) - 32);  // Worst case rouding is a length of 34
     }
-  } else if (last_mode == kModeRfc3389Cng) {
+  } else if (last_mode == NetEq::Mode::kRfc3389Cng) {
     RTC_DCHECK_EQ(output->Channels(), 1);  // Not adapted for multi-channel yet.
     static const size_t kCngLength = 48;
     RTC_DCHECK_LE(8 * fs_mult, kCngLength);
diff --git a/modules/audio_coding/neteq/normal.h b/modules/audio_coding/neteq/normal.h
index 2059c5a..d8c13e6 100644
--- a/modules/audio_coding/neteq/normal.h
+++ b/modules/audio_coding/neteq/normal.h
@@ -14,7 +14,7 @@
 #include <stdint.h>
 #include <string.h>  // Access to size_t.
 
-#include "modules/audio_coding/neteq/defines.h"
+#include "api/neteq/neteq.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/constructor_magic.h"
 #include "rtc_base/numerics/safe_conversions.h"
@@ -54,7 +54,7 @@
   // GetAudio call (i.e., not the current one).
   int Process(const int16_t* input,
               size_t length,
-              Modes last_mode,
+              NetEq::Mode last_mode,
               AudioMultiVector* output);
 
  private:
diff --git a/modules/audio_coding/neteq/normal_unittest.cc b/modules/audio_coding/neteq/normal_unittest.cc
index 222fcaa..36751f8 100644
--- a/modules/audio_coding/neteq/normal_unittest.cc
+++ b/modules/audio_coding/neteq/normal_unittest.cc
@@ -70,7 +70,7 @@
   AudioMultiVector output(channels);
 
   // Zero input length.
-  EXPECT_EQ(0, normal.Process(input, 0, kModeExpand, &output));
+  EXPECT_EQ(0, normal.Process(input, 0, NetEq::Mode::kExpand, &output));
   EXPECT_EQ(0u, output.Size());
 
   // Try to make energy_length >> scaling = 0;
@@ -82,8 +82,8 @@
   // will be zero, and scaling will be >= 6. Thus, energy_length >> scaling = 0,
   // and using this as a denominator would lead to problems.
   int input_size_samples = 63;
-  EXPECT_EQ(input_size_samples,
-            normal.Process(input, input_size_samples, kModeExpand, &output));
+  EXPECT_EQ(input_size_samples, normal.Process(input, input_size_samples,
+                                               NetEq::Mode::kExpand, &output));
 
   EXPECT_CALL(db, Die());      // Called when |db| goes out of scope.
   EXPECT_CALL(expand, Die());  // Called when |expand| goes out of scope.
@@ -106,7 +106,7 @@
 
   // Let the number of samples be one sample less than 80 samples per channel.
   size_t input_len = 80 * channels - 1;
-  EXPECT_EQ(0, normal.Process(input, input_len, kModeExpand, &output));
+  EXPECT_EQ(0, normal.Process(input, input_len, NetEq::Mode::kExpand, &output));
   EXPECT_EQ(0u, output.Size());
 
   EXPECT_CALL(db, Die());      // Called when |db| goes out of scope.
@@ -132,8 +132,9 @@
   EXPECT_CALL(expand, SetParametersForNormalAfterExpand());
   EXPECT_CALL(expand, Process(_)).WillOnce(Invoke(ExpandProcess120ms));
   EXPECT_CALL(expand, Reset());
-  EXPECT_EQ(static_cast<int>(kPacketsizeBytes),
-            normal.Process(input, kPacketsizeBytes, kModeExpand, &output));
+  EXPECT_EQ(
+      static_cast<int>(kPacketsizeBytes),
+      normal.Process(input, kPacketsizeBytes, NetEq::Mode::kExpand, &output));
 
   EXPECT_EQ(kPacketsizeBytes, output.Size());
 
diff --git a/modules/audio_coding/neteq/packet.h b/modules/audio_coding/neteq/packet.h
index 238e769..4455494 100644
--- a/modules/audio_coding/neteq/packet.h
+++ b/modules/audio_coding/neteq/packet.h
@@ -17,8 +17,8 @@
 #include <memory>
 
 #include "api/audio_codecs/audio_decoder.h"
+#include "api/neteq/tick_timer.h"
 #include "api/rtp_packet_info.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/checks.h"
 
diff --git a/modules/audio_coding/neteq/packet_buffer.cc b/modules/audio_coding/neteq/packet_buffer.cc
index 540d279..059308f 100644
--- a/modules/audio_coding/neteq/packet_buffer.cc
+++ b/modules/audio_coding/neteq/packet_buffer.cc
@@ -21,9 +21,9 @@
 #include <utility>
 
 #include "api/audio_codecs/audio_decoder.h"
+#include "api/neteq/tick_timer.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"
 #include "rtc_base/numerics/safe_conversions.h"
diff --git a/modules/audio_coding/neteq/packet_buffer_unittest.cc b/modules/audio_coding/neteq/packet_buffer_unittest.cc
index 0b638bf..0aff955 100644
--- a/modules/audio_coding/neteq/packet_buffer_unittest.cc
+++ b/modules/audio_coding/neteq/packet_buffer_unittest.cc
@@ -15,10 +15,10 @@
 #include <memory>
 
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/neteq/tick_timer.h"
 #include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
 #include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
 #include "modules/audio_coding/neteq/packet.h"
-#include "modules/audio_coding/neteq/tick_timer.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
 
diff --git a/modules/audio_coding/neteq/statistics_calculator.h b/modules/audio_coding/neteq/statistics_calculator.h
index a438811..38e463c 100644
--- a/modules/audio_coding/neteq/statistics_calculator.h
+++ b/modules/audio_coding/neteq/statistics_calculator.h
@@ -14,7 +14,7 @@
 #include <deque>
 #include <string>
 
-#include "modules/audio_coding/neteq/include/neteq.h"
+#include "api/neteq/neteq.h"
 #include "rtc_base/constructor_magic.h"
 
 namespace webrtc {
diff --git a/modules/audio_coding/neteq/tick_timer.cc b/modules/audio_coding/neteq/tick_timer.cc
deleted file mode 100644
index 17f83b1..0000000
--- a/modules/audio_coding/neteq/tick_timer.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Copyright (c) 2016 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_coding/neteq/tick_timer.h"
-
-namespace webrtc {
-
-TickTimer::Stopwatch::Stopwatch(const TickTimer& ticktimer)
-    : ticktimer_(ticktimer), starttick_(ticktimer.ticks()) {}
-
-TickTimer::Countdown::Countdown(const TickTimer& ticktimer,
-                                uint64_t ticks_to_count)
-    : stopwatch_(ticktimer.GetNewStopwatch()),
-      ticks_to_count_(ticks_to_count) {}
-
-TickTimer::Countdown::~Countdown() = default;
-
-}  // namespace webrtc
diff --git a/modules/audio_coding/neteq/tick_timer.h b/modules/audio_coding/neteq/tick_timer.h
deleted file mode 100644
index 2504ce3..0000000
--- a/modules/audio_coding/neteq/tick_timer.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- *  Copyright (c) 2016 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_CODING_NETEQ_TICK_TIMER_H_
-#define MODULES_AUDIO_CODING_NETEQ_TICK_TIMER_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "rtc_base/checks.h"
-#include "rtc_base/constructor_magic.h"
-
-namespace webrtc {
-
-// Implements a time counter. The counter is advanced with the Increment()
-// methods, and is queried with the ticks() accessor. It is assumed that one
-// "tick" och the counter corresponds to 10 ms.
-// A TickTimer object can provide two types of associated time-measuring
-// objects: Stopwatch and Countdown.
-class TickTimer {
- public:
-  // Stopwatch measures time elapsed since it was started, by querying the
-  // associated TickTimer for the current time. The intended use is to request a
-  // new Stopwatch object from a TickTimer object with the GetNewStopwatch()
-  // method. Note: since the Stopwatch object contains a reference to the
-  // TickTimer it is associated with, it cannot outlive the TickTimer.
-  class Stopwatch {
-   public:
-    explicit Stopwatch(const TickTimer& ticktimer);
-
-    uint64_t ElapsedTicks() const { return ticktimer_.ticks() - starttick_; }
-
-    uint64_t ElapsedMs() const {
-      const uint64_t elapsed_ticks = ticktimer_.ticks() - starttick_;
-      const int ms_per_tick = ticktimer_.ms_per_tick();
-      return elapsed_ticks < UINT64_MAX / ms_per_tick
-                 ? elapsed_ticks * ms_per_tick
-                 : UINT64_MAX;
-    }
-
-   private:
-    const TickTimer& ticktimer_;
-    const uint64_t starttick_;
-  };
-
-  // Countdown counts down from a given start value with each tick of the
-  // associated TickTimer, until zero is reached. The Finished() method will
-  // return true if zero has been reached, false otherwise. The intended use is
-  // to request a new Countdown object from a TickTimer object with the
-  // GetNewCountdown() method. Note: since the Countdown object contains a
-  // reference to the TickTimer it is associated with, it cannot outlive the
-  // TickTimer.
-  class Countdown {
-   public:
-    Countdown(const TickTimer& ticktimer, uint64_t ticks_to_count);
-
-    ~Countdown();
-
-    bool Finished() const {
-      return stopwatch_->ElapsedTicks() >= ticks_to_count_;
-    }
-
-   private:
-    const std::unique_ptr<Stopwatch> stopwatch_;
-    const uint64_t ticks_to_count_;
-  };
-
-  TickTimer() : TickTimer(10) {}
-  explicit TickTimer(int ms_per_tick) : ms_per_tick_(ms_per_tick) {
-    RTC_DCHECK_GT(ms_per_tick_, 0);
-  }
-
-  void Increment() { ++ticks_; }
-
-  // Mainly intended for testing.
-  void Increment(uint64_t x) { ticks_ += x; }
-
-  uint64_t ticks() const { return ticks_; }
-
-  int ms_per_tick() const { return ms_per_tick_; }
-
-  // Returns a new Stopwatch object, based on the current TickTimer. Note that
-  // the new Stopwatch object contains a reference to the current TickTimer,
-  // and must therefore not outlive the TickTimer.
-  std::unique_ptr<Stopwatch> GetNewStopwatch() const {
-    return std::unique_ptr<Stopwatch>(new Stopwatch(*this));
-  }
-
-  // Returns a new Countdown object, based on the current TickTimer. Note that
-  // the new Countdown object contains a reference to the current TickTimer,
-  // and must therefore not outlive the TickTimer.
-  std::unique_ptr<Countdown> GetNewCountdown(uint64_t ticks_to_count) const {
-    return std::unique_ptr<Countdown>(new Countdown(*this, ticks_to_count));
-  }
-
- private:
-  uint64_t ticks_ = 0;
-  const int ms_per_tick_;
-  RTC_DISALLOW_COPY_AND_ASSIGN(TickTimer);
-};
-
-}  // namespace webrtc
-#endif  // MODULES_AUDIO_CODING_NETEQ_TICK_TIMER_H_
diff --git a/modules/audio_coding/neteq/tick_timer_unittest.cc b/modules/audio_coding/neteq/tick_timer_unittest.cc
deleted file mode 100644
index c501329..0000000
--- a/modules/audio_coding/neteq/tick_timer_unittest.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *  Copyright (c) 2016 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_coding/neteq/tick_timer.h"
-
-#include <memory>
-
-#include "test/gmock.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-
-// Verify that the default value for ms_per_tick is 10.
-TEST(TickTimer, DefaultMsPerTick) {
-  TickTimer tt;
-  EXPECT_EQ(10, tt.ms_per_tick());
-}
-
-TEST(TickTimer, CustomMsPerTick) {
-  TickTimer tt(17);
-  EXPECT_EQ(17, tt.ms_per_tick());
-}
-
-TEST(TickTimer, Increment) {
-  TickTimer tt;
-  EXPECT_EQ(0u, tt.ticks());
-  tt.Increment();
-  EXPECT_EQ(1u, tt.ticks());
-
-  for (int i = 0; i < 17; ++i) {
-    tt.Increment();
-  }
-  EXPECT_EQ(18u, tt.ticks());
-
-  tt.Increment(17);
-  EXPECT_EQ(35u, tt.ticks());
-}
-
-TEST(TickTimer, WrapAround) {
-  TickTimer tt;
-  tt.Increment(UINT64_MAX);
-  EXPECT_EQ(UINT64_MAX, tt.ticks());
-  tt.Increment();
-  EXPECT_EQ(0u, tt.ticks());
-}
-
-TEST(TickTimer, Stopwatch) {
-  TickTimer tt;
-  // Increment it a "random" number of steps.
-  tt.Increment(17);
-
-  std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
-  ASSERT_TRUE(sw);
-
-  EXPECT_EQ(0u, sw->ElapsedTicks());  // Starts at zero.
-  EXPECT_EQ(0u, sw->ElapsedMs());
-  tt.Increment();
-  EXPECT_EQ(1u, sw->ElapsedTicks());  // Increases with the TickTimer.
-  EXPECT_EQ(10u, sw->ElapsedMs());
-}
-
-TEST(TickTimer, StopwatchWrapAround) {
-  TickTimer tt;
-  tt.Increment(UINT64_MAX);
-
-  std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
-  ASSERT_TRUE(sw);
-
-  tt.Increment();
-  EXPECT_EQ(0u, tt.ticks());
-  EXPECT_EQ(1u, sw->ElapsedTicks());
-  EXPECT_EQ(10u, sw->ElapsedMs());
-
-  tt.Increment();
-  EXPECT_EQ(1u, tt.ticks());
-  EXPECT_EQ(2u, sw->ElapsedTicks());
-  EXPECT_EQ(20u, sw->ElapsedMs());
-}
-
-TEST(TickTimer, StopwatchMsOverflow) {
-  TickTimer tt;
-  std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
-  ASSERT_TRUE(sw);
-
-  tt.Increment(UINT64_MAX / 10);
-  EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
-
-  tt.Increment();
-  EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
-
-  tt.Increment(UINT64_MAX - tt.ticks());
-  EXPECT_EQ(UINT64_MAX, tt.ticks());
-  EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
-}
-
-TEST(TickTimer, StopwatchWithCustomTicktime) {
-  const int kMsPerTick = 17;
-  TickTimer tt(kMsPerTick);
-  std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
-  ASSERT_TRUE(sw);
-
-  EXPECT_EQ(0u, sw->ElapsedMs());
-  tt.Increment();
-  EXPECT_EQ(static_cast<uint64_t>(kMsPerTick), sw->ElapsedMs());
-}
-
-TEST(TickTimer, Countdown) {
-  TickTimer tt;
-  // Increment it a "random" number of steps.
-  tt.Increment(4711);
-
-  std::unique_ptr<TickTimer::Countdown> cd = tt.GetNewCountdown(17);
-  ASSERT_TRUE(cd);
-
-  EXPECT_FALSE(cd->Finished());
-  tt.Increment();
-  EXPECT_FALSE(cd->Finished());
-
-  tt.Increment(16);  // Total increment is now 17.
-  EXPECT_TRUE(cd->Finished());
-
-  // Further increments do not change the state.
-  tt.Increment();
-  EXPECT_TRUE(cd->Finished());
-  tt.Increment(1234);
-  EXPECT_TRUE(cd->Finished());
-}
-}  // namespace webrtc
diff --git a/modules/audio_coding/neteq/tools/neteq_performance_test.cc b/modules/audio_coding/neteq/tools/neteq_performance_test.cc
index dfd61d8..d963903 100644
--- a/modules/audio_coding/neteq/tools/neteq_performance_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_performance_test.cc
@@ -11,9 +11,9 @@
 #include "modules/audio_coding/neteq/tools/neteq_performance_test.h"
 
 #include "api/audio/audio_frame.h"
-#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/neteq/neteq.h"
+#include "api/test/neteq_factory_with_codecs.h"
 #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "modules/audio_coding/neteq/tools/audio_loop.h"
 #include "modules/audio_coding/neteq/tools/rtp_generator.h"
 #include "rtc_base/checks.h"
@@ -40,8 +40,8 @@
   NetEq::Config config;
   config.sample_rate_hz = kSampRateHz;
   webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
-  NetEq* neteq =
-      NetEq::Create(config, clock, CreateBuiltinAudioDecoderFactory());
+  std::unique_ptr<NetEqFactory> neteq_factory = CreateNetEqFactoryWithCodecs();
+  auto neteq = neteq_factory->CreateNetEq(config, clock);
   // Register decoder in |neteq|.
   if (!neteq->RegisterPayloadType(kPayloadType,
                                   SdpAudioFormat("l16", kSampRateHz, 1)))
@@ -119,7 +119,6 @@
     }
   }
   int64_t end_time_ms = clock->TimeInMilliseconds();
-  delete neteq;
   return end_time_ms - start_time_ms;
 }
 
diff --git a/modules/audio_coding/neteq/tools/neteq_quality_test.cc b/modules/audio_coding/neteq/tools/neteq_quality_test.cc
index 3b3d337..ba53954 100644
--- a/modules/audio_coding/neteq/tools/neteq_quality_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_quality_test.cc
@@ -15,6 +15,8 @@
 #include <cmath>
 
 #include "absl/flags/flag.h"
+#include "api/neteq/custom_neteq_factory.h"
+#include "api/neteq/default_neteq_controller_factory.h"
 #include "modules/audio_coding/neteq/tools/neteq_quality_test.h"
 #include "modules/audio_coding/neteq/tools/output_audio_file.h"
 #include "modules/audio_coding/neteq/tools/output_wav_file.h"
@@ -87,6 +89,19 @@
 namespace webrtc {
 namespace test {
 
+namespace {
+
+std::unique_ptr<NetEq> CreateNetEq(
+    const NetEq::Config& config,
+    Clock* clock,
+    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
+  CustomNetEqFactory neteq_factory(
+      decoder_factory, std::make_unique<DefaultNetEqControllerFactory>());
+  return neteq_factory.CreateNetEq(config, clock);
+}
+
+}  // namespace
+
 const uint8_t kPayloadType = 95;
 const int kOutputSizeMs = 10;
 const int kInitSeed = 0x12345678;
@@ -228,8 +243,7 @@
 
   NetEq::Config config;
   config.sample_rate_hz = out_sampling_khz_ * 1000;
-  neteq_.reset(
-      NetEq::Create(config, Clock::GetRealTimeClock(), decoder_factory));
+  neteq_ = CreateNetEq(config, Clock::GetRealTimeClock(), decoder_factory);
   max_payload_bytes_ = in_size_samples_ * channels_ * sizeof(int16_t);
   in_data_.reset(new int16_t[in_size_samples_ * channels_]);
 }
diff --git a/modules/audio_coding/neteq/tools/neteq_quality_test.h b/modules/audio_coding/neteq/tools/neteq_quality_test.h
index 8bf5e5a..11d347a 100644
--- a/modules/audio_coding/neteq/tools/neteq_quality_test.h
+++ b/modules/audio_coding/neteq/tools/neteq_quality_test.h
@@ -15,7 +15,7 @@
 #include <memory>
 
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
+#include "api/neteq/neteq.h"
 #include "modules/audio_coding/neteq/tools/audio_sink.h"
 #include "modules/audio_coding/neteq/tools/input_audio_file.h"
 #include "modules/audio_coding/neteq/tools/rtp_generator.h"
diff --git a/modules/audio_coding/neteq/tools/neteq_test.cc b/modules/audio_coding/neteq/tools/neteq_test.cc
index c4fdef0..50d8ba1 100644
--- a/modules/audio_coding/neteq/tools/neteq_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test.cc
@@ -13,6 +13,8 @@
 #include <iomanip>
 #include <iostream>
 
+#include "api/neteq/custom_neteq_factory.h"
+#include "api/neteq/default_neteq_controller_factory.h"
 #include "modules/rtp_rtcp/source/byte_io.h"
 #include "system_wrappers/include/clock.h"
 
@@ -20,23 +22,32 @@
 namespace test {
 namespace {
 
-absl::optional<Operations> ActionToOperations(
+absl::optional<NetEq::Operation> ActionToOperations(
     absl::optional<NetEqSimulator::Action> a) {
   if (!a) {
     return absl::nullopt;
   }
   switch (*a) {
     case NetEqSimulator::Action::kAccelerate:
-      return absl::make_optional(kAccelerate);
+      return absl::make_optional(NetEq::Operation::kAccelerate);
     case NetEqSimulator::Action::kExpand:
-      return absl::make_optional(kExpand);
+      return absl::make_optional(NetEq::Operation::kExpand);
     case NetEqSimulator::Action::kNormal:
-      return absl::make_optional(kNormal);
+      return absl::make_optional(NetEq::Operation::kNormal);
     case NetEqSimulator::Action::kPreemptiveExpand:
-      return absl::make_optional(kPreemptiveExpand);
+      return absl::make_optional(NetEq::Operation::kPreemptiveExpand);
   }
 }
 
+std::unique_ptr<NetEq> CreateNetEq(
+    const NetEq::Config& config,
+    Clock* clock,
+    const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) {
+  CustomNetEqFactory neteq_factory(
+      decoder_factory, std::make_unique<DefaultNetEqControllerFactory>());
+  return neteq_factory.CreateNetEq(config, clock);
+}
+
 }  // namespace
 
 void DefaultNetEqTestErrorCallback::OnInsertPacketError(
@@ -59,7 +70,7 @@
                      std::unique_ptr<AudioSink> output,
                      Callbacks callbacks)
     : clock_(0),
-      neteq_(NetEq::Create(config, &clock_, decoder_factory)),
+      neteq_(CreateNetEq(config, &clock_, decoder_factory)),
       input_(std::move(input)),
       output_(std::move(output)),
       callbacks_(callbacks),
diff --git a/modules/audio_coding/neteq/tools/neteq_test.h b/modules/audio_coding/neteq/tools/neteq_test.h
index 3cf105c..c6dbca7 100644
--- a/modules/audio_coding/neteq/tools/neteq_test.h
+++ b/modules/audio_coding/neteq/tools/neteq_test.h
@@ -19,8 +19,8 @@
 
 #include "absl/types/optional.h"
 #include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/neteq/neteq.h"
 #include "api/test/neteq_simulator.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
 #include "modules/audio_coding/neteq/tools/audio_sink.h"
 #include "modules/audio_coding/neteq/tools/neteq_input.h"
 #include "system_wrappers/include/clock.h"
diff --git a/modules/audio_coding/neteq/tools/neteq_test_factory.cc b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
index c50f7d9..55bc46d 100644
--- a/modules/audio_coding/neteq/tools/neteq_test_factory.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test_factory.cc
@@ -23,7 +23,7 @@
 #include <utility>
 
 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
-#include "modules/audio_coding/neteq/include/neteq.h"
+#include "api/neteq/neteq.h"
 #include "modules/audio_coding/neteq/tools/audio_sink.h"
 #include "modules/audio_coding/neteq/tools/fake_decode_from_file.h"
 #include "modules/audio_coding/neteq/tools/initial_packet_inserter_neteq_input.h"