Using Rent-A-Codec for static Codec access in WVoE/MC.

Mostly moved code around in WebRtcVoiceEngine:
- Added new internal class WebRtcVoiceCodecs for static codec functions and the CodecPrefs.
- ConstructCodecs() -> WebRtcVoiceCodecs::SupportedCodecs().
- FindWebRtcCodec -> WebRtcVoiceCodecs::ToCodecInst().
- WebRtcVoiceMediaChannel::SetRecvCodecsInternal() folded into WebRtcVoiceMediaChannel::SetRecvCodecs() (slight logic change).
- Change to how SetRecPayloadType() is implemented in fakewebrtcvoiceengine.h (lines 460-470).

BUG=webrtc:4690

Review URL: https://codereview.webrtc.org/1461333002

Cr-Commit-Position: refs/heads/master@{#10819}
diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h
index f0bd6a6..6ca3341 100644
--- a/talk/media/webrtc/fakewebrtcvoiceengine.h
+++ b/talk/media/webrtc/fakewebrtcvoiceengine.h
@@ -41,6 +41,7 @@
 #include "webrtc/base/gunit.h"
 #include "webrtc/base/stringutils.h"
 #include "webrtc/config.h"
+#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
 #include "webrtc/modules/audio_processing/include/audio_processing.h"
 
 namespace cricket {
@@ -63,18 +64,6 @@
 #define WEBRTC_CHECK_CHANNEL(channel) \
   if (channels_.find(channel) == channels_.end()) return -1;
 
-#define WEBRTC_ASSERT_CHANNEL(channel) \
-  RTC_DCHECK(channels_.find(channel) != channels_.end());
-
-// Verify the header extension ID, if enabled, is within the bounds specified in
-// [RFC5285]: 1-14 inclusive.
-#define WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id) \
-  do { \
-    if (enable && (id < 1 || id > 14)) { \
-      return -1; \
-    } \
-  } while (0);
-
 class FakeAudioProcessing : public webrtc::AudioProcessing {
  public:
   FakeAudioProcessing() : experimental_ns_enabled_(false) {}
@@ -189,6 +178,7 @@
           nack_max_packets(0),
           send_ssrc(0),
           associate_send_channel(-1),
+          recv_codecs(),
           neteq_capacity(-1),
           neteq_fast_accelerate(false) {
       memset(&send_codec, 0, sizeof(send_codec));
@@ -219,13 +209,10 @@
     bool neteq_fast_accelerate;
   };
 
-  FakeWebRtcVoiceEngine(const cricket::AudioCodec* const* codecs,
-                        int num_codecs)
+  FakeWebRtcVoiceEngine()
       : inited_(false),
         last_channel_(-1),
         fail_create_channel_(false),
-        codecs_(codecs),
-        num_codecs_(num_codecs),
         num_set_send_codecs_(0),
         ec_enabled_(false),
         ec_metrics_enabled_(false),
@@ -247,12 +234,7 @@
     memset(&agc_config_, 0, sizeof(agc_config_));
   }
   ~FakeWebRtcVoiceEngine() {
-    // Ought to have all been deleted by the WebRtcVoiceMediaChannel
-    // destructors, but just in case ...
-    for (std::map<int, Channel*>::const_iterator i = channels_.begin();
-         i != channels_.end(); ++i) {
-      delete i->second;
-    }
+    RTC_CHECK(channels_.empty());
   }
 
   bool ec_metrics_enabled() const { return ec_metrics_enabled_; }
@@ -291,7 +273,7 @@
     return channels_[channel]->nack_max_packets;
   }
   const webrtc::PacketTime& GetLastRtpPacketTime(int channel) {
-    WEBRTC_ASSERT_CHANNEL(channel);
+    RTC_DCHECK(channels_.find(channel) != channels_.end());
     return channels_[channel]->last_rtp_packet_time;
   }
   int GetSendCNPayloadType(int channel, bool wideband) {
@@ -335,11 +317,8 @@
       return -1;
     }
     Channel* ch = new Channel();
-    for (int i = 0; i < NumOfCodecs(); ++i) {
-      webrtc::CodecInst codec;
-      GetCodec(i, codec);
-      ch->recv_codecs.push_back(codec);
-    }
+    auto db = webrtc::acm2::RentACodec::Database();
+    ch->recv_codecs.assign(db.begin(), db.end());
     if (config.Get<webrtc::NetEqCapacityConfig>().enabled) {
       ch->neteq_capacity = config.Get<webrtc::NetEqCapacityConfig>().capacity;
     }
@@ -439,22 +418,8 @@
   webrtc::RtcEventLog* GetEventLog() { return nullptr; }
 
   // webrtc::VoECodec
-  WEBRTC_FUNC(NumOfCodecs, ()) {
-    return num_codecs_;
-  }
-  WEBRTC_FUNC(GetCodec, (int index, webrtc::CodecInst& codec)) {
-    if (index < 0 || index >= NumOfCodecs()) {
-      return -1;
-    }
-    const cricket::AudioCodec& c(*codecs_[index]);
-    codec.pltype = c.id;
-    rtc::strcpyn(codec.plname, sizeof(codec.plname), c.name.c_str());
-    codec.plfreq = c.clockrate;
-    codec.pacsize = 0;
-    codec.channels = c.channels;
-    codec.rate = c.bitrate;
-    return 0;
-  }
+  WEBRTC_STUB(NumOfCodecs, ());
+  WEBRTC_STUB(GetCodec, (int index, webrtc::CodecInst& codec));
   WEBRTC_FUNC(SetSendCodec, (int channel, const webrtc::CodecInst& codec)) {
     WEBRTC_CHECK_CHANNEL(channel);
     // To match the behavior of the real implementation.
@@ -492,16 +457,17 @@
       }
     }
     // Otherwise try to find this codec and update its payload type.
+    int result = -1;  // not found
     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
          it != ch->recv_codecs.end(); ++it) {
       if (strcmp(it->plname, codec.plname) == 0 &&
-          it->plfreq == codec.plfreq) {
+          it->plfreq == codec.plfreq &&
+          it->channels == codec.channels) {
         it->pltype = codec.pltype;
-        it->channels = codec.channels;
-        return 0;
+        result = 0;
       }
     }
-    return -1;  // not found
+    return result;
   }
   WEBRTC_FUNC(SetSendCNPayloadType, (int channel, int type,
                                      webrtc::PayloadFrequencies frequency)) {
@@ -932,8 +898,6 @@
   int last_channel_;
   std::map<int, Channel*> channels_;
   bool fail_create_channel_;
-  const cricket::AudioCodec* const* codecs_;
-  int num_codecs_;
   int num_set_send_codecs_;  // how many times we call SetSendCodec().
   bool ec_enabled_;
   bool ec_metrics_enabled_;
@@ -957,8 +921,6 @@
   FakeAudioProcessing audio_processing_;
 };
 
-#undef WEBRTC_CHECK_HEADER_EXTENSION_ID
-
 }  // namespace cricket
 
 #endif  // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index 721990a..4bd0400 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -53,6 +53,7 @@
 #include "webrtc/base/stringutils.h"
 #include "webrtc/call/rtc_event_log.h"
 #include "webrtc/common.h"
+#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
 #include "webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/system_wrappers/include/field_trial.h"
 #include "webrtc/system_wrappers/include/trace.h"
@@ -66,32 +67,6 @@
 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo |
                                  webrtc::kTraceInfo;
 
-const int kMaxNumPacketSize = 6;
-struct CodecPref {
-  const char* name;
-  int clockrate;
-  int channels;
-  int payload_type;
-  bool is_multi_rate;
-  int packet_sizes_ms[kMaxNumPacketSize];
-};
-// Note: keep the supported packet sizes in ascending order.
-const CodecPref kCodecPrefs[] = {
-  { kOpusCodecName,   48000, 2, 111, true,  { 10, 20, 40, 60 } },
-  { kIsacCodecName,   16000, 1, 103, true,  { 30, 60 } },
-  { kIsacCodecName,   32000, 1, 104, true,  { 30 } },
-  // G722 should be advertised as 8000 Hz because of the RFC "bug".
-  { kG722CodecName,   8000,  1, 9,   false, { 10, 20, 30, 40, 50, 60 } },
-  { kIlbcCodecName,   8000,  1, 102, false, { 20, 30, 40, 60 } },
-  { kPcmuCodecName,   8000,  1, 0,   false, { 10, 20, 30, 40, 50, 60 } },
-  { kPcmaCodecName,   8000,  1, 8,   false, { 10, 20, 30, 40, 50, 60 } },
-  { kCnCodecName,     32000, 1, 106, false, { } },
-  { kCnCodecName,     16000, 1, 105, false, { } },
-  { kCnCodecName,     8000,  1, 13,  false, { } },
-  { kRedCodecName,    8000,  1, 127, false, { } },
-  { kDtmfCodecName,   8000,  1, 126, false, { } },
-};
-
 // For Linux/Mac, using the default device is done by specifying index 0 for
 // VoE 4.0 and not -1 (which was the case for VoE 3.5).
 //
@@ -185,13 +160,6 @@
   return ss.str();
 }
 
-void LogMultiline(rtc::LoggingSeverity sev, char* text) {
-  const char* delim = "\r\n";
-  for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) {
-    LOG_V(sev) << tok;
-  }
-}
-
 bool IsCodec(const AudioCodec& codec, const char* ref_name) {
   return (_stricmp(codec.name.c_str(), ref_name) == 0);
 }
@@ -200,19 +168,9 @@
   return (_stricmp(codec.plname, ref_name) == 0);
 }
 
-bool IsCodecMultiRate(const webrtc::CodecInst& codec) {
-  for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
-    if (IsCodec(codec, kCodecPrefs[i].name) &&
-        kCodecPrefs[i].clockrate == codec.plfreq) {
-      return kCodecPrefs[i].is_multi_rate;
-    }
-  }
-  return false;
-}
-
 bool FindCodec(const std::vector<AudioCodec>& codecs,
-                      const AudioCodec& codec,
-                      AudioCodec* found_codec) {
+               const AudioCodec& codec,
+               AudioCodec* found_codec) {
   for (const AudioCodec& c : codecs) {
     if (c.Matches(codec)) {
       if (found_codec != NULL) {
@@ -242,38 +200,8 @@
                                               kParamValueEmpty));
 }
 
-int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) {
-  int selected_packet_size_ms = codec_pref.packet_sizes_ms[0];
-  for (int packet_size_ms : codec_pref.packet_sizes_ms) {
-    if (packet_size_ms && packet_size_ms <= ptime_ms) {
-      selected_packet_size_ms = packet_size_ms;
-    }
-  }
-  return selected_packet_size_ms;
-}
-
-// If the AudioCodec param kCodecParamPTime is set, then we will set it to codec
-// pacsize if it's valid, or we will pick the next smallest value we support.
-// TODO(Brave): Query supported packet sizes from ACM when the API is ready.
-bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) {
-  for (const CodecPref& codec_pref : kCodecPrefs) {
-    if ((IsCodec(*codec, codec_pref.name) &&
-        codec_pref.clockrate == codec->plfreq) ||
-        IsCodec(*codec, kG722CodecName)) {
-      int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms);
-      if (packet_size_ms) {
-        // Convert unit from milli-seconds to samples.
-        codec->pacsize = (codec->plfreq / 1000) * packet_size_ms;
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 // Return true if codec.params[feature] == "1", false otherwise.
-bool IsCodecFeatureEnabled(const AudioCodec& codec,
-                                  const char* feature) {
+bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) {
   int value;
   return codec.GetParam(feature, &value) && value == 1;
 }
@@ -340,18 +268,6 @@
   voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate);
 }
 
-// Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC
-// which says that G722 should be advertised as 8 kHz although it is a 16 kHz
-// codec.
-void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
-  if (IsCodec(*voe_codec, kG722CodecName)) {
-    // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine
-    // has changed, and this special case is no longer needed.
-    RTC_DCHECK(voe_codec->plfreq != new_plfreq);
-    voe_codec->plfreq = new_plfreq;
-  }
-}
-
 // Gets the default set of options applied to the engine. Historically, these
 // were supplied as a combination of flags from the channel manager (ec, agc,
 // ns, and highpass) and the rest hardcoded in InitInternal.
@@ -393,54 +309,17 @@
   }
   return result;
 }
-} // namespace {
 
-WebRtcVoiceEngine::WebRtcVoiceEngine()
-    : voe_wrapper_(new VoEWrapper()),
-      audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))) {
-  Construct();
-}
-
-WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper)
-    : voe_wrapper_(voe_wrapper) {
-  Construct();
-}
-
-void WebRtcVoiceEngine::Construct() {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
-
-  signal_thread_checker_.DetachFromThread();
-  std::memset(&default_agc_config_, 0, sizeof(default_agc_config_));
-
-  webrtc::Trace::set_level_filter(kDefaultTraceFilter);
-  webrtc::Trace::SetTraceCallback(this);
-
-  // Load our audio codec list.
-  ConstructCodecs();
-
-  // Load our RTP Header extensions.
-  rtp_header_extensions_.push_back(
-      RtpHeaderExtension(kRtpAudioLevelHeaderExtension,
-                         kRtpAudioLevelHeaderExtensionDefaultId));
-  rtp_header_extensions_.push_back(
-      RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
-                         kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
-  if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") {
-    rtp_header_extensions_.push_back(RtpHeaderExtension(
-        kRtpTransportSequenceNumberHeaderExtension,
-        kRtpTransportSequenceNumberHeaderExtensionDefaultId));
-  }
-  options_ = GetDefaultEngineOptions();
-}
-
-void WebRtcVoiceEngine::ConstructCodecs() {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
-  int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (GetVoeCodec(i, &voe_codec)) {
+class WebRtcVoiceCodecs final {
+ public:
+  // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec
+  // list and add a test which verifies VoE supports the listed codecs.
+  static std::vector<AudioCodec> SupportedCodecs() {
+    LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
+    std::vector<AudioCodec> result;
+    for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
+      // Change the sample rate of G722 to 8000 to match SDP.
+      MaybeFixupG722(&voe_codec, 8000);
       // Skip uncompressed formats.
       if (IsCodec(voe_codec, kL16CodecName)) {
         continue;
@@ -483,24 +362,181 @@
           // TODO(hellner): Add ptime, sprop-stereo, and stereo
           // when they can be set to values other than the default.
         }
-        codecs_.push_back(codec);
+        result.push_back(codec);
       } else {
         LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec);
       }
     }
+    // Make sure they are in local preference order.
+    std::sort(result.begin(), result.end(), &AudioCodec::Preferable);
+    return result;
   }
-  // Make sure they are in local preference order.
-  std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable);
-}
 
-bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst* codec) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  if (voe_wrapper_->codec()->GetCodec(index, *codec) == -1) {
+  static bool ToCodecInst(const AudioCodec& in,
+                          webrtc::CodecInst* out) {
+    for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
+      // Change the sample rate of G722 to 8000 to match SDP.
+      MaybeFixupG722(&voe_codec, 8000);
+      AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
+                       voe_codec.rate, voe_codec.channels, 0);
+      bool multi_rate = IsCodecMultiRate(voe_codec);
+      // Allow arbitrary rates for ISAC to be specified.
+      if (multi_rate) {
+        // Set codec.bitrate to 0 so the check for codec.Matches() passes.
+        codec.bitrate = 0;
+      }
+      if (codec.Matches(in)) {
+        if (out) {
+          // Fixup the payload type.
+          voe_codec.pltype = in.id;
+
+          // Set bitrate if specified.
+          if (multi_rate && in.bitrate != 0) {
+            voe_codec.rate = in.bitrate;
+          }
+
+          // Reset G722 sample rate to 16000 to match WebRTC.
+          MaybeFixupG722(&voe_codec, 16000);
+
+          // Apply codec-specific settings.
+          if (IsCodec(codec, kIsacCodecName)) {
+            // If ISAC and an explicit bitrate is not specified,
+            // enable auto bitrate adjustment.
+            voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1;
+          }
+          *out = voe_codec;
+        }
+        return true;
+      }
+    }
     return false;
   }
-  // Change the sample rate of G722 to 8000 to match SDP.
-  MaybeFixupG722(codec, 8000);
-  return true;
+
+  static bool IsCodecMultiRate(const webrtc::CodecInst& codec) {
+    for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
+      if (IsCodec(codec, kCodecPrefs[i].name) &&
+          kCodecPrefs[i].clockrate == codec.plfreq) {
+        return kCodecPrefs[i].is_multi_rate;
+      }
+    }
+    return false;
+  }
+
+  // If the AudioCodec param kCodecParamPTime is set, then we will set it to
+  // codec pacsize if it's valid, or we will pick the next smallest value we
+  // support.
+  // TODO(Brave): Query supported packet sizes from ACM when the API is ready.
+  static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) {
+    for (const CodecPref& codec_pref : kCodecPrefs) {
+      if ((IsCodec(*codec, codec_pref.name) &&
+          codec_pref.clockrate == codec->plfreq) ||
+          IsCodec(*codec, kG722CodecName)) {
+        int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms);
+        if (packet_size_ms) {
+          // Convert unit from milli-seconds to samples.
+          codec->pacsize = (codec->plfreq / 1000) * packet_size_ms;
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+ private:
+  static const int kMaxNumPacketSize = 6;
+  struct CodecPref {
+    const char* name;
+    int clockrate;
+    int channels;
+    int payload_type;
+    bool is_multi_rate;
+    int packet_sizes_ms[kMaxNumPacketSize];
+  };
+  // Note: keep the supported packet sizes in ascending order.
+  static const CodecPref kCodecPrefs[12];
+
+  static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) {
+    int selected_packet_size_ms = codec_pref.packet_sizes_ms[0];
+    for (int packet_size_ms : codec_pref.packet_sizes_ms) {
+      if (packet_size_ms && packet_size_ms <= ptime_ms) {
+        selected_packet_size_ms = packet_size_ms;
+      }
+    }
+    return selected_packet_size_ms;
+  }
+
+  // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC
+  // which says that G722 should be advertised as 8 kHz although it is a 16 kHz
+  // codec.
+  static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
+    if (IsCodec(*voe_codec, kG722CodecName)) {
+      // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine
+      // has changed, and this special case is no longer needed.
+      RTC_DCHECK(voe_codec->plfreq != new_plfreq);
+      voe_codec->plfreq = new_plfreq;
+    }
+  }
+};
+
+const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[12] = {
+  { kOpusCodecName,   48000, 2, 111, true,  { 10, 20, 40, 60 } },
+  { kIsacCodecName,   16000, 1, 103, true,  { 30, 60 } },
+  { kIsacCodecName,   32000, 1, 104, true,  { 30 } },
+  // G722 should be advertised as 8000 Hz because of the RFC "bug".
+  { kG722CodecName,   8000,  1, 9,   false, { 10, 20, 30, 40, 50, 60 } },
+  { kIlbcCodecName,   8000,  1, 102, false, { 20, 30, 40, 60 } },
+  { kPcmuCodecName,   8000,  1, 0,   false, { 10, 20, 30, 40, 50, 60 } },
+  { kPcmaCodecName,   8000,  1, 8,   false, { 10, 20, 30, 40, 50, 60 } },
+  { kCnCodecName,     32000, 1, 106, false, { } },
+  { kCnCodecName,     16000, 1, 105, false, { } },
+  { kCnCodecName,     8000,  1, 13,  false, { } },
+  { kRedCodecName,    8000,  1, 127, false, { } },
+  { kDtmfCodecName,   8000,  1, 126, false, { } },
+};
+} // namespace {
+
+bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in,
+                                    webrtc::CodecInst* out) {
+  return WebRtcVoiceCodecs::ToCodecInst(in, out);
+}
+
+WebRtcVoiceEngine::WebRtcVoiceEngine()
+    : voe_wrapper_(new VoEWrapper()),
+      audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))) {
+  Construct();
+}
+
+WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper)
+    : voe_wrapper_(voe_wrapper) {
+  Construct();
+}
+
+void WebRtcVoiceEngine::Construct() {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+  LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
+
+  signal_thread_checker_.DetachFromThread();
+  std::memset(&default_agc_config_, 0, sizeof(default_agc_config_));
+
+  webrtc::Trace::set_level_filter(kDefaultTraceFilter);
+  webrtc::Trace::SetTraceCallback(this);
+
+  // Load our audio codec list.
+  codecs_ = WebRtcVoiceCodecs::SupportedCodecs();
+
+  // Load our RTP Header extensions.
+  rtp_header_extensions_.push_back(
+      RtpHeaderExtension(kRtpAudioLevelHeaderExtension,
+                         kRtpAudioLevelHeaderExtensionDefaultId));
+  rtp_header_extensions_.push_back(
+      RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
+                         kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
+  if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") {
+    rtp_header_extensions_.push_back(RtpHeaderExtension(
+        kRtpTransportSequenceNumberHeaderExtension,
+        kRtpTransportSequenceNumberHeaderExtensionDefaultId));
+  }
+  options_ = GetDefaultEngineOptions();
 }
 
 WebRtcVoiceEngine::~WebRtcVoiceEngine() {
@@ -539,10 +575,15 @@
   webrtc::Trace::set_level_filter(kDefaultTraceFilter);
 
   // Log the VoiceEngine version info
-  char buffer[1024] = "";
-  voe_wrapper_->base()->GetVersion(buffer);
-  LOG(LS_INFO) << "WebRtc VoiceEngine Version:";
-  LogMultiline(rtc::LS_INFO, buffer);
+  {
+    char buffer[1024] = "";
+    voe_wrapper_->base()->GetVersion(buffer);
+    LOG(LS_INFO) << "WebRtc VoiceEngine Version:";
+    const char* delim = "\r\n";
+    for (char* tok = strtok(buffer, delim); tok; tok = strtok(NULL, delim)) {
+      LOG(LS_INFO) << tok;
+    }
+  }
 
   // Save the default AGC configuration settings. This must happen before
   // calling SetOptions or the default will be overwritten.
@@ -1056,55 +1097,6 @@
   return codecs_;
 }
 
-bool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return FindWebRtcCodec(in, NULL);
-}
-
-// Get the VoiceEngine codec that matches |in|, with the supplied settings.
-bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in,
-                                        webrtc::CodecInst* out) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (GetVoeCodec(i, &voe_codec)) {
-      AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
-                       voe_codec.rate, voe_codec.channels, 0);
-      bool multi_rate = IsCodecMultiRate(voe_codec);
-      // Allow arbitrary rates for ISAC to be specified.
-      if (multi_rate) {
-        // Set codec.bitrate to 0 so the check for codec.Matches() passes.
-        codec.bitrate = 0;
-      }
-      if (codec.Matches(in)) {
-        if (out) {
-          // Fixup the payload type.
-          voe_codec.pltype = in.id;
-
-          // Set bitrate if specified.
-          if (multi_rate && in.bitrate != 0) {
-            voe_codec.rate = in.bitrate;
-          }
-
-          // Reset G722 sample rate to 16000 to match WebRTC.
-          MaybeFixupG722(&voe_codec, 16000);
-
-          // Apply codec-specific settings.
-          if (IsCodec(codec, kIsacCodecName)) {
-            // If ISAC and an explicit bitrate is not specified,
-            // enable auto bitrate adjustment.
-            voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1;
-          }
-          *out = voe_codec;
-        }
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 const std::vector<RtpHeaderExtension>&
 WebRtcVoiceEngine::rtp_header_extensions() const {
   RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
@@ -1592,7 +1584,26 @@
     PausePlayout();
   }
 
-  bool result = SetRecvCodecsInternal(new_codecs);
+  bool result = true;
+  for (const AudioCodec& codec : new_codecs) {
+    webrtc::CodecInst voe_codec;
+    if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
+      LOG(LS_INFO) << ToString(codec);
+      voe_codec.pltype = codec.id;
+      for (const auto& ch : recv_streams_) {
+        if (engine()->voe()->codec()->SetRecPayloadType(
+                ch.second->channel(), voe_codec) == -1) {
+          LOG_RTCERR2(SetRecPayloadType, ch.second->channel(),
+                      ToString(voe_codec));
+          result = false;
+        }
+      }
+    } else {
+      LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
+      result = false;
+      break;
+    }
+  }
   if (result) {
     recv_codecs_ = codecs;
   }
@@ -1627,7 +1638,7 @@
     // Ignore codecs we don't know about. The negotiation step should prevent
     // this, but double-check to be sure.
     webrtc::CodecInst voe_codec;
-    if (!engine()->FindWebRtcCodec(codec, &voe_codec)) {
+    if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
       LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
       continue;
     }
@@ -1668,7 +1679,7 @@
       // Set packet size if the AudioCodec param kCodecParamPTime is set.
       int ptime_ms = 0;
       if (codec.GetParam(kCodecParamPTime, &ptime_ms)) {
-        if (!SetPTimeAsPacketSize(&send_codec, ptime_ms)) {
+        if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize(&send_codec, ptime_ms)) {
           LOG(LS_WARNING) << "Failed to set packet size for codec "
                           << send_codec.plname;
           return false;
@@ -1746,7 +1757,7 @@
     // Ignore codecs we don't know about. The negotiation step should prevent
     // this, but double-check to be sure.
     webrtc::CodecInst voe_codec;
-    if (!engine()->FindWebRtcCodec(codec, &voe_codec)) {
+    if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
       LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
       continue;
     }
@@ -2116,24 +2127,20 @@
   }
 
   // Turn off all supported codecs.
-  const int ncodecs = engine()->voe()->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
-      voe_codec.pltype = -1;
-      if (engine()->voe()->codec()->SetRecPayloadType(
-          channel, voe_codec) == -1) {
-        LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
-        DeleteVoEChannel(channel);
-        return false;
-      }
+  // TODO(solenberg): Remove once "no codecs" is the default state of a stream.
+  for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
+    voe_codec.pltype = -1;
+    if (engine()->voe()->codec()->SetRecPayloadType(channel, voe_codec) == -1) {
+      LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
+      DeleteVoEChannel(channel);
+      return false;
     }
   }
 
   // Only enable those configured for this channel.
   for (const auto& codec : recv_codecs_) {
     webrtc::CodecInst voe_codec;
-    if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
+    if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
       voe_codec.pltype = codec.id;
       if (engine()->voe()->codec()->SetRecPayloadType(
           channel, voe_codec) == -1) {
@@ -2486,7 +2493,7 @@
     return true;
 
   webrtc::CodecInst codec = *send_codec_;
-  bool is_multi_rate = IsCodecMultiRate(codec);
+  bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec);
 
   if (is_multi_rate) {
     // If codec is multi-rate then just set the bitrate.
@@ -2635,7 +2642,7 @@
     if (codec.id == red_pt) {
       // If we find the right codec, that will be the codec we pass to
       // SetSendCodec, with the desired payload type.
-      if (engine()->FindWebRtcCodec(codec, send_codec)) {
+      if (WebRtcVoiceEngine::ToCodecInst(codec, send_codec)) {
         return true;
       } else {
         break;
@@ -2659,30 +2666,6 @@
   }
   return true;
 }
-
-bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal(
-    const std::vector<AudioCodec>& new_codecs) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  for (const AudioCodec& codec : new_codecs) {
-    webrtc::CodecInst voe_codec;
-    if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
-      LOG(LS_INFO) << ToString(codec);
-      voe_codec.pltype = codec.id;
-      for (const auto& ch : recv_streams_) {
-        if (engine()->voe()->codec()->SetRecPayloadType(
-                ch.second->channel(), voe_codec) == -1) {
-          LOG_RTCERR2(SetRecPayloadType, ch.second->channel(),
-                      ToString(voe_codec));
-          return false;
-        }
-      }
-    } else {
-      LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
-      return false;
-    }
-  }
-  return true;
-}
 }  // namespace cricket
 
 #endif  // HAVE_WEBRTC_VOICE
diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h
index 9c7f7bb..57c9439 100644
--- a/talk/media/webrtc/webrtcvoiceengine.h
+++ b/talk/media/webrtc/webrtcvoiceengine.h
@@ -57,8 +57,10 @@
 // It uses the WebRtc VoiceEngine library for audio handling.
 class WebRtcVoiceEngine final : public webrtc::TraceCallback  {
   friend class WebRtcVoiceMediaChannel;
-
  public:
+  // Exposed for the WVoE/MC unit test.
+  static bool ToCodecInst(const AudioCodec& in, webrtc::CodecInst* out);
+
   WebRtcVoiceEngine();
   // Dependency injection for testing.
   explicit WebRtcVoiceEngine(VoEWrapper* voe_wrapper);
@@ -78,9 +80,6 @@
   int GetInputLevel();
 
   const std::vector<AudioCodec>& codecs();
-  bool FindCodec(const AudioCodec& codec);
-  bool FindWebRtcCodec(const AudioCodec& codec, webrtc::CodecInst* gcodec);
-
   const std::vector<RtpHeaderExtension>& rtp_header_extensions() const;
 
   // For tracking WebRtc channels. Needed because we have to pause them
@@ -114,8 +113,6 @@
 
  private:
   void Construct();
-  void ConstructCodecs();
-  bool GetVoeCodec(int index, webrtc::CodecInst* codec);
   bool InitInternal();
   // Every option that is "set" will be applied. Every option not "set" will be
   // ignored. This allows us to selectively turn on and off different options
@@ -258,7 +255,6 @@
   }
   bool SetSendCodecs(int channel, const std::vector<AudioCodec>& codecs);
   bool SetSendBitrateInternal(int bps);
-  bool SetRecvCodecsInternal(const std::vector<AudioCodec>& new_codecs);
 
   rtc::ThreadChecker worker_thread_checker_;
 
diff --git a/talk/media/webrtc/webrtcvoiceengine_unittest.cc b/talk/media/webrtc/webrtcvoiceengine_unittest.cc
index b52f6fc..888de7d 100644
--- a/talk/media/webrtc/webrtcvoiceengine_unittest.cc
+++ b/talk/media/webrtc/webrtcvoiceengine_unittest.cc
@@ -54,10 +54,6 @@
 const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
 const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0,
                                                1, 0);
-const cricket::AudioCodec* const kAudioCodecs[] = {
-    &kPcmuCodec, &kIsacCodec, &kOpusCodec, &kG722CodecVoE, &kRedCodec,
-    &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
-};
 const uint32_t kSsrc1 = 0x99;
 const uint32_t kSsrc2 = 0x98;
 const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
@@ -81,7 +77,6 @@
  public:
   WebRtcVoiceEngineTestFake()
       : call_(webrtc::Call::Config()),
-        voe_(kAudioCodecs, arraysize(kAudioCodecs)),
         engine_(new FakeVoEWrapper(&voe_)),
         channel_(nullptr) {
     send_parameters_.codecs.push_back(kPcmuCodec);
@@ -451,32 +446,33 @@
   cricket::AudioCodec codec;
   webrtc::CodecInst codec_inst;
   // Find PCMU with explicit clockrate and bitrate.
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
   // Find ISAC with explicit clockrate and 0 bitrate.
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
   // Find telephone-event with explicit clockrate and 0 bitrate.
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec,
+                                                      &codec_inst));
   // Find ISAC with a different payload id.
   codec = kIsacCodec;
   codec.id = 127;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
   EXPECT_EQ(codec.id, codec_inst.pltype);
   // Find PCMU with a 0 clockrate.
   codec = kPcmuCodec;
   codec.clockrate = 0;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
   EXPECT_EQ(codec.id, codec_inst.pltype);
   EXPECT_EQ(8000, codec_inst.plfreq);
   // Find PCMU with a 0 bitrate.
   codec = kPcmuCodec;
   codec.bitrate = 0;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
   EXPECT_EQ(codec.id, codec_inst.pltype);
   EXPECT_EQ(64000, codec_inst.rate);
   // Find ISAC with an explicit bitrate.
   codec = kIsacCodec;
   codec.bitrate = 32000;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
   EXPECT_EQ(codec.id, codec_inst.pltype);
   EXPECT_EQ(32000, codec_inst.rate);
 }
@@ -539,7 +535,7 @@
       cricket::StreamParams::CreateLegacy(kSsrc1)));
   int channel_num = voe_.GetLastChannel();
   webrtc::CodecInst opus;
-  engine_.FindWebRtcCodec(kOpusCodec, &opus);
+  cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
   // Even without stereo parameters, recv codecs still specify channels = 2.
   EXPECT_EQ(2, opus.channels);
   EXPECT_EQ(111, opus.pltype);
@@ -562,7 +558,7 @@
       cricket::StreamParams::CreateLegacy(kSsrc1)));
   int channel_num2 = voe_.GetLastChannel();
   webrtc::CodecInst opus;
-  engine_.FindWebRtcCodec(kOpusCodec, &opus);
+  cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
   // Even when stereo is off, recv codecs still specify channels = 2.
   EXPECT_EQ(2, opus.channels);
   EXPECT_EQ(111, opus.pltype);
@@ -585,7 +581,7 @@
       cricket::StreamParams::CreateLegacy(kSsrc1)));
   int channel_num2 = voe_.GetLastChannel();
   webrtc::CodecInst opus;
-  engine_.FindWebRtcCodec(kOpusCodec, &opus);
+  cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
   EXPECT_EQ(2, opus.channels);
   EXPECT_EQ(111, opus.pltype);
   EXPECT_STREQ("opus", opus.plname);
@@ -670,7 +666,7 @@
   int channel_num = voe_.GetLastChannel();
   EXPECT_TRUE(voe_.GetPlayout(channel_num));
   webrtc::CodecInst gcodec;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
   EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
 }
 
@@ -3246,54 +3242,60 @@
 
 // Tests that the library is configured with the codecs we want.
 TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
-  cricket::WebRtcVoiceEngine engine;
   // Check codecs by name.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0), nullptr));
   // Check that name matching is case-insensitive.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "G722", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "G722", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "red", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "CN", 32000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "CN", 16000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "CN", 8000, 0, 1, 0), nullptr));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0), nullptr));
   // Check codecs with an id by id.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(0, "", 8000, 0, 1, 0)));   // PCMU
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(8, "", 8000, 0, 1, 0)));   // PCMA
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(9, "", 8000, 0, 1, 0)));  // G722
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(13, "", 8000, 0, 1, 0)));  // CN
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(0, "", 8000, 0, 1, 0), nullptr));   // PCMU
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(8, "", 8000, 0, 1, 0), nullptr));   // PCMA
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(9, "", 8000, 0, 1, 0), nullptr));  // G722
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(13, "", 8000, 0, 1, 0), nullptr));  // CN
   // Check sample/bitrate matching.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
+  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0), nullptr));
   // Check that bad codecs fail.
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
+  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0), nullptr));
+  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(88, "", 0, 0, 1, 0), nullptr));
+  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(0, "", 0, 0, 2, 0), nullptr));
+  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(0, "", 5000, 0, 1, 0), nullptr));
+  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
+      cricket::AudioCodec(0, "", 0, 5000, 1, 0), nullptr));
+
   // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
+  cricket::WebRtcVoiceEngine engine;
   for (std::vector<cricket::AudioCodec>::const_iterator it =
       engine.codecs().begin(); it != engine.codecs().end(); ++it) {
     if (it->name == "CN" && it->clockrate == 16000) {
@@ -3320,7 +3322,6 @@
       EXPECT_EQ("1", it->params.find("useinbandfec")->second);
     }
   }
-
   engine.Terminate();
 }