| Index: talk/media/webrtc/webrtcvoiceengine.cc
|
| diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
|
| index fd0fc4be173e3300b2d37fd307a81aa6a73cdab0..0b5bed1623753545b2087a6c61f595ea52fcf7f4 100644
|
| --- a/talk/media/webrtc/webrtcvoiceengine.cc
|
| +++ b/talk/media/webrtc/webrtcvoiceengine.cc
|
| @@ -68,21 +68,12 @@ const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo |
|
| const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo |
|
| webrtc::kTraceInfo;
|
|
|
| -// For Linux/Mac, using the default device is done by specifying index 0 for
|
| -// VoE 4.0 and not -1 (which was the case for VoE 3.5).
|
| -//
|
| // On Windows Vista and newer, Microsoft introduced the concept of "Default
|
| // Communications Device". This means that there are two types of default
|
| // devices (old Wave Audio style default and Default Communications Device).
|
| //
|
| // On Windows systems which only support Wave Audio style default, uses either
|
| // -1 or 0 to select the default device.
|
| -//
|
| -// On Windows systems which support both "Default Communication Device" and
|
| -// old Wave Audio style default, use -1 for Default Communications Device and
|
| -// -2 for Wave Audio style default, which is what we want to use for clips.
|
| -// It's not clear yet whether the -2 index is handled properly on other OSes.
|
| -
|
| #ifdef WIN32
|
| const int kDefaultAudioDeviceId = -1;
|
| #else
|
| @@ -275,28 +266,6 @@ void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec,
|
| voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate);
|
| }
|
|
|
| -// Gets the default set of options applied to the engine. Historically, these
|
| -// were supplied as a combination of flags from the channel manager (ec, agc,
|
| -// ns, and highpass) and the rest hardcoded in InitInternal.
|
| -AudioOptions GetDefaultEngineOptions() {
|
| - AudioOptions options;
|
| - options.echo_cancellation = rtc::Optional<bool>(true);
|
| - options.auto_gain_control = rtc::Optional<bool>(true);
|
| - options.noise_suppression = rtc::Optional<bool>(true);
|
| - options.highpass_filter = rtc::Optional<bool>(true);
|
| - options.stereo_swapping = rtc::Optional<bool>(false);
|
| - options.audio_jitter_buffer_max_packets = rtc::Optional<int>(50);
|
| - options.audio_jitter_buffer_fast_accelerate = rtc::Optional<bool>(false);
|
| - options.typing_detection = rtc::Optional<bool>(true);
|
| - options.adjust_agc_delta = rtc::Optional<int>(0);
|
| - options.experimental_agc = rtc::Optional<bool>(false);
|
| - options.extended_filter_aec = rtc::Optional<bool>(false);
|
| - options.delay_agnostic_aec = rtc::Optional<bool>(false);
|
| - options.experimental_ns = rtc::Optional<bool>(false);
|
| - options.aec_dump = rtc::Optional<bool>(false);
|
| - return options;
|
| -}
|
| -
|
| webrtc::AudioState::Config MakeAudioStateConfig(VoEWrapper* voe_wrapper) {
|
| webrtc::AudioState::Config config;
|
| config.voice_engine = voe_wrapper->engine();
|
| @@ -510,15 +479,13 @@ void WebRtcVoiceEngine::Construct() {
|
|
|
| signal_thread_checker_.DetachFromThread();
|
| std::memset(&default_agc_config_, 0, sizeof(default_agc_config_));
|
| + voe_config_.Set<webrtc::VoicePacing>(new webrtc::VoicePacing(true));
|
|
|
| webrtc::Trace::set_level_filter(kDefaultTraceFilter);
|
| webrtc::Trace::SetTraceCallback(this);
|
|
|
| // Load our audio codec list.
|
| codecs_ = WebRtcVoiceCodecs::SupportedCodecs();
|
| -
|
| - options_ = GetDefaultEngineOptions();
|
| - voe_config_.Set<webrtc::VoicePacing>(new webrtc::VoicePacing(true));
|
| }
|
|
|
| WebRtcVoiceEngine::~WebRtcVoiceEngine() {
|
| @@ -558,25 +525,20 @@ bool WebRtcVoiceEngine::InitInternal() {
|
| webrtc::Trace::set_level_filter(kDefaultTraceFilter);
|
|
|
| // Save the default AGC configuration settings. This must happen before
|
| - // calling SetOptions or the default will be overwritten.
|
| + // calling ApplyOptions or the default will be overwritten.
|
| if (voe_wrapper_->processing()->GetAgcConfig(default_agc_config_) == -1) {
|
| LOG_RTCERR0(GetAgcConfig);
|
| return false;
|
| }
|
|
|
| - // Set defaults for options, so that ApplyOptions applies them explicitly
|
| - // when we clear option (channel) overrides. External clients can still
|
| - // modify the defaults via SetOptions (on the media engine).
|
| - if (!SetOptions(GetDefaultEngineOptions())) {
|
| - return false;
|
| - }
|
| -
|
| // Print our codec list again for the call diagnostic log
|
| LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
|
| for (const AudioCodec& codec : codecs_) {
|
| LOG(LS_INFO) << ToString(codec);
|
| }
|
|
|
| + SetDefaultDevices();
|
| +
|
| initialized_ = true;
|
| return true;
|
| }
|
| @@ -603,21 +565,30 @@ VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call,
|
| return new WebRtcVoiceMediaChannel(this, options, call);
|
| }
|
|
|
| -bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) {
|
| - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| - if (!ApplyOptions(options)) {
|
| - return false;
|
| - }
|
| - options_ = options;
|
| - return true;
|
| -}
|
| -
|
| -// AudioOptions defaults are set in InitInternal (for options with corresponding
|
| -// MediaEngineInterface flags) and in SetOptions(int) for flagless options.
|
| bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
|
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| LOG(LS_INFO) << "ApplyOptions: " << options_in.ToString();
|
| - AudioOptions options = options_in; // The options are modified below.
|
| +
|
| + // Default engine options.
|
| + AudioOptions options;
|
| + options.echo_cancellation = rtc::Optional<bool>(true);
|
| + options.auto_gain_control = rtc::Optional<bool>(true);
|
| + options.noise_suppression = rtc::Optional<bool>(true);
|
| + options.highpass_filter = rtc::Optional<bool>(true);
|
| + options.stereo_swapping = rtc::Optional<bool>(false);
|
| + options.audio_jitter_buffer_max_packets = rtc::Optional<int>(50);
|
| + options.audio_jitter_buffer_fast_accelerate = rtc::Optional<bool>(false);
|
| + options.typing_detection = rtc::Optional<bool>(true);
|
| + options.adjust_agc_delta = rtc::Optional<int>(0);
|
| + options.experimental_agc = rtc::Optional<bool>(false);
|
| + options.extended_filter_aec = rtc::Optional<bool>(false);
|
| + options.delay_agnostic_aec = rtc::Optional<bool>(false);
|
| + options.experimental_ns = rtc::Optional<bool>(false);
|
| + options.aec_dump = rtc::Optional<bool>(false);
|
| +
|
| + // Apply any given options on top.
|
| + options.SetAll(options_in);
|
| +
|
| // kEcConference is AEC with high suppression.
|
| webrtc::EcModes ec_mode = webrtc::kEcConference;
|
| webrtc::AecmModes aecm_mode = webrtc::kAecmSpeakerphone;
|
| @@ -887,149 +858,36 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
|
| return true;
|
| }
|
|
|
| -// TODO(juberti): Refactor this so that the core logic can be used to set the
|
| -// soundclip device. At that time, reinstate the soundclip pause/resume code.
|
| -bool WebRtcVoiceEngine::SetDevices(const Device* in_device,
|
| - const Device* out_device) {
|
| +void WebRtcVoiceEngine::SetDefaultDevices() {
|
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| #if !defined(IOS)
|
| - int in_id = in_device ? rtc::FromString<int>(in_device->id) :
|
| - kDefaultAudioDeviceId;
|
| - int out_id = out_device ? rtc::FromString<int>(out_device->id) :
|
| - kDefaultAudioDeviceId;
|
| - // The device manager uses -1 as the default device, which was the case for
|
| - // VoE 3.5. VoE 4.0, however, uses 0 as the default in Linux and Mac.
|
| -#ifndef WIN32
|
| - if (-1 == in_id) {
|
| - in_id = kDefaultAudioDeviceId;
|
| - }
|
| - if (-1 == out_id) {
|
| - out_id = kDefaultAudioDeviceId;
|
| - }
|
| -#endif
|
| + int in_id = kDefaultAudioDeviceId;
|
| + int out_id = kDefaultAudioDeviceId;
|
| + LOG(LS_INFO) << "Setting microphone to (id=" << in_id
|
| + << ") and speaker to (id=" << out_id << ")";
|
|
|
| - std::string in_name = (in_id != kDefaultAudioDeviceId) ?
|
| - in_device->name : "Default device";
|
| - std::string out_name = (out_id != kDefaultAudioDeviceId) ?
|
| - out_device->name : "Default device";
|
| - LOG(LS_INFO) << "Setting microphone to (id=" << in_id << ", name=" << in_name
|
| - << ") and speaker to (id=" << out_id << ", name=" << out_name
|
| - << ")";
|
| -
|
| - // Must also pause all audio playback and capture.
|
| bool ret = true;
|
| - for (WebRtcVoiceMediaChannel* channel : channels_) {
|
| - if (!channel->PausePlayout()) {
|
| - LOG(LS_WARNING) << "Failed to pause playout";
|
| - ret = false;
|
| - }
|
| - if (!channel->PauseSend()) {
|
| - LOG(LS_WARNING) << "Failed to pause send";
|
| - ret = false;
|
| - }
|
| - }
|
| -
|
| - // Find the recording device id in VoiceEngine and set recording device.
|
| - if (!FindWebRtcAudioDeviceId(true, in_name, in_id, &in_id)) {
|
| + if (voe_wrapper_->hw()->SetRecordingDevice(in_id) == -1) {
|
| + LOG_RTCERR1(SetRecordingDevice, in_id);
|
| ret = false;
|
| }
|
| - if (ret) {
|
| - if (voe_wrapper_->hw()->SetRecordingDevice(in_id) == -1) {
|
| - LOG_RTCERR2(SetRecordingDevice, in_name, in_id);
|
| - ret = false;
|
| - }
|
| - webrtc::AudioProcessing* ap = voe()->base()->audio_processing();
|
| - if (ap)
|
| - ap->Initialize();
|
| + webrtc::AudioProcessing* ap = voe()->base()->audio_processing();
|
| + if (ap) {
|
| + ap->Initialize();
|
| }
|
|
|
| - // Find the playout device id in VoiceEngine and set playout device.
|
| - if (!FindWebRtcAudioDeviceId(false, out_name, out_id, &out_id)) {
|
| - LOG(LS_WARNING) << "Failed to find VoiceEngine device id for " << out_name;
|
| + if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) {
|
| + LOG_RTCERR1(SetPlayoutDevice, out_id);
|
| ret = false;
|
| }
|
| - if (ret) {
|
| - if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) {
|
| - LOG_RTCERR2(SetPlayoutDevice, out_name, out_id);
|
| - ret = false;
|
| - }
|
| - }
|
| -
|
| - // Resume all audio playback and capture.
|
| - for (WebRtcVoiceMediaChannel* channel : channels_) {
|
| - if (!channel->ResumePlayout()) {
|
| - LOG(LS_WARNING) << "Failed to resume playout";
|
| - ret = false;
|
| - }
|
| - if (!channel->ResumeSend()) {
|
| - LOG(LS_WARNING) << "Failed to resume send";
|
| - ret = false;
|
| - }
|
| - }
|
|
|
| if (ret) {
|
| - LOG(LS_INFO) << "Set microphone to (id=" << in_id <<" name=" << in_name
|
| - << ") and speaker to (id="<< out_id << " name=" << out_name
|
| - << ")";
|
| + LOG(LS_INFO) << "Set microphone to (id=" << in_id
|
| + << ") and speaker to (id=" << out_id << ")";
|
| }
|
| -
|
| - return ret;
|
| -#else
|
| - return true;
|
| #endif // !IOS
|
| }
|
|
|
| -bool WebRtcVoiceEngine::FindWebRtcAudioDeviceId(
|
| - bool is_input, const std::string& dev_name, int dev_id, int* rtc_id) {
|
| - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| - // In Linux, VoiceEngine uses the same device dev_id as the device manager.
|
| -#if defined(LINUX) || defined(ANDROID)
|
| - *rtc_id = dev_id;
|
| - return true;
|
| -#else
|
| - // In Windows and Mac, we need to find the VoiceEngine device id by name
|
| - // unless the input dev_id is the default device id.
|
| - if (kDefaultAudioDeviceId == dev_id) {
|
| - *rtc_id = dev_id;
|
| - return true;
|
| - }
|
| -
|
| - // Get the number of VoiceEngine audio devices.
|
| - int count = 0;
|
| - if (is_input) {
|
| - if (-1 == voe_wrapper_->hw()->GetNumOfRecordingDevices(count)) {
|
| - LOG_RTCERR0(GetNumOfRecordingDevices);
|
| - return false;
|
| - }
|
| - } else {
|
| - if (-1 == voe_wrapper_->hw()->GetNumOfPlayoutDevices(count)) {
|
| - LOG_RTCERR0(GetNumOfPlayoutDevices);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - for (int i = 0; i < count; ++i) {
|
| - char name[128];
|
| - char guid[128];
|
| - if (is_input) {
|
| - voe_wrapper_->hw()->GetRecordingDeviceName(i, name, guid);
|
| - LOG(LS_VERBOSE) << "VoiceEngine microphone " << i << ": " << name;
|
| - } else {
|
| - voe_wrapper_->hw()->GetPlayoutDeviceName(i, name, guid);
|
| - LOG(LS_VERBOSE) << "VoiceEngine speaker " << i << ": " << name;
|
| - }
|
| -
|
| - std::string webrtc_name(name);
|
| - if (dev_name.compare(0, webrtc_name.size(), webrtc_name) == 0) {
|
| - *rtc_id = i;
|
| - return true;
|
| - }
|
| - }
|
| - LOG(LS_WARNING) << "VoiceEngine cannot find device: " << dev_name;
|
| - return false;
|
| -#endif
|
| -}
|
| -
|
| bool WebRtcVoiceEngine::GetOutputVolume(int* level) {
|
| RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
| unsigned int ulevel;
|
| @@ -1511,19 +1369,17 @@ bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) {
|
| // on top. This means there is no way to "clear" options such that
|
| // they go back to the engine default.
|
| options_.SetAll(options);
|
| -
|
| - if (send_ != SEND_NOTHING) {
|
| - if (!engine()->ApplyOptions(options_)) {
|
| - LOG(LS_WARNING) <<
|
| - "Failed to apply engine options during channel SetOptions.";
|
| - return false;
|
| - }
|
| + if (!engine()->ApplyOptions(options_)) {
|
| + LOG(LS_WARNING) <<
|
| + "Failed to apply engine options during channel SetOptions.";
|
| + return false;
|
| }
|
|
|
| if (dscp_option_changed) {
|
| rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT;
|
| - if (options_.dscp.value_or(false))
|
| + if (options_.dscp.value_or(false)) {
|
| dscp = kAudioDscpValue;
|
| + }
|
| if (MediaChannel::SetDscp(dscp) != 0) {
|
| LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel";
|
| }
|
| @@ -1921,7 +1777,7 @@ bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) {
|
| return true;
|
| }
|
|
|
| - // Apply channel specific options.
|
| + // Apply channel specific options when channel is enabled for sending.
|
| if (send == SEND_MICROPHONE) {
|
| engine()->ApplyOptions(options_);
|
| }
|
| @@ -1933,13 +1789,6 @@ bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) {
|
| }
|
| }
|
|
|
| - // Clear up the options after stopping sending. Since we may previously have
|
| - // applied the channel specific options, now apply the original options stored
|
| - // in WebRtcVoiceEngine.
|
| - if (send == SEND_NOTHING) {
|
| - engine()->ApplyOptions(engine()->GetOptions());
|
| - }
|
| -
|
| send_ = send;
|
| return true;
|
| }
|
|
|