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:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user