Move the AudioDecoder interface out of NetEq

It belongs with the codecs, next to the AudioEncoder interface.

R=andrew@webrtc.org, henrik.lundin@webrtc.org, kjellander@webrtc.org

Previously committed here: https://code.google.com/p/webrtc/source/detail?r=7798
and reverted here: https://code.google.com/p/webrtc/source/detail?r=7799

Review URL: https://webrtc-codereview.appspot.com/27309004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7839 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn
index 184d37e..fb6120f 100644
--- a/webrtc/modules/audio_coding/BUILD.gn
+++ b/webrtc/modules/audio_coding/BUILD.gn
@@ -113,6 +113,15 @@
   }
 }
 
+source_set("audio_decoder_interface") {
+  sources = [
+    "codecs/audio_decoder.cc",
+    "codecs/audio_decoder.h",
+  ]
+  configs += [ "../..:common_config" ]
+  public_configs = [ "../..:common_inherited_config" ]
+}
+
 config("cng_config") {
   include_dirs = [
     "../../..",
@@ -636,7 +645,6 @@
 
 source_set("neteq") {
   sources = [
-    "neteq/interface/audio_decoder.h",
     "neteq/interface/neteq.h",
     "neteq/accelerate.cc",
     "neteq/accelerate.h",
@@ -644,7 +652,6 @@
     "neteq/audio_classifier.h",
     "neteq/audio_decoder_impl.cc",
     "neteq/audio_decoder_impl.h",
-    "neteq/audio_decoder.cc",
     "neteq/audio_multi_vector.cc",
     "neteq/audio_multi_vector.h",
     "neteq/audio_vector.cc",
@@ -721,6 +728,7 @@
   }
 
   deps = [
+    ":audio_decoder_interface",
     ":cng",
     ":g711",
     ":g722",
diff --git a/webrtc/modules/audio_coding/codecs/audio_decoder.cc b/webrtc/modules/audio_coding/codecs/audio_decoder.cc
new file mode 100644
index 0000000..6114e70
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/audio_decoder.cc
@@ -0,0 +1,72 @@
+/*
+ *  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 "webrtc/modules/audio_coding/codecs/audio_decoder.h"
+
+#include <assert.h>
+
+#include "webrtc/base/checks.h"
+
+namespace webrtc {
+
+int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
+                                  size_t encoded_len,
+                                  int16_t* decoded,
+                                  SpeechType* speech_type) {
+  return Decode(encoded, encoded_len, decoded, speech_type);
+}
+
+bool AudioDecoder::HasDecodePlc() const { return false; }
+
+int AudioDecoder::DecodePlc(int num_frames, int16_t* decoded) { return -1; }
+
+int AudioDecoder::IncomingPacket(const uint8_t* payload,
+                                 size_t payload_len,
+                                 uint16_t rtp_sequence_number,
+                                 uint32_t rtp_timestamp,
+                                 uint32_t arrival_timestamp) {
+  return 0;
+}
+
+int AudioDecoder::ErrorCode() { return 0; }
+
+int AudioDecoder::PacketDuration(const uint8_t* encoded, size_t encoded_len) {
+  return kNotImplemented;
+}
+
+int AudioDecoder::PacketDurationRedundant(const uint8_t* encoded,
+                                          size_t encoded_len) const {
+  return kNotImplemented;
+}
+
+bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
+                                size_t encoded_len) const {
+  return false;
+}
+
+CNG_dec_inst* AudioDecoder::CngDecoderInstance() {
+  FATAL() << "Not a CNG decoder";
+  return NULL;
+}
+
+AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
+  switch (type) {
+    case 0:  // TODO(hlundin): Both iSAC and Opus return 0 for speech.
+    case 1:
+      return kSpeech;
+    case 2:
+      return kComfortNoise;
+    default:
+      assert(false);
+      return kSpeech;
+  }
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/interface/audio_decoder.h b/webrtc/modules/audio_coding/codecs/audio_decoder.h
similarity index 78%
rename from webrtc/modules/audio_coding/neteq/interface/audio_decoder.h
rename to webrtc/modules/audio_coding/codecs/audio_decoder.h
index be85c4d..0b4e20c 100644
--- a/webrtc/modules/audio_coding/neteq/interface/audio_decoder.h
+++ b/webrtc/modules/audio_coding/codecs/audio_decoder.h
@@ -19,39 +19,6 @@
 
 namespace webrtc {
 
-enum NetEqDecoder {
-  kDecoderPCMu,
-  kDecoderPCMa,
-  kDecoderPCMu_2ch,
-  kDecoderPCMa_2ch,
-  kDecoderILBC,
-  kDecoderISAC,
-  kDecoderISACswb,
-  kDecoderISACfb,
-  kDecoderPCM16B,
-  kDecoderPCM16Bwb,
-  kDecoderPCM16Bswb32kHz,
-  kDecoderPCM16Bswb48kHz,
-  kDecoderPCM16B_2ch,
-  kDecoderPCM16Bwb_2ch,
-  kDecoderPCM16Bswb32kHz_2ch,
-  kDecoderPCM16Bswb48kHz_2ch,
-  kDecoderPCM16B_5ch,
-  kDecoderG722,
-  kDecoderG722_2ch,
-  kDecoderRED,
-  kDecoderAVT,
-  kDecoderCNGnb,
-  kDecoderCNGwb,
-  kDecoderCNGswb32kHz,
-  kDecoderCNGswb48kHz,
-  kDecoderArbitrary,
-  kDecoderOpus,
-  kDecoderOpus_2ch,
-  kDecoderCELT_32,
-  kDecoderCELT_32_2ch,
-};
-
 // This is the interface class for decoders in NetEQ. Each codec type will have
 // and implementation of this class.
 class AudioDecoder {
@@ -119,17 +86,6 @@
   // isn't a CNG decoder, don't call this method.
   virtual CNG_dec_inst* CngDecoderInstance();
 
-  // Returns true if |codec_type| is supported.
-  static bool CodecSupported(NetEqDecoder codec_type);
-
-  // Returns the sample rate for |codec_type|.
-  static int CodecSampleRateHz(NetEqDecoder codec_type);
-
-  // Creates an AudioDecoder object of type |codec_type|. Returns NULL for
-  // for unsupported codecs, and when creating an AudioDecoder is not
-  // applicable (e.g., for RED and DTMF/AVT types).
-  static AudioDecoder* CreateAudioDecoder(NetEqDecoder codec_type);
-
   size_t channels() const { return channels_; }
 
  protected:
diff --git a/webrtc/modules/audio_coding/codecs/interfaces.gypi b/webrtc/modules/audio_coding/codecs/interfaces.gypi
new file mode 100644
index 0000000..931d7f7
--- /dev/null
+++ b/webrtc/modules/audio_coding/codecs/interfaces.gypi
@@ -0,0 +1,20 @@
+# Copyright (c) 2014 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'audio_decoder_interface',
+      'type': 'static_library',
+      'sources': [
+        'audio_decoder.cc',
+        'audio_decoder.h',
+      ],
+    },
+  ],
+}
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc b/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc
index e55b6c4..e8ea858 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc
@@ -20,7 +20,6 @@
 #include <assert.h>
 
 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
 // Includes needed to create the codecs.
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
index 2ed62e9..d55d91e 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
+++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
@@ -13,9 +13,9 @@
 
 #include "webrtc/base/thread_annotations.h"
 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_isac.cc b/webrtc/modules/audio_coding/main/acm2/acm_isac.cc
index 8fa96e5..8a63410 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_isac.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_isac.cc
@@ -11,10 +11,10 @@
 
 #include <assert.h>
 
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_isac.h b/webrtc/modules/audio_coding/main/acm2/acm_isac.h
index 486313a..b83d1d3 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_isac.h
+++ b/webrtc/modules/audio_coding/main/acm2/acm_isac.h
@@ -12,8 +12,8 @@
 #define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_ISAC_H_
 
 #include "webrtc/base/thread_annotations.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 
 namespace webrtc {
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
index bbe5a16..f0531ed 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
@@ -17,11 +17,11 @@
 
 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
 #include "webrtc/common_types.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h"
 #include "webrtc/modules/audio_coding/main/acm2/call_statistics.h"
 #include "webrtc/modules/audio_coding/main/acm2/nack.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
 #include "webrtc/system_wrappers/interface/clock.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder.cc b/webrtc/modules/audio_coding/neteq/audio_decoder.cc
deleted file mode 100644
index d5a2762..0000000
--- a/webrtc/modules/audio_coding/neteq/audio_decoder.cc
+++ /dev/null
@@ -1,268 +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 "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
-
-#include <assert.h>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
-
-namespace webrtc {
-
-int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
-                                  size_t encoded_len,
-                                  int16_t* decoded,
-                                  SpeechType* speech_type) {
-  return Decode(encoded, encoded_len, decoded, speech_type);
-}
-
-bool AudioDecoder::HasDecodePlc() const { return false; }
-
-int AudioDecoder::DecodePlc(int num_frames, int16_t* decoded) { return -1; }
-
-int AudioDecoder::IncomingPacket(const uint8_t* payload,
-                                 size_t payload_len,
-                                 uint16_t rtp_sequence_number,
-                                 uint32_t rtp_timestamp,
-                                 uint32_t arrival_timestamp) {
-  return 0;
-}
-
-int AudioDecoder::ErrorCode() { return 0; }
-
-int AudioDecoder::PacketDuration(const uint8_t* encoded, size_t encoded_len) {
-  return kNotImplemented;
-}
-
-int AudioDecoder::PacketDurationRedundant(const uint8_t* encoded,
-                                          size_t encoded_len) const {
-  return kNotImplemented;
-}
-
-bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
-                                size_t encoded_len) const {
-  return false;
-}
-
-CNG_dec_inst* AudioDecoder::CngDecoderInstance() {
-  FATAL() << "Not a CNG decoder";
-  return NULL;
-}
-
-bool AudioDecoder::CodecSupported(NetEqDecoder codec_type) {
-  switch (codec_type) {
-    case kDecoderPCMu:
-    case kDecoderPCMa:
-    case kDecoderPCMu_2ch:
-    case kDecoderPCMa_2ch:
-#ifdef WEBRTC_CODEC_ILBC
-    case kDecoderILBC:
-#endif
-#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
-    case kDecoderISAC:
-#endif
-#ifdef WEBRTC_CODEC_ISAC
-    case kDecoderISACswb:
-    case kDecoderISACfb:
-#endif
-#ifdef WEBRTC_CODEC_PCM16
-    case kDecoderPCM16B:
-    case kDecoderPCM16Bwb:
-    case kDecoderPCM16Bswb32kHz:
-    case kDecoderPCM16Bswb48kHz:
-    case kDecoderPCM16B_2ch:
-    case kDecoderPCM16Bwb_2ch:
-    case kDecoderPCM16Bswb32kHz_2ch:
-    case kDecoderPCM16Bswb48kHz_2ch:
-    case kDecoderPCM16B_5ch:
-#endif
-#ifdef WEBRTC_CODEC_G722
-    case kDecoderG722:
-    case kDecoderG722_2ch:
-#endif
-#ifdef WEBRTC_CODEC_CELT
-    case kDecoderCELT_32:
-    case kDecoderCELT_32_2ch:
-#endif
-#ifdef WEBRTC_CODEC_OPUS
-    case kDecoderOpus:
-    case kDecoderOpus_2ch:
-#endif
-    case kDecoderRED:
-    case kDecoderAVT:
-    case kDecoderCNGnb:
-    case kDecoderCNGwb:
-    case kDecoderCNGswb32kHz:
-    case kDecoderCNGswb48kHz:
-    case kDecoderArbitrary: {
-      return true;
-    }
-    default: {
-      return false;
-    }
-  }
-}
-
-int AudioDecoder::CodecSampleRateHz(NetEqDecoder codec_type) {
-  switch (codec_type) {
-    case kDecoderPCMu:
-    case kDecoderPCMa:
-    case kDecoderPCMu_2ch:
-    case kDecoderPCMa_2ch:
-#ifdef WEBRTC_CODEC_ILBC
-    case kDecoderILBC:
-#endif
-#ifdef WEBRTC_CODEC_PCM16
-    case kDecoderPCM16B:
-    case kDecoderPCM16B_2ch:
-    case kDecoderPCM16B_5ch:
-#endif
-    case kDecoderCNGnb: {
-      return 8000;
-    }
-#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
-    case kDecoderISAC:
-#endif
-#ifdef WEBRTC_CODEC_PCM16
-    case kDecoderPCM16Bwb:
-    case kDecoderPCM16Bwb_2ch:
-#endif
-#ifdef WEBRTC_CODEC_G722
-    case kDecoderG722:
-    case kDecoderG722_2ch:
-#endif
-    case kDecoderCNGwb: {
-      return 16000;
-    }
-#ifdef WEBRTC_CODEC_ISAC
-    case kDecoderISACswb:
-    case kDecoderISACfb:
-#endif
-#ifdef WEBRTC_CODEC_PCM16
-    case kDecoderPCM16Bswb32kHz:
-    case kDecoderPCM16Bswb32kHz_2ch:
-#endif
-#ifdef WEBRTC_CODEC_CELT
-    case kDecoderCELT_32:
-    case kDecoderCELT_32_2ch:
-#endif
-    case kDecoderCNGswb32kHz: {
-      return 32000;
-    }
-#ifdef WEBRTC_CODEC_PCM16
-    case kDecoderPCM16Bswb48kHz:
-    case kDecoderPCM16Bswb48kHz_2ch: {
-      return 48000;
-    }
-#endif
-#ifdef WEBRTC_CODEC_OPUS
-    case kDecoderOpus:
-    case kDecoderOpus_2ch: {
-      return 48000;
-    }
-#endif
-    case kDecoderCNGswb48kHz: {
-      // TODO(tlegrand): Remove limitation once ACM has full 48 kHz support.
-      return 32000;
-    }
-    default: {
-      return -1;  // Undefined sample rate.
-    }
-  }
-}
-
-AudioDecoder* AudioDecoder::CreateAudioDecoder(NetEqDecoder codec_type) {
-  if (!CodecSupported(codec_type)) {
-    return NULL;
-  }
-  switch (codec_type) {
-    case kDecoderPCMu:
-      return new AudioDecoderPcmU;
-    case kDecoderPCMa:
-      return new AudioDecoderPcmA;
-    case kDecoderPCMu_2ch:
-      return new AudioDecoderPcmUMultiCh(2);
-    case kDecoderPCMa_2ch:
-      return new AudioDecoderPcmAMultiCh(2);
-#ifdef WEBRTC_CODEC_ILBC
-    case kDecoderILBC:
-      return new AudioDecoderIlbc;
-#endif
-#if defined(WEBRTC_CODEC_ISACFX)
-    case kDecoderISAC:
-      return new AudioDecoderIsacFix;
-#elif defined(WEBRTC_CODEC_ISAC)
-    case kDecoderISAC:
-      return new AudioDecoderIsac(16000);
-    case kDecoderISACswb:
-    case kDecoderISACfb:
-      return new AudioDecoderIsac(32000);
-#endif
-#ifdef WEBRTC_CODEC_PCM16
-    case kDecoderPCM16B:
-    case kDecoderPCM16Bwb:
-    case kDecoderPCM16Bswb32kHz:
-    case kDecoderPCM16Bswb48kHz:
-      return new AudioDecoderPcm16B;
-    case kDecoderPCM16B_2ch:
-    case kDecoderPCM16Bwb_2ch:
-    case kDecoderPCM16Bswb32kHz_2ch:
-    case kDecoderPCM16Bswb48kHz_2ch:
-      return new AudioDecoderPcm16BMultiCh(2);
-    case kDecoderPCM16B_5ch:
-      return new AudioDecoderPcm16BMultiCh(5);
-#endif
-#ifdef WEBRTC_CODEC_G722
-    case kDecoderG722:
-      return new AudioDecoderG722;
-    case kDecoderG722_2ch:
-      return new AudioDecoderG722Stereo;
-#endif
-#ifdef WEBRTC_CODEC_CELT
-    case kDecoderCELT_32:
-      return new AudioDecoderCelt(1);
-    case kDecoderCELT_32_2ch:
-      return new AudioDecoderCelt(2);
-#endif
-#ifdef WEBRTC_CODEC_OPUS
-    case kDecoderOpus:
-      return new AudioDecoderOpus(1);
-    case kDecoderOpus_2ch:
-      return new AudioDecoderOpus(2);
-#endif
-    case kDecoderCNGnb:
-    case kDecoderCNGwb:
-    case kDecoderCNGswb32kHz:
-    case kDecoderCNGswb48kHz:
-      return new AudioDecoderCng;
-    case kDecoderRED:
-    case kDecoderAVT:
-    case kDecoderArbitrary:
-    default: {
-      return NULL;
-    }
-  }
-}
-
-AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
-  switch (type) {
-    case 0:  // TODO(hlundin): Both iSAC and Opus return 0 for speech.
-    case 1:
-      return kSpeech;
-    case 2:
-      return kComfortNoise;
-    default:
-      assert(false);
-      return kSpeech;
-  }
-}
-
-}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
index 799ac7b..a34c177 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc
@@ -461,4 +461,199 @@
   return WebRtcCng_InitDec(dec_state_);
 }
 
+bool CodecSupported(NetEqDecoder codec_type) {
+  switch (codec_type) {
+    case kDecoderPCMu:
+    case kDecoderPCMa:
+    case kDecoderPCMu_2ch:
+    case kDecoderPCMa_2ch:
+#ifdef WEBRTC_CODEC_ILBC
+    case kDecoderILBC:
+#endif
+#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
+    case kDecoderISAC:
+#endif
+#ifdef WEBRTC_CODEC_ISAC
+    case kDecoderISACswb:
+    case kDecoderISACfb:
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    case kDecoderPCM16B:
+    case kDecoderPCM16Bwb:
+    case kDecoderPCM16Bswb32kHz:
+    case kDecoderPCM16Bswb48kHz:
+    case kDecoderPCM16B_2ch:
+    case kDecoderPCM16Bwb_2ch:
+    case kDecoderPCM16Bswb32kHz_2ch:
+    case kDecoderPCM16Bswb48kHz_2ch:
+    case kDecoderPCM16B_5ch:
+#endif
+#ifdef WEBRTC_CODEC_G722
+    case kDecoderG722:
+    case kDecoderG722_2ch:
+#endif
+#ifdef WEBRTC_CODEC_CELT
+    case kDecoderCELT_32:
+    case kDecoderCELT_32_2ch:
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+    case kDecoderOpus:
+    case kDecoderOpus_2ch:
+#endif
+    case kDecoderRED:
+    case kDecoderAVT:
+    case kDecoderCNGnb:
+    case kDecoderCNGwb:
+    case kDecoderCNGswb32kHz:
+    case kDecoderCNGswb48kHz:
+    case kDecoderArbitrary: {
+      return true;
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+int CodecSampleRateHz(NetEqDecoder codec_type) {
+  switch (codec_type) {
+    case kDecoderPCMu:
+    case kDecoderPCMa:
+    case kDecoderPCMu_2ch:
+    case kDecoderPCMa_2ch:
+#ifdef WEBRTC_CODEC_ILBC
+    case kDecoderILBC:
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    case kDecoderPCM16B:
+    case kDecoderPCM16B_2ch:
+    case kDecoderPCM16B_5ch:
+#endif
+    case kDecoderCNGnb: {
+      return 8000;
+    }
+#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
+    case kDecoderISAC:
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    case kDecoderPCM16Bwb:
+    case kDecoderPCM16Bwb_2ch:
+#endif
+#ifdef WEBRTC_CODEC_G722
+    case kDecoderG722:
+    case kDecoderG722_2ch:
+#endif
+    case kDecoderCNGwb: {
+      return 16000;
+    }
+#ifdef WEBRTC_CODEC_ISAC
+    case kDecoderISACswb:
+    case kDecoderISACfb:
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    case kDecoderPCM16Bswb32kHz:
+    case kDecoderPCM16Bswb32kHz_2ch:
+#endif
+#ifdef WEBRTC_CODEC_CELT
+    case kDecoderCELT_32:
+    case kDecoderCELT_32_2ch:
+#endif
+    case kDecoderCNGswb32kHz: {
+      return 32000;
+    }
+#ifdef WEBRTC_CODEC_PCM16
+    case kDecoderPCM16Bswb48kHz:
+    case kDecoderPCM16Bswb48kHz_2ch: {
+      return 48000;
+    }
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+    case kDecoderOpus:
+    case kDecoderOpus_2ch: {
+      return 48000;
+    }
+#endif
+    case kDecoderCNGswb48kHz: {
+      // TODO(tlegrand): Remove limitation once ACM has full 48 kHz support.
+      return 32000;
+    }
+    default: {
+      return -1;  // Undefined sample rate.
+    }
+  }
+}
+
+AudioDecoder* CreateAudioDecoder(NetEqDecoder codec_type) {
+  if (!CodecSupported(codec_type)) {
+    return NULL;
+  }
+  switch (codec_type) {
+    case kDecoderPCMu:
+      return new AudioDecoderPcmU;
+    case kDecoderPCMa:
+      return new AudioDecoderPcmA;
+    case kDecoderPCMu_2ch:
+      return new AudioDecoderPcmUMultiCh(2);
+    case kDecoderPCMa_2ch:
+      return new AudioDecoderPcmAMultiCh(2);
+#ifdef WEBRTC_CODEC_ILBC
+    case kDecoderILBC:
+      return new AudioDecoderIlbc;
+#endif
+#if defined(WEBRTC_CODEC_ISACFX)
+    case kDecoderISAC:
+      return new AudioDecoderIsacFix;
+#elif defined(WEBRTC_CODEC_ISAC)
+    case kDecoderISAC:
+      return new AudioDecoderIsac(16000);
+    case kDecoderISACswb:
+    case kDecoderISACfb:
+      return new AudioDecoderIsac(32000);
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    case kDecoderPCM16B:
+    case kDecoderPCM16Bwb:
+    case kDecoderPCM16Bswb32kHz:
+    case kDecoderPCM16Bswb48kHz:
+      return new AudioDecoderPcm16B;
+    case kDecoderPCM16B_2ch:
+    case kDecoderPCM16Bwb_2ch:
+    case kDecoderPCM16Bswb32kHz_2ch:
+    case kDecoderPCM16Bswb48kHz_2ch:
+      return new AudioDecoderPcm16BMultiCh(2);
+    case kDecoderPCM16B_5ch:
+      return new AudioDecoderPcm16BMultiCh(5);
+#endif
+#ifdef WEBRTC_CODEC_G722
+    case kDecoderG722:
+      return new AudioDecoderG722;
+    case kDecoderG722_2ch:
+      return new AudioDecoderG722Stereo;
+#endif
+#ifdef WEBRTC_CODEC_CELT
+    case kDecoderCELT_32:
+      return new AudioDecoderCelt(1);
+    case kDecoderCELT_32_2ch:
+      return new AudioDecoderCelt(2);
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+    case kDecoderOpus:
+      return new AudioDecoderOpus(1);
+    case kDecoderOpus_2ch:
+      return new AudioDecoderOpus(2);
+#endif
+    case kDecoderCNGnb:
+    case kDecoderCNGwb:
+    case kDecoderCNGswb32kHz:
+    case kDecoderCNGswb48kHz:
+      return new AudioDecoderCng;
+    case kDecoderRED:
+    case kDecoderAVT:
+    case kDecoderArbitrary:
+    default: {
+      return NULL;
+    }
+  }
+}
+
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h
index b30331f..b75d39a 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h
@@ -19,6 +19,7 @@
 #include "webrtc/engine_configurations.h"
 #endif
 #include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h"
 #ifdef WEBRTC_CODEC_G722
 #include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h"
@@ -35,7 +36,6 @@
 #ifdef WEBRTC_CODEC_OPUS
 #include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
 #endif
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
@@ -280,5 +280,49 @@
   DISALLOW_COPY_AND_ASSIGN(AudioDecoderCng);
 };
 
+enum NetEqDecoder {
+  kDecoderPCMu,
+  kDecoderPCMa,
+  kDecoderPCMu_2ch,
+  kDecoderPCMa_2ch,
+  kDecoderILBC,
+  kDecoderISAC,
+  kDecoderISACswb,
+  kDecoderISACfb,
+  kDecoderPCM16B,
+  kDecoderPCM16Bwb,
+  kDecoderPCM16Bswb32kHz,
+  kDecoderPCM16Bswb48kHz,
+  kDecoderPCM16B_2ch,
+  kDecoderPCM16Bwb_2ch,
+  kDecoderPCM16Bswb32kHz_2ch,
+  kDecoderPCM16Bswb48kHz_2ch,
+  kDecoderPCM16B_5ch,
+  kDecoderG722,
+  kDecoderG722_2ch,
+  kDecoderRED,
+  kDecoderAVT,
+  kDecoderCNGnb,
+  kDecoderCNGwb,
+  kDecoderCNGswb32kHz,
+  kDecoderCNGswb48kHz,
+  kDecoderArbitrary,
+  kDecoderOpus,
+  kDecoderOpus_2ch,
+  kDecoderCELT_32,
+  kDecoderCELT_32_2ch,
+};
+
+// Returns true if |codec_type| is supported.
+bool CodecSupported(NetEqDecoder codec_type);
+
+// Returns the sample rate for |codec_type|.
+int CodecSampleRateHz(NetEqDecoder codec_type);
+
+// Creates an AudioDecoder object of type |codec_type|. Returns NULL for for
+// unsupported codecs, and when creating an AudioDecoder is not applicable
+// (e.g., for RED and DTMF/AVT types).
+AudioDecoder* CreateAudioDecoder(NetEqDecoder codec_type);
+
 }  // namespace webrtc
 #endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_AUDIO_DECODER_IMPL_H_
diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
index 5d371396..271b9ea 100644
--- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc
@@ -602,7 +602,7 @@
 TEST_F(AudioDecoderPcmUTest, EncodeDecode) {
   int tolerance = 251;
   double mse = 1734.0;
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMu));
+  EXPECT_TRUE(CodecSupported(kDecoderPCMu));
   EncodeDecodeTest(data_length_, tolerance, mse);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -611,7 +611,7 @@
 TEST_F(AudioDecoderPcmATest, EncodeDecode) {
   int tolerance = 308;
   double mse = 1931.0;
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMa));
+  EXPECT_TRUE(CodecSupported(kDecoderPCMa));
   EncodeDecodeTest(data_length_, tolerance, mse);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -620,10 +620,10 @@
 TEST_F(AudioDecoderPcm16BTest, EncodeDecode) {
   int tolerance = 0;
   double mse = 0.0;
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb48kHz));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16B));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bwb));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bswb32kHz));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bswb48kHz));
   EncodeDecodeTest(2 * data_length_, tolerance, mse);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -633,7 +633,7 @@
   int tolerance = 6808;
   double mse = 2.13e6;
   int delay = 80;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderILBC));
+  EXPECT_TRUE(CodecSupported(kDecoderILBC));
   EncodeDecodeTest(500, tolerance, mse, delay);
   ReInitTest();
   EXPECT_TRUE(decoder_->HasDecodePlc());
@@ -644,7 +644,7 @@
   int tolerance = 3399;
   double mse = 434951.0;
   int delay = 48;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
+  EXPECT_TRUE(CodecSupported(kDecoderISAC));
   EncodeDecodeTest(0, tolerance, mse, delay);
   ReInitTest();
   EXPECT_TRUE(decoder_->HasDecodePlc());
@@ -655,7 +655,7 @@
   int tolerance = 19757;
   double mse = 8.18e6;
   int delay = 160;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACswb));
+  EXPECT_TRUE(CodecSupported(kDecoderISACswb));
   EncodeDecodeTest(0, tolerance, mse, delay);
   ReInitTest();
   EXPECT_TRUE(decoder_->HasDecodePlc());
@@ -666,7 +666,7 @@
   int tolerance = 11034;
   double mse = 3.46e6;
   int delay = 54;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
+  EXPECT_TRUE(CodecSupported(kDecoderISAC));
   EncodeDecodeTest(735, tolerance, mse, delay);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -676,14 +676,14 @@
   int tolerance = 6176;
   double mse = 238630.0;
   int delay = 22;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722));
+  EXPECT_TRUE(CodecSupported(kDecoderG722));
   EncodeDecodeTest(data_length_ / 2, tolerance, mse, delay);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
 }
 
 TEST_F(AudioDecoderG722StereoTest, CreateAndDestroy) {
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderG722_2ch));
 }
 
 TEST_F(AudioDecoderG722StereoTest, EncodeDecode) {
@@ -691,7 +691,7 @@
   int channel_diff_tolerance = 0;
   double mse = 238630.0;
   int delay = 22;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderG722_2ch));
   EncodeDecodeTest(data_length_, tolerance, mse, delay, channel_diff_tolerance);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -701,7 +701,7 @@
   int tolerance = 6176;
   double mse = 238630.0;
   int delay = 22;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus));
+  EXPECT_TRUE(CodecSupported(kDecoderOpus));
   EncodeDecodeTest(0, tolerance, mse, delay);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -712,7 +712,7 @@
   int channel_diff_tolerance = 0;
   double mse = 238630.0;
   int delay = 22;  // Delay from input to output.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderOpus_2ch));
   EncodeDecodeTest(0, tolerance, mse, delay, channel_diff_tolerance);
   ReInitTest();
   EXPECT_FALSE(decoder_->HasDecodePlc());
@@ -727,7 +727,7 @@
   int tolerance = 20;
   double mse = 17.0;
   int delay = 80;  // Delay from input to output in samples.
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCELT_32));
+  EXPECT_TRUE(CodecSupported(kDecoderCELT_32));
   EncodeDecodeTest(1600, tolerance, mse, delay);
   ReInitTest();
   EXPECT_TRUE(decoder_->HasDecodePlc());
@@ -742,7 +742,7 @@
   double mse = 20.0;
   // Delay from input to output in samples, accounting for stereo.
   int delay = 160;
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCELT_32_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderCELT_32_2ch));
   EncodeDecodeTest(1600, tolerance, mse, delay, channel_diff_tolerance);
   ReInitTest();
   EXPECT_TRUE(decoder_->HasDecodePlc());
@@ -751,79 +751,79 @@
 #endif
 
 TEST(AudioDecoder, CodecSampleRateHz) {
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMu));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMa));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMu_2ch));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMa_2ch));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderILBC));
-  EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderISAC));
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderISACswb));
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderISACfb));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B));
-  EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bwb));
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb32kHz));
-  EXPECT_EQ(48000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb48kHz));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B_2ch));
-  EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bwb_2ch));
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb32kHz_2ch));
-  EXPECT_EQ(48000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb48kHz_2ch));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B_5ch));
-  EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderG722));
-  EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderG722_2ch));
-  EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderRED));
-  EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderAVT));
-  EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderCNGnb));
-  EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderCNGwb));
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderCNGswb32kHz));
-  EXPECT_EQ(48000, AudioDecoder::CodecSampleRateHz(kDecoderOpus));
-  EXPECT_EQ(48000, AudioDecoder::CodecSampleRateHz(kDecoderOpus_2ch));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCMu));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCMa));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCMu_2ch));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCMa_2ch));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderILBC));
+  EXPECT_EQ(16000, CodecSampleRateHz(kDecoderISAC));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderISACswb));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderISACfb));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCM16B));
+  EXPECT_EQ(16000, CodecSampleRateHz(kDecoderPCM16Bwb));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderPCM16Bswb32kHz));
+  EXPECT_EQ(48000, CodecSampleRateHz(kDecoderPCM16Bswb48kHz));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCM16B_2ch));
+  EXPECT_EQ(16000, CodecSampleRateHz(kDecoderPCM16Bwb_2ch));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderPCM16Bswb32kHz_2ch));
+  EXPECT_EQ(48000, CodecSampleRateHz(kDecoderPCM16Bswb48kHz_2ch));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderPCM16B_5ch));
+  EXPECT_EQ(16000, CodecSampleRateHz(kDecoderG722));
+  EXPECT_EQ(16000, CodecSampleRateHz(kDecoderG722_2ch));
+  EXPECT_EQ(-1, CodecSampleRateHz(kDecoderRED));
+  EXPECT_EQ(-1, CodecSampleRateHz(kDecoderAVT));
+  EXPECT_EQ(8000, CodecSampleRateHz(kDecoderCNGnb));
+  EXPECT_EQ(16000, CodecSampleRateHz(kDecoderCNGwb));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderCNGswb32kHz));
+  EXPECT_EQ(48000, CodecSampleRateHz(kDecoderOpus));
+  EXPECT_EQ(48000, CodecSampleRateHz(kDecoderOpus_2ch));
   // TODO(tlegrand): Change 32000 to 48000 below once ACM has 48 kHz support.
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderCNGswb48kHz));
-  EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderArbitrary));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderCNGswb48kHz));
+  EXPECT_EQ(-1, CodecSampleRateHz(kDecoderArbitrary));
 #ifdef WEBRTC_CODEC_CELT
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderCELT_32));
-  EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderCELT_32_2ch));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderCELT_32));
+  EXPECT_EQ(32000, CodecSampleRateHz(kDecoderCELT_32_2ch));
 #else
-  EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderCELT_32));
-  EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderCELT_32_2ch));
+  EXPECT_EQ(-1, CodecSampleRateHz(kDecoderCELT_32));
+  EXPECT_EQ(-1, CodecSampleRateHz(kDecoderCELT_32_2ch));
 #endif
 }
 
 TEST(AudioDecoder, CodecSupported) {
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMu));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMa));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMu_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMa_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderILBC));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACswb));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACfb));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb48kHz));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb48kHz_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B_5ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722_2ch));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderRED));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderAVT));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGnb));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGwb));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGswb32kHz));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGswb48kHz));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderArbitrary));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderPCMu));
+  EXPECT_TRUE(CodecSupported(kDecoderPCMa));
+  EXPECT_TRUE(CodecSupported(kDecoderPCMu_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderPCMa_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderILBC));
+  EXPECT_TRUE(CodecSupported(kDecoderISAC));
+  EXPECT_TRUE(CodecSupported(kDecoderISACswb));
+  EXPECT_TRUE(CodecSupported(kDecoderISACfb));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16B));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bwb));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bswb32kHz));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bswb48kHz));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16B_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bwb_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bswb32kHz_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16Bswb48kHz_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderPCM16B_5ch));
+  EXPECT_TRUE(CodecSupported(kDecoderG722));
+  EXPECT_TRUE(CodecSupported(kDecoderG722_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderRED));
+  EXPECT_TRUE(CodecSupported(kDecoderAVT));
+  EXPECT_TRUE(CodecSupported(kDecoderCNGnb));
+  EXPECT_TRUE(CodecSupported(kDecoderCNGwb));
+  EXPECT_TRUE(CodecSupported(kDecoderCNGswb32kHz));
+  EXPECT_TRUE(CodecSupported(kDecoderCNGswb48kHz));
+  EXPECT_TRUE(CodecSupported(kDecoderArbitrary));
+  EXPECT_TRUE(CodecSupported(kDecoderOpus));
+  EXPECT_TRUE(CodecSupported(kDecoderOpus_2ch));
 #ifdef WEBRTC_CODEC_CELT
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCELT_32));
-  EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCELT_32_2ch));
+  EXPECT_TRUE(CodecSupported(kDecoderCELT_32));
+  EXPECT_TRUE(CodecSupported(kDecoderCELT_32_2ch));
 #else
-  EXPECT_FALSE(AudioDecoder::CodecSupported(kDecoderCELT_32));
-  EXPECT_FALSE(AudioDecoder::CodecSupported(kDecoderCELT_32_2ch));
+  EXPECT_FALSE(CodecSupported(kDecoderCELT_32));
+  EXPECT_FALSE(CodecSupported(kDecoderCELT_32_2ch));
 #endif
 }
 
diff --git a/webrtc/modules/audio_coding/neteq/comfort_noise.cc b/webrtc/modules/audio_coding/neteq/comfort_noise.cc
index e2be066..54b0a28 100644
--- a/webrtc/modules/audio_coding/neteq/comfort_noise.cc
+++ b/webrtc/modules/audio_coding/neteq/comfort_noise.cc
@@ -12,10 +12,10 @@
 
 #include <assert.h>
 
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h"
 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
 #include "webrtc/modules/audio_coding/neteq/dsp_helper.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
 
 namespace webrtc {
diff --git a/webrtc/modules/audio_coding/neteq/decoder_database.cc b/webrtc/modules/audio_coding/neteq/decoder_database.cc
index 5049962..69c7b7b 100644
--- a/webrtc/modules/audio_coding/neteq/decoder_database.cc
+++ b/webrtc/modules/audio_coding/neteq/decoder_database.cc
@@ -13,7 +13,7 @@
 #include <assert.h>
 #include <utility>  // pair
 
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 
 namespace webrtc {
 
@@ -41,10 +41,10 @@
   if (rtp_payload_type > kMaxRtpPayloadType) {
     return kInvalidRtpPayloadType;
   }
-  if (!AudioDecoder::CodecSupported(codec_type)) {
+  if (!CodecSupported(codec_type)) {
     return kCodecNotSupported;
   }
-  int fs_hz = AudioDecoder::CodecSampleRateHz(codec_type);
+  int fs_hz = CodecSampleRateHz(codec_type);
   std::pair<DecoderMap::iterator, bool> ret;
   DecoderInfo info(codec_type, fs_hz, NULL, false);
   ret = decoders_.insert(std::make_pair(rtp_payload_type, info));
@@ -62,7 +62,7 @@
   if (rtp_payload_type > 0x7F) {
     return kInvalidRtpPayloadType;
   }
-  if (!AudioDecoder::CodecSupported(codec_type)) {
+  if (!CodecSupported(codec_type)) {
     return kCodecNotSupported;
   }
   if (fs_hz != 8000 && fs_hz != 16000 && fs_hz != 32000 && fs_hz != 48000) {
@@ -133,7 +133,7 @@
   DecoderInfo* info = &(*it).second;
   if (!info->decoder) {
     // Create the decoder object.
-    AudioDecoder* decoder = AudioDecoder::CreateAudioDecoder(info->codec_type);
+    AudioDecoder* decoder = CreateAudioDecoder(info->codec_type);
     assert(decoder);  // Should not be able to have an unsupported codec here.
     info->decoder = decoder;
     info->decoder->Init();
diff --git a/webrtc/modules/audio_coding/neteq/decoder_database.h b/webrtc/modules/audio_coding/neteq/decoder_database.h
index 8a03f21..cae1021 100644
--- a/webrtc/modules/audio_coding/neteq/decoder_database.h
+++ b/webrtc/modules/audio_coding/neteq/decoder_database.h
@@ -15,15 +15,12 @@
 
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/common_types.h"  // NULL
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
 #include "webrtc/modules/audio_coding/neteq/packet.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
 
-// Forward declaration.
-class AudioDecoder;
-
 class DecoderDatabase {
  public:
   enum DatabaseReturnCodes {
diff --git a/webrtc/modules/audio_coding/neteq/delay_manager.h b/webrtc/modules/audio_coding/neteq/delay_manager.h
index 96b5e19..33c4a40 100644
--- a/webrtc/modules/audio_coding/neteq/delay_manager.h
+++ b/webrtc/modules/audio_coding/neteq/delay_manager.h
@@ -16,7 +16,7 @@
 #include <vector>
 
 #include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
diff --git a/webrtc/modules/audio_coding/neteq/interface/neteq.h b/webrtc/modules/audio_coding/neteq/interface/neteq.h
index b630e86..2c0dbdc 100644
--- a/webrtc/modules/audio_coding/neteq/interface/neteq.h
+++ b/webrtc/modules/audio_coding/neteq/interface/neteq.h
@@ -17,7 +17,7 @@
 
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/common_types.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h
index 95b564d..503e46f 100644
--- a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h
+++ b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h
@@ -11,7 +11,7 @@
 #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_AUDIO_DECODER_H_
 #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_AUDIO_DECODER_H_
 
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 
 #include "testing/gmock/include/gmock/gmock.h"
 
diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
index 400c0b0..68b4c11 100644
--- a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
+++ b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
@@ -11,7 +11,7 @@
 #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_EXTERNAL_DECODER_PCM16B_H_
 #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_EXTERNAL_DECODER_PCM16B_H_
 
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "webrtc/base/constructormagic.h"
diff --git a/webrtc/modules/audio_coding/neteq/neteq.gypi b/webrtc/modules/audio_coding/neteq/neteq.gypi
index 3ca2aaa..98b1683 100644
--- a/webrtc/modules/audio_coding/neteq/neteq.gypi
+++ b/webrtc/modules/audio_coding/neteq/neteq.gypi
@@ -29,6 +29,7 @@
       '<(DEPTH)/third_party/opus/opus.gyp:opus',
       '<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
       '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
+      'audio_decoder_interface',
     ],
   },
   'targets': [
@@ -57,7 +58,6 @@
         '<(DEPTH)/third_party/opus/opus.gyp:opus',
       ],
       'sources': [
-        'interface/audio_decoder.h',
         'interface/neteq.h',
         'accelerate.cc',
         'accelerate.h',
@@ -65,7 +65,6 @@
         'audio_classifier.h',
         'audio_decoder_impl.cc',
         'audio_decoder_impl.h',
-        'audio_decoder.cc',
         'audio_multi_vector.cc',
         'audio_multi_vector.h',
         'audio_vector.cc',
@@ -136,6 +135,7 @@
           'type': '<(gtest_target_type)',
           'dependencies': [
             '<@(codecs)',
+            'audio_decoder_interface',
             'neteq_unittest_tools',
             '<(DEPTH)/testing/gtest.gyp:gtest',
             '<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
@@ -154,8 +154,6 @@
             'audio_decoder_impl.cc',
             'audio_decoder_impl.h',
             'audio_decoder_unittest.cc',
-            'audio_decoder.cc',
-            'interface/audio_decoder.h',
           ],
           'conditions': [
             ['OS=="android"', {
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
index 958eb76..4060a02 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
@@ -16,6 +16,7 @@
 #include <algorithm>
 
 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/accelerate.h"
 #include "webrtc/modules/audio_coding/neteq/background_noise.h"
 #include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
@@ -28,7 +29,6 @@
 #include "webrtc/modules/audio_coding/neteq/dtmf_buffer.h"
 #include "webrtc/modules/audio_coding/neteq/dtmf_tone_generator.h"
 #include "webrtc/modules/audio_coding/neteq/expand.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/merge.h"
 #include "webrtc/modules/audio_coding/neteq/normal.h"
 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h"
@@ -211,7 +211,7 @@
     assert(false);
     return kFail;
   }
-  const int sample_rate_hz = AudioDecoder::CodecSampleRateHz(codec);
+  const int sample_rate_hz = CodecSampleRateHz(codec);
   int ret = decoder_database_->InsertExternal(rtp_payload_type, codec,
                                               sample_rate_hz, decoder);
   if (ret != DecoderDatabase::kOK) {
diff --git a/webrtc/modules/audio_coding/neteq/normal.cc b/webrtc/modules/audio_coding/neteq/normal.cc
index ca2c1ee..4924470 100644
--- a/webrtc/modules/audio_coding/neteq/normal.cc
+++ b/webrtc/modules/audio_coding/neteq/normal.cc
@@ -15,12 +15,12 @@
 #include <algorithm>  // min
 
 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h"
 #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
 #include "webrtc/modules/audio_coding/neteq/background_noise.h"
 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
 #include "webrtc/modules/audio_coding/neteq/expand.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 
 namespace webrtc {
 
diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.cc b/webrtc/modules/audio_coding/neteq/packet_buffer.cc
index 816713d..b0c939b 100644
--- a/webrtc/modules/audio_coding/neteq/packet_buffer.cc
+++ b/webrtc/modules/audio_coding/neteq/packet_buffer.cc
@@ -16,8 +16,8 @@
 
 #include <algorithm>  // find_if()
 
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 
 namespace webrtc {
 
diff --git a/webrtc/modules/audio_coding/neteq/post_decode_vad.h b/webrtc/modules/audio_coding/neteq/post_decode_vad.h
index e713009..fa276aa 100644
--- a/webrtc/modules/audio_coding/neteq/post_decode_vad.h
+++ b/webrtc/modules/audio_coding/neteq/post_decode_vad.h
@@ -16,8 +16,8 @@
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/common_audio/vad/include/webrtc_vad.h"
 #include "webrtc/common_types.h"  // NULL
+#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/defines.h"
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
 #include "webrtc/modules/audio_coding/neteq/packet.h"
 #include "webrtc/typedefs.h"
 
diff --git a/webrtc/modules/audio_coding/neteq/test/RTPencode.cc b/webrtc/modules/audio_coding/neteq/test/RTPencode.cc
index 49d66e9..bdd7163 100644
--- a/webrtc/modules/audio_coding/neteq/test/RTPencode.cc
+++ b/webrtc/modules/audio_coding/neteq/test/RTPencode.cc
@@ -25,7 +25,7 @@
 
 #include "webrtc/typedefs.h"
 // needed for NetEqDecoder
-#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
+#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h"
 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
 
 /************************/
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 6fbf3f5..1988287 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -9,6 +9,7 @@
 {
   'includes': [
     '../build/common.gypi',
+    'audio_coding/codecs/interfaces.gypi',
     'audio_coding/codecs/cng/cng.gypi',
     'audio_coding/codecs/g711/g711.gypi',
     'audio_coding/codecs/g722/g722.gypi',