| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 | 125 |
| 126 bool CodecSupported(const CodecInst& codec) { | 126 bool CodecSupported(const CodecInst& codec) { |
| 127 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || | 127 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || |
| 128 IsIlbc(codec) || IsG722(codec) || IsIsac(codec); | 128 IsIlbc(codec) || IsG722(codec) || IsIsac(codec); |
| 129 } | 129 } |
| 130 | 130 |
| 131 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; | 131 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; |
| 132 } // namespace | 132 } // namespace |
| 133 | 133 |
| 134 CodecManager::CodecManager() | 134 CodecManager::CodecManager() |
| 135 : cng_nb_pltype_(255), | 135 : dtx_enabled_(false), |
| 136 cng_wb_pltype_(255), | |
| 137 cng_swb_pltype_(255), | |
| 138 cng_fb_pltype_(255), | |
| 139 red_nb_pltype_(255), | |
| 140 dtx_enabled_(false), | |
| 141 vad_mode_(VADNormal), | 136 vad_mode_(VADNormal), |
| 142 send_codec_inst_(kEmptyCodecInst), | 137 send_codec_inst_(kEmptyCodecInst), |
| 143 red_enabled_(false), | 138 red_enabled_(false), |
| 144 codec_fec_enabled_(false), | 139 codec_fec_enabled_(false), |
| 145 encoder_is_opus_(false) { | 140 encoder_is_opus_(false) { |
| 146 // Register the default payload type for RED and for CNG at sampling rates of | 141 // Register the default payload types for RED and CNG. |
| 147 // 8, 16, 32 and 48 kHz. | |
| 148 for (const CodecInst& ci : RentACodec::Database()) { | 142 for (const CodecInst& ci : RentACodec::Database()) { |
| 149 if (IsCodecRED(ci) && ci.plfreq == 8000) { | 143 RentACodec::RegisterCngPayloadType(&cng_payload_types_, ci); |
| 150 red_nb_pltype_ = static_cast<uint8_t>(ci.pltype); | 144 RentACodec::RegisterRedPayloadType(&red_payload_types_, ci); |
| 151 } else if (IsCodecCN(ci)) { | |
| 152 if (ci.plfreq == 8000) { | |
| 153 cng_nb_pltype_ = static_cast<uint8_t>(ci.pltype); | |
| 154 } else if (ci.plfreq == 16000) { | |
| 155 cng_wb_pltype_ = static_cast<uint8_t>(ci.pltype); | |
| 156 } else if (ci.plfreq == 32000) { | |
| 157 cng_swb_pltype_ = static_cast<uint8_t>(ci.pltype); | |
| 158 } else if (ci.plfreq == 48000) { | |
| 159 cng_fb_pltype_ = static_cast<uint8_t>(ci.pltype); | |
| 160 } | |
| 161 } | |
| 162 } | 145 } |
| 163 thread_checker_.DetachFromThread(); | 146 thread_checker_.DetachFromThread(); |
| 164 } | 147 } |
| 165 | 148 |
| 166 CodecManager::~CodecManager() = default; | 149 CodecManager::~CodecManager() = default; |
| 167 | 150 |
| 168 int CodecManager::RegisterEncoder(const CodecInst& send_codec) { | 151 int CodecManager::RegisterEncoder(const CodecInst& send_codec) { |
| 169 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 152 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 170 int codec_id = IsValidSendCodec(send_codec, true); | 153 int codec_id = IsValidSendCodec(send_codec, true); |
| 171 | 154 |
| 172 // Check for reported errors from function IsValidSendCodec(). | 155 // Check for reported errors from function IsValidSendCodec(). |
| 173 if (codec_id < 0) { | 156 if (codec_id < 0) { |
| 174 return -1; | 157 return -1; |
| 175 } | 158 } |
| 176 | 159 |
| 177 int dummy_id = 0; | 160 int dummy_id = 0; |
| 178 // RED can be registered with other payload type. If not registered a default | 161 switch (RentACodec::RegisterRedPayloadType(&red_payload_types_, send_codec)) { |
| 179 // payload type is used. | 162 case RentACodec::RegistrationResult::kOk: |
| 180 if (IsCodecRED(send_codec)) { | 163 return 0; |
| 181 // TODO(tlegrand): Remove this check. Already taken care of in | 164 case RentACodec::RegistrationResult::kBadFreq: |
| 182 // ACMCodecDB::CodecNumber(). | |
| 183 // Check if the payload-type is valid | |
| 184 if (!RentACodec::IsPayloadTypeValid(send_codec.pltype)) { | |
| 185 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | 165 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, |
| 186 "Invalid payload-type %d for %s.", send_codec.pltype, | 166 "RegisterSendCodec() failed, invalid frequency for RED" |
| 187 send_codec.plname); | 167 " registration"); |
| 188 return -1; | 168 return -1; |
| 189 } | 169 case RentACodec::RegistrationResult::kSkip: |
| 190 // Set RED payload type. | 170 break; |
| 191 if (send_codec.plfreq == 8000) { | 171 } |
| 192 red_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype); | 172 switch (RentACodec::RegisterCngPayloadType(&cng_payload_types_, send_codec)) { |
| 193 } else { | 173 case RentACodec::RegistrationResult::kOk: |
| 174 return 0; |
| 175 case RentACodec::RegistrationResult::kBadFreq: |
| 194 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | 176 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, |
| 195 "RegisterSendCodec() failed, invalid frequency for RED " | 177 "RegisterSendCodec() failed, invalid frequency for CNG" |
| 196 "registration"); | 178 " registration"); |
| 197 return -1; | 179 return -1; |
| 198 } | 180 case RentACodec::RegistrationResult::kSkip: |
| 199 return 0; | 181 break; |
| 200 } | |
| 201 | |
| 202 // CNG can be registered with other payload type. If not registered the | |
| 203 // default payload types from codec database will be used. | |
| 204 if (IsCodecCN(send_codec)) { | |
| 205 // CNG is registered. | |
| 206 switch (send_codec.plfreq) { | |
| 207 case 8000: { | |
| 208 cng_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype); | |
| 209 return 0; | |
| 210 } | |
| 211 case 16000: { | |
| 212 cng_wb_pltype_ = static_cast<uint8_t>(send_codec.pltype); | |
| 213 return 0; | |
| 214 } | |
| 215 case 32000: { | |
| 216 cng_swb_pltype_ = static_cast<uint8_t>(send_codec.pltype); | |
| 217 return 0; | |
| 218 } | |
| 219 case 48000: { | |
| 220 cng_fb_pltype_ = static_cast<uint8_t>(send_codec.pltype); | |
| 221 return 0; | |
| 222 } | |
| 223 default: { | |
| 224 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, | |
| 225 "RegisterSendCodec() failed, invalid frequency for CNG " | |
| 226 "registration"); | |
| 227 return -1; | |
| 228 } | |
| 229 } | |
| 230 } | 182 } |
| 231 | 183 |
| 232 // Set Stereo, and make sure VAD and DTX is turned off. | 184 // Set Stereo, and make sure VAD and DTX is turned off. |
| 233 if (send_codec.channels != 1) { | 185 if (send_codec.channels != 1) { |
| 234 if (dtx_enabled_) { | 186 if (dtx_enabled_) { |
| 235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, | 187 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, |
| 236 "VAD/DTX is turned off, not supported when sending stereo."); | 188 "VAD/DTX is turned off, not supported when sending stereo."); |
| 237 } | 189 } |
| 238 dtx_enabled_ = false; | 190 dtx_enabled_ = false; |
| 239 } | 191 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 RTC_CHECK(CurrentEncoder()); | 363 RTC_CHECK(CurrentEncoder()); |
| 412 codec_fec_enabled_ = | 364 codec_fec_enabled_ = |
| 413 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; | 365 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; |
| 414 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; | 366 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; |
| 415 } | 367 } |
| 416 | 368 |
| 417 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { | 369 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { |
| 418 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; | 370 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; |
| 419 } | 371 } |
| 420 | 372 |
| 421 int CodecManager::CngPayloadType(int sample_rate_hz) const { | 373 int CodecManager::CngPayloadType(int rtp_timestamp_rate_hz) const { |
| 422 switch (sample_rate_hz) { | 374 RTC_CHECK(rtp_timestamp_rate_hz == 8000 || rtp_timestamp_rate_hz == 16000 || |
| 423 case 8000: | 375 rtp_timestamp_rate_hz == 32000 || rtp_timestamp_rate_hz == 48000) |
| 424 return cng_nb_pltype_; | 376 << rtp_timestamp_rate_hz << " Hz is not supported"; |
| 425 case 16000: | 377 auto it = cng_payload_types_.find(rtp_timestamp_rate_hz); |
| 426 return cng_wb_pltype_; | 378 return it == cng_payload_types_.end() ? -1 : it->second; |
| 427 case 32000: | |
| 428 return cng_swb_pltype_; | |
| 429 case 48000: | |
| 430 return cng_fb_pltype_; | |
| 431 default: | |
| 432 FATAL() << sample_rate_hz << " Hz is not supported"; | |
| 433 return -1; | |
| 434 } | |
| 435 } | 379 } |
| 436 | 380 |
| 437 int CodecManager::RedPayloadType(int sample_rate_hz) const { | 381 int CodecManager::RedPayloadType(int rtp_timestamp_rate_hz) const { |
| 438 switch (sample_rate_hz) { | 382 RTC_CHECK(rtp_timestamp_rate_hz == 8000 || rtp_timestamp_rate_hz == 16000 || |
| 439 case 8000: | 383 rtp_timestamp_rate_hz == 32000 || rtp_timestamp_rate_hz == 48000) |
| 440 return red_nb_pltype_; | 384 << rtp_timestamp_rate_hz << " Hz is not supported"; |
| 441 case 16000: | 385 auto it = red_payload_types_.find(rtp_timestamp_rate_hz); |
| 442 case 32000: | 386 return it == red_payload_types_.end() ? -1 : it->second; |
| 443 case 48000: | |
| 444 return -1; | |
| 445 default: | |
| 446 FATAL() << sample_rate_hz << " Hz is not supported"; | |
| 447 return -1; | |
| 448 } | |
| 449 } | 387 } |
| 450 | 388 |
| 451 void CodecManager::RentEncoderStack(AudioEncoder* speech_encoder, | 389 void CodecManager::RentEncoderStack(AudioEncoder* speech_encoder, |
| 452 int sample_rate_hz) { | 390 int sample_rate_hz) { |
| 453 auto cng_config = | 391 auto cng_config = |
| 454 dtx_enabled_ ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ | 392 dtx_enabled_ ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ |
| 455 CngPayloadType(sample_rate_hz), vad_mode_}) | 393 CngPayloadType(sample_rate_hz), vad_mode_}) |
| 456 : rtc::Optional<RentACodec::CngConfig>(); | 394 : rtc::Optional<RentACodec::CngConfig>(); |
| 457 auto red_pt = red_enabled_ | 395 auto red_pt = red_enabled_ |
| 458 ? rtc::Optional<int>(RedPayloadType(sample_rate_hz)) | 396 ? rtc::Optional<int>(RedPayloadType(sample_rate_hz)) |
| 459 : rtc::Optional<int>(); | 397 : rtc::Optional<int>(); |
| 460 rent_a_codec_.RentEncoderStack(speech_encoder, cng_config, red_pt); | 398 rent_a_codec_.RentEncoderStack(speech_encoder, cng_config, red_pt); |
| 461 } | 399 } |
| 462 | 400 |
| 463 } // namespace acm2 | 401 } // namespace acm2 |
| 464 } // namespace webrtc | 402 } // namespace webrtc |
| OLD | NEW |