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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 if (send_codec.channels != 1) { | 233 if (send_codec.channels != 1) { |
234 if (dtx_enabled_) { | 234 if (dtx_enabled_) { |
235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, | 235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, |
236 "VAD/DTX is turned off, not supported when sending stereo."); | 236 "VAD/DTX is turned off, not supported when sending stereo."); |
237 } | 237 } |
238 dtx_enabled_ = false; | 238 dtx_enabled_ = false; |
239 } | 239 } |
240 | 240 |
241 // Check if the codec is already registered as send codec. | 241 // Check if the codec is already registered as send codec. |
242 bool new_codec = true; | 242 bool new_codec = true; |
243 if (codec_owner_.Encoder()) { | 243 if (CurrentEncoder()) { |
244 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); | 244 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); |
245 RTC_DCHECK(new_codec_id); | 245 RTC_DCHECK(new_codec_id); |
246 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); | 246 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); |
247 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; | 247 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; |
248 } | 248 } |
249 | 249 |
250 if (RedPayloadType(send_codec.plfreq) == -1) { | 250 if (RedPayloadType(send_codec.plfreq) == -1) { |
251 red_enabled_ = false; | 251 red_enabled_ = false; |
252 } | 252 } |
253 | 253 |
254 encoder_is_opus_ = IsOpus(send_codec); | 254 encoder_is_opus_ = IsOpus(send_codec); |
255 | 255 |
256 if (new_codec) { | 256 if (new_codec) { |
257 // This is a new codec. Register it and return. | 257 // This is a new codec. Register it and return. |
258 RTC_DCHECK(CodecSupported(send_codec)); | 258 RTC_DCHECK(CodecSupported(send_codec)); |
259 if (IsOpus(send_codec)) { | 259 if (IsOpus(send_codec)) { |
260 // VAD/DTX not supported. | 260 // VAD/DTX not supported. |
261 dtx_enabled_ = false; | 261 dtx_enabled_ = false; |
262 } | 262 } |
263 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 263 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); |
264 if (!enc) | 264 if (!enc) |
265 return -1; | 265 return -1; |
266 codec_owner_.SetEncoders( | 266 rent_a_codec_.RentEncoderStack( |
267 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, | 267 enc, dtx_enabled_ |
hlundin-webrtc
2015/11/16 08:59:17
The two conditionals in this expression are slight
kwiberg-webrtc
2015/11/16 12:01:37
Done.
| |
268 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1); | 268 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ |
269 RTC_DCHECK(codec_owner_.Encoder()); | 269 CngPayloadType(send_codec.plfreq), vad_mode_}) |
270 : rtc::Optional<RentACodec::CngConfig>(), | |
271 red_enabled_ ? rtc::Optional<int>(RedPayloadType(send_codec.plfreq)) | |
272 : rtc::Optional<int>()); | |
273 RTC_DCHECK(CurrentEncoder()); | |
270 | 274 |
271 codec_fec_enabled_ = codec_fec_enabled_ && | 275 codec_fec_enabled_ = codec_fec_enabled_ && |
272 enc->SetFec(codec_fec_enabled_); | 276 enc->SetFec(codec_fec_enabled_); |
273 | 277 |
274 send_codec_inst_ = send_codec; | 278 send_codec_inst_ = send_codec; |
275 return 0; | 279 return 0; |
276 } | 280 } |
277 | 281 |
278 // This is an existing codec; re-create it if any parameters have changed. | 282 // This is an existing codec; re-create it if any parameters have changed. |
279 if (send_codec_inst_.plfreq != send_codec.plfreq || | 283 if (send_codec_inst_.plfreq != send_codec.plfreq || |
280 send_codec_inst_.pacsize != send_codec.pacsize || | 284 send_codec_inst_.pacsize != send_codec.pacsize || |
281 send_codec_inst_.channels != send_codec.channels) { | 285 send_codec_inst_.channels != send_codec.channels) { |
282 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 286 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); |
283 if (!enc) | 287 if (!enc) |
284 return -1; | 288 return -1; |
285 codec_owner_.SetEncoders( | 289 rent_a_codec_.RentEncoderStack( |
286 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, | 290 enc, dtx_enabled_ |
287 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1); | 291 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ |
288 RTC_DCHECK(codec_owner_.Encoder()); | 292 CngPayloadType(send_codec.plfreq), vad_mode_}) |
293 : rtc::Optional<RentACodec::CngConfig>(), | |
294 red_enabled_ ? rtc::Optional<int>(RedPayloadType(send_codec.plfreq)) | |
295 : rtc::Optional<int>()); | |
296 RTC_DCHECK(CurrentEncoder()); | |
289 } | 297 } |
290 send_codec_inst_.plfreq = send_codec.plfreq; | 298 send_codec_inst_.plfreq = send_codec.plfreq; |
291 send_codec_inst_.pacsize = send_codec.pacsize; | 299 send_codec_inst_.pacsize = send_codec.pacsize; |
292 send_codec_inst_.channels = send_codec.channels; | 300 send_codec_inst_.channels = send_codec.channels; |
293 send_codec_inst_.pltype = send_codec.pltype; | 301 send_codec_inst_.pltype = send_codec.pltype; |
294 | 302 |
295 // Check if a change in Rate is required. | 303 // Check if a change in Rate is required. |
296 if (send_codec.rate != send_codec_inst_.rate) { | 304 if (send_codec.rate != send_codec_inst_.rate) { |
297 codec_owner_.Encoder()->SetTargetBitrate(send_codec.rate); | 305 CurrentEncoder()->SetTargetBitrate(send_codec.rate); |
298 send_codec_inst_.rate = send_codec.rate; | 306 send_codec_inst_.rate = send_codec.rate; |
299 } | 307 } |
300 | 308 |
301 codec_fec_enabled_ = | 309 codec_fec_enabled_ = |
302 codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); | 310 codec_fec_enabled_ && CurrentEncoder()->SetFec(codec_fec_enabled_); |
303 | 311 |
304 return 0; | 312 return 0; |
305 } | 313 } |
306 | 314 |
307 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { | 315 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { |
308 // Make up a CodecInst. | 316 // Make up a CodecInst. |
309 send_codec_inst_.channels = external_speech_encoder->NumChannels(); | 317 send_codec_inst_.channels = external_speech_encoder->NumChannels(); |
310 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); | 318 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); |
311 send_codec_inst_.pacsize = rtc::CheckedDivExact( | 319 send_codec_inst_.pacsize = rtc::CheckedDivExact( |
312 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * | 320 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * |
313 send_codec_inst_.plfreq), | 321 send_codec_inst_.plfreq), |
314 100); | 322 100); |
315 send_codec_inst_.pltype = -1; // Not valid. | 323 send_codec_inst_.pltype = -1; // Not valid. |
316 send_codec_inst_.rate = -1; // Not valid. | 324 send_codec_inst_.rate = -1; // Not valid. |
317 static const char kName[] = "external"; | 325 static const char kName[] = "external"; |
318 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); | 326 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); |
319 | 327 |
320 if (send_codec_inst_.channels != 1) | 328 if (send_codec_inst_.channels != 1) |
321 dtx_enabled_ = false; | 329 dtx_enabled_ = false; |
322 if (codec_fec_enabled_) { | 330 if (codec_fec_enabled_) { |
323 // Switch FEC on. On failure, remember that FEC is off. | 331 // Switch FEC on. On failure, remember that FEC is off. |
324 if (!external_speech_encoder->SetFec(true)) | 332 if (!external_speech_encoder->SetFec(true)) |
325 codec_fec_enabled_ = false; | 333 codec_fec_enabled_ = false; |
326 } else { | 334 } else { |
327 // Switch FEC off. This shouldn't fail. | 335 // Switch FEC off. This shouldn't fail. |
328 const bool success = external_speech_encoder->SetFec(false); | 336 const bool success = external_speech_encoder->SetFec(false); |
329 RTC_DCHECK(success); | 337 RTC_DCHECK(success); |
330 } | 338 } |
331 int cng_pt = dtx_enabled_ | 339 |
332 ? CngPayloadType(external_speech_encoder->SampleRateHz()) | 340 rent_a_codec_.RentEncoderStack( |
333 : -1; | 341 external_speech_encoder, |
334 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; | 342 dtx_enabled_ |
335 codec_owner_.SetEncoders(external_speech_encoder, cng_pt, vad_mode_, red_pt); | 343 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ |
344 CngPayloadType(external_speech_encoder->SampleRateHz()), | |
345 vad_mode_}) | |
346 : rtc::Optional<RentACodec::CngConfig>(), | |
347 red_enabled_ ? rtc::Optional<int>(RedPayloadType( | |
348 external_speech_encoder->SampleRateHz())) | |
349 : rtc::Optional<int>()); | |
336 } | 350 } |
337 | 351 |
338 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { | 352 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { |
339 int dummy_id = 0; | 353 int dummy_id = 0; |
340 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 354 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, |
341 "SendCodec()"); | 355 "SendCodec()"); |
342 | 356 |
343 if (!codec_owner_.Encoder()) { | 357 if (!CurrentEncoder()) { |
344 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 358 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, |
345 "SendCodec Failed, no codec is registered"); | 359 "SendCodec Failed, no codec is registered"); |
346 return rtc::Optional<CodecInst>(); | 360 return rtc::Optional<CodecInst>(); |
347 } | 361 } |
348 return rtc::Optional<CodecInst>(send_codec_inst_); | 362 return rtc::Optional<CodecInst>(send_codec_inst_); |
349 } | 363 } |
350 | 364 |
351 bool CodecManager::SetCopyRed(bool enable) { | 365 bool CodecManager::SetCopyRed(bool enable) { |
352 if (enable && codec_fec_enabled_) { | 366 if (enable && codec_fec_enabled_) { |
353 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 367 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
354 "Codec internal FEC and RED cannot be co-enabled."); | 368 "Codec internal FEC and RED cannot be co-enabled."); |
355 return false; | 369 return false; |
356 } | 370 } |
357 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { | 371 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { |
358 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 372 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
359 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); | 373 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); |
360 return false; | 374 return false; |
361 } | 375 } |
362 if (red_enabled_ != enable) { | 376 if (red_enabled_ != enable) { |
363 red_enabled_ = enable; | 377 red_enabled_ = enable; |
364 if (codec_owner_.Encoder()) { | 378 if (CurrentEncoder()) { |
365 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; | 379 rent_a_codec_.RentEncoderStack( |
366 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; | 380 rent_a_codec_.GetEncoder(), |
367 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); | 381 dtx_enabled_ |
382 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ | |
383 CngPayloadType(send_codec_inst_.plfreq), vad_mode_}) | |
384 : rtc::Optional<RentACodec::CngConfig>(), | |
385 red_enabled_ | |
386 ? rtc::Optional<int>(RedPayloadType(send_codec_inst_.plfreq)) | |
387 : rtc::Optional<int>()); | |
368 } | 388 } |
369 } | 389 } |
370 return true; | 390 return true; |
371 } | 391 } |
372 | 392 |
373 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { | 393 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { |
374 // Sanity check of the mode. | 394 // Sanity check of the mode. |
375 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || | 395 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || |
376 mode == VADVeryAggr); | 396 mode == VADVeryAggr); |
377 | 397 |
378 // Check that the send codec is mono. We don't support VAD/DTX for stereo | 398 // Check that the send codec is mono. We don't support VAD/DTX for stereo |
379 // sending. | 399 // sending. |
380 const auto* enc = codec_owner_.Encoder(); | 400 auto* enc = rent_a_codec_.GetEncoder(); |
381 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; | 401 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; |
382 if (enable && stereo_send) { | 402 if (enable && stereo_send) { |
383 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, | 403 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, |
384 "VAD/DTX not supported for stereo sending"); | 404 "VAD/DTX not supported for stereo sending"); |
385 dtx_enabled_ = false; | 405 dtx_enabled_ = false; |
386 return -1; | 406 return -1; |
387 } | 407 } |
388 | 408 |
389 // If a send codec is registered, set VAD/DTX for the codec. | 409 // If a send codec is registered, set VAD/DTX for the codec. |
390 if (IsOpus(send_codec_inst_)) { | 410 if (IsOpus(send_codec_inst_)) { |
391 // VAD/DTX not supported. | 411 // VAD/DTX not supported. |
392 dtx_enabled_ = false; | 412 dtx_enabled_ = false; |
393 return 0; | 413 return 0; |
394 } | 414 } |
395 | 415 |
396 if (dtx_enabled_ != enable || vad_mode_ != mode) { | 416 if (dtx_enabled_ != enable || vad_mode_ != mode) { |
397 dtx_enabled_ = enable; | 417 dtx_enabled_ = enable; |
398 vad_mode_ = mode; | 418 vad_mode_ = mode; |
399 if (enc) { | 419 if (enc) { |
400 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; | 420 rent_a_codec_.RentEncoderStack( |
401 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; | 421 enc, dtx_enabled_ |
402 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); | 422 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ |
423 CngPayloadType(send_codec_inst_.plfreq), vad_mode_}) | |
424 : rtc::Optional<RentACodec::CngConfig>(), | |
425 red_enabled_ | |
426 ? rtc::Optional<int>(RedPayloadType(send_codec_inst_.plfreq)) | |
427 : rtc::Optional<int>()); | |
403 } | 428 } |
404 } | 429 } |
405 return 0; | 430 return 0; |
406 } | 431 } |
407 | 432 |
408 void CodecManager::VAD(bool* dtx_enabled, | 433 void CodecManager::VAD(bool* dtx_enabled, |
409 bool* vad_enabled, | 434 bool* vad_enabled, |
410 ACMVADMode* mode) const { | 435 ACMVADMode* mode) const { |
411 *dtx_enabled = dtx_enabled_; | 436 *dtx_enabled = dtx_enabled_; |
412 *vad_enabled = dtx_enabled_; | 437 *vad_enabled = dtx_enabled_; |
413 *mode = vad_mode_; | 438 *mode = vad_mode_; |
414 } | 439 } |
415 | 440 |
416 int CodecManager::SetCodecFEC(bool enable_codec_fec) { | 441 int CodecManager::SetCodecFEC(bool enable_codec_fec) { |
417 if (enable_codec_fec == true && red_enabled_ == true) { | 442 if (enable_codec_fec == true && red_enabled_ == true) { |
418 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 443 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
419 "Codec internal FEC and RED cannot be co-enabled."); | 444 "Codec internal FEC and RED cannot be co-enabled."); |
420 return -1; | 445 return -1; |
421 } | 446 } |
422 | 447 |
423 RTC_CHECK(codec_owner_.Encoder()); | 448 RTC_CHECK(CurrentEncoder()); |
424 codec_fec_enabled_ = | 449 codec_fec_enabled_ = |
425 codec_owner_.Encoder()->SetFec(enable_codec_fec) && enable_codec_fec; | 450 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; |
426 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; | 451 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; |
427 } | 452 } |
428 | 453 |
429 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { | 454 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { |
430 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; | 455 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; |
431 } | 456 } |
432 | 457 |
433 int CodecManager::CngPayloadType(int sample_rate_hz) const { | 458 int CodecManager::CngPayloadType(int sample_rate_hz) const { |
434 switch (sample_rate_hz) { | 459 switch (sample_rate_hz) { |
435 case 8000: | 460 case 8000: |
(...skipping 19 matching lines...) Expand all Loading... | |
455 case 48000: | 480 case 48000: |
456 return -1; | 481 return -1; |
457 default: | 482 default: |
458 FATAL() << sample_rate_hz << " Hz is not supported"; | 483 FATAL() << sample_rate_hz << " Hz is not supported"; |
459 return -1; | 484 return -1; |
460 } | 485 } |
461 } | 486 } |
462 | 487 |
463 } // namespace acm2 | 488 } // namespace acm2 |
464 } // namespace webrtc | 489 } // namespace webrtc |
OLD | NEW |