| Index: webrtc/modules/audio_coding/acm2/codec_manager.cc | 
| diff --git a/webrtc/modules/audio_coding/acm2/codec_manager.cc b/webrtc/modules/audio_coding/acm2/codec_manager.cc | 
| index 19a79c25b1658485152987d0ce15cfc01042aa8c..bc507dd8c7debf614b0263eedaa09c256e081bde 100644 | 
| --- a/webrtc/modules/audio_coding/acm2/codec_manager.cc | 
| +++ b/webrtc/modules/audio_coding/acm2/codec_manager.cc | 
| @@ -55,14 +55,6 @@ int IsValidSendCodec(const CodecInst& send_codec) { | 
| return RentACodec::CodecIndexFromId(*maybe_codec_id).value_or(-1); | 
| } | 
|  | 
| -bool IsIsac(const CodecInst& codec) { | 
| -  return | 
| -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) | 
| -      !STR_CASE_CMP(codec.plname, "isac") || | 
| -#endif | 
| -      false; | 
| -} | 
| - | 
| bool IsOpus(const CodecInst& codec) { | 
| return | 
| #ifdef WEBRTC_CODEC_OPUS | 
| @@ -71,138 +63,73 @@ bool IsOpus(const CodecInst& codec) { | 
| false; | 
| } | 
|  | 
| -bool IsPcmU(const CodecInst& codec) { | 
| -  return !STR_CASE_CMP(codec.plname, "pcmu"); | 
| -} | 
| - | 
| -bool IsPcmA(const CodecInst& codec) { | 
| -  return !STR_CASE_CMP(codec.plname, "pcma"); | 
| -} | 
| - | 
| -bool IsPcm16B(const CodecInst& codec) { | 
| -  return !STR_CASE_CMP(codec.plname, "l16"); | 
| -} | 
| - | 
| -bool IsIlbc(const CodecInst& codec) { | 
| -  return | 
| -#ifdef WEBRTC_CODEC_ILBC | 
| -      !STR_CASE_CMP(codec.plname, "ilbc") || | 
| -#endif | 
| -      false; | 
| -} | 
| - | 
| -bool IsG722(const CodecInst& codec) { | 
| -  return | 
| -#ifdef WEBRTC_CODEC_G722 | 
| -      !STR_CASE_CMP(codec.plname, "g722") || | 
| -#endif | 
| -      false; | 
| -} | 
| - | 
| -bool CodecSupported(const CodecInst& codec) { | 
| -  return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || | 
| -         IsIlbc(codec) || IsG722(codec) || IsIsac(codec); | 
| -} | 
| - | 
| -const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; | 
| }  // namespace | 
|  | 
| -CodecManager::CodecManager() | 
| -    : send_codec_inst_(kEmptyCodecInst), encoder_is_opus_(false) { | 
| +CodecManager::CodecManager() { | 
| thread_checker_.DetachFromThread(); | 
| } | 
|  | 
| CodecManager::~CodecManager() = default; | 
|  | 
| -int CodecManager::RegisterEncoder(const CodecInst& send_codec) { | 
| +bool CodecManager::RegisterEncoder(const CodecInst& send_codec) { | 
| RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 
| int codec_id = IsValidSendCodec(send_codec); | 
|  | 
| // Check for reported errors from function IsValidSendCodec(). | 
| if (codec_id < 0) { | 
| -    return -1; | 
| +    return false; | 
| } | 
|  | 
| int dummy_id = 0; | 
| switch (RentACodec::RegisterRedPayloadType( | 
| &codec_stack_params_.red_payload_types, send_codec)) { | 
| case RentACodec::RegistrationResult::kOk: | 
| -      return 0; | 
| +      return true; | 
| case RentACodec::RegistrationResult::kBadFreq: | 
| WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | 
| "RegisterSendCodec() failed, invalid frequency for RED" | 
| " registration"); | 
| -      return -1; | 
| +      return false; | 
| case RentACodec::RegistrationResult::kSkip: | 
| break; | 
| } | 
| switch (RentACodec::RegisterCngPayloadType( | 
| &codec_stack_params_.cng_payload_types, send_codec)) { | 
| case RentACodec::RegistrationResult::kOk: | 
| -      return 0; | 
| +      return true; | 
| case RentACodec::RegistrationResult::kBadFreq: | 
| WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | 
| "RegisterSendCodec() failed, invalid frequency for CNG" | 
| " registration"); | 
| -      return -1; | 
| +      return false; | 
| case RentACodec::RegistrationResult::kSkip: | 
| break; | 
| } | 
|  | 
| -  encoder_is_opus_ = IsOpus(send_codec); | 
| -  if (encoder_is_opus_) { | 
| +  if (IsOpus(send_codec)) { | 
| // VAD/DTX not supported. | 
| codec_stack_params_.use_cng = false; | 
| } | 
|  | 
| -  // Recreate the encoder if anything except the send bitrate has changed. | 
| -  if (!CurrentEncoder() || send_codec_inst_.pltype != send_codec.pltype || | 
| -      STR_CASE_CMP(send_codec_inst_.plname, send_codec.plname) != 0 || | 
| -      send_codec_inst_.plfreq != send_codec.plfreq || | 
| -      send_codec_inst_.pacsize != send_codec.pacsize || | 
| -      send_codec_inst_.channels != send_codec.channels) { | 
| -    RTC_DCHECK(CodecSupported(send_codec)); | 
| -    AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 
| -    if (!enc) | 
| -      return -1; | 
| -    codec_stack_params_.speech_encoder = enc; | 
| -    rent_a_codec_.RentEncoderStack(&codec_stack_params_); | 
| -    RTC_DCHECK(CurrentEncoder()); | 
| -  } | 
| - | 
| -  send_codec_inst_ = send_codec; | 
| -  CurrentEncoder()->SetTargetBitrate(send_codec_inst_.rate); | 
| -  return 0; | 
| +  send_codec_inst_ = rtc::Optional<CodecInst>(send_codec); | 
| +  codec_stack_params_.speech_encoder = nullptr;  // Caller must recreate it. | 
| +  return true; | 
| } | 
|  | 
| -void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { | 
| -  // Make up a CodecInst. | 
| -  send_codec_inst_.channels = external_speech_encoder->NumChannels(); | 
| -  send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); | 
| -  send_codec_inst_.pacsize = rtc::CheckedDivExact( | 
| +CodecInst CodecManager::ForgeCodecInst( | 
| +    const AudioEncoder* external_speech_encoder) { | 
| +  CodecInst ci; | 
| +  ci.channels = external_speech_encoder->NumChannels(); | 
| +  ci.plfreq = external_speech_encoder->SampleRateHz(); | 
| +  ci.pacsize = rtc::CheckedDivExact( | 
| static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * | 
| -                       send_codec_inst_.plfreq), | 
| +                       ci.plfreq), | 
| 100); | 
| -  send_codec_inst_.pltype = -1;  // Not valid. | 
| -  send_codec_inst_.rate = -1;    // Not valid. | 
| +  ci.pltype = -1;  // Not valid. | 
| +  ci.rate = -1;    // Not valid. | 
| static const char kName[] = "external"; | 
| -  memcpy(send_codec_inst_.plname, kName, sizeof(kName)); | 
| - | 
| -  codec_stack_params_.speech_encoder = external_speech_encoder; | 
| -  rent_a_codec_.RentEncoderStack(&codec_stack_params_); | 
| -} | 
| - | 
| -rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { | 
| -  int dummy_id = 0; | 
| -  WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 
| -               "SendCodec()"); | 
| - | 
| -  if (!CurrentEncoder()) { | 
| -    WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 
| -                 "SendCodec Failed, no codec is registered"); | 
| -    return rtc::Optional<CodecInst>(); | 
| -  } | 
| -  return rtc::Optional<CodecInst>(send_codec_inst_); | 
| +  memcpy(ci.plname, kName, sizeof(kName)); | 
| +  return ci; | 
| } | 
|  | 
| bool CodecManager::SetCopyRed(bool enable) { | 
| @@ -211,22 +138,18 @@ bool CodecManager::SetCopyRed(bool enable) { | 
| "Codec internal FEC and RED cannot be co-enabled."); | 
| return false; | 
| } | 
| -  if (enable && | 
| -      codec_stack_params_.red_payload_types.count(send_codec_inst_.plfreq) < | 
| +  if (enable && send_codec_inst_ && | 
| +      codec_stack_params_.red_payload_types.count(send_codec_inst_->plfreq) < | 
| 1) { | 
| WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 
| -                 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); | 
| +                 "Cannot enable RED at %i Hz.", send_codec_inst_->plfreq); | 
| return false; | 
| } | 
| -  if (codec_stack_params_.use_red != enable) { | 
| -    codec_stack_params_.use_red = enable; | 
| -    if (CurrentEncoder()) | 
| -      rent_a_codec_.RentEncoderStack(&codec_stack_params_); | 
| -  } | 
| +  codec_stack_params_.use_red = enable; | 
| return true; | 
| } | 
|  | 
| -int CodecManager::SetVAD(bool enable, ACMVADMode mode) { | 
| +bool CodecManager::SetVAD(bool enable, ACMVADMode mode) { | 
| // Sanity check of the mode. | 
| RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || | 
| mode == VADVeryAggr); | 
| @@ -240,49 +163,32 @@ int CodecManager::SetVAD(bool enable, ACMVADMode mode) { | 
| if (enable && stereo_send) { | 
| WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, | 
| "VAD/DTX not supported for stereo sending"); | 
| -    codec_stack_params_.use_cng = false; | 
| -    return -1; | 
| +    return false; | 
| } | 
|  | 
| -  // If a send codec is registered, set VAD/DTX for the codec. | 
| -  if (IsOpus(send_codec_inst_)) { | 
| -    // VAD/DTX not supported. | 
| -    codec_stack_params_.use_cng = false; | 
| -    return 0; | 
| +  if (CurrentEncoderIsOpus()) { | 
| +    // VAD/DTX not supported, but don't fail. | 
| +    enable = false; | 
| } | 
|  | 
| -  if (codec_stack_params_.use_cng != enable || | 
| -      codec_stack_params_.vad_mode != mode) { | 
| -    codec_stack_params_.use_cng = enable; | 
| -    codec_stack_params_.vad_mode = mode; | 
| -    if (codec_stack_params_.speech_encoder) | 
| -      rent_a_codec_.RentEncoderStack(&codec_stack_params_); | 
| -  } | 
| -  return 0; | 
| -} | 
| - | 
| -void CodecManager::VAD(bool* dtx_enabled, | 
| -                       bool* vad_enabled, | 
| -                       ACMVADMode* mode) const { | 
| -  *dtx_enabled = *vad_enabled = codec_stack_params_.use_cng; | 
| -  *mode = codec_stack_params_.vad_mode; | 
| +  codec_stack_params_.use_cng = enable; | 
| +  codec_stack_params_.vad_mode = mode; | 
| +  return true; | 
| } | 
|  | 
| -int CodecManager::SetCodecFEC(bool enable_codec_fec) { | 
| +bool CodecManager::SetCodecFEC(bool enable_codec_fec) { | 
| if (enable_codec_fec && codec_stack_params_.use_red) { | 
| WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 
| "Codec internal FEC and RED cannot be co-enabled."); | 
| -    return -1; | 
| +    return false; | 
| } | 
|  | 
| -  RTC_CHECK(CurrentEncoder()); | 
| -  codec_stack_params_.use_codec_fec = | 
| -      CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; | 
| -  return codec_stack_params_.use_codec_fec == enable_codec_fec ? 0 : -1; | 
| +  codec_stack_params_.use_codec_fec = enable_codec_fec; | 
| +  return true; | 
| } | 
|  | 
| -AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { | 
| -  return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; | 
| +bool CodecManager::CurrentEncoderIsOpus() const { | 
| +  return send_codec_inst_ ? IsOpus(*send_codec_inst_) : false; | 
| } | 
|  | 
| }  // namespace acm2 | 
|  |