| 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 |