Move AudioDecoder and related stuff to the api/ directory

BUG=webrtc:5805, webrtc:6725

Review-Url: https://codereview.webrtc.org/2668523004
Cr-Commit-Position: refs/heads/master@{#16534}
diff --git a/webrtc/api/BUILD.gn b/webrtc/api/BUILD.gn
index 8c443cb..2e3d5fe 100644
--- a/webrtc/api/BUILD.gn
+++ b/webrtc/api/BUILD.gn
@@ -29,8 +29,8 @@
     ":transport_api",
     "..:webrtc_common",
     "../base:rtc_base_approved",
-    "../modules/audio_coding:audio_decoder_factory_interface",
     "../modules/audio_coding:audio_encoder_interface",
+    "audio_codecs:audio_codecs_api",
   ]
 }
 
diff --git a/webrtc/api/DEPS b/webrtc/api/DEPS
index 4543a44..0b3778b 100644
--- a/webrtc/api/DEPS
+++ b/webrtc/api/DEPS
@@ -12,9 +12,11 @@
     "+webrtc/voice_engine",
   ],
 
-  # TODO(kwiberg): Remove this exception when audio_decoder_factory.h
-  # has moved to api/.
-  "peerconnectioninterface\.h": [
-    "+webrtc/modules/audio_coding/codecs/audio_decoder_factory.h",
+  # We allow .cc files in webrtc/api/ to #include a bunch of stuff
+  # that's off-limits for the .h files. That's because .h files leak
+  # their #includes to whoever's #including them, but .cc files do not
+  # since no one #includes them.
+  ".*\.cc": [
+    "+webrtc/modules/audio_coding",
   ],
 }
diff --git a/webrtc/api/audio_codecs/BUILD.gn b/webrtc/api/audio_codecs/BUILD.gn
new file mode 100644
index 0000000..c003df8
--- /dev/null
+++ b/webrtc/api/audio_codecs/BUILD.gn
@@ -0,0 +1,39 @@
+# 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.
+
+import("../../webrtc.gni")
+if (is_android) {
+  import("//build/config/android/config.gni")
+  import("//build/config/android/rules.gni")
+}
+
+rtc_source_set("audio_codecs_api") {
+  sources = [
+    "audio_decoder.cc",
+    "audio_decoder.h",
+    "audio_decoder_factory.h",
+    "audio_format.cc",
+    "audio_format.h",
+  ]
+  deps = [
+    "../..:webrtc_common",
+    "../../base:rtc_base_approved",
+  ]
+}
+
+rtc_static_library("builtin_audio_decoder_factory") {
+  sources = [
+    "builtin_audio_decoder_factory.cc",
+    "builtin_audio_decoder_factory.h",
+  ]
+  deps = [
+    ":audio_codecs_api",
+    "../../base:rtc_base_approved",
+    "../../modules/audio_coding:builtin_audio_decoder_factory_internal",
+  ]
+}
diff --git a/webrtc/api/audio_codecs/audio_decoder.cc b/webrtc/api/audio_codecs/audio_decoder.cc
new file mode 100644
index 0000000..90342a8
--- /dev/null
+++ b/webrtc/api/audio_codecs/audio_decoder.cc
@@ -0,0 +1,169 @@
+/*
+ *  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/api/audio_codecs/audio_decoder.h"
+
+#include <assert.h>
+#include <memory>
+#include <utility>
+
+#include "webrtc/base/array_view.h"
+#include "webrtc/base/checks.h"
+#include "webrtc/base/sanitizer.h"
+#include "webrtc/base/trace_event.h"
+
+namespace webrtc {
+
+namespace {
+
+class OldStyleEncodedFrame final : public AudioDecoder::EncodedAudioFrame {
+ public:
+  OldStyleEncodedFrame(AudioDecoder* decoder, rtc::Buffer&& payload)
+      : decoder_(decoder), payload_(std::move(payload)) {}
+
+  size_t Duration() const override {
+    const int ret = decoder_->PacketDuration(payload_.data(), payload_.size());
+    return ret < 0 ? 0 : static_cast<size_t>(ret);
+  }
+
+  rtc::Optional<DecodeResult> Decode(
+      rtc::ArrayView<int16_t> decoded) const override {
+    auto speech_type = AudioDecoder::kSpeech;
+    const int ret = decoder_->Decode(
+        payload_.data(), payload_.size(), decoder_->SampleRateHz(),
+        decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
+    return ret < 0 ? rtc::Optional<DecodeResult>()
+                   : rtc::Optional<DecodeResult>(
+                         {static_cast<size_t>(ret), speech_type});
+  }
+
+ private:
+  AudioDecoder* const decoder_;
+  const rtc::Buffer payload_;
+};
+
+}  // namespace
+
+AudioDecoder::ParseResult::ParseResult() = default;
+AudioDecoder::ParseResult::ParseResult(ParseResult&& b) = default;
+AudioDecoder::ParseResult::ParseResult(uint32_t timestamp,
+                                       int priority,
+                                       std::unique_ptr<EncodedAudioFrame> frame)
+    : timestamp(timestamp), priority(priority), frame(std::move(frame)) {
+  RTC_DCHECK_GE(priority, 0);
+}
+
+AudioDecoder::ParseResult::~ParseResult() = default;
+
+AudioDecoder::ParseResult& AudioDecoder::ParseResult::operator=(
+    ParseResult&& b) = default;
+
+std::vector<AudioDecoder::ParseResult> AudioDecoder::ParsePayload(
+    rtc::Buffer&& payload,
+    uint32_t timestamp) {
+  std::vector<ParseResult> results;
+  std::unique_ptr<EncodedAudioFrame> frame(
+      new OldStyleEncodedFrame(this, std::move(payload)));
+  results.emplace_back(timestamp, 0, std::move(frame));
+  return results;
+}
+
+int AudioDecoder::Decode(const uint8_t* encoded,
+                         size_t encoded_len,
+                         int sample_rate_hz,
+                         size_t max_decoded_bytes,
+                         int16_t* decoded,
+                         SpeechType* speech_type) {
+  TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
+  rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
+  int duration = PacketDuration(encoded, encoded_len);
+  if (duration >= 0 &&
+      duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
+    return -1;
+  }
+  return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
+                        speech_type);
+}
+
+int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
+                                  size_t encoded_len,
+                                  int sample_rate_hz,
+                                  size_t max_decoded_bytes,
+                                  int16_t* decoded,
+                                  SpeechType* speech_type) {
+  TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
+  rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
+  int duration = PacketDurationRedundant(encoded, encoded_len);
+  if (duration >= 0 &&
+      duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
+    return -1;
+  }
+  return DecodeRedundantInternal(encoded, encoded_len, sample_rate_hz, decoded,
+                                 speech_type);
+}
+
+int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded,
+                                          size_t encoded_len,
+                                          int sample_rate_hz,
+                                          int16_t* decoded,
+                                          SpeechType* speech_type) {
+  return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
+                        speech_type);
+}
+
+bool AudioDecoder::HasDecodePlc() const {
+  return false;
+}
+
+size_t AudioDecoder::DecodePlc(size_t num_frames, int16_t* decoded) {
+  return 0;
+}
+
+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) const {
+  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;
+}
+
+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/api/audio_codecs/audio_decoder.h b/webrtc/api/audio_codecs/audio_decoder.h
new file mode 100644
index 0000000..dab7d3b
--- /dev/null
+++ b/webrtc/api/audio_codecs/audio_decoder.h
@@ -0,0 +1,177 @@
+/*
+ *  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 WEBRTC_API_AUDIO_CODECS_AUDIO_DECODER_H_
+#define WEBRTC_API_AUDIO_CODECS_AUDIO_DECODER_H_
+
+#include <memory>
+#include <vector>
+
+#include "webrtc/base/array_view.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/base/optional.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+class AudioDecoder {
+ public:
+  enum SpeechType {
+    kSpeech = 1,
+    kComfortNoise = 2,
+  };
+
+  // Used by PacketDuration below. Save the value -1 for errors.
+  enum { kNotImplemented = -2 };
+
+  AudioDecoder() = default;
+  virtual ~AudioDecoder() = default;
+
+  class EncodedAudioFrame {
+   public:
+    struct DecodeResult {
+      size_t num_decoded_samples;
+      SpeechType speech_type;
+    };
+
+    virtual ~EncodedAudioFrame() = default;
+
+    // Returns the duration in samples-per-channel of this audio frame.
+    // If no duration can be ascertained, returns zero.
+    virtual size_t Duration() const = 0;
+
+    // Decodes this frame of audio and writes the result in |decoded|.
+    // |decoded| must be large enough to store as many samples as indicated by a
+    // call to Duration() . On success, returns an rtc::Optional containing the
+    // total number of samples across all channels, as well as whether the
+    // decoder produced comfort noise or speech. On failure, returns an empty
+    // rtc::Optional. Decode may be called at most once per frame object.
+    virtual rtc::Optional<DecodeResult> Decode(
+        rtc::ArrayView<int16_t> decoded) const = 0;
+  };
+
+  struct ParseResult {
+    ParseResult();
+    ParseResult(uint32_t timestamp,
+                int priority,
+                std::unique_ptr<EncodedAudioFrame> frame);
+    ParseResult(ParseResult&& b);
+    ~ParseResult();
+
+    ParseResult& operator=(ParseResult&& b);
+
+    // The timestamp of the frame is in samples per channel.
+    uint32_t timestamp;
+    // The relative priority of the frame compared to other frames of the same
+    // payload and the same timeframe. A higher value means a lower priority.
+    // The highest priority is zero - negative values are not allowed.
+    int priority;
+    std::unique_ptr<EncodedAudioFrame> frame;
+  };
+
+  // Let the decoder parse this payload and prepare zero or more decodable
+  // frames. Each frame must be between 10 ms and 120 ms long. The caller must
+  // ensure that the AudioDecoder object outlives any frame objects returned by
+  // this call. The decoder is free to swap or move the data from the |payload|
+  // buffer. |timestamp| is the input timestamp, in samples, corresponding to
+  // the start of the payload.
+  virtual std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
+                                                uint32_t timestamp);
+
+  // Decodes |encode_len| bytes from |encoded| and writes the result in
+  // |decoded|. The maximum bytes allowed to be written into |decoded| is
+  // |max_decoded_bytes|. Returns the total number of samples across all
+  // channels. If the decoder produced comfort noise, |speech_type|
+  // is set to kComfortNoise, otherwise it is kSpeech. The desired output
+  // sample rate is provided in |sample_rate_hz|, which must be valid for the
+  // codec at hand.
+  int Decode(const uint8_t* encoded,
+             size_t encoded_len,
+             int sample_rate_hz,
+             size_t max_decoded_bytes,
+             int16_t* decoded,
+             SpeechType* speech_type);
+
+  // Same as Decode(), but interfaces to the decoders redundant decode function.
+  // The default implementation simply calls the regular Decode() method.
+  int DecodeRedundant(const uint8_t* encoded,
+                      size_t encoded_len,
+                      int sample_rate_hz,
+                      size_t max_decoded_bytes,
+                      int16_t* decoded,
+                      SpeechType* speech_type);
+
+  // Indicates if the decoder implements the DecodePlc method.
+  virtual bool HasDecodePlc() const;
+
+  // Calls the packet-loss concealment of the decoder to update the state after
+  // one or several lost packets. The caller has to make sure that the
+  // memory allocated in |decoded| should accommodate |num_frames| frames.
+  virtual size_t DecodePlc(size_t num_frames, int16_t* decoded);
+
+  // Resets the decoder state (empty buffers etc.).
+  virtual void Reset() = 0;
+
+  // Notifies the decoder of an incoming packet to NetEQ.
+  virtual int IncomingPacket(const uint8_t* payload,
+                             size_t payload_len,
+                             uint16_t rtp_sequence_number,
+                             uint32_t rtp_timestamp,
+                             uint32_t arrival_timestamp);
+
+  // Returns the last error code from the decoder.
+  virtual int ErrorCode();
+
+  // Returns the duration in samples-per-channel of the payload in |encoded|
+  // which is |encoded_len| bytes long. Returns kNotImplemented if no duration
+  // estimate is available, or -1 in case of an error.
+  virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
+
+  // Returns the duration in samples-per-channel of the redandant payload in
+  // |encoded| which is |encoded_len| bytes long. Returns kNotImplemented if no
+  // duration estimate is available, or -1 in case of an error.
+  virtual int PacketDurationRedundant(const uint8_t* encoded,
+                                      size_t encoded_len) const;
+
+  // Detects whether a packet has forward error correction. The packet is
+  // comprised of the samples in |encoded| which is |encoded_len| bytes long.
+  // Returns true if the packet has FEC and false otherwise.
+  virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;
+
+  // Returns the actual sample rate of the decoder's output. This value may not
+  // change during the lifetime of the decoder.
+  virtual int SampleRateHz() const = 0;
+
+  // The number of channels in the decoder's output. This value may not change
+  // during the lifetime of the decoder.
+  virtual size_t Channels() const = 0;
+
+ protected:
+  static SpeechType ConvertSpeechType(int16_t type);
+
+  virtual int DecodeInternal(const uint8_t* encoded,
+                             size_t encoded_len,
+                             int sample_rate_hz,
+                             int16_t* decoded,
+                             SpeechType* speech_type) = 0;
+
+  virtual int DecodeRedundantInternal(const uint8_t* encoded,
+                                      size_t encoded_len,
+                                      int sample_rate_hz,
+                                      int16_t* decoded,
+                                      SpeechType* speech_type);
+
+ private:
+  RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoder);
+};
+
+}  // namespace webrtc
+#endif  // WEBRTC_API_AUDIO_CODECS_AUDIO_DECODER_H_
diff --git a/webrtc/api/audio_codecs/audio_decoder_factory.h b/webrtc/api/audio_codecs/audio_decoder_factory.h
new file mode 100644
index 0000000..3479a4e
--- /dev/null
+++ b/webrtc/api/audio_codecs/audio_decoder_factory.h
@@ -0,0 +1,37 @@
+/*
+ *  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_API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
+#define WEBRTC_API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "webrtc/api/audio_codecs/audio_decoder.h"
+#include "webrtc/api/audio_codecs/audio_format.h"
+#include "webrtc/base/refcount.h"
+
+namespace webrtc {
+
+// A factory that creates AudioDecoders.
+// NOTE: This class is still under development and may change without notice.
+class AudioDecoderFactory : public rtc::RefCountInterface {
+ public:
+  virtual std::vector<AudioCodecSpec> GetSupportedDecoders() = 0;
+
+  virtual bool IsSupportedDecoder(const SdpAudioFormat& format) = 0;
+
+  virtual std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+      const SdpAudioFormat& format) = 0;
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
diff --git a/webrtc/api/audio_codecs/audio_format.cc b/webrtc/api/audio_codecs/audio_format.cc
new file mode 100644
index 0000000..b0a86e2
--- /dev/null
+++ b/webrtc/api/audio_codecs/audio_format.cc
@@ -0,0 +1,85 @@
+/*
+ *  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/api/audio_codecs/audio_format.h"
+
+#include "webrtc/common_types.h"
+
+namespace webrtc {
+
+SdpAudioFormat::SdpAudioFormat(const SdpAudioFormat&) = default;
+SdpAudioFormat::SdpAudioFormat(SdpAudioFormat&&) = default;
+
+SdpAudioFormat::SdpAudioFormat(const char* name,
+                               int clockrate_hz,
+                               int num_channels)
+    : name(name), clockrate_hz(clockrate_hz), num_channels(num_channels) {}
+
+SdpAudioFormat::SdpAudioFormat(const std::string& name,
+                               int clockrate_hz,
+                               int num_channels)
+    : name(name), clockrate_hz(clockrate_hz), num_channels(num_channels) {}
+
+SdpAudioFormat::SdpAudioFormat(const char* name,
+                               int clockrate_hz,
+                               int num_channels,
+                               const Parameters& param)
+    : name(name),
+      clockrate_hz(clockrate_hz),
+      num_channels(num_channels),
+      parameters(param) {}
+
+SdpAudioFormat::SdpAudioFormat(const std::string& name,
+                               int clockrate_hz,
+                               int num_channels,
+                               const Parameters& param)
+    : name(name),
+      clockrate_hz(clockrate_hz),
+      num_channels(num_channels),
+      parameters(param) {}
+
+SdpAudioFormat::~SdpAudioFormat() = default;
+SdpAudioFormat& SdpAudioFormat::operator=(const SdpAudioFormat&) = default;
+SdpAudioFormat& SdpAudioFormat::operator=(SdpAudioFormat&&) = default;
+
+bool operator==(const SdpAudioFormat& a, const SdpAudioFormat& b) {
+  return STR_CASE_CMP(a.name.c_str(), b.name.c_str()) == 0 &&
+         a.clockrate_hz == b.clockrate_hz && a.num_channels == b.num_channels &&
+         a.parameters == b.parameters;
+}
+
+void swap(SdpAudioFormat& a, SdpAudioFormat& b) {
+  using std::swap;
+  swap(a.name, b.name);
+  swap(a.clockrate_hz, b.clockrate_hz);
+  swap(a.num_channels, b.num_channels);
+  swap(a.parameters, b.parameters);
+}
+
+std::ostream& operator<<(std::ostream& os, const SdpAudioFormat& saf) {
+  os << "{name: " << saf.name;
+  os << ", clockrate_hz: " << saf.clockrate_hz;
+  os << ", num_channels: " << saf.num_channels;
+  os << ", parameters: {";
+  const char* sep = "";
+  for (const auto& kv : saf.parameters) {
+    os << sep << kv.first << ": " << kv.second;
+    sep = ", ";
+  }
+  os << "}}";
+  return os;
+}
+
+AudioCodecSpec::AudioCodecSpec(const SdpAudioFormat& format) : format(format) {}
+
+AudioCodecSpec::AudioCodecSpec(SdpAudioFormat&& format)
+    : format(std::move(format)) {}
+
+}  // namespace webrtc
diff --git a/webrtc/api/audio_codecs/audio_format.h b/webrtc/api/audio_codecs/audio_format.h
new file mode 100644
index 0000000..db3990f
--- /dev/null
+++ b/webrtc/api/audio_codecs/audio_format.h
@@ -0,0 +1,81 @@
+/*
+ *  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_API_AUDIO_CODECS_AUDIO_FORMAT_H_
+#define WEBRTC_API_AUDIO_CODECS_AUDIO_FORMAT_H_
+
+#include <map>
+#include <ostream>
+#include <string>
+#include <utility>
+
+namespace webrtc {
+
+// SDP specification for a single audio codec.
+// NOTE: This class is still under development and may change without notice.
+struct SdpAudioFormat {
+  using Parameters = std::map<std::string, std::string>;
+
+  SdpAudioFormat(const SdpAudioFormat&);
+  SdpAudioFormat(SdpAudioFormat&&);
+  SdpAudioFormat(const char* name, int clockrate_hz, int num_channels);
+  SdpAudioFormat(const std::string& name, int clockrate_hz, int num_channels);
+  SdpAudioFormat(const char* name,
+                 int clockrate_hz,
+                 int num_channels,
+                 const Parameters& param);
+  SdpAudioFormat(const std::string& name,
+                 int clockrate_hz,
+                 int num_channels,
+                 const Parameters& param);
+  ~SdpAudioFormat();
+
+  SdpAudioFormat& operator=(const SdpAudioFormat&);
+  SdpAudioFormat& operator=(SdpAudioFormat&&);
+
+  friend bool operator==(const SdpAudioFormat& a, const SdpAudioFormat& b);
+  friend bool operator!=(const SdpAudioFormat& a, const SdpAudioFormat& b) {
+    return !(a == b);
+  }
+
+  std::string name;
+  int clockrate_hz;
+  int num_channels;
+  Parameters parameters;
+};
+
+void swap(SdpAudioFormat& a, SdpAudioFormat& b);
+std::ostream& operator<<(std::ostream& os, const SdpAudioFormat& saf);
+
+// To avoid API breakage, and make the code clearer, AudioCodecSpec should not
+// be directly initializable with any flags indicating optional support. If it
+// were, these initializers would break any time a new flag was added. It's also
+// more difficult to understand:
+//   AudioCodecSpec spec{{"format", 8000, 1}, true, false, false, true, true};
+// than
+//   AudioCodecSpec spec({"format", 8000, 1});
+//   spec.allow_comfort_noise = true;
+//   spec.future_flag_b = true;
+//   spec.future_flag_c = true;
+struct AudioCodecSpec {
+  explicit AudioCodecSpec(const SdpAudioFormat& format);
+  explicit AudioCodecSpec(SdpAudioFormat&& format);
+  ~AudioCodecSpec() = default;
+
+  SdpAudioFormat format;
+  bool allow_comfort_noise = true;  // This codec can be used with an external
+                                    // comfort noise generator.
+  bool supports_network_adaption = false;  // This codec can adapt to varying
+                                           // network conditions.
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_API_AUDIO_CODECS_AUDIO_FORMAT_H_
diff --git a/webrtc/api/audio_codecs/builtin_audio_decoder_factory.cc b/webrtc/api/audio_codecs/builtin_audio_decoder_factory.cc
new file mode 100644
index 0000000..9bd049b
--- /dev/null
+++ b/webrtc/api/audio_codecs/builtin_audio_decoder_factory.cc
@@ -0,0 +1,21 @@
+/*
+ *  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/api/audio_codecs/builtin_audio_decoder_factory.h"
+
+#include "webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
+  return CreateBuiltinAudioDecoderFactoryInternal();
+}
+
+}  // namespace webrtc
diff --git a/webrtc/api/audio_codecs/builtin_audio_decoder_factory.h b/webrtc/api/audio_codecs/builtin_audio_decoder_factory.h
new file mode 100644
index 0000000..f7452f4
--- /dev/null
+++ b/webrtc/api/audio_codecs/builtin_audio_decoder_factory.h
@@ -0,0 +1,25 @@
+/*
+ *  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_API_AUDIO_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_
+#define WEBRTC_API_AUDIO_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_
+
+#include "webrtc/api/audio_codecs/audio_decoder_factory.h"
+#include "webrtc/base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create the built-in types of audio decoders.
+// NOTE: This function is still under development and may change without notice.
+rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory();
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_API_AUDIO_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_
diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h
index ea94f50..2a22258 100644
--- a/webrtc/api/peerconnectioninterface.h
+++ b/webrtc/api/peerconnectioninterface.h
@@ -73,13 +73,14 @@
 #include <utility>
 #include <vector>
 
+#include "webrtc/api/audio_codecs/audio_decoder_factory.h"
 #include "webrtc/api/datachannelinterface.h"
 #include "webrtc/api/dtmfsenderinterface.h"
 #include "webrtc/api/jsep.h"
 #include "webrtc/api/mediastreaminterface.h"
-#include "webrtc/api/stats/rtcstatscollectorcallback.h"
 #include "webrtc/api/rtpreceiverinterface.h"
 #include "webrtc/api/rtpsenderinterface.h"
+#include "webrtc/api/stats/rtcstatscollectorcallback.h"
 #include "webrtc/api/statstypes.h"
 #include "webrtc/api/umametrics.h"
 #include "webrtc/base/fileutils.h"
@@ -89,7 +90,6 @@
 #include "webrtc/base/socketaddress.h"
 #include "webrtc/base/sslstreamadapter.h"
 #include "webrtc/media/base/mediachannel.h"
-#include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h"
 #include "webrtc/p2p/base/portallocator.h"
 
 namespace rtc {