diff options
Diffstat (limited to 'webrtc/modules/audio_coding/main/acm2/codec_manager.cc')
-rw-r--r-- | webrtc/modules/audio_coding/main/acm2/codec_manager.cc | 465 |
1 files changed, 0 insertions, 465 deletions
diff --git a/webrtc/modules/audio_coding/main/acm2/codec_manager.cc b/webrtc/modules/audio_coding/main/acm2/codec_manager.cc deleted file mode 100644 index f9b77e8985..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/codec_manager.cc +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2015 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/modules/audio_coding/main/acm2/codec_manager.h" - -#include "webrtc/base/checks.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { -namespace acm2 { - -namespace { -bool IsCodecRED(const CodecInst& codec) { - return (STR_CASE_CMP(codec.plname, "RED") == 0); -} - -bool IsCodecCN(const CodecInst& codec) { - return (STR_CASE_CMP(codec.plname, "CN") == 0); -} - -// Check if the given codec is a valid to be registered as send codec. -int IsValidSendCodec(const CodecInst& send_codec, bool is_primary_encoder) { - int dummy_id = 0; - if ((send_codec.channels != 1) && (send_codec.channels != 2)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Wrong number of channels (%d, only mono and stereo are " - "supported) for %s encoder", - send_codec.channels, - is_primary_encoder ? "primary" : "secondary"); - return -1; - } - - int codec_id = ACMCodecDB::CodecNumber(send_codec); - if (codec_id < 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Invalid codec setting for the send codec."); - return -1; - } - - // TODO(tlegrand): Remove this check. Already taken care of in - // ACMCodecDB::CodecNumber(). - // Check if the payload-type is valid - if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Invalid payload-type %d for %s.", send_codec.pltype, - send_codec.plname); - return -1; - } - - // Telephone-event cannot be a send codec. - if (!STR_CASE_CMP(send_codec.plname, "telephone-event")) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "telephone-event cannot be a send codec"); - return -1; - } - - if (ACMCodecDB::codec_settings_[codec_id].channel_support < - send_codec.channels) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "%d number of channels not supportedn for %s.", - send_codec.channels, send_codec.plname); - return -1; - } - - if (!is_primary_encoder) { - // If registering the secondary encoder, then RED and CN are not valid - // choices as encoder. - if (IsCodecRED(send_codec)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "RED cannot be secondary codec"); - return -1; - } - - if (IsCodecCN(send_codec)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "DTX cannot be secondary codec"); - return -1; - } - } - return codec_id; -} - -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 - !STR_CASE_CMP(codec.plname, "opus") || -#endif - 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() - : cng_nb_pltype_(255), - cng_wb_pltype_(255), - cng_swb_pltype_(255), - cng_fb_pltype_(255), - red_nb_pltype_(255), - stereo_send_(false), - dtx_enabled_(false), - vad_mode_(VADNormal), - send_codec_inst_(kEmptyCodecInst), - red_enabled_(false), - codec_fec_enabled_(false), - encoder_is_opus_(false) { - // Register the default payload type for RED and for CNG at sampling rates of - // 8, 16, 32 and 48 kHz. - for (const CodecInst& ci : RentACodec::Database()) { - if (IsCodecRED(ci) && ci.plfreq == 8000) { - red_nb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (IsCodecCN(ci)) { - if (ci.plfreq == 8000) { - cng_nb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (ci.plfreq == 16000) { - cng_wb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (ci.plfreq == 32000) { - cng_swb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (ci.plfreq == 48000) { - cng_fb_pltype_ = static_cast<uint8_t>(ci.pltype); - } - } - } - thread_checker_.DetachFromThread(); -} - -CodecManager::~CodecManager() = default; - -int CodecManager::RegisterEncoder(const CodecInst& send_codec) { - RTC_DCHECK(thread_checker_.CalledOnValidThread()); - int codec_id = IsValidSendCodec(send_codec, true); - - // Check for reported errors from function IsValidSendCodec(). - if (codec_id < 0) { - return -1; - } - - int dummy_id = 0; - // RED can be registered with other payload type. If not registered a default - // payload type is used. - if (IsCodecRED(send_codec)) { - // TODO(tlegrand): Remove this check. Already taken care of in - // ACMCodecDB::CodecNumber(). - // Check if the payload-type is valid - if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Invalid payload-type %d for %s.", send_codec.pltype, - send_codec.plname); - return -1; - } - // Set RED payload type. - if (send_codec.plfreq == 8000) { - red_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - } else { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "RegisterSendCodec() failed, invalid frequency for RED " - "registration"); - return -1; - } - return 0; - } - - // CNG can be registered with other payload type. If not registered the - // default payload types from codec database will be used. - if (IsCodecCN(send_codec)) { - // CNG is registered. - switch (send_codec.plfreq) { - case 8000: { - cng_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - case 16000: { - cng_wb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - case 32000: { - cng_swb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - case 48000: { - cng_fb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - default: { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "RegisterSendCodec() failed, invalid frequency for CNG " - "registration"); - return -1; - } - } - } - - // Set Stereo, and make sure VAD and DTX is turned off. - if (send_codec.channels == 2) { - stereo_send_ = true; - if (dtx_enabled_) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, - "VAD/DTX is turned off, not supported when sending stereo."); - } - dtx_enabled_ = false; - } else { - stereo_send_ = false; - } - - // Check if the codec is already registered as send codec. - bool new_codec = true; - if (codec_owner_.Encoder()) { - int new_codec_id = ACMCodecDB::CodecNumber(send_codec_inst_); - RTC_DCHECK_GE(new_codec_id, 0); - new_codec = new_codec_id != codec_id; - } - - if (RedPayloadType(send_codec.plfreq) == -1) { - red_enabled_ = false; - } - - encoder_is_opus_ = IsOpus(send_codec); - - if (new_codec) { - // This is a new codec. Register it and return. - RTC_DCHECK(CodecSupported(send_codec)); - if (IsOpus(send_codec)) { - // VAD/DTX not supported. - dtx_enabled_ = false; - } - if (!codec_owner_.SetEncoders( - send_codec, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, - vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1)) - return -1; - RTC_DCHECK(codec_owner_.Encoder()); - - codec_fec_enabled_ = codec_fec_enabled_ && - codec_owner_.Encoder()->SetFec(codec_fec_enabled_); - - send_codec_inst_ = send_codec; - return 0; - } - - // This is an existing codec; re-create it if any parameters have changed. - if (send_codec_inst_.plfreq != send_codec.plfreq || - send_codec_inst_.pacsize != send_codec.pacsize || - send_codec_inst_.channels != send_codec.channels) { - if (!codec_owner_.SetEncoders( - send_codec, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, - vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1)) - return -1; - RTC_DCHECK(codec_owner_.Encoder()); - } - send_codec_inst_.plfreq = send_codec.plfreq; - send_codec_inst_.pacsize = send_codec.pacsize; - send_codec_inst_.channels = send_codec.channels; - send_codec_inst_.pltype = send_codec.pltype; - - // Check if a change in Rate is required. - if (send_codec.rate != send_codec_inst_.rate) { - codec_owner_.Encoder()->SetTargetBitrate(send_codec.rate); - send_codec_inst_.rate = send_codec.rate; - } - - codec_fec_enabled_ = - codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); - - return 0; -} - -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( - static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * - send_codec_inst_.plfreq), - 100); - send_codec_inst_.pltype = -1; // Not valid. - send_codec_inst_.rate = -1; // Not valid. - static const char kName[] = "external"; - memcpy(send_codec_inst_.plname, kName, sizeof(kName)); - - if (stereo_send_) - dtx_enabled_ = false; - codec_fec_enabled_ = - codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); - int cng_pt = dtx_enabled_ - ? CngPayloadType(external_speech_encoder->SampleRateHz()) - : -1; - int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; - codec_owner_.SetEncoders(external_speech_encoder, cng_pt, vad_mode_, red_pt); -} - -int CodecManager::GetCodecInst(CodecInst* current_codec) const { - int dummy_id = 0; - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, - "SendCodec()"); - - if (!codec_owner_.Encoder()) { - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, - "SendCodec Failed, no codec is registered"); - return -1; - } - *current_codec = send_codec_inst_; - return 0; -} - -bool CodecManager::SetCopyRed(bool enable) { - if (enable && codec_fec_enabled_) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, - "Codec internal FEC and RED cannot be co-enabled."); - return false; - } - if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, - "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); - return false; - } - if (red_enabled_ != enable) { - red_enabled_ = enable; - if (codec_owner_.Encoder()) { - int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; - int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; - codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); - } - } - return true; -} - -int CodecManager::SetVAD(bool enable, ACMVADMode mode) { - // Sanity check of the mode. - RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || - mode == VADVeryAggr); - - // Check that the send codec is mono. We don't support VAD/DTX for stereo - // sending. - if (enable && stereo_send_) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, - "VAD/DTX not supported for stereo sending"); - dtx_enabled_ = false; - return -1; - } - - // If a send codec is registered, set VAD/DTX for the codec. - if (IsOpus(send_codec_inst_)) { - // VAD/DTX not supported. - dtx_enabled_ = false; - return 0; - } - - if (dtx_enabled_ != enable || vad_mode_ != mode) { - dtx_enabled_ = enable; - vad_mode_ = mode; - if (codec_owner_.Encoder()) { - int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; - int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; - codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); - } - } - return 0; -} - -void CodecManager::VAD(bool* dtx_enabled, - bool* vad_enabled, - ACMVADMode* mode) const { - *dtx_enabled = dtx_enabled_; - *vad_enabled = dtx_enabled_; - *mode = vad_mode_; -} - -int CodecManager::SetCodecFEC(bool enable_codec_fec) { - if (enable_codec_fec == true && red_enabled_ == true) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, - "Codec internal FEC and RED cannot be co-enabled."); - return -1; - } - - RTC_CHECK(codec_owner_.Encoder()); - codec_fec_enabled_ = - codec_owner_.Encoder()->SetFec(enable_codec_fec) && enable_codec_fec; - return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; -} - -AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { - return IsIsac(codec) ? codec_owner_.GetIsacDecoder() : nullptr; -} - -int CodecManager::CngPayloadType(int sample_rate_hz) const { - switch (sample_rate_hz) { - case 8000: - return cng_nb_pltype_; - case 16000: - return cng_wb_pltype_; - case 32000: - return cng_swb_pltype_; - case 48000: - return cng_fb_pltype_; - default: - FATAL() << sample_rate_hz << " Hz is not supported"; - return -1; - } -} - -int CodecManager::RedPayloadType(int sample_rate_hz) const { - switch (sample_rate_hz) { - case 8000: - return red_nb_pltype_; - case 16000: - case 32000: - case 48000: - return -1; - default: - FATAL() << sample_rate_hz << " Hz is not supported"; - return -1; - } -} - -} // namespace acm2 -} // namespace webrtc |