OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 options.extended_filter_aec = rtc::Maybe<bool>(false); | 381 options.extended_filter_aec = rtc::Maybe<bool>(false); |
382 options.delay_agnostic_aec = rtc::Maybe<bool>(false); | 382 options.delay_agnostic_aec = rtc::Maybe<bool>(false); |
383 options.experimental_ns = rtc::Maybe<bool>(false); | 383 options.experimental_ns = rtc::Maybe<bool>(false); |
384 options.aec_dump = rtc::Maybe<bool>(false); | 384 options.aec_dump = rtc::Maybe<bool>(false); |
385 return options; | 385 return options; |
386 } | 386 } |
387 | 387 |
388 std::string GetEnableString(bool enable) { | 388 std::string GetEnableString(bool enable) { |
389 return enable ? "enable" : "disable"; | 389 return enable ? "enable" : "disable"; |
390 } | 390 } |
| 391 |
| 392 webrtc::AudioState::Config MakeAudioStateConfig(VoEWrapper* voe_wrapper) { |
| 393 webrtc::AudioState::Config config; |
| 394 config.voice_engine = voe_wrapper->engine(); |
| 395 return config; |
| 396 } |
| 397 |
391 } // namespace { | 398 } // namespace { |
392 | 399 |
393 WebRtcVoiceEngine::WebRtcVoiceEngine() | 400 WebRtcVoiceEngine::WebRtcVoiceEngine() |
394 : voe_wrapper_(new VoEWrapper()), | 401 : voe_wrapper_(new VoEWrapper()), |
395 tracing_(new VoETraceWrapper()), | 402 tracing_(new VoETraceWrapper()), |
396 adm_(NULL), | 403 audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))), |
397 log_filter_(SeverityToFilter(kDefaultLogSeverity)), | 404 log_filter_(SeverityToFilter(kDefaultLogSeverity)) { |
398 is_dumping_aec_(false) { | |
399 Construct(); | 405 Construct(); |
400 } | 406 } |
401 | 407 |
402 WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper, | 408 WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper, |
403 VoETraceWrapper* tracing) | 409 VoETraceWrapper* tracing) |
404 : voe_wrapper_(voe_wrapper), | 410 : voe_wrapper_(voe_wrapper), |
405 tracing_(tracing), | 411 tracing_(tracing), |
406 adm_(NULL), | 412 log_filter_(SeverityToFilter(kDefaultLogSeverity)) { |
407 log_filter_(SeverityToFilter(kDefaultLogSeverity)), | |
408 is_dumping_aec_(false) { | |
409 Construct(); | 413 Construct(); |
410 } | 414 } |
411 | 415 |
412 void WebRtcVoiceEngine::Construct() { | 416 void WebRtcVoiceEngine::Construct() { |
| 417 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 418 signal_thread_checker_.DetachFromThread(); |
| 419 std::memset(&default_agc_config_, 0, sizeof(default_agc_config_)); |
413 SetTraceFilter(log_filter_); | 420 SetTraceFilter(log_filter_); |
414 initialized_ = false; | |
415 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; | 421 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; |
416 SetTraceOptions(""); | 422 SetTraceOptions(""); |
417 if (tracing_->SetTraceCallback(this) == -1) { | 423 if (tracing_->SetTraceCallback(this) == -1) { |
418 LOG_RTCERR0(SetTraceCallback); | 424 LOG_RTCERR0(SetTraceCallback); |
419 } | 425 } |
420 if (voe_wrapper_->base()->RegisterVoiceEngineObserver(*this) == -1) { | |
421 LOG_RTCERR0(RegisterVoiceEngineObserver); | |
422 } | |
423 // Clear the default agc state. | |
424 memset(&default_agc_config_, 0, sizeof(default_agc_config_)); | |
425 | 426 |
426 // Load our audio codec list. | 427 // Load our audio codec list. |
427 ConstructCodecs(); | 428 ConstructCodecs(); |
428 | 429 |
429 // Load our RTP Header extensions. | 430 // Load our RTP Header extensions. |
430 rtp_header_extensions_.push_back( | 431 rtp_header_extensions_.push_back( |
431 RtpHeaderExtension(kRtpAudioLevelHeaderExtension, | 432 RtpHeaderExtension(kRtpAudioLevelHeaderExtension, |
432 kRtpAudioLevelHeaderExtensionDefaultId)); | 433 kRtpAudioLevelHeaderExtensionDefaultId)); |
433 rtp_header_extensions_.push_back( | 434 rtp_header_extensions_.push_back( |
434 RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, | 435 RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, |
435 kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); | 436 kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); |
436 if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") { | 437 if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") { |
437 rtp_header_extensions_.push_back(RtpHeaderExtension( | 438 rtp_header_extensions_.push_back(RtpHeaderExtension( |
438 kRtpTransportSequenceNumberHeaderExtension, | 439 kRtpTransportSequenceNumberHeaderExtension, |
439 kRtpTransportSequenceNumberHeaderExtensionDefaultId)); | 440 kRtpTransportSequenceNumberHeaderExtensionDefaultId)); |
440 } | 441 } |
441 options_ = GetDefaultEngineOptions(); | 442 options_ = GetDefaultEngineOptions(); |
442 } | 443 } |
443 | 444 |
444 void WebRtcVoiceEngine::ConstructCodecs() { | 445 void WebRtcVoiceEngine::ConstructCodecs() { |
| 446 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
445 LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; | 447 LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; |
446 int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); | 448 int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); |
447 for (int i = 0; i < ncodecs; ++i) { | 449 for (int i = 0; i < ncodecs; ++i) { |
448 webrtc::CodecInst voe_codec; | 450 webrtc::CodecInst voe_codec; |
449 if (GetVoeCodec(i, &voe_codec)) { | 451 if (GetVoeCodec(i, &voe_codec)) { |
450 // Skip uncompressed formats. | 452 // Skip uncompressed formats. |
451 if (IsCodec(voe_codec, kL16CodecName)) { | 453 if (IsCodec(voe_codec, kL16CodecName)) { |
452 continue; | 454 continue; |
453 } | 455 } |
454 | 456 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 } else { | 494 } else { |
493 LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec); | 495 LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec); |
494 } | 496 } |
495 } | 497 } |
496 } | 498 } |
497 // Make sure they are in local preference order. | 499 // Make sure they are in local preference order. |
498 std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); | 500 std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); |
499 } | 501 } |
500 | 502 |
501 bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst* codec) { | 503 bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst* codec) { |
| 504 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
502 if (voe_wrapper_->codec()->GetCodec(index, *codec) == -1) { | 505 if (voe_wrapper_->codec()->GetCodec(index, *codec) == -1) { |
503 return false; | 506 return false; |
504 } | 507 } |
505 // Change the sample rate of G722 to 8000 to match SDP. | 508 // Change the sample rate of G722 to 8000 to match SDP. |
506 MaybeFixupG722(codec, 8000); | 509 MaybeFixupG722(codec, 8000); |
507 return true; | 510 return true; |
508 } | 511 } |
509 | 512 |
510 WebRtcVoiceEngine::~WebRtcVoiceEngine() { | 513 WebRtcVoiceEngine::~WebRtcVoiceEngine() { |
| 514 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
511 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; | 515 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; |
512 if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) { | |
513 LOG_RTCERR0(DeRegisterVoiceEngineObserver); | |
514 } | |
515 if (adm_) { | 516 if (adm_) { |
516 voe_wrapper_.reset(); | 517 voe_wrapper_.reset(); |
517 adm_->Release(); | 518 adm_->Release(); |
518 adm_ = NULL; | 519 adm_ = NULL; |
519 } | 520 } |
520 | 521 |
521 tracing_->SetTraceCallback(NULL); | 522 tracing_->SetTraceCallback(NULL); |
522 } | 523 } |
523 | 524 |
524 bool WebRtcVoiceEngine::Init(rtc::Thread* worker_thread) { | 525 bool WebRtcVoiceEngine::Init(rtc::Thread* worker_thread) { |
| 526 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
525 RTC_DCHECK(worker_thread == rtc::Thread::Current()); | 527 RTC_DCHECK(worker_thread == rtc::Thread::Current()); |
526 LOG(LS_INFO) << "WebRtcVoiceEngine::Init"; | 528 LOG(LS_INFO) << "WebRtcVoiceEngine::Init"; |
527 bool res = InitInternal(); | 529 bool res = InitInternal(); |
528 if (res) { | 530 if (res) { |
529 LOG(LS_INFO) << "WebRtcVoiceEngine::Init Done!"; | 531 LOG(LS_INFO) << "WebRtcVoiceEngine::Init Done!"; |
530 } else { | 532 } else { |
531 LOG(LS_ERROR) << "WebRtcVoiceEngine::Init failed"; | 533 LOG(LS_ERROR) << "WebRtcVoiceEngine::Init failed"; |
532 Terminate(); | 534 Terminate(); |
533 } | 535 } |
534 return res; | 536 return res; |
535 } | 537 } |
536 | 538 |
537 bool WebRtcVoiceEngine::InitInternal() { | 539 bool WebRtcVoiceEngine::InitInternal() { |
| 540 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
538 // Temporarily turn logging level up for the Init call | 541 // Temporarily turn logging level up for the Init call |
539 int old_filter = log_filter_; | 542 int old_filter = log_filter_; |
540 int extended_filter = log_filter_ | SeverityToFilter(rtc::LS_INFO); | 543 int extended_filter = log_filter_ | SeverityToFilter(rtc::LS_INFO); |
541 SetTraceFilter(extended_filter); | 544 SetTraceFilter(extended_filter); |
542 SetTraceOptions(""); | 545 SetTraceOptions(""); |
543 | 546 |
544 // Init WebRtc VoiceEngine. | 547 // Init WebRtc VoiceEngine. |
545 if (voe_wrapper_->base()->Init(adm_) == -1) { | 548 if (voe_wrapper_->base()->Init(adm_) == -1) { |
546 LOG_RTCERR0_EX(Init, voe_wrapper_->error()); | 549 LOG_RTCERR0_EX(Init, voe_wrapper_->error()); |
547 SetTraceFilter(old_filter); | 550 SetTraceFilter(old_filter); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 // PlayDtmfTone will be used if local playout is needed. | 584 // PlayDtmfTone will be used if local playout is needed. |
582 if (voe_wrapper_->dtmf()->SetDtmfFeedbackStatus(false) == -1) { | 585 if (voe_wrapper_->dtmf()->SetDtmfFeedbackStatus(false) == -1) { |
583 LOG_RTCERR1(SetDtmfFeedbackStatus, false); | 586 LOG_RTCERR1(SetDtmfFeedbackStatus, false); |
584 } | 587 } |
585 | 588 |
586 initialized_ = true; | 589 initialized_ = true; |
587 return true; | 590 return true; |
588 } | 591 } |
589 | 592 |
590 void WebRtcVoiceEngine::Terminate() { | 593 void WebRtcVoiceEngine::Terminate() { |
| 594 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
591 LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; | 595 LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; |
592 initialized_ = false; | 596 initialized_ = false; |
593 | 597 |
594 StopAecDump(); | 598 StopAecDump(); |
595 | 599 |
596 voe_wrapper_->base()->Terminate(); | 600 voe_wrapper_->base()->Terminate(); |
597 } | 601 } |
598 | 602 |
| 603 rtc::scoped_refptr<webrtc::AudioState> |
| 604 WebRtcVoiceEngine::GetAudioState() const { |
| 605 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 606 return audio_state_; |
| 607 } |
| 608 |
599 VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call, | 609 VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call, |
600 const AudioOptions& options) { | 610 const AudioOptions& options) { |
| 611 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
601 return new WebRtcVoiceMediaChannel(this, options, call); | 612 return new WebRtcVoiceMediaChannel(this, options, call); |
602 } | 613 } |
603 | 614 |
604 bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { | 615 bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { |
| 616 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
605 if (!ApplyOptions(options)) { | 617 if (!ApplyOptions(options)) { |
606 return false; | 618 return false; |
607 } | 619 } |
608 options_ = options; | 620 options_ = options; |
609 return true; | 621 return true; |
610 } | 622 } |
611 | 623 |
612 // AudioOptions defaults are set in InitInternal (for options with corresponding | 624 // AudioOptions defaults are set in InitInternal (for options with corresponding |
613 // MediaEngineInterface flags) and in SetOptions(int) for flagless options. | 625 // MediaEngineInterface flags) and in SetOptions(int) for flagless options. |
614 bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { | 626 bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { |
| 627 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
615 LOG(LS_INFO) << "ApplyOptions: " << options_in.ToString(); | 628 LOG(LS_INFO) << "ApplyOptions: " << options_in.ToString(); |
616 AudioOptions options = options_in; // The options are modified below. | 629 AudioOptions options = options_in; // The options are modified below. |
617 // kEcConference is AEC with high suppression. | 630 // kEcConference is AEC with high suppression. |
618 webrtc::EcModes ec_mode = webrtc::kEcConference; | 631 webrtc::EcModes ec_mode = webrtc::kEcConference; |
619 webrtc::AecmModes aecm_mode = webrtc::kAecmSpeakerphone; | 632 webrtc::AecmModes aecm_mode = webrtc::kAecmSpeakerphone; |
620 webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog; | 633 webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog; |
621 webrtc::NsModes ns_mode = webrtc::kNsHighSuppression; | 634 webrtc::NsModes ns_mode = webrtc::kNsHighSuppression; |
622 if (options.aecm_generate_comfort_noise) { | 635 if (options.aecm_generate_comfort_noise) { |
623 LOG(LS_VERBOSE) << "Comfort noise explicitly set to " | 636 LOG(LS_VERBOSE) << "Comfort noise explicitly set to " |
624 << *options.aecm_generate_comfort_noise | 637 << *options.aecm_generate_comfort_noise |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 } | 893 } |
881 } | 894 } |
882 | 895 |
883 return true; | 896 return true; |
884 } | 897 } |
885 | 898 |
886 // TODO(juberti): Refactor this so that the core logic can be used to set the | 899 // TODO(juberti): Refactor this so that the core logic can be used to set the |
887 // soundclip device. At that time, reinstate the soundclip pause/resume code. | 900 // soundclip device. At that time, reinstate the soundclip pause/resume code. |
888 bool WebRtcVoiceEngine::SetDevices(const Device* in_device, | 901 bool WebRtcVoiceEngine::SetDevices(const Device* in_device, |
889 const Device* out_device) { | 902 const Device* out_device) { |
| 903 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
890 #if !defined(IOS) | 904 #if !defined(IOS) |
891 int in_id = in_device ? rtc::FromString<int>(in_device->id) : | 905 int in_id = in_device ? rtc::FromString<int>(in_device->id) : |
892 kDefaultAudioDeviceId; | 906 kDefaultAudioDeviceId; |
893 int out_id = out_device ? rtc::FromString<int>(out_device->id) : | 907 int out_id = out_device ? rtc::FromString<int>(out_device->id) : |
894 kDefaultAudioDeviceId; | 908 kDefaultAudioDeviceId; |
895 // The device manager uses -1 as the default device, which was the case for | 909 // The device manager uses -1 as the default device, which was the case for |
896 // VoE 3.5. VoE 4.0, however, uses 0 as the default in Linux and Mac. | 910 // VoE 3.5. VoE 4.0, however, uses 0 as the default in Linux and Mac. |
897 #ifndef WIN32 | 911 #ifndef WIN32 |
898 if (-1 == in_id) { | 912 if (-1 == in_id) { |
899 in_id = kDefaultAudioDeviceId; | 913 in_id = kDefaultAudioDeviceId; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 } | 983 } |
970 | 984 |
971 return ret; | 985 return ret; |
972 #else | 986 #else |
973 return true; | 987 return true; |
974 #endif // !IOS | 988 #endif // !IOS |
975 } | 989 } |
976 | 990 |
977 bool WebRtcVoiceEngine::FindWebRtcAudioDeviceId( | 991 bool WebRtcVoiceEngine::FindWebRtcAudioDeviceId( |
978 bool is_input, const std::string& dev_name, int dev_id, int* rtc_id) { | 992 bool is_input, const std::string& dev_name, int dev_id, int* rtc_id) { |
| 993 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
979 // In Linux, VoiceEngine uses the same device dev_id as the device manager. | 994 // In Linux, VoiceEngine uses the same device dev_id as the device manager. |
980 #if defined(LINUX) || defined(ANDROID) | 995 #if defined(LINUX) || defined(ANDROID) |
981 *rtc_id = dev_id; | 996 *rtc_id = dev_id; |
982 return true; | 997 return true; |
983 #else | 998 #else |
984 // In Windows and Mac, we need to find the VoiceEngine device id by name | 999 // In Windows and Mac, we need to find the VoiceEngine device id by name |
985 // unless the input dev_id is the default device id. | 1000 // unless the input dev_id is the default device id. |
986 if (kDefaultAudioDeviceId == dev_id) { | 1001 if (kDefaultAudioDeviceId == dev_id) { |
987 *rtc_id = dev_id; | 1002 *rtc_id = dev_id; |
988 return true; | 1003 return true; |
(...skipping 29 matching lines...) Expand all Loading... |
1018 *rtc_id = i; | 1033 *rtc_id = i; |
1019 return true; | 1034 return true; |
1020 } | 1035 } |
1021 } | 1036 } |
1022 LOG(LS_WARNING) << "VoiceEngine cannot find device: " << dev_name; | 1037 LOG(LS_WARNING) << "VoiceEngine cannot find device: " << dev_name; |
1023 return false; | 1038 return false; |
1024 #endif | 1039 #endif |
1025 } | 1040 } |
1026 | 1041 |
1027 bool WebRtcVoiceEngine::GetOutputVolume(int* level) { | 1042 bool WebRtcVoiceEngine::GetOutputVolume(int* level) { |
| 1043 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1028 unsigned int ulevel; | 1044 unsigned int ulevel; |
1029 if (voe_wrapper_->volume()->GetSpeakerVolume(ulevel) == -1) { | 1045 if (voe_wrapper_->volume()->GetSpeakerVolume(ulevel) == -1) { |
1030 LOG_RTCERR1(GetSpeakerVolume, level); | 1046 LOG_RTCERR1(GetSpeakerVolume, level); |
1031 return false; | 1047 return false; |
1032 } | 1048 } |
1033 *level = ulevel; | 1049 *level = ulevel; |
1034 return true; | 1050 return true; |
1035 } | 1051 } |
1036 | 1052 |
1037 bool WebRtcVoiceEngine::SetOutputVolume(int level) { | 1053 bool WebRtcVoiceEngine::SetOutputVolume(int level) { |
| 1054 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1038 RTC_DCHECK(level >= 0 && level <= 255); | 1055 RTC_DCHECK(level >= 0 && level <= 255); |
1039 if (voe_wrapper_->volume()->SetSpeakerVolume(level) == -1) { | 1056 if (voe_wrapper_->volume()->SetSpeakerVolume(level) == -1) { |
1040 LOG_RTCERR1(SetSpeakerVolume, level); | 1057 LOG_RTCERR1(SetSpeakerVolume, level); |
1041 return false; | 1058 return false; |
1042 } | 1059 } |
1043 return true; | 1060 return true; |
1044 } | 1061 } |
1045 | 1062 |
1046 int WebRtcVoiceEngine::GetInputLevel() { | 1063 int WebRtcVoiceEngine::GetInputLevel() { |
| 1064 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1047 unsigned int ulevel; | 1065 unsigned int ulevel; |
1048 return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ? | 1066 return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ? |
1049 static_cast<int>(ulevel) : -1; | 1067 static_cast<int>(ulevel) : -1; |
1050 } | 1068 } |
1051 | 1069 |
1052 const std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() { | 1070 const std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() { |
| 1071 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); |
1053 return codecs_; | 1072 return codecs_; |
1054 } | 1073 } |
1055 | 1074 |
1056 bool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) { | 1075 bool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) { |
| 1076 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1057 return FindWebRtcCodec(in, NULL); | 1077 return FindWebRtcCodec(in, NULL); |
1058 } | 1078 } |
1059 | 1079 |
1060 // Get the VoiceEngine codec that matches |in|, with the supplied settings. | 1080 // Get the VoiceEngine codec that matches |in|, with the supplied settings. |
1061 bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, | 1081 bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, |
1062 webrtc::CodecInst* out) { | 1082 webrtc::CodecInst* out) { |
| 1083 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1063 int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); | 1084 int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); |
1064 for (int i = 0; i < ncodecs; ++i) { | 1085 for (int i = 0; i < ncodecs; ++i) { |
1065 webrtc::CodecInst voe_codec; | 1086 webrtc::CodecInst voe_codec; |
1066 if (GetVoeCodec(i, &voe_codec)) { | 1087 if (GetVoeCodec(i, &voe_codec)) { |
1067 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, | 1088 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, |
1068 voe_codec.rate, voe_codec.channels, 0); | 1089 voe_codec.rate, voe_codec.channels, 0); |
1069 bool multi_rate = IsCodecMultiRate(voe_codec); | 1090 bool multi_rate = IsCodecMultiRate(voe_codec); |
1070 // Allow arbitrary rates for ISAC to be specified. | 1091 // Allow arbitrary rates for ISAC to be specified. |
1071 if (multi_rate) { | 1092 if (multi_rate) { |
1072 // Set codec.bitrate to 0 so the check for codec.Matches() passes. | 1093 // Set codec.bitrate to 0 so the check for codec.Matches() passes. |
(...skipping 21 matching lines...) Expand all Loading... |
1094 *out = voe_codec; | 1115 *out = voe_codec; |
1095 } | 1116 } |
1096 return true; | 1117 return true; |
1097 } | 1118 } |
1098 } | 1119 } |
1099 } | 1120 } |
1100 return false; | 1121 return false; |
1101 } | 1122 } |
1102 const std::vector<RtpHeaderExtension>& | 1123 const std::vector<RtpHeaderExtension>& |
1103 WebRtcVoiceEngine::rtp_header_extensions() const { | 1124 WebRtcVoiceEngine::rtp_header_extensions() const { |
| 1125 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); |
1104 return rtp_header_extensions_; | 1126 return rtp_header_extensions_; |
1105 } | 1127 } |
1106 | 1128 |
1107 void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) { | 1129 void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) { |
| 1130 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1108 // if min_sev == -1, we keep the current log level. | 1131 // if min_sev == -1, we keep the current log level. |
1109 if (min_sev >= 0) { | 1132 if (min_sev >= 0) { |
1110 SetTraceFilter(SeverityToFilter(min_sev)); | 1133 SetTraceFilter(SeverityToFilter(min_sev)); |
1111 } | 1134 } |
1112 log_options_ = filter; | 1135 log_options_ = filter; |
1113 SetTraceOptions(initialized_ ? log_options_ : ""); | 1136 SetTraceOptions(initialized_ ? log_options_ : ""); |
1114 } | 1137 } |
1115 | 1138 |
1116 int WebRtcVoiceEngine::GetLastEngineError() { | 1139 int WebRtcVoiceEngine::GetLastEngineError() { |
| 1140 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1117 return voe_wrapper_->error(); | 1141 return voe_wrapper_->error(); |
1118 } | 1142 } |
1119 | 1143 |
1120 void WebRtcVoiceEngine::SetTraceFilter(int filter) { | 1144 void WebRtcVoiceEngine::SetTraceFilter(int filter) { |
| 1145 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1121 log_filter_ = filter; | 1146 log_filter_ = filter; |
1122 tracing_->SetTraceFilter(filter); | 1147 tracing_->SetTraceFilter(filter); |
1123 } | 1148 } |
1124 | 1149 |
1125 // We suppport three different logging settings for VoiceEngine: | 1150 // We suppport three different logging settings for VoiceEngine: |
1126 // 1. Observer callback that goes into talk diagnostic logfile. | 1151 // 1. Observer callback that goes into talk diagnostic logfile. |
1127 // Use --logfile and --loglevel | 1152 // Use --logfile and --loglevel |
1128 // | 1153 // |
1129 // 2. Encrypted VoiceEngine log for debugging VoiceEngine. | 1154 // 2. Encrypted VoiceEngine log for debugging VoiceEngine. |
1130 // Use --voice_loglevel --voice_logfilter "tracefile file_name" | 1155 // Use --voice_loglevel --voice_logfilter "tracefile file_name" |
1131 // | 1156 // |
1132 // 3. EC log and dump for debugging QualityEngine. | 1157 // 3. EC log and dump for debugging QualityEngine. |
1133 // Use --voice_loglevel --voice_logfilter "recordEC file_name" | 1158 // Use --voice_loglevel --voice_logfilter "recordEC file_name" |
1134 // | 1159 // |
1135 // For more details see: "https://sites.google.com/a/google.com/wavelet/Home/ | 1160 // For more details see: "https://sites.google.com/a/google.com/wavelet/Home/ |
1136 // Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters" | 1161 // Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters" |
1137 void WebRtcVoiceEngine::SetTraceOptions(const std::string& options) { | 1162 void WebRtcVoiceEngine::SetTraceOptions(const std::string& options) { |
| 1163 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1138 // Set encrypted trace file. | 1164 // Set encrypted trace file. |
1139 std::vector<std::string> opts; | 1165 std::vector<std::string> opts; |
1140 rtc::tokenize(options, ' ', '"', '"', &opts); | 1166 rtc::tokenize(options, ' ', '"', '"', &opts); |
1141 std::vector<std::string>::iterator tracefile = | 1167 std::vector<std::string>::iterator tracefile = |
1142 std::find(opts.begin(), opts.end(), "tracefile"); | 1168 std::find(opts.begin(), opts.end(), "tracefile"); |
1143 if (tracefile != opts.end() && ++tracefile != opts.end()) { | 1169 if (tracefile != opts.end() && ++tracefile != opts.end()) { |
1144 // Write encrypted debug output (at same loglevel) to file | 1170 // Write encrypted debug output (at same loglevel) to file |
1145 // EncryptedTraceFile no longer supported. | 1171 // EncryptedTraceFile no longer supported. |
1146 if (tracing_->SetTraceFile(tracefile->c_str()) == -1) { | 1172 if (tracing_->SetTraceFile(tracefile->c_str()) == -1) { |
1147 LOG_RTCERR1(SetTraceFile, *tracefile); | 1173 LOG_RTCERR1(SetTraceFile, *tracefile); |
(...skipping 19 matching lines...) Expand all Loading... |
1167 ++recordEC; | 1193 ++recordEC; |
1168 if (recordEC != opts.end()) | 1194 if (recordEC != opts.end()) |
1169 StartAecDump(recordEC->c_str()); | 1195 StartAecDump(recordEC->c_str()); |
1170 else | 1196 else |
1171 StopAecDump(); | 1197 StopAecDump(); |
1172 } | 1198 } |
1173 } | 1199 } |
1174 | 1200 |
1175 void WebRtcVoiceEngine::Print(webrtc::TraceLevel level, const char* trace, | 1201 void WebRtcVoiceEngine::Print(webrtc::TraceLevel level, const char* trace, |
1176 int length) { | 1202 int length) { |
| 1203 // Note: This callback can happen on any thread! |
1177 rtc::LoggingSeverity sev = rtc::LS_VERBOSE; | 1204 rtc::LoggingSeverity sev = rtc::LS_VERBOSE; |
1178 if (level == webrtc::kTraceError || level == webrtc::kTraceCritical) | 1205 if (level == webrtc::kTraceError || level == webrtc::kTraceCritical) |
1179 sev = rtc::LS_ERROR; | 1206 sev = rtc::LS_ERROR; |
1180 else if (level == webrtc::kTraceWarning) | 1207 else if (level == webrtc::kTraceWarning) |
1181 sev = rtc::LS_WARNING; | 1208 sev = rtc::LS_WARNING; |
1182 else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo) | 1209 else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo) |
1183 sev = rtc::LS_INFO; | 1210 sev = rtc::LS_INFO; |
1184 else if (level == webrtc::kTraceTerseInfo) | 1211 else if (level == webrtc::kTraceTerseInfo) |
1185 sev = rtc::LS_INFO; | 1212 sev = rtc::LS_INFO; |
1186 | 1213 |
1187 // Skip past boilerplate prefix text | 1214 // Skip past boilerplate prefix text |
1188 if (length < 72) { | 1215 if (length < 72) { |
1189 std::string msg(trace, length); | 1216 std::string msg(trace, length); |
1190 LOG(LS_ERROR) << "Malformed webrtc log message: "; | 1217 LOG(LS_ERROR) << "Malformed webrtc log message: "; |
1191 LOG_V(sev) << msg; | 1218 LOG_V(sev) << msg; |
1192 } else { | 1219 } else { |
1193 std::string msg(trace + 71, length - 72); | 1220 std::string msg(trace + 71, length - 72); |
1194 LOG_V(sev) << "webrtc: " << msg; | 1221 LOG_V(sev) << "webrtc: " << msg; |
1195 } | 1222 } |
1196 } | 1223 } |
1197 | 1224 |
1198 void WebRtcVoiceEngine::CallbackOnError(int channel_id, int err_code) { | |
1199 RTC_DCHECK(channel_id == -1); | |
1200 LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel " | |
1201 << channel_id << "."; | |
1202 rtc::CritScope lock(&channels_cs_); | |
1203 for (WebRtcVoiceMediaChannel* channel : channels_) { | |
1204 channel->OnError(err_code); | |
1205 } | |
1206 } | |
1207 | |
1208 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) { | 1225 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) { |
1209 RTC_DCHECK(channel != NULL); | 1226 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1210 rtc::CritScope lock(&channels_cs_); | 1227 RTC_DCHECK(channel); |
1211 channels_.push_back(channel); | 1228 channels_.push_back(channel); |
1212 } | 1229 } |
1213 | 1230 |
1214 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { | 1231 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { |
1215 rtc::CritScope lock(&channels_cs_); | 1232 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1216 auto it = std::find(channels_.begin(), channels_.end(), channel); | 1233 auto it = std::find(channels_.begin(), channels_.end(), channel); |
1217 if (it != channels_.end()) { | 1234 RTC_DCHECK(it != channels_.end()); |
1218 channels_.erase(it); | 1235 channels_.erase(it); |
1219 } | |
1220 } | 1236 } |
1221 | 1237 |
1222 // Adjusts the default AGC target level by the specified delta. | 1238 // Adjusts the default AGC target level by the specified delta. |
1223 // NB: If we start messing with other config fields, we'll want | 1239 // NB: If we start messing with other config fields, we'll want |
1224 // to save the current webrtc::AgcConfig as well. | 1240 // to save the current webrtc::AgcConfig as well. |
1225 bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) { | 1241 bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) { |
| 1242 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1226 webrtc::AgcConfig config = default_agc_config_; | 1243 webrtc::AgcConfig config = default_agc_config_; |
1227 config.targetLeveldBOv -= delta; | 1244 config.targetLeveldBOv -= delta; |
1228 | 1245 |
1229 LOG(LS_INFO) << "Adjusting AGC level from default -" | 1246 LOG(LS_INFO) << "Adjusting AGC level from default -" |
1230 << default_agc_config_.targetLeveldBOv << "dB to -" | 1247 << default_agc_config_.targetLeveldBOv << "dB to -" |
1231 << config.targetLeveldBOv << "dB"; | 1248 << config.targetLeveldBOv << "dB"; |
1232 | 1249 |
1233 if (voe_wrapper_->processing()->SetAgcConfig(config) == -1) { | 1250 if (voe_wrapper_->processing()->SetAgcConfig(config) == -1) { |
1234 LOG_RTCERR1(SetAgcConfig, config.targetLeveldBOv); | 1251 LOG_RTCERR1(SetAgcConfig, config.targetLeveldBOv); |
1235 return false; | 1252 return false; |
1236 } | 1253 } |
1237 return true; | 1254 return true; |
1238 } | 1255 } |
1239 | 1256 |
1240 bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm) { | 1257 bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm) { |
| 1258 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1241 if (initialized_) { | 1259 if (initialized_) { |
1242 LOG(LS_WARNING) << "SetAudioDeviceModule can not be called after Init."; | 1260 LOG(LS_WARNING) << "SetAudioDeviceModule can not be called after Init."; |
1243 return false; | 1261 return false; |
1244 } | 1262 } |
1245 if (adm_) { | 1263 if (adm_) { |
1246 adm_->Release(); | 1264 adm_->Release(); |
1247 adm_ = NULL; | 1265 adm_ = NULL; |
1248 } | 1266 } |
1249 if (adm) { | 1267 if (adm) { |
1250 adm_ = adm; | 1268 adm_ = adm; |
1251 adm_->AddRef(); | 1269 adm_->AddRef(); |
1252 } | 1270 } |
1253 return true; | 1271 return true; |
1254 } | 1272 } |
1255 | 1273 |
1256 bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file) { | 1274 bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file) { |
| 1275 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1257 FILE* aec_dump_file_stream = rtc::FdopenPlatformFileForWriting(file); | 1276 FILE* aec_dump_file_stream = rtc::FdopenPlatformFileForWriting(file); |
1258 if (!aec_dump_file_stream) { | 1277 if (!aec_dump_file_stream) { |
1259 LOG(LS_ERROR) << "Could not open AEC dump file stream."; | 1278 LOG(LS_ERROR) << "Could not open AEC dump file stream."; |
1260 if (!rtc::ClosePlatformFile(file)) | 1279 if (!rtc::ClosePlatformFile(file)) |
1261 LOG(LS_WARNING) << "Could not close file."; | 1280 LOG(LS_WARNING) << "Could not close file."; |
1262 return false; | 1281 return false; |
1263 } | 1282 } |
1264 StopAecDump(); | 1283 StopAecDump(); |
1265 if (voe_wrapper_->processing()->StartDebugRecording(aec_dump_file_stream) != | 1284 if (voe_wrapper_->processing()->StartDebugRecording(aec_dump_file_stream) != |
1266 webrtc::AudioProcessing::kNoError) { | 1285 webrtc::AudioProcessing::kNoError) { |
1267 LOG_RTCERR0(StartDebugRecording); | 1286 LOG_RTCERR0(StartDebugRecording); |
1268 fclose(aec_dump_file_stream); | 1287 fclose(aec_dump_file_stream); |
1269 return false; | 1288 return false; |
1270 } | 1289 } |
1271 is_dumping_aec_ = true; | 1290 is_dumping_aec_ = true; |
1272 return true; | 1291 return true; |
1273 } | 1292 } |
1274 | 1293 |
1275 void WebRtcVoiceEngine::StartAecDump(const std::string& filename) { | 1294 void WebRtcVoiceEngine::StartAecDump(const std::string& filename) { |
| 1295 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1276 if (!is_dumping_aec_) { | 1296 if (!is_dumping_aec_) { |
1277 // Start dumping AEC when we are not dumping. | 1297 // Start dumping AEC when we are not dumping. |
1278 if (voe_wrapper_->processing()->StartDebugRecording( | 1298 if (voe_wrapper_->processing()->StartDebugRecording( |
1279 filename.c_str()) != webrtc::AudioProcessing::kNoError) { | 1299 filename.c_str()) != webrtc::AudioProcessing::kNoError) { |
1280 LOG_RTCERR1(StartDebugRecording, filename.c_str()); | 1300 LOG_RTCERR1(StartDebugRecording, filename.c_str()); |
1281 } else { | 1301 } else { |
1282 is_dumping_aec_ = true; | 1302 is_dumping_aec_ = true; |
1283 } | 1303 } |
1284 } | 1304 } |
1285 } | 1305 } |
1286 | 1306 |
1287 void WebRtcVoiceEngine::StopAecDump() { | 1307 void WebRtcVoiceEngine::StopAecDump() { |
| 1308 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1288 if (is_dumping_aec_) { | 1309 if (is_dumping_aec_) { |
1289 // Stop dumping AEC when we are dumping. | 1310 // Stop dumping AEC when we are dumping. |
1290 if (voe_wrapper_->processing()->StopDebugRecording() != | 1311 if (voe_wrapper_->processing()->StopDebugRecording() != |
1291 webrtc::AudioProcessing::kNoError) { | 1312 webrtc::AudioProcessing::kNoError) { |
1292 LOG_RTCERR0(StopDebugRecording); | 1313 LOG_RTCERR0(StopDebugRecording); |
1293 } | 1314 } |
1294 is_dumping_aec_ = false; | 1315 is_dumping_aec_ = false; |
1295 } | 1316 } |
1296 } | 1317 } |
1297 | 1318 |
1298 bool WebRtcVoiceEngine::StartRtcEventLog(rtc::PlatformFile file) { | 1319 bool WebRtcVoiceEngine::StartRtcEventLog(rtc::PlatformFile file) { |
| 1320 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1299 return voe_wrapper_->codec()->GetEventLog()->StartLogging(file); | 1321 return voe_wrapper_->codec()->GetEventLog()->StartLogging(file); |
1300 } | 1322 } |
1301 | 1323 |
1302 void WebRtcVoiceEngine::StopRtcEventLog() { | 1324 void WebRtcVoiceEngine::StopRtcEventLog() { |
| 1325 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1303 voe_wrapper_->codec()->GetEventLog()->StopLogging(); | 1326 voe_wrapper_->codec()->GetEventLog()->StopLogging(); |
1304 } | 1327 } |
1305 | 1328 |
1306 int WebRtcVoiceEngine::CreateVoEChannel() { | 1329 int WebRtcVoiceEngine::CreateVoEChannel() { |
| 1330 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1307 return voe_wrapper_->base()->CreateChannel(voe_config_); | 1331 return voe_wrapper_->base()->CreateChannel(voe_config_); |
1308 } | 1332 } |
1309 | 1333 |
1310 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1334 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1311 : public AudioRenderer::Sink { | 1335 : public AudioRenderer::Sink { |
1312 public: | 1336 public: |
1313 WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, | 1337 WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, |
1314 uint32_t ssrc, webrtc::Call* call) | 1338 uint32_t ssrc, webrtc::Call* call) |
1315 : channel_(ch), | 1339 : channel_(ch), |
1316 voe_audio_transport_(voe_audio_transport), | 1340 voe_audio_transport_(voe_audio_transport), |
1317 call_(call) { | 1341 call_(call) { |
1318 RTC_DCHECK_GE(ch, 0); | 1342 RTC_DCHECK_GE(ch, 0); |
1319 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1343 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1320 // RTC_DCHECK(voe_audio_transport); | 1344 // RTC_DCHECK(voe_audio_transport); |
1321 RTC_DCHECK(call); | 1345 RTC_DCHECK(call); |
1322 audio_capture_thread_checker_.DetachFromThread(); | 1346 audio_capture_thread_checker_.DetachFromThread(); |
1323 webrtc::AudioSendStream::Config config(nullptr); | 1347 webrtc::AudioSendStream::Config config(nullptr); |
1324 config.voe_channel_id = channel_; | 1348 config.voe_channel_id = channel_; |
1325 config.rtp.ssrc = ssrc; | 1349 config.rtp.ssrc = ssrc; |
1326 stream_ = call_->CreateAudioSendStream(config); | 1350 stream_ = call_->CreateAudioSendStream(config); |
1327 RTC_DCHECK(stream_); | 1351 RTC_DCHECK(stream_); |
1328 } | 1352 } |
1329 ~WebRtcAudioSendStream() override { | 1353 ~WebRtcAudioSendStream() override { |
1330 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1354 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1331 Stop(); | 1355 Stop(); |
1332 call_->DestroyAudioSendStream(stream_); | 1356 call_->DestroyAudioSendStream(stream_); |
1333 } | 1357 } |
1334 | 1358 |
1335 // Starts the rendering by setting a sink to the renderer to get data | 1359 // Starts the rendering by setting a sink to the renderer to get data |
1336 // callback. | 1360 // callback. |
1337 // This method is called on the libjingle worker thread. | 1361 // This method is called on the libjingle worker thread. |
1338 // TODO(xians): Make sure Start() is called only once. | 1362 // TODO(xians): Make sure Start() is called only once. |
1339 void Start(AudioRenderer* renderer) { | 1363 void Start(AudioRenderer* renderer) { |
1340 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1364 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1341 RTC_DCHECK(renderer); | 1365 RTC_DCHECK(renderer); |
1342 if (renderer_) { | 1366 if (renderer_) { |
1343 RTC_DCHECK(renderer_ == renderer); | 1367 RTC_DCHECK(renderer_ == renderer); |
1344 return; | 1368 return; |
1345 } | 1369 } |
1346 renderer->SetSink(this); | 1370 renderer->SetSink(this); |
1347 renderer_ = renderer; | 1371 renderer_ = renderer; |
1348 } | 1372 } |
1349 | 1373 |
1350 webrtc::AudioSendStream::Stats GetStats() const { | 1374 webrtc::AudioSendStream::Stats GetStats() const { |
1351 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1375 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1352 return stream_->GetStats(); | 1376 return stream_->GetStats(); |
1353 } | 1377 } |
1354 | 1378 |
1355 // Stops rendering by setting the sink of the renderer to nullptr. No data | 1379 // Stops rendering by setting the sink of the renderer to nullptr. No data |
1356 // callback will be received after this method. | 1380 // callback will be received after this method. |
1357 // This method is called on the libjingle worker thread. | 1381 // This method is called on the libjingle worker thread. |
1358 void Stop() { | 1382 void Stop() { |
1359 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1383 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1360 if (renderer_) { | 1384 if (renderer_) { |
1361 renderer_->SetSink(nullptr); | 1385 renderer_->SetSink(nullptr); |
1362 renderer_ = nullptr; | 1386 renderer_ = nullptr; |
1363 } | 1387 } |
1364 } | 1388 } |
1365 | 1389 |
1366 // AudioRenderer::Sink implementation. | 1390 // AudioRenderer::Sink implementation. |
1367 // This method is called on the audio thread. | 1391 // This method is called on the audio thread. |
1368 void OnData(const void* audio_data, | 1392 void OnData(const void* audio_data, |
1369 int bits_per_sample, | 1393 int bits_per_sample, |
1370 int sample_rate, | 1394 int sample_rate, |
1371 int number_of_channels, | 1395 int number_of_channels, |
1372 size_t number_of_frames) override { | 1396 size_t number_of_frames) override { |
| 1397 RTC_DCHECK(!worker_thread_checker_.CalledOnValidThread()); |
1373 RTC_DCHECK(audio_capture_thread_checker_.CalledOnValidThread()); | 1398 RTC_DCHECK(audio_capture_thread_checker_.CalledOnValidThread()); |
1374 RTC_DCHECK(voe_audio_transport_); | 1399 RTC_DCHECK(voe_audio_transport_); |
1375 voe_audio_transport_->OnData(channel_, | 1400 voe_audio_transport_->OnData(channel_, |
1376 audio_data, | 1401 audio_data, |
1377 bits_per_sample, | 1402 bits_per_sample, |
1378 sample_rate, | 1403 sample_rate, |
1379 number_of_channels, | 1404 number_of_channels, |
1380 number_of_frames); | 1405 number_of_frames); |
1381 } | 1406 } |
1382 | 1407 |
1383 // Callback from the |renderer_| when it is going away. In case Start() has | 1408 // Callback from the |renderer_| when it is going away. In case Start() has |
1384 // never been called, this callback won't be triggered. | 1409 // never been called, this callback won't be triggered. |
1385 void OnClose() override { | 1410 void OnClose() override { |
1386 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1411 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1387 // Set |renderer_| to nullptr to make sure no more callback will get into | 1412 // Set |renderer_| to nullptr to make sure no more callback will get into |
1388 // the renderer. | 1413 // the renderer. |
1389 renderer_ = nullptr; | 1414 renderer_ = nullptr; |
1390 } | 1415 } |
1391 | 1416 |
1392 // Accessor to the VoE channel ID. | 1417 // Accessor to the VoE channel ID. |
1393 int channel() const { | 1418 int channel() const { |
1394 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); | 1419 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1395 return channel_; | 1420 return channel_; |
1396 } | 1421 } |
1397 | 1422 |
1398 private: | 1423 private: |
1399 rtc::ThreadChecker signal_thread_checker_; | 1424 rtc::ThreadChecker worker_thread_checker_; |
1400 rtc::ThreadChecker audio_capture_thread_checker_; | 1425 rtc::ThreadChecker audio_capture_thread_checker_; |
1401 const int channel_ = -1; | 1426 const int channel_ = -1; |
1402 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1427 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
1403 webrtc::Call* call_ = nullptr; | 1428 webrtc::Call* call_ = nullptr; |
1404 webrtc::AudioSendStream* stream_ = nullptr; | 1429 webrtc::AudioSendStream* stream_ = nullptr; |
1405 | 1430 |
1406 // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. | 1431 // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. |
1407 // PeerConnection will make sure invalidating the pointer before the object | 1432 // PeerConnection will make sure invalidating the pointer before the object |
1408 // goes away. | 1433 // goes away. |
1409 AudioRenderer* renderer_ = nullptr; | 1434 AudioRenderer* renderer_ = nullptr; |
(...skipping 11 matching lines...) Expand all Loading... |
1421 private: | 1446 private: |
1422 int channel_; | 1447 int channel_; |
1423 | 1448 |
1424 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); | 1449 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); |
1425 }; | 1450 }; |
1426 | 1451 |
1427 // WebRtcVoiceMediaChannel | 1452 // WebRtcVoiceMediaChannel |
1428 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, | 1453 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
1429 const AudioOptions& options, | 1454 const AudioOptions& options, |
1430 webrtc::Call* call) | 1455 webrtc::Call* call) |
1431 : engine_(engine), | 1456 : engine_(engine), call_(call) { |
1432 send_bitrate_setting_(false), | |
1433 send_bitrate_bps_(0), | |
1434 options_(), | |
1435 dtmf_allowed_(false), | |
1436 desired_playout_(false), | |
1437 nack_enabled_(false), | |
1438 playout_(false), | |
1439 typing_noise_detected_(false), | |
1440 desired_send_(SEND_NOTHING), | |
1441 send_(SEND_NOTHING), | |
1442 call_(call) { | |
1443 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; | 1457 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; |
1444 RTC_DCHECK(nullptr != call); | 1458 RTC_DCHECK(call); |
1445 engine->RegisterChannel(this); | 1459 engine->RegisterChannel(this); |
1446 SetOptions(options); | 1460 SetOptions(options); |
1447 } | 1461 } |
1448 | 1462 |
1449 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1463 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
1450 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1464 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1451 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; | 1465 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; |
1452 | 1466 |
1453 // Remove any remaining send streams. | 1467 // Remove any remaining send streams. |
1454 while (!send_streams_.empty()) { | 1468 while (!send_streams_.empty()) { |
1455 RemoveSendStream(send_streams_.begin()->first); | 1469 RemoveSendStream(send_streams_.begin()->first); |
1456 } | 1470 } |
1457 | 1471 |
1458 // Remove any remaining receive streams. | 1472 // Remove any remaining receive streams. |
1459 while (!receive_channels_.empty()) { | 1473 while (!receive_channels_.empty()) { |
1460 RemoveRecvStream(receive_channels_.begin()->first); | 1474 RemoveRecvStream(receive_channels_.begin()->first); |
1461 } | 1475 } |
1462 RTC_DCHECK(receive_streams_.empty()); | 1476 RTC_DCHECK(receive_streams_.empty()); |
1463 | 1477 |
1464 // Unregister ourselves from the engine. | 1478 // Unregister ourselves from the engine. |
1465 engine()->UnregisterChannel(this); | 1479 engine()->UnregisterChannel(this); |
1466 } | 1480 } |
1467 | 1481 |
1468 bool WebRtcVoiceMediaChannel::SetSendParameters( | 1482 bool WebRtcVoiceMediaChannel::SetSendParameters( |
1469 const AudioSendParameters& params) { | 1483 const AudioSendParameters& params) { |
1470 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1484 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1471 // TODO(pthatcher): Refactor this to be more clean now that we have | 1485 // TODO(pthatcher): Refactor this to be more clean now that we have |
1472 // all the information at once. | 1486 // all the information at once. |
1473 return (SetSendCodecs(params.codecs) && | 1487 return (SetSendCodecs(params.codecs) && |
1474 SetSendRtpHeaderExtensions(params.extensions) && | 1488 SetSendRtpHeaderExtensions(params.extensions) && |
1475 SetMaxSendBandwidth(params.max_bandwidth_bps) && | 1489 SetMaxSendBandwidth(params.max_bandwidth_bps) && |
1476 SetOptions(params.options)); | 1490 SetOptions(params.options)); |
1477 } | 1491 } |
1478 | 1492 |
1479 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1493 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
1480 const AudioRecvParameters& params) { | 1494 const AudioRecvParameters& params) { |
1481 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1495 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1482 // TODO(pthatcher): Refactor this to be more clean now that we have | 1496 // TODO(pthatcher): Refactor this to be more clean now that we have |
1483 // all the information at once. | 1497 // all the information at once. |
1484 return (SetRecvCodecs(params.codecs) && | 1498 return (SetRecvCodecs(params.codecs) && |
1485 SetRecvRtpHeaderExtensions(params.extensions)); | 1499 SetRecvRtpHeaderExtensions(params.extensions)); |
1486 } | 1500 } |
1487 | 1501 |
1488 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 1502 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { |
1489 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1503 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1490 LOG(LS_INFO) << "Setting voice channel options: " | 1504 LOG(LS_INFO) << "Setting voice channel options: " |
1491 << options.ToString(); | 1505 << options.ToString(); |
1492 | 1506 |
1493 // Check if DSCP value is changed from previous. | 1507 // Check if DSCP value is changed from previous. |
1494 bool dscp_option_changed = (options_.dscp != options.dscp); | 1508 bool dscp_option_changed = (options_.dscp != options.dscp); |
1495 | 1509 |
1496 // We retain all of the existing options, and apply the given ones | 1510 // We retain all of the existing options, and apply the given ones |
1497 // on top. This means there is no way to "clear" options such that | 1511 // on top. This means there is no way to "clear" options such that |
1498 // they go back to the engine default. | 1512 // they go back to the engine default. |
1499 options_.SetAll(options); | 1513 options_.SetAll(options); |
(...skipping 18 matching lines...) Expand all Loading... |
1518 // TODO(solenberg): Don't recreate unless options changed. | 1532 // TODO(solenberg): Don't recreate unless options changed. |
1519 RecreateAudioReceiveStreams(); | 1533 RecreateAudioReceiveStreams(); |
1520 | 1534 |
1521 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1535 LOG(LS_INFO) << "Set voice channel options. Current options: " |
1522 << options_.ToString(); | 1536 << options_.ToString(); |
1523 return true; | 1537 return true; |
1524 } | 1538 } |
1525 | 1539 |
1526 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1540 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1527 const std::vector<AudioCodec>& codecs) { | 1541 const std::vector<AudioCodec>& codecs) { |
1528 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1542 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1529 | 1543 |
1530 // Set the payload types to be used for incoming media. | 1544 // Set the payload types to be used for incoming media. |
1531 LOG(LS_INFO) << "Setting receive voice codecs."; | 1545 LOG(LS_INFO) << "Setting receive voice codecs."; |
1532 | 1546 |
1533 if (!VerifyUniquePayloadTypes(codecs)) { | 1547 if (!VerifyUniquePayloadTypes(codecs)) { |
1534 LOG(LS_ERROR) << "Codec payload types overlap."; | 1548 LOG(LS_ERROR) << "Codec payload types overlap."; |
1535 return false; | 1549 return false; |
1536 } | 1550 } |
1537 | 1551 |
1538 std::vector<AudioCodec> new_codecs; | 1552 std::vector<AudioCodec> new_codecs; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 return false; | 1790 return false; |
1777 } | 1791 } |
1778 } | 1792 } |
1779 } | 1793 } |
1780 } | 1794 } |
1781 return true; | 1795 return true; |
1782 } | 1796 } |
1783 | 1797 |
1784 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1798 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1785 const std::vector<AudioCodec>& codecs) { | 1799 const std::vector<AudioCodec>& codecs) { |
1786 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1800 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1787 | 1801 |
1788 dtmf_allowed_ = false; | 1802 dtmf_allowed_ = false; |
1789 for (const AudioCodec& codec : codecs) { | 1803 for (const AudioCodec& codec : codecs) { |
1790 // Find the DTMF telephone event "codec". | 1804 // Find the DTMF telephone event "codec". |
1791 if (IsCodec(codec, kDtmfCodecName)) { | 1805 if (IsCodec(codec, kDtmfCodecName)) { |
1792 dtmf_allowed_ = true; | 1806 dtmf_allowed_ = true; |
1793 } | 1807 } |
1794 } | 1808 } |
1795 | 1809 |
1796 // Cache the codecs in order to configure the channel created later. | 1810 // Cache the codecs in order to configure the channel created later. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 | 1847 |
1834 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { | 1848 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { |
1835 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); | 1849 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); |
1836 return false; | 1850 return false; |
1837 } | 1851 } |
1838 return true; | 1852 return true; |
1839 } | 1853 } |
1840 | 1854 |
1841 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( | 1855 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( |
1842 const std::vector<RtpHeaderExtension>& extensions) { | 1856 const std::vector<RtpHeaderExtension>& extensions) { |
1843 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1857 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1844 if (receive_extensions_ == extensions) { | 1858 if (receive_extensions_ == extensions) { |
1845 return true; | 1859 return true; |
1846 } | 1860 } |
1847 | 1861 |
1848 for (const auto& ch : receive_channels_) { | 1862 for (const auto& ch : receive_channels_) { |
1849 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { | 1863 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { |
1850 return false; | 1864 return false; |
1851 } | 1865 } |
1852 } | 1866 } |
1853 | 1867 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 &webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id, | 1908 &webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id, |
1895 send_time_extension)) { | 1909 send_time_extension)) { |
1896 return false; | 1910 return false; |
1897 } | 1911 } |
1898 | 1912 |
1899 return true; | 1913 return true; |
1900 } | 1914 } |
1901 | 1915 |
1902 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( | 1916 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( |
1903 const std::vector<RtpHeaderExtension>& extensions) { | 1917 const std::vector<RtpHeaderExtension>& extensions) { |
1904 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1918 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1905 if (send_extensions_ == extensions) { | 1919 if (send_extensions_ == extensions) { |
1906 return true; | 1920 return true; |
1907 } | 1921 } |
1908 | 1922 |
1909 for (const auto& ch : send_streams_) { | 1923 for (const auto& ch : send_streams_) { |
1910 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { | 1924 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { |
1911 return false; | 1925 return false; |
1912 } | 1926 } |
1913 } | 1927 } |
1914 | 1928 |
(...skipping 30 matching lines...) Expand all Loading... |
1945 | 1959 |
1946 bool WebRtcVoiceMediaChannel::PausePlayout() { | 1960 bool WebRtcVoiceMediaChannel::PausePlayout() { |
1947 return ChangePlayout(false); | 1961 return ChangePlayout(false); |
1948 } | 1962 } |
1949 | 1963 |
1950 bool WebRtcVoiceMediaChannel::ResumePlayout() { | 1964 bool WebRtcVoiceMediaChannel::ResumePlayout() { |
1951 return ChangePlayout(desired_playout_); | 1965 return ChangePlayout(desired_playout_); |
1952 } | 1966 } |
1953 | 1967 |
1954 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { | 1968 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { |
1955 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1969 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1956 if (playout_ == playout) { | 1970 if (playout_ == playout) { |
1957 return true; | 1971 return true; |
1958 } | 1972 } |
1959 | 1973 |
1960 for (const auto& ch : receive_channels_) { | 1974 for (const auto& ch : receive_channels_) { |
1961 if (!SetPlayout(ch.second->channel(), playout)) { | 1975 if (!SetPlayout(ch.second->channel(), playout)) { |
1962 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " | 1976 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " |
1963 << ch.second->channel() << " failed"; | 1977 << ch.second->channel() << " failed"; |
1964 return false; | 1978 return false; |
1965 } | 1979 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2026 } | 2040 } |
2027 } | 2041 } |
2028 | 2042 |
2029 return true; | 2043 return true; |
2030 } | 2044 } |
2031 | 2045 |
2032 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32_t ssrc, | 2046 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32_t ssrc, |
2033 bool enable, | 2047 bool enable, |
2034 const AudioOptions* options, | 2048 const AudioOptions* options, |
2035 AudioRenderer* renderer) { | 2049 AudioRenderer* renderer) { |
2036 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2050 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2037 // TODO(solenberg): The state change should be fully rolled back if any one of | 2051 // TODO(solenberg): The state change should be fully rolled back if any one of |
2038 // these calls fail. | 2052 // these calls fail. |
2039 if (!SetLocalRenderer(ssrc, renderer)) { | 2053 if (!SetLocalRenderer(ssrc, renderer)) { |
2040 return false; | 2054 return false; |
2041 } | 2055 } |
2042 if (!MuteStream(ssrc, !enable)) { | 2056 if (!MuteStream(ssrc, !enable)) { |
2043 return false; | 2057 return false; |
2044 } | 2058 } |
2045 if (enable && options) { | 2059 if (enable && options) { |
2046 return SetOptions(*options); | 2060 return SetOptions(*options); |
(...skipping 20 matching lines...) Expand all Loading... |
2067 LOG_RTCERR1(DeRegisterExternalTransport, channel); | 2081 LOG_RTCERR1(DeRegisterExternalTransport, channel); |
2068 } | 2082 } |
2069 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { | 2083 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { |
2070 LOG_RTCERR1(DeleteChannel, channel); | 2084 LOG_RTCERR1(DeleteChannel, channel); |
2071 return false; | 2085 return false; |
2072 } | 2086 } |
2073 return true; | 2087 return true; |
2074 } | 2088 } |
2075 | 2089 |
2076 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { | 2090 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
2077 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2091 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2078 LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); | 2092 LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); |
2079 | 2093 |
2080 uint32_t ssrc = sp.first_ssrc(); | 2094 uint32_t ssrc = sp.first_ssrc(); |
2081 RTC_DCHECK(0 != ssrc); | 2095 RTC_DCHECK(0 != ssrc); |
2082 | 2096 |
2083 if (GetSendChannelId(ssrc) != -1) { | 2097 if (GetSendChannelId(ssrc) != -1) { |
2084 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2098 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2085 return false; | 2099 return false; |
2086 } | 2100 } |
2087 | 2101 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); | 2155 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); |
2142 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel | 2156 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel |
2143 << " is associated with channel #" << channel << "."; | 2157 << " is associated with channel #" << channel << "."; |
2144 } | 2158 } |
2145 } | 2159 } |
2146 | 2160 |
2147 return ChangeSend(channel, desired_send_); | 2161 return ChangeSend(channel, desired_send_); |
2148 } | 2162 } |
2149 | 2163 |
2150 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { | 2164 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { |
2151 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2165 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2152 auto it = send_streams_.find(ssrc); | 2166 auto it = send_streams_.find(ssrc); |
2153 if (it == send_streams_.end()) { | 2167 if (it == send_streams_.end()) { |
2154 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2168 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2155 << " which doesn't exist."; | 2169 << " which doesn't exist."; |
2156 return false; | 2170 return false; |
2157 } | 2171 } |
2158 | 2172 |
2159 int channel = it->second->channel(); | 2173 int channel = it->second->channel(); |
2160 ChangeSend(channel, SEND_NOTHING); | 2174 ChangeSend(channel, SEND_NOTHING); |
2161 | 2175 |
2162 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, | 2176 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, |
2163 // this will disconnect the audio renderer with the send channel. | 2177 // this will disconnect the audio renderer with the send channel. |
2164 delete it->second; | 2178 delete it->second; |
2165 send_streams_.erase(it); | 2179 send_streams_.erase(it); |
2166 | 2180 |
2167 // Clean up and delete the send channel. | 2181 // Clean up and delete the send channel. |
2168 LOG(LS_INFO) << "Removing audio send stream " << ssrc | 2182 LOG(LS_INFO) << "Removing audio send stream " << ssrc |
2169 << " with VoiceEngine channel #" << channel << "."; | 2183 << " with VoiceEngine channel #" << channel << "."; |
2170 if (!DeleteChannel(channel)) { | 2184 if (!DeleteChannel(channel)) { |
2171 return false; | 2185 return false; |
2172 } | 2186 } |
2173 if (send_streams_.empty()) { | 2187 if (send_streams_.empty()) { |
2174 ChangeSend(SEND_NOTHING); | 2188 ChangeSend(SEND_NOTHING); |
2175 } | 2189 } |
2176 return true; | 2190 return true; |
2177 } | 2191 } |
2178 | 2192 |
2179 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2193 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
2180 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2194 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2181 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); | 2195 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
2182 | 2196 |
2183 if (!ValidateStreamParams(sp)) { | 2197 if (!ValidateStreamParams(sp)) { |
2184 return false; | 2198 return false; |
2185 } | 2199 } |
2186 | 2200 |
2187 uint32_t ssrc = sp.first_ssrc(); | 2201 uint32_t ssrc = sp.first_ssrc(); |
2188 if (ssrc == 0) { | 2202 if (ssrc == 0) { |
2189 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; | 2203 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; |
2190 return false; | 2204 return false; |
(...skipping 26 matching lines...) Expand all Loading... |
2217 receive_stream_params_[ssrc] = sp; | 2231 receive_stream_params_[ssrc] = sp; |
2218 AddAudioReceiveStream(ssrc); | 2232 AddAudioReceiveStream(ssrc); |
2219 | 2233 |
2220 LOG(LS_INFO) << "New audio stream " << ssrc | 2234 LOG(LS_INFO) << "New audio stream " << ssrc |
2221 << " registered to VoiceEngine channel #" | 2235 << " registered to VoiceEngine channel #" |
2222 << channel << "."; | 2236 << channel << "."; |
2223 return true; | 2237 return true; |
2224 } | 2238 } |
2225 | 2239 |
2226 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { | 2240 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { |
2227 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2241 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2228 | 2242 |
2229 int send_channel = GetSendChannelId(receiver_reports_ssrc_); | 2243 int send_channel = GetSendChannelId(receiver_reports_ssrc_); |
2230 if (send_channel != -1) { | 2244 if (send_channel != -1) { |
2231 // Associate receive channel with first send channel (so the receive channel | 2245 // Associate receive channel with first send channel (so the receive channel |
2232 // can obtain RTT from the send channel) | 2246 // can obtain RTT from the send channel) |
2233 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); | 2247 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); |
2234 LOG(LS_INFO) << "VoiceEngine channel #" << channel | 2248 LOG(LS_INFO) << "VoiceEngine channel #" << channel |
2235 << " is associated with channel #" << send_channel << "."; | 2249 << " is associated with channel #" << send_channel << "."; |
2236 } | 2250 } |
2237 if (engine()->voe()->rtp()->SetLocalSSRC(channel, | 2251 if (engine()->voe()->rtp()->SetLocalSSRC(channel, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2272 // Set RTP header extension for the new channel. | 2286 // Set RTP header extension for the new channel. |
2273 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { | 2287 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { |
2274 return false; | 2288 return false; |
2275 } | 2289 } |
2276 | 2290 |
2277 SetPlayout(channel, playout_); | 2291 SetPlayout(channel, playout_); |
2278 return true; | 2292 return true; |
2279 } | 2293 } |
2280 | 2294 |
2281 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { | 2295 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { |
2282 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2296 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2283 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 2297 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
2284 | 2298 |
2285 auto it = receive_channels_.find(ssrc); | 2299 auto it = receive_channels_.find(ssrc); |
2286 if (it == receive_channels_.end()) { | 2300 if (it == receive_channels_.end()) { |
2287 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2301 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2288 << " which doesn't exist."; | 2302 << " which doesn't exist."; |
2289 return false; | 2303 return false; |
2290 } | 2304 } |
2291 | 2305 |
2292 RemoveAudioReceiveStream(ssrc); | 2306 RemoveAudioReceiveStream(ssrc); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 it->second->Start(renderer); | 2338 it->second->Start(renderer); |
2325 } else { | 2339 } else { |
2326 it->second->Stop(); | 2340 it->second->Stop(); |
2327 } | 2341 } |
2328 | 2342 |
2329 return true; | 2343 return true; |
2330 } | 2344 } |
2331 | 2345 |
2332 bool WebRtcVoiceMediaChannel::GetActiveStreams( | 2346 bool WebRtcVoiceMediaChannel::GetActiveStreams( |
2333 AudioInfo::StreamList* actives) { | 2347 AudioInfo::StreamList* actives) { |
2334 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2348 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2335 actives->clear(); | 2349 actives->clear(); |
2336 for (const auto& ch : receive_channels_) { | 2350 for (const auto& ch : receive_channels_) { |
2337 int level = GetOutputLevel(ch.second->channel()); | 2351 int level = GetOutputLevel(ch.second->channel()); |
2338 if (level > 0) { | 2352 if (level > 0) { |
2339 actives->push_back(std::make_pair(ch.first, level)); | 2353 actives->push_back(std::make_pair(ch.first, level)); |
2340 } | 2354 } |
2341 } | 2355 } |
2342 return true; | 2356 return true; |
2343 } | 2357 } |
2344 | 2358 |
2345 int WebRtcVoiceMediaChannel::GetOutputLevel() { | 2359 int WebRtcVoiceMediaChannel::GetOutputLevel() { |
2346 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2360 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2347 int highest = 0; | 2361 int highest = 0; |
2348 for (const auto& ch : receive_channels_) { | 2362 for (const auto& ch : receive_channels_) { |
2349 highest = std::max(GetOutputLevel(ch.second->channel()), highest); | 2363 highest = std::max(GetOutputLevel(ch.second->channel()), highest); |
2350 } | 2364 } |
2351 return highest; | 2365 return highest; |
2352 } | 2366 } |
2353 | 2367 |
2354 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { | 2368 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { |
2355 int ret; | 2369 int ret; |
2356 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { | 2370 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { |
(...skipping 13 matching lines...) Expand all Loading... |
2370 time_window, cost_per_typing, | 2384 time_window, cost_per_typing, |
2371 reporting_threshold, penalty_decay, type_event_delay) == -1) { | 2385 reporting_threshold, penalty_decay, type_event_delay) == -1) { |
2372 // In case of error, log the info and continue | 2386 // In case of error, log the info and continue |
2373 LOG_RTCERR5(SetTypingDetectionParameters, time_window, | 2387 LOG_RTCERR5(SetTypingDetectionParameters, time_window, |
2374 cost_per_typing, reporting_threshold, penalty_decay, | 2388 cost_per_typing, reporting_threshold, penalty_decay, |
2375 type_event_delay); | 2389 type_event_delay); |
2376 } | 2390 } |
2377 } | 2391 } |
2378 | 2392 |
2379 bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { | 2393 bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { |
2380 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2394 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2381 if (ssrc == 0) { | 2395 if (ssrc == 0) { |
2382 default_recv_volume_ = volume; | 2396 default_recv_volume_ = volume; |
2383 if (default_recv_ssrc_ == -1) { | 2397 if (default_recv_ssrc_ == -1) { |
2384 return true; | 2398 return true; |
2385 } | 2399 } |
2386 ssrc = static_cast<uint32_t>(default_recv_ssrc_); | 2400 ssrc = static_cast<uint32_t>(default_recv_ssrc_); |
2387 } | 2401 } |
2388 int ch_id = GetReceiveChannelId(ssrc); | 2402 int ch_id = GetReceiveChannelId(ssrc); |
2389 if (ch_id < 0) { | 2403 if (ch_id < 0) { |
2390 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; | 2404 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; |
(...skipping 11 matching lines...) Expand all Loading... |
2402 } | 2416 } |
2403 | 2417 |
2404 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { | 2418 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { |
2405 return dtmf_allowed_; | 2419 return dtmf_allowed_; |
2406 } | 2420 } |
2407 | 2421 |
2408 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, | 2422 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, |
2409 int event, | 2423 int event, |
2410 int duration, | 2424 int duration, |
2411 int flags) { | 2425 int flags) { |
2412 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2426 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2413 if (!dtmf_allowed_) { | 2427 if (!dtmf_allowed_) { |
2414 return false; | 2428 return false; |
2415 } | 2429 } |
2416 | 2430 |
2417 // Send the event. | 2431 // Send the event. |
2418 if (flags & cricket::DF_SEND) { | 2432 if (flags & cricket::DF_SEND) { |
2419 int channel = -1; | 2433 int channel = -1; |
2420 if (ssrc == 0) { | 2434 if (ssrc == 0) { |
2421 if (send_streams_.size() > 0) { | 2435 if (send_streams_.size() > 0) { |
2422 channel = send_streams_.begin()->second->channel(); | 2436 channel = send_streams_.begin()->second->channel(); |
(...skipping 21 matching lines...) Expand all Loading... |
2444 LOG_RTCERR2(PlayDtmfTone, event, duration); | 2458 LOG_RTCERR2(PlayDtmfTone, event, duration); |
2445 return false; | 2459 return false; |
2446 } | 2460 } |
2447 } | 2461 } |
2448 | 2462 |
2449 return true; | 2463 return true; |
2450 } | 2464 } |
2451 | 2465 |
2452 void WebRtcVoiceMediaChannel::OnPacketReceived( | 2466 void WebRtcVoiceMediaChannel::OnPacketReceived( |
2453 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { | 2467 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { |
2454 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2468 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2455 | 2469 |
2456 uint32_t ssrc = 0; | 2470 uint32_t ssrc = 0; |
2457 if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { | 2471 if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { |
2458 return; | 2472 return; |
2459 } | 2473 } |
2460 | 2474 |
2461 if (receive_channels_.empty()) { | 2475 if (receive_channels_.empty()) { |
2462 // Create new channel, which will be the default receive channel. | 2476 // Create new channel, which will be the default receive channel. |
2463 StreamParams sp; | 2477 StreamParams sp; |
2464 sp.ssrcs.push_back(ssrc); | 2478 sp.ssrcs.push_back(ssrc); |
(...skipping 22 matching lines...) Expand all Loading... |
2487 int channel = GetReceiveChannelId(ssrc); | 2501 int channel = GetReceiveChannelId(ssrc); |
2488 RTC_DCHECK(channel != -1); | 2502 RTC_DCHECK(channel != -1); |
2489 | 2503 |
2490 // Pass it off to the decoder. | 2504 // Pass it off to the decoder. |
2491 engine()->voe()->network()->ReceivedRTPPacket( | 2505 engine()->voe()->network()->ReceivedRTPPacket( |
2492 channel, packet->data(), packet->size(), webrtc_packet_time); | 2506 channel, packet->data(), packet->size(), webrtc_packet_time); |
2493 } | 2507 } |
2494 | 2508 |
2495 void WebRtcVoiceMediaChannel::OnRtcpReceived( | 2509 void WebRtcVoiceMediaChannel::OnRtcpReceived( |
2496 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { | 2510 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { |
2497 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2511 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2498 | 2512 |
2499 // Forward packet to Call as well. | 2513 // Forward packet to Call as well. |
2500 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 2514 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
2501 packet_time.not_before); | 2515 packet_time.not_before); |
2502 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2516 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2503 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), | 2517 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), |
2504 webrtc_packet_time); | 2518 webrtc_packet_time); |
2505 | 2519 |
2506 // Sending channels need all RTCP packets with feedback information. | 2520 // Sending channels need all RTCP packets with feedback information. |
2507 // Even sender reports can contain attached report blocks. | 2521 // Even sender reports can contain attached report blocks. |
(...skipping 21 matching lines...) Expand all Loading... |
2529 // SR may continue RR and any RR entry may correspond to any one of the send | 2543 // SR may continue RR and any RR entry may correspond to any one of the send |
2530 // channels. So all RTCP packets must be forwarded all send channels. VoE | 2544 // channels. So all RTCP packets must be forwarded all send channels. VoE |
2531 // will filter out RR internally. | 2545 // will filter out RR internally. |
2532 for (const auto& ch : send_streams_) { | 2546 for (const auto& ch : send_streams_) { |
2533 engine()->voe()->network()->ReceivedRTCPPacket( | 2547 engine()->voe()->network()->ReceivedRTCPPacket( |
2534 ch.second->channel(), packet->data(), packet->size()); | 2548 ch.second->channel(), packet->data(), packet->size()); |
2535 } | 2549 } |
2536 } | 2550 } |
2537 | 2551 |
2538 bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) { | 2552 bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) { |
2539 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2553 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2540 int channel = GetSendChannelId(ssrc); | 2554 int channel = GetSendChannelId(ssrc); |
2541 if (channel == -1) { | 2555 if (channel == -1) { |
2542 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; | 2556 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; |
2543 return false; | 2557 return false; |
2544 } | 2558 } |
2545 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { | 2559 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { |
2546 LOG_RTCERR2(SetInputMute, channel, muted); | 2560 LOG_RTCERR2(SetInputMute, channel, muted); |
2547 return false; | 2561 return false; |
2548 } | 2562 } |
2549 // We set the AGC to mute state only when all the channels are muted. | 2563 // We set the AGC to mute state only when all the channels are muted. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2616 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 2630 LOG(LS_INFO) << "Failed to set codec " << codec.plname |
2617 << " to bitrate " << bps << " bps" | 2631 << " to bitrate " << bps << " bps" |
2618 << ", requires at least " << codec.rate << " bps."; | 2632 << ", requires at least " << codec.rate << " bps."; |
2619 return false; | 2633 return false; |
2620 } | 2634 } |
2621 return true; | 2635 return true; |
2622 } | 2636 } |
2623 } | 2637 } |
2624 | 2638 |
2625 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { | 2639 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { |
2626 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2640 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2627 RTC_DCHECK(info); | 2641 RTC_DCHECK(info); |
2628 | 2642 |
2629 // Get SSRC and stats for each sender. | 2643 // Get SSRC and stats for each sender. |
2630 RTC_DCHECK(info->senders.size() == 0); | 2644 RTC_DCHECK(info->senders.size() == 0); |
2631 for (const auto& stream : send_streams_) { | 2645 for (const auto& stream : send_streams_) { |
2632 webrtc::AudioSendStream::Stats stats = stream.second->GetStats(); | 2646 webrtc::AudioSendStream::Stats stats = stream.second->GetStats(); |
2633 VoiceSenderInfo sinfo; | 2647 VoiceSenderInfo sinfo; |
2634 sinfo.add_ssrc(stats.local_ssrc); | 2648 sinfo.add_ssrc(stats.local_ssrc); |
2635 sinfo.bytes_sent = stats.bytes_sent; | 2649 sinfo.bytes_sent = stats.bytes_sent; |
2636 sinfo.packets_sent = stats.packets_sent; | 2650 sinfo.packets_sent = stats.packets_sent; |
2637 sinfo.packets_lost = stats.packets_lost; | 2651 sinfo.packets_lost = stats.packets_lost; |
2638 sinfo.fraction_lost = stats.fraction_lost; | 2652 sinfo.fraction_lost = stats.fraction_lost; |
2639 sinfo.codec_name = stats.codec_name; | 2653 sinfo.codec_name = stats.codec_name; |
2640 sinfo.ext_seqnum = stats.ext_seqnum; | 2654 sinfo.ext_seqnum = stats.ext_seqnum; |
2641 sinfo.jitter_ms = stats.jitter_ms; | 2655 sinfo.jitter_ms = stats.jitter_ms; |
2642 sinfo.rtt_ms = stats.rtt_ms; | 2656 sinfo.rtt_ms = stats.rtt_ms; |
2643 sinfo.audio_level = stats.audio_level; | 2657 sinfo.audio_level = stats.audio_level; |
2644 sinfo.aec_quality_min = stats.aec_quality_min; | 2658 sinfo.aec_quality_min = stats.aec_quality_min; |
2645 sinfo.echo_delay_median_ms = stats.echo_delay_median_ms; | 2659 sinfo.echo_delay_median_ms = stats.echo_delay_median_ms; |
2646 sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; | 2660 sinfo.echo_delay_std_ms = stats.echo_delay_std_ms; |
2647 sinfo.echo_return_loss = stats.echo_return_loss; | 2661 sinfo.echo_return_loss = stats.echo_return_loss; |
2648 sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; | 2662 sinfo.echo_return_loss_enhancement = stats.echo_return_loss_enhancement; |
2649 sinfo.typing_noise_detected = typing_noise_detected_; | 2663 sinfo.typing_noise_detected = |
2650 // TODO(solenberg): Move to AudioSendStream. | 2664 (send_ == SEND_NOTHING ? false : stats.typing_noise_detected); |
2651 // sinfo.typing_noise_detected = stats.typing_noise_detected; | |
2652 info->senders.push_back(sinfo); | 2665 info->senders.push_back(sinfo); |
2653 } | 2666 } |
2654 | 2667 |
2655 // Get SSRC and stats for each receiver. | 2668 // Get SSRC and stats for each receiver. |
2656 RTC_DCHECK(info->receivers.size() == 0); | 2669 RTC_DCHECK(info->receivers.size() == 0); |
2657 for (const auto& stream : receive_streams_) { | 2670 for (const auto& stream : receive_streams_) { |
2658 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); | 2671 webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); |
2659 VoiceReceiverInfo rinfo; | 2672 VoiceReceiverInfo rinfo; |
2660 rinfo.add_ssrc(stats.remote_ssrc); | 2673 rinfo.add_ssrc(stats.remote_ssrc); |
2661 rinfo.bytes_rcvd = stats.bytes_rcvd; | 2674 rinfo.bytes_rcvd = stats.bytes_rcvd; |
(...skipping 19 matching lines...) Expand all Loading... |
2681 rinfo.decoding_plc = stats.decoding_plc; | 2694 rinfo.decoding_plc = stats.decoding_plc; |
2682 rinfo.decoding_cng = stats.decoding_cng; | 2695 rinfo.decoding_cng = stats.decoding_cng; |
2683 rinfo.decoding_plc_cng = stats.decoding_plc_cng; | 2696 rinfo.decoding_plc_cng = stats.decoding_plc_cng; |
2684 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; | 2697 rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms; |
2685 info->receivers.push_back(rinfo); | 2698 info->receivers.push_back(rinfo); |
2686 } | 2699 } |
2687 | 2700 |
2688 return true; | 2701 return true; |
2689 } | 2702 } |
2690 | 2703 |
2691 void WebRtcVoiceMediaChannel::OnError(int error) { | |
2692 if (send_ == SEND_NOTHING) { | |
2693 return; | |
2694 } | |
2695 if (error == VE_TYPING_NOISE_WARNING) { | |
2696 typing_noise_detected_ = true; | |
2697 } else if (error == VE_TYPING_NOISE_OFF_WARNING) { | |
2698 typing_noise_detected_ = false; | |
2699 } | |
2700 } | |
2701 | |
2702 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2704 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
2703 unsigned int ulevel = 0; | 2705 unsigned int ulevel = 0; |
2704 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 2706 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
2705 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2707 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
2706 } | 2708 } |
2707 | 2709 |
2708 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { | 2710 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const { |
2709 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2711 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2710 const auto it = receive_channels_.find(ssrc); | 2712 const auto it = receive_channels_.find(ssrc); |
2711 if (it != receive_channels_.end()) { | 2713 if (it != receive_channels_.end()) { |
2712 return it->second->channel(); | 2714 return it->second->channel(); |
2713 } | 2715 } |
2714 return -1; | 2716 return -1; |
2715 } | 2717 } |
2716 | 2718 |
2717 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { | 2719 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const { |
2718 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2720 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2719 const auto it = send_streams_.find(ssrc); | 2721 const auto it = send_streams_.find(ssrc); |
2720 if (it != send_streams_.end()) { | 2722 if (it != send_streams_.end()) { |
2721 return it->second->channel(); | 2723 return it->second->channel(); |
2722 } | 2724 } |
2723 return -1; | 2725 return -1; |
2724 } | 2726 } |
2725 | 2727 |
2726 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, | 2728 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, |
2727 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { | 2729 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { |
2728 // Get the RED encodings from the parameter with no name. This may | 2730 // Get the RED encodings from the parameter with no name. This may |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2774 LOG_RTCERR1(StartPlayout, channel); | 2776 LOG_RTCERR1(StartPlayout, channel); |
2775 return false; | 2777 return false; |
2776 } | 2778 } |
2777 } else { | 2779 } else { |
2778 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2780 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2779 engine()->voe()->base()->StopPlayout(channel); | 2781 engine()->voe()->base()->StopPlayout(channel); |
2780 } | 2782 } |
2781 return true; | 2783 return true; |
2782 } | 2784 } |
2783 | 2785 |
2784 // Convert VoiceEngine error code into VoiceMediaChannel::Error enum. | |
2785 VoiceMediaChannel::Error | |
2786 WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) { | |
2787 switch (err_code) { | |
2788 case 0: | |
2789 return ERROR_NONE; | |
2790 case VE_CANNOT_START_RECORDING: | |
2791 case VE_MIC_VOL_ERROR: | |
2792 case VE_GET_MIC_VOL_ERROR: | |
2793 case VE_CANNOT_ACCESS_MIC_VOL: | |
2794 return ERROR_REC_DEVICE_OPEN_FAILED; | |
2795 case VE_SATURATION_WARNING: | |
2796 return ERROR_REC_DEVICE_SATURATION; | |
2797 case VE_REC_DEVICE_REMOVED: | |
2798 return ERROR_REC_DEVICE_REMOVED; | |
2799 case VE_RUNTIME_REC_WARNING: | |
2800 case VE_RUNTIME_REC_ERROR: | |
2801 return ERROR_REC_RUNTIME_ERROR; | |
2802 case VE_CANNOT_START_PLAYOUT: | |
2803 case VE_SPEAKER_VOL_ERROR: | |
2804 case VE_GET_SPEAKER_VOL_ERROR: | |
2805 case VE_CANNOT_ACCESS_SPEAKER_VOL: | |
2806 return ERROR_PLAY_DEVICE_OPEN_FAILED; | |
2807 case VE_RUNTIME_PLAY_WARNING: | |
2808 case VE_RUNTIME_PLAY_ERROR: | |
2809 return ERROR_PLAY_RUNTIME_ERROR; | |
2810 case VE_TYPING_NOISE_WARNING: | |
2811 return ERROR_REC_TYPING_NOISE_DETECTED; | |
2812 default: | |
2813 return VoiceMediaChannel::ERROR_OTHER; | |
2814 } | |
2815 } | |
2816 | |
2817 bool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, | 2786 bool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, |
2818 int channel_id, const RtpHeaderExtension* extension) { | 2787 int channel_id, const RtpHeaderExtension* extension) { |
2819 bool enable = false; | 2788 bool enable = false; |
2820 int id = 0; | 2789 int id = 0; |
2821 std::string uri; | 2790 std::string uri; |
2822 if (extension) { | 2791 if (extension) { |
2823 enable = true; | 2792 enable = true; |
2824 id = extension->id; | 2793 id = extension->id; |
2825 uri = extension->uri; | 2794 uri = extension->uri; |
2826 } | 2795 } |
2827 if ((engine()->voe()->rtp()->*setter)(channel_id, enable, id) != 0) { | 2796 if ((engine()->voe()->rtp()->*setter)(channel_id, enable, id) != 0) { |
2828 LOG_RTCERR4(*setter, uri, channel_id, enable, id); | 2797 LOG_RTCERR4(*setter, uri, channel_id, enable, id); |
2829 return false; | 2798 return false; |
2830 } | 2799 } |
2831 return true; | 2800 return true; |
2832 } | 2801 } |
2833 | 2802 |
2834 void WebRtcVoiceMediaChannel::RecreateAudioReceiveStreams() { | 2803 void WebRtcVoiceMediaChannel::RecreateAudioReceiveStreams() { |
2835 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2804 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2836 for (const auto& it : receive_channels_) { | 2805 for (const auto& it : receive_channels_) { |
2837 RemoveAudioReceiveStream(it.first); | 2806 RemoveAudioReceiveStream(it.first); |
2838 } | 2807 } |
2839 for (const auto& it : receive_channels_) { | 2808 for (const auto& it : receive_channels_) { |
2840 AddAudioReceiveStream(it.first); | 2809 AddAudioReceiveStream(it.first); |
2841 } | 2810 } |
2842 } | 2811 } |
2843 | 2812 |
2844 void WebRtcVoiceMediaChannel::AddAudioReceiveStream(uint32_t ssrc) { | 2813 void WebRtcVoiceMediaChannel::AddAudioReceiveStream(uint32_t ssrc) { |
2845 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2814 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2846 WebRtcAudioReceiveStream* stream = receive_channels_[ssrc]; | 2815 WebRtcAudioReceiveStream* stream = receive_channels_[ssrc]; |
2847 RTC_DCHECK(stream != nullptr); | 2816 RTC_DCHECK(stream != nullptr); |
2848 RTC_DCHECK(receive_streams_.find(ssrc) == receive_streams_.end()); | 2817 RTC_DCHECK(receive_streams_.find(ssrc) == receive_streams_.end()); |
2849 webrtc::AudioReceiveStream::Config config; | 2818 webrtc::AudioReceiveStream::Config config; |
2850 config.rtp.remote_ssrc = ssrc; | 2819 config.rtp.remote_ssrc = ssrc; |
2851 // Only add RTP extensions if we support combined A/V BWE. | 2820 // Only add RTP extensions if we support combined A/V BWE. |
2852 config.rtp.extensions = recv_rtp_extensions_; | 2821 config.rtp.extensions = recv_rtp_extensions_; |
2853 config.combined_audio_video_bwe = | 2822 config.combined_audio_video_bwe = |
2854 options_.combined_audio_video_bwe.value_or(false); | 2823 options_.combined_audio_video_bwe.value_or(false); |
2855 config.voe_channel_id = stream->channel(); | 2824 config.voe_channel_id = stream->channel(); |
2856 config.sync_group = receive_stream_params_[ssrc].sync_label; | 2825 config.sync_group = receive_stream_params_[ssrc].sync_label; |
2857 webrtc::AudioReceiveStream* s = call_->CreateAudioReceiveStream(config); | 2826 webrtc::AudioReceiveStream* s = call_->CreateAudioReceiveStream(config); |
2858 receive_streams_.insert(std::make_pair(ssrc, s)); | 2827 receive_streams_.insert(std::make_pair(ssrc, s)); |
2859 } | 2828 } |
2860 | 2829 |
2861 void WebRtcVoiceMediaChannel::RemoveAudioReceiveStream(uint32_t ssrc) { | 2830 void WebRtcVoiceMediaChannel::RemoveAudioReceiveStream(uint32_t ssrc) { |
2862 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2831 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2863 auto stream_it = receive_streams_.find(ssrc); | 2832 auto stream_it = receive_streams_.find(ssrc); |
2864 if (stream_it != receive_streams_.end()) { | 2833 if (stream_it != receive_streams_.end()) { |
2865 call_->DestroyAudioReceiveStream(stream_it->second); | 2834 call_->DestroyAudioReceiveStream(stream_it->second); |
2866 receive_streams_.erase(stream_it); | 2835 receive_streams_.erase(stream_it); |
2867 } | 2836 } |
2868 } | 2837 } |
2869 | 2838 |
2870 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( | 2839 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( |
2871 const std::vector<AudioCodec>& new_codecs) { | 2840 const std::vector<AudioCodec>& new_codecs) { |
2872 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2841 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2873 for (const AudioCodec& codec : new_codecs) { | 2842 for (const AudioCodec& codec : new_codecs) { |
2874 webrtc::CodecInst voe_codec; | 2843 webrtc::CodecInst voe_codec; |
2875 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { | 2844 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
2876 LOG(LS_INFO) << ToString(codec); | 2845 LOG(LS_INFO) << ToString(codec); |
2877 voe_codec.pltype = codec.id; | 2846 voe_codec.pltype = codec.id; |
2878 for (const auto& ch : receive_channels_) { | 2847 for (const auto& ch : receive_channels_) { |
2879 if (engine()->voe()->codec()->SetRecPayloadType( | 2848 if (engine()->voe()->codec()->SetRecPayloadType( |
2880 ch.second->channel(), voe_codec) == -1) { | 2849 ch.second->channel(), voe_codec) == -1) { |
2881 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), | 2850 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), |
2882 ToString(voe_codec)); | 2851 ToString(voe_codec)); |
2883 return false; | 2852 return false; |
2884 } | 2853 } |
2885 } | 2854 } |
2886 } else { | 2855 } else { |
2887 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 2856 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
2888 return false; | 2857 return false; |
2889 } | 2858 } |
2890 } | 2859 } |
2891 return true; | 2860 return true; |
2892 } | 2861 } |
2893 | 2862 |
2894 } // namespace cricket | 2863 } // namespace cricket |
2895 | 2864 |
2896 #endif // HAVE_WEBRTC_VOICE | 2865 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |