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 |