Revert of Reimplement the builtin audio codec factories using the new stuff in api/ (patchset #1 id:60001 of https://codereview.webrtc.org/2997713002/ )

Reason for revert:
Speculatively reverting, likely breaks chromium.webrtc.fyi.

Failed to create local offer: Test failed: Error: setSdpDefaultCodec() failed: "Unknown ID for |codec| = 'G722'."

Failing bots:
https://build.chromium.org/p/chromium.webrtc.fyi/builders/Mac%20Tester/builds/42349
https://build.chromium.org/p/chromium.webrtc.fyi/builders/Win8%20Tester/builds/1561
https://build.chromium.org/p/chromium.webrtc.fyi/builders/Win10%20Tester/builds/8517

Original issue's description:
> Reimplement the builtin audio codec factories using the new stuff in api/
>
> The whole point of all the audio codec stuff we've recently published
> in api/ is to function as lego bricks so that building stuff like our
> builtin audio codec factories will be easy.
>
> BUG=webrtc:7821, webrtc:7822
>
> Review-Url: https://codereview.webrtc.org/2997713002
> Cr-Commit-Position: refs/heads/master@{#19446}
> Committed: https://chromium.googlesource.com/external/webrtc/+/417989a8643d0d19052a87e95905b469d5ede173

TBR=ossu@webrtc.org,kwiberg@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:7821, webrtc:7822

Review-Url: https://codereview.webrtc.org/2996373002
Cr-Original-Commit-Position: refs/heads/master@{#19452}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: bcc655c2c71bb1df2ef94cdbf126b318135f1920
diff --git a/api/audio_codecs/BUILD.gn b/api/audio_codecs/BUILD.gn
index 3ed6396..2174fb1 100644
--- a/api/audio_codecs/BUILD.gn
+++ b/api/audio_codecs/BUILD.gn
@@ -38,46 +38,9 @@
   ]
   deps = [
     ":audio_codecs_api",
+    "../../modules/audio_coding:builtin_audio_decoder_factory_internal",
     "../../rtc_base:rtc_base_approved",
-    "L16:audio_decoder_L16",
-    "g711:audio_decoder_g711",
   ]
-  defines = []
-  if (rtc_include_ilbc) {
-    deps += [ "ilbc:audio_decoder_ilbc" ]
-    defines += [ "WEBRTC_USE_BUILTIN_ILBC=1" ]
-  } else {
-    defines += [ "WEBRTC_USE_BUILTIN_ILBC=0" ]
-  }
-  if (rtc_include_opus) {
-    deps += [ "opus:audio_decoder_opus" ]
-    defines += [ "WEBRTC_USE_BUILTIN_OPUS=1" ]
-  } else {
-    defines += [ "WEBRTC_USE_BUILTIN_OPUS=0" ]
-  }
-  if (build_with_mozilla) {
-    defines += [
-      "WEBRTC_USE_BUILTIN_G722=0",
-      "WEBRTC_USE_BUILTIN_ISAC_FIX=0",
-      "WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
-    ]
-  } else {
-    if (current_cpu == "arm") {
-      deps += [ "isac:audio_decoder_isac_fix" ]
-      defines += [
-        "WEBRTC_USE_BUILTIN_ISAC_FIX=1",
-        "WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
-      ]
-    } else {
-      deps += [ "isac:audio_decoder_isac_float" ]
-      defines += [
-        "WEBRTC_USE_BUILTIN_ISAC_FIX=0",
-        "WEBRTC_USE_BUILTIN_ISAC_FLOAT=1",
-      ]
-    }
-    deps += [ "g722:audio_decoder_g722" ]
-    defines += [ "WEBRTC_USE_BUILTIN_G722=1" ]
-  }
 }
 
 rtc_static_library("builtin_audio_encoder_factory") {
@@ -87,44 +50,7 @@
   ]
   deps = [
     ":audio_codecs_api",
+    "../../modules/audio_coding:builtin_audio_encoder_factory_internal",
     "../../rtc_base:rtc_base_approved",
-    "L16:audio_encoder_L16",
-    "g711:audio_encoder_g711",
   ]
-  defines = []
-  if (rtc_include_ilbc) {
-    deps += [ "ilbc:audio_encoder_ilbc" ]
-    defines += [ "WEBRTC_USE_BUILTIN_ILBC=1" ]
-  } else {
-    defines += [ "WEBRTC_USE_BUILTIN_ILBC=0" ]
-  }
-  if (rtc_include_opus) {
-    deps += [ "opus:audio_encoder_opus" ]
-    defines += [ "WEBRTC_USE_BUILTIN_OPUS=1" ]
-  } else {
-    defines += [ "WEBRTC_USE_BUILTIN_OPUS=0" ]
-  }
-  if (build_with_mozilla) {
-    defines += [
-      "WEBRTC_USE_BUILTIN_G722=0",
-      "WEBRTC_USE_BUILTIN_ISAC_FIX=0",
-      "WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
-    ]
-  } else {
-    if (current_cpu == "arm") {
-      deps += [ "isac:audio_encoder_isac_fix" ]
-      defines += [
-        "WEBRTC_USE_BUILTIN_ISAC_FIX=1",
-        "WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
-      ]
-    } else {
-      deps += [ "isac:audio_encoder_isac_float" ]
-      defines += [
-        "WEBRTC_USE_BUILTIN_ISAC_FIX=0",
-        "WEBRTC_USE_BUILTIN_ISAC_FLOAT=1",
-      ]
-    }
-    deps += [ "g722:audio_encoder_g722" ]
-    defines += [ "WEBRTC_USE_BUILTIN_G722=1" ]
-  }
 }
diff --git a/api/audio_codecs/builtin_audio_decoder_factory.cc b/api/audio_codecs/builtin_audio_decoder_factory.cc
index 69a3e7c..9bd049b 100644
--- a/api/audio_codecs/builtin_audio_decoder_factory.cc
+++ b/api/audio_codecs/builtin_audio_decoder_factory.cc
@@ -10,70 +10,12 @@
 
 #include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
 
-#include <memory>
-#include <vector>
-
-#include "webrtc/api/audio_codecs/L16/audio_decoder_L16.h"
-#include "webrtc/api/audio_codecs/audio_decoder_factory_template.h"
-#include "webrtc/api/audio_codecs/g711/audio_decoder_g711.h"
-#if WEBRTC_USE_BUILTIN_G722
-#include "webrtc/api/audio_codecs/g722/audio_decoder_g722.h"  // nogncheck
-#endif
-#if WEBRTC_USE_BUILTIN_ILBC
-#include "webrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h"  // nogncheck
-#endif
-#if WEBRTC_USE_BUILTIN_ISAC_FIX
-#include "webrtc/api/audio_codecs/isac/audio_decoder_isac_fix.h"  // nogncheck
-#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
-#include "webrtc/api/audio_codecs/isac/audio_decoder_isac_float.h"  // nogncheck
-#endif
-#if WEBRTC_USE_BUILTIN_OPUS
-#include "webrtc/api/audio_codecs/opus/audio_decoder_opus.h"  // nogncheck
-#endif
+#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.h"
 
 namespace webrtc {
 
-namespace {
-
-// Modify an audio decoder to not advertise support for anything.
-template <typename T>
-struct NotAdvertised {
-  using Config = typename T::Config;
-  static rtc::Optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
-    return T::SdpToConfig(audio_format);
-  }
-  static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
-    // Don't advertise support for anything.
-  }
-  static std::unique_ptr<AudioDecoder> MakeAudioDecoder(const Config& config) {
-    return T::MakeAudioDecoder(config);
-  }
-};
-
-}  // namespace
-
 rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
-  return CreateAudioDecoderFactory<
-
-#if WEBRTC_USE_BUILTIN_OPUS
-      AudioDecoderOpus,
-#endif
-
-#if WEBRTC_USE_BUILTIN_ISAC_FIX
-      AudioDecoderIsacFix,
-#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
-      AudioDecoderIsacFloat,
-#endif
-
-#if WEBRTC_USE_BUILTIN_G722
-      AudioDecoderG722,
-#endif
-
-#if WEBRTC_USE_BUILTIN_ILBC
-      AudioDecoderIlbc,
-#endif
-
-      AudioDecoderG711, NotAdvertised<AudioDecoderL16>>();
+  return CreateBuiltinAudioDecoderFactoryInternal();
 }
 
 }  // namespace webrtc
diff --git a/api/audio_codecs/builtin_audio_encoder_factory.cc b/api/audio_codecs/builtin_audio_encoder_factory.cc
index ae1bf4b..bb57a5f 100644
--- a/api/audio_codecs/builtin_audio_encoder_factory.cc
+++ b/api/audio_codecs/builtin_audio_encoder_factory.cc
@@ -10,74 +10,12 @@
 
 #include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
 
-#include <memory>
-#include <vector>
-
-#include "webrtc/api/audio_codecs/L16/audio_encoder_L16.h"
-#include "webrtc/api/audio_codecs/audio_encoder_factory_template.h"
-#include "webrtc/api/audio_codecs/g711/audio_encoder_g711.h"
-#if WEBRTC_USE_BUILTIN_G722
-#include "webrtc/api/audio_codecs/g722/audio_encoder_g722.h"  // nogncheck
-#endif
-#if WEBRTC_USE_BUILTIN_ILBC
-#include "webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h"  // nogncheck
-#endif
-#if WEBRTC_USE_BUILTIN_ISAC_FIX
-#include "webrtc/api/audio_codecs/isac/audio_encoder_isac_fix.h"  // nogncheck
-#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
-#include "webrtc/api/audio_codecs/isac/audio_encoder_isac_float.h"  // nogncheck
-#endif
-#if WEBRTC_USE_BUILTIN_OPUS
-#include "webrtc/api/audio_codecs/opus/audio_encoder_opus.h"  // nogncheck
-#endif
+#include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.h"
 
 namespace webrtc {
 
-namespace {
-
-// Modify an audio encoder to not advertise support for anything.
-template <typename T>
-struct NotAdvertised {
-  using Config = typename T::Config;
-  static rtc::Optional<Config> SdpToConfig(const SdpAudioFormat& audio_format) {
-    return T::SdpToConfig(audio_format);
-  }
-  static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
-    // Don't advertise support for anything.
-  }
-  static AudioCodecInfo QueryAudioEncoder(const Config& config) {
-    return T::QueryAudioEncoder(config);
-  }
-  static std::unique_ptr<AudioEncoder> MakeAudioEncoder(const Config& config,
-                                                        int payload_type) {
-    return T::MakeAudioEncoder(config, payload_type);
-  }
-};
-
-}  // namespace
-
 rtc::scoped_refptr<AudioEncoderFactory> CreateBuiltinAudioEncoderFactory() {
-  return CreateAudioEncoderFactory<
-
-#if WEBRTC_USE_BUILTIN_OPUS
-      AudioEncoderOpus,
-#endif
-
-#if WEBRTC_USE_BUILTIN_ISAC_FIX
-      AudioEncoderIsacFix,
-#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
-      AudioEncoderIsacFloat,
-#endif
-
-#if WEBRTC_USE_BUILTIN_G722
-      AudioEncoderG722,
-#endif
-
-#if WEBRTC_USE_BUILTIN_ILBC
-      AudioEncoderIlbc,
-#endif
-
-      AudioEncoderG711, NotAdvertised<AudioEncoderL16>>();
+  return CreateBuiltinAudioEncoderFactoryInternal();
 }
 
 }  // namespace webrtc
diff --git a/api/audio_codecs/opus/BUILD.gn b/api/audio_codecs/opus/BUILD.gn
index 658d151..29a68ff 100644
--- a/api/audio_codecs/opus/BUILD.gn
+++ b/api/audio_codecs/opus/BUILD.gn
@@ -36,12 +36,9 @@
     ":audio_encoder_opus_config",
     "..:audio_codecs_api",
     "../../../modules/audio_coding:webrtc_opus",
+    "../../../rtc_base:protobuf_utils",  # TODO(kwiberg): Why is this needed?
     "../../../rtc_base:rtc_base_approved",
   ]
-  public_deps = [
-    # TODO(kwiberg): Remove this public_dep when bug 7847 has been fixed.
-    "../../../rtc_base:protobuf_utils",
-  ]
 }
 
 rtc_static_library("audio_decoder_opus") {
diff --git a/api/audio_codecs/test/BUILD.gn b/api/audio_codecs/test/BUILD.gn
index 0f742f5..16fdeb9 100644
--- a/api/audio_codecs/test/BUILD.gn
+++ b/api/audio_codecs/test/BUILD.gn
@@ -21,6 +21,7 @@
     ]
     deps = [
       "..:audio_codecs_api",
+      "../../../rtc_base:protobuf_utils",  # TODO(kwiberg): Why is this needed?
       "../../../rtc_base:rtc_base_approved",
       "../../../test:audio_codec_mocks",
       "../../../test:test_support",
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index a3964c9..3e6a183 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -51,6 +51,34 @@
   ]
 }
 
+rtc_static_library("builtin_audio_decoder_factory_internal") {
+  sources = [
+    "codecs/builtin_audio_decoder_factory_internal.cc",
+    "codecs/builtin_audio_decoder_factory_internal.h",
+  ]
+  deps = [
+           "../..:webrtc_common",
+           "../../rtc_base:protobuf_utils",
+           "../../rtc_base:rtc_base_approved",
+           "../../api/audio_codecs:audio_codecs_api",
+         ] + audio_codec_deps
+  defines = audio_codec_defines
+}
+
+rtc_static_library("builtin_audio_encoder_factory_internal") {
+  sources = [
+    "codecs/builtin_audio_encoder_factory_internal.cc",
+    "codecs/builtin_audio_encoder_factory_internal.h",
+  ]
+  deps = [
+           "../..:webrtc_common",
+           "../../rtc_base:protobuf_utils",
+           "../../rtc_base:rtc_base_approved",
+           "../../api/audio_codecs:audio_codecs_api",
+         ] + audio_codec_deps
+  defines = audio_codec_defines
+}
+
 rtc_static_library("rent_a_codec") {
   sources = [
     "acm2/acm_codec_database.cc",
@@ -812,13 +840,13 @@
     "../../api/audio_codecs:audio_codecs_api",
     "../../api/audio_codecs/opus:audio_encoder_opus_config",
     "../../common_audio",
+    "../../rtc_base:protobuf_utils",
     "../../rtc_base:rtc_base_approved",
     "../../rtc_base:rtc_numerics",
     "../../system_wrappers",
   ]
   public_deps = [
     ":webrtc_opus_c",
-    "../../rtc_base:protobuf_utils",
   ]
 
   defines = audio_codec_defines
diff --git a/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc b/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc
new file mode 100644
index 0000000..f853cbd
--- /dev/null
+++ b/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc
@@ -0,0 +1,257 @@
+/*
+ *  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 "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.h"
+
+#include <memory>
+#include <vector>
+
+#include "webrtc/common_types.h"
+#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h"
+#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/rtc_base/optional.h"
+#ifdef WEBRTC_CODEC_G722
+#include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h"
+#endif
+#ifdef WEBRTC_CODEC_ILBC
+#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
+#endif
+#ifdef WEBRTC_CODEC_ISACFX
+#include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"  // nogncheck
+#endif
+#ifdef WEBRTC_CODEC_ISAC
+#include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"  // nogncheck
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+#include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h"
+#endif
+#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
+
+namespace webrtc {
+
+namespace {
+
+struct NamedDecoderConstructor {
+  const char* name;
+
+  // If |format| is good, return true and (if |out| isn't null) reset |*out| to
+  // a new decoder object. If the |format| is not good, return false.
+  bool (*constructor)(const SdpAudioFormat& format,
+                      std::unique_ptr<AudioDecoder>* out);
+};
+
+// TODO(kwiberg): These factory functions should probably be moved to each
+// decoder.
+NamedDecoderConstructor decoder_constructors[] = {
+    {"pcmu",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if (format.clockrate_hz == 8000 && format.num_channels >= 1) {
+         if (out) {
+           out->reset(new AudioDecoderPcmU(format.num_channels));
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+    {"pcma",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if (format.clockrate_hz == 8000 && format.num_channels >= 1) {
+         if (out) {
+           out->reset(new AudioDecoderPcmA(format.num_channels));
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+#ifdef WEBRTC_CODEC_ILBC
+    {"ilbc",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if (format.clockrate_hz == 8000 && format.num_channels == 1) {
+         if (out) {
+           out->reset(new AudioDecoderIlbcImpl);
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+#endif
+#if defined(WEBRTC_CODEC_ISACFX)
+    {"isac",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if (format.clockrate_hz == 16000 && format.num_channels == 1) {
+         if (out) {
+           out->reset(new AudioDecoderIsacFixImpl(format.clockrate_hz));
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+#elif defined(WEBRTC_CODEC_ISAC)
+    {"isac",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if ((format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
+           format.num_channels == 1) {
+         if (out) {
+           out->reset(new AudioDecoderIsacFloatImpl(format.clockrate_hz));
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+#endif
+    {"l16",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if (format.num_channels >= 1) {
+         if (out) {
+           out->reset(new AudioDecoderPcm16B(format.clockrate_hz,
+                                             format.num_channels));
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+#ifdef WEBRTC_CODEC_G722
+    {"g722",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       if (format.clockrate_hz == 8000) {
+         if (format.num_channels == 1) {
+           if (out) {
+             out->reset(new AudioDecoderG722Impl);
+           }
+           return true;
+         } else if (format.num_channels == 2) {
+           if (out) {
+             out->reset(new AudioDecoderG722StereoImpl);
+           }
+           return true;
+         }
+       }
+       return false;
+     }},
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+    {"opus",
+     [](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
+       const rtc::Optional<int> num_channels = [&] {
+         auto stereo = format.parameters.find("stereo");
+         if (stereo != format.parameters.end()) {
+           if (stereo->second == "0") {
+             return rtc::Optional<int>(1);
+           } else if (stereo->second == "1") {
+             return rtc::Optional<int>(2);
+           } else {
+             return rtc::Optional<int>();  // Bad stereo parameter.
+           }
+         }
+         return rtc::Optional<int>(1);  // Default to mono.
+       }();
+       if (format.clockrate_hz == 48000 && format.num_channels == 2 &&
+           num_channels) {
+         if (out) {
+           out->reset(new AudioDecoderOpusImpl(*num_channels));
+         }
+         return true;
+       } else {
+         return false;
+       }
+     }},
+#endif
+};
+
+class BuiltinAudioDecoderFactory : public AudioDecoderFactory {
+ public:
+  std::vector<AudioCodecSpec> GetSupportedDecoders() override {
+    // Although this looks a bit strange, it means specs need only be
+    // initialized once, and that that initialization is thread-safe.
+    static std::vector<AudioCodecSpec> specs = [] {
+      std::vector<AudioCodecSpec> specs;
+#ifdef WEBRTC_CODEC_OPUS
+      AudioCodecInfo opus_info{48000, 1, 64000, 6000, 510000};
+      opus_info.allow_comfort_noise = false;
+      opus_info.supports_network_adaption = true;
+      // clang-format off
+      SdpAudioFormat opus_format({"opus", 48000, 2, {
+                                    {"minptime", "10"},
+                                    {"useinbandfec", "1"}
+                                  }});
+      // clang-format on
+      specs.push_back({std::move(opus_format), opus_info});
+#endif
+#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
+      specs.push_back(AudioCodecSpec{{"ISAC", 16000, 1},
+                                     {16000, 1, 32000, 10000, 56000}});
+#endif
+#if (defined(WEBRTC_CODEC_ISAC))
+      specs.push_back(AudioCodecSpec{{"ISAC", 32000, 1},
+                                     {32000, 1, 56000, 10000, 56000}});
+#endif
+#ifdef WEBRTC_CODEC_G722
+      specs.push_back(AudioCodecSpec{{"G722", 8000, 1},
+                                     {16000, 1, 64000}});
+#endif
+#ifdef WEBRTC_CODEC_ILBC
+      specs.push_back(AudioCodecSpec{{"ILBC", 8000, 1},
+                                     {8000, 1, 13300}});
+#endif
+      specs.push_back(AudioCodecSpec{{"PCMU", 8000, 1},
+                                     {8000, 1, 64000}});
+      specs.push_back(AudioCodecSpec{{"PCMA", 8000, 1},
+                                     {8000, 1, 64000}});
+      return specs;
+    }();
+    return specs;
+  }
+
+  bool IsSupportedDecoder(const SdpAudioFormat& format) override {
+    for (const auto& dc : decoder_constructors) {
+      if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) {
+        return dc.constructor(format, nullptr);
+      }
+    }
+    return false;
+  }
+
+  std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+      const SdpAudioFormat& format) override {
+    for (const auto& dc : decoder_constructors) {
+      if (STR_CASE_CMP(format.name.c_str(), dc.name) == 0) {
+        std::unique_ptr<AudioDecoder> decoder;
+        bool ok = dc.constructor(format, &decoder);
+        RTC_DCHECK_EQ(ok, decoder != nullptr);
+        if (decoder) {
+          const int expected_sample_rate_hz =
+              STR_CASE_CMP(format.name.c_str(), "g722") == 0
+                  ? 2 * format.clockrate_hz
+                  : format.clockrate_hz;
+          RTC_CHECK_EQ(expected_sample_rate_hz, decoder->SampleRateHz());
+        }
+        return decoder;
+      }
+    }
+    return nullptr;
+  }
+};
+
+}  // namespace
+
+rtc::scoped_refptr<AudioDecoderFactory>
+CreateBuiltinAudioDecoderFactoryInternal() {
+  return rtc::scoped_refptr<AudioDecoderFactory>(
+      new rtc::RefCountedObject<BuiltinAudioDecoderFactory>);
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.h b/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.h
new file mode 100644
index 0000000..c856954
--- /dev/null
+++ b/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.h
@@ -0,0 +1,24 @@
+/*
+ *  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 WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_INTERNAL_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_INTERNAL_H_
+
+#include "webrtc/api/audio_codecs/audio_decoder_factory.h"
+#include "webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<AudioDecoderFactory>
+CreateBuiltinAudioDecoderFactoryInternal();
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_INTERNAL_H_
diff --git a/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc b/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc
new file mode 100644
index 0000000..b44268a
--- /dev/null
+++ b/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.cc
@@ -0,0 +1,144 @@
+/*
+ *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.h"
+
+#include <memory>
+#include <vector>
+
+#include "webrtc/common_types.h"
+#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/rtc_base/logging.h"
+#include "webrtc/rtc_base/optional.h"
+#ifdef WEBRTC_CODEC_G722
+#include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h"
+#endif
+#ifdef WEBRTC_CODEC_ILBC
+#include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
+#endif
+#ifdef WEBRTC_CODEC_ISACFX
+#include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"  // nogncheck
+#endif
+#ifdef WEBRTC_CODEC_ISAC
+#include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"  // nogncheck
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+#include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h"
+#endif
+#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
+
+namespace webrtc {
+
+namespace {
+
+struct NamedEncoderFactory {
+  const char* name;
+  rtc::Optional<AudioCodecInfo> (*QueryAudioEncoder)(
+      const SdpAudioFormat& format);
+  std::unique_ptr<AudioEncoder> (
+      *MakeAudioEncoder)(int payload_type, const SdpAudioFormat& format);
+
+  template <typename T>
+  static NamedEncoderFactory ForEncoder() {
+    auto constructor = [](int payload_type, const SdpAudioFormat& format) {
+      auto opt_info = T::QueryAudioEncoder(format);
+      if (opt_info) {
+        return std::unique_ptr<AudioEncoder>(new T(payload_type, format));
+      }
+      return std::unique_ptr<AudioEncoder>();
+    };
+
+    return {T::GetPayloadName(), T::QueryAudioEncoder, constructor};
+  }
+};
+
+NamedEncoderFactory encoder_factories[] = {
+#ifdef WEBRTC_CODEC_G722
+    NamedEncoderFactory::ForEncoder<AudioEncoderG722Impl>(),
+#endif
+#ifdef WEBRTC_CODEC_ILBC
+    NamedEncoderFactory::ForEncoder<AudioEncoderIlbcImpl>(),
+#endif
+#if defined(WEBRTC_CODEC_ISACFX)
+    NamedEncoderFactory::ForEncoder<AudioEncoderIsacFixImpl>(),
+#elif defined(WEBRTC_CODEC_ISAC)
+    NamedEncoderFactory::ForEncoder<AudioEncoderIsacFloatImpl>(),
+#endif
+
+#ifdef WEBRTC_CODEC_OPUS
+    NamedEncoderFactory::ForEncoder<AudioEncoderOpus>(),
+#endif
+    NamedEncoderFactory::ForEncoder<AudioEncoderPcm16B>(),
+    NamedEncoderFactory::ForEncoder<AudioEncoderPcmA>(),
+    NamedEncoderFactory::ForEncoder<AudioEncoderPcmU>(),
+};
+}  // namespace
+
+class BuiltinAudioEncoderFactory : public AudioEncoderFactory {
+ public:
+  std::vector<AudioCodecSpec> GetSupportedEncoders() override {
+    static const SdpAudioFormat desired_encoders[] = {
+        {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}},
+        {"ISAC", 16000, 1},
+        {"ISAC", 32000, 1},
+        {"G722", 8000, 1},
+        {"ILBC", 8000, 1},
+        {"PCMU", 8000, 1},
+        {"PCMA", 8000, 1},
+    };
+
+    // Initialize thread-safely, once, on first use.
+    static const std::vector<AudioCodecSpec> specs = [] {
+      std::vector<AudioCodecSpec> specs;
+      for (const auto& format : desired_encoders) {
+        for (const auto& ef : encoder_factories) {
+          if (STR_CASE_CMP(format.name.c_str(), ef.name) == 0) {
+            auto opt_info = ef.QueryAudioEncoder(format);
+            if (opt_info) {
+              specs.push_back({format, *opt_info});
+            }
+          }
+        }
+      }
+      return specs;
+    }();
+    return specs;
+  }
+
+  rtc::Optional<AudioCodecInfo> QueryAudioEncoder(
+      const SdpAudioFormat& format) override {
+    for (const auto& ef : encoder_factories) {
+      if (STR_CASE_CMP(format.name.c_str(), ef.name) == 0) {
+        return ef.QueryAudioEncoder(format);
+      }
+    }
+    return rtc::Optional<AudioCodecInfo>();
+  }
+
+  std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+      int payload_type,
+      const SdpAudioFormat& format) override {
+    for (const auto& ef : encoder_factories) {
+      if (STR_CASE_CMP(format.name.c_str(), ef.name) == 0) {
+        return ef.MakeAudioEncoder(payload_type, format);
+      }
+    }
+    return nullptr;
+  }
+};
+
+rtc::scoped_refptr<AudioEncoderFactory>
+CreateBuiltinAudioEncoderFactoryInternal() {
+  return rtc::scoped_refptr<AudioEncoderFactory>(
+      new rtc::RefCountedObject<BuiltinAudioEncoderFactory>());
+}
+
+}  // namespace webrtc
diff --git a/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.h b/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.h
new file mode 100644
index 0000000..327e6ca
--- /dev/null
+++ b/modules/audio_coding/codecs/builtin_audio_encoder_factory_internal.h
@@ -0,0 +1,26 @@
+/*
+ *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_ENCODER_FACTORY_INTERNAL_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_ENCODER_FACTORY_INTERNAL_H_
+
+#include "webrtc/api/audio_codecs/audio_encoder_factory.h"
+#include "webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create the built-in types of audio encoders.
+// NOTE: This function is still under development and may change without notice.
+rtc::scoped_refptr<AudioEncoderFactory>
+CreateBuiltinAudioEncoderFactoryInternal();
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_CODECS_BUILTIN_AUDIO_ENCODER_FACTORY_INTERNAL_H_