Move Rent-A-Codec out of CodecManager

So that the two of them sit next to each other at the top level of
AudioCodingModuleImpl. CodecManager now manages the specifications for
Rent-A-Codec, rather than managing encoders directly.

BUG=webrtc:5028

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

Cr-Commit-Position: refs/heads/master@{#11048}
This commit is contained in:
kwiberg
2015-12-16 04:19:08 -08:00
committed by Commit bot
parent a29386c26d
commit a6db4958c9
6 changed files with 167 additions and 221 deletions

View File

@ -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;
codec_stack_params_.use_cng = enable;
codec_stack_params_.vad_mode = mode;
return true;
}
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;
}
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