Refactor handling of AudioOptions.

- Remove MediaEngineInterface::GetAudioOptions(), SetAudioOptions() and SetSoundDevices().
- Remove the WebRtcVoiceEngine infrastructure for those calls.

BUG=webrtc:4690
TBR=pthatcher@webrtc.org

Review URL: https://codereview.webrtc.org/1500633002

Cr-Commit-Position: refs/heads/master@{#10938}
This commit is contained in:
solenberg
2015-12-08 09:50:23 -08:00
committed by Commit bot
parent 8237abf563
commit 246b8171a6
9 changed files with 106 additions and 534 deletions

View File

@ -722,14 +722,6 @@ class FakeVoiceEngine : public FakeBaseEngine {
rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const {
return rtc::scoped_refptr<webrtc::AudioState>();
}
AudioOptions GetOptions() const {
return options_;
}
bool SetOptions(const AudioOptions& options) {
options_ = options;
options_changed_ = true;
return true;
}
VoiceMediaChannel* CreateChannel(webrtc::Call* call,
const AudioOptions& options) {
@ -751,21 +743,12 @@ class FakeVoiceEngine : public FakeBaseEngine {
const std::vector<AudioCodec>& codecs() { return codecs_; }
void SetCodecs(const std::vector<AudioCodec> codecs) { codecs_ = codecs; }
bool SetDevices(const Device* in_device, const Device* out_device) {
in_device_ = (in_device) ? in_device->name : "";
out_device_ = (out_device) ? out_device->name : "";
options_changed_ = true;
return true;
}
bool GetOutputVolume(int* level) {
*level = output_volume_;
return true;
}
bool SetOutputVolume(int level) {
output_volume_ = level;
options_changed_ = true;
return true;
}
@ -783,9 +766,6 @@ class FakeVoiceEngine : public FakeBaseEngine {
std::vector<FakeVoiceMediaChannel*> channels_;
std::vector<AudioCodec> codecs_;
int output_volume_;
std::string in_device_;
std::string out_device_;
AudioOptions options_;
friend class FakeMediaEngine;
};
@ -863,10 +843,7 @@ class FakeVideoEngine : public FakeBaseEngine {
class FakeMediaEngine :
public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> {
public:
FakeMediaEngine() {
voice_ = FakeVoiceEngine();
video_ = FakeVideoEngine();
}
FakeMediaEngine() {}
virtual ~FakeMediaEngine() {}
void SetAudioCodecs(const std::vector<AudioCodec>& codecs) {
@ -892,20 +869,16 @@ class FakeMediaEngine :
return video_.GetChannel(index);
}
AudioOptions audio_options() const { return voice_.options_; }
int output_volume() const { return voice_.output_volume_; }
const VideoEncoderConfig& default_video_encoder_config() const {
return video_.default_encoder_config_;
}
const std::string& audio_in_device() const { return voice_.in_device_; }
const std::string& audio_out_device() const { return voice_.out_device_; }
bool capture() const { return video_.capture_; }
bool options_changed() const {
return voice_.options_changed_ || video_.options_changed_;
return video_.options_changed_;
}
void clear_options_changed() {
video_.options_changed_ = false;
voice_.options_changed_ = false;
}
void set_fail_create_channel(bool fail) {
voice_.set_fail_create_channel(fail);

View File

@ -553,7 +553,6 @@ class MediaChannel : public sigslot::has_slots<> {
enum SendFlags {
SEND_NOTHING,
SEND_RINGBACKTONE,
SEND_MICROPHONE
};

View File

@ -88,20 +88,11 @@ class MediaEngineInterface {
webrtc::Call* call,
const VideoOptions& options) = 0;
// Configuration
// Gets global audio options.
virtual AudioOptions GetAudioOptions() const = 0;
// Sets global audio options. "options" are from AudioOptions, above.
virtual bool SetAudioOptions(const AudioOptions& options) = 0;
// Sets the default (maximum) codec/resolution and encoder option to capture
// and encode video.
virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config)
= 0;
// Device selection
virtual bool SetSoundDevices(const Device* in_device,
const Device* out_device) = 0;
// Device configuration
// Gets the current speaker volume, as a value between 0 and 255.
virtual bool GetOutputVolume(int* level) = 0;
@ -176,21 +167,10 @@ class CompositeMediaEngine : public MediaEngineInterface {
return video_.CreateChannel(call, options);
}
virtual AudioOptions GetAudioOptions() const {
return voice_.GetOptions();
}
virtual bool SetAudioOptions(const AudioOptions& options) {
return voice_.SetOptions(options);
}
virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
return video_.SetDefaultEncoderConfig(config);
}
virtual bool SetSoundDevices(const Device* in_device,
const Device* out_device) {
return voice_.SetDevices(in_device, out_device);
}
virtual bool GetOutputVolume(int* level) {
return voice_.GetOutputVolume(level);
}

View File

@ -46,15 +46,6 @@
namespace cricket {
static const char kFakeDefaultDeviceName[] = "Fake Default";
static const int kFakeDefaultDeviceId = -1;
static const char kFakeDeviceName[] = "Fake Device";
#ifdef WIN32
static const int kFakeDeviceId = 0;
#else
static const int kFakeDeviceId = 1;
#endif
static const int kOpusBandwidthNb = 4000;
static const int kOpusBandwidthMb = 6000;
static const int kOpusBandwidthWb = 8000;
@ -538,18 +529,10 @@ class FakeWebRtcVoiceEngine
}
// webrtc::VoEHardware
WEBRTC_FUNC(GetNumOfRecordingDevices, (int& num)) {
return GetNumDevices(num);
}
WEBRTC_FUNC(GetNumOfPlayoutDevices, (int& num)) {
return GetNumDevices(num);
}
WEBRTC_FUNC(GetRecordingDeviceName, (int i, char* name, char* guid)) {
return GetDeviceName(i, name, guid);
}
WEBRTC_FUNC(GetPlayoutDeviceName, (int i, char* name, char* guid)) {
return GetDeviceName(i, name, guid);
}
WEBRTC_STUB(GetNumOfRecordingDevices, (int& num));
WEBRTC_STUB(GetNumOfPlayoutDevices, (int& num));
WEBRTC_STUB(GetRecordingDeviceName, (int i, char* name, char* guid));
WEBRTC_STUB(GetPlayoutDeviceName, (int i, char* name, char* guid));
WEBRTC_STUB(SetRecordingDevice, (int, webrtc::StereoChannel));
WEBRTC_STUB(SetPlayoutDevice, (int));
WEBRTC_STUB(SetAudioDeviceLayer, (webrtc::AudioLayers));
@ -808,41 +791,6 @@ class FakeWebRtcVoiceEngine
}
private:
int GetNumDevices(int& num) {
#ifdef WIN32
num = 1;
#else
// On non-Windows platforms VE adds a special entry for the default device,
// so if there is one physical device then there are two entries in the
// list.
num = 2;
#endif
return 0;
}
int GetDeviceName(int i, char* name, char* guid) {
const char *s;
#ifdef WIN32
if (0 == i) {
s = kFakeDeviceName;
} else {
return -1;
}
#else
// See comment above.
if (0 == i) {
s = kFakeDefaultDeviceName;
} else if (1 == i) {
s = kFakeDeviceName;
} else {
return -1;
}
#endif
strcpy(name, s);
guid[0] = '\0';
return 0;
}
bool inited_;
int last_channel_;
std::map<int, Channel*> channels_;

View File

@ -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;
}

View File

@ -29,7 +29,6 @@
#define TALK_MEDIA_WEBRTCVOICEENGINE_H_
#include <map>
#include <set>
#include <string>
#include <vector>
@ -72,9 +71,6 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback {
VoiceMediaChannel* CreateChannel(webrtc::Call* call,
const AudioOptions& options);
AudioOptions GetOptions() const { return options_; }
bool SetOptions(const AudioOptions& options);
bool SetDevices(const Device* in_device, const Device* out_device);
bool GetOutputVolume(int* level);
bool SetOutputVolume(int level);
int GetInputLevel();
@ -118,15 +114,11 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback {
// ignored. This allows us to selectively turn on and off different options
// easily at any time.
bool ApplyOptions(const AudioOptions& options);
void SetDefaultDevices();
// webrtc::TraceCallback:
void Print(webrtc::TraceLevel level, const char* trace, int length) override;
// Given the device type, name, and id, find device id. Return true and
// set the output parameter rtc_id if successful.
bool FindWebRtcAudioDeviceId(
bool is_input, const std::string& dev_name, int dev_id, int* rtc_id);
void StartAecDump(const std::string& filename);
int CreateVoEChannel();
@ -138,16 +130,13 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback {
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
// The external audio device manager
webrtc::AudioDeviceModule* adm_ = nullptr;
bool is_dumping_aec_ = false;
std::vector<AudioCodec> codecs_;
std::vector<WebRtcVoiceMediaChannel*> channels_;
webrtc::AgcConfig default_agc_config_;
webrtc::Config voe_config_;
bool initialized_ = false;
AudioOptions options_;
bool is_dumping_aec_ = false;
webrtc::AgcConfig default_agc_config_;
// Cache received extended_filter_aec, delay_agnostic_aec and experimental_ns
// values, and apply them in case they are missing in the audio options. We
// need to do this because SetExtraOptions() will revert to defaults for

View File

@ -80,7 +80,6 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
channel_(nullptr) {
send_parameters_.codecs.push_back(kPcmuCodec);
recv_parameters_.codecs.push_back(kPcmuCodec);
options_adjust_agc_.adjust_agc_delta = rtc::Optional<int>(-10);
}
bool SetupEngine() {
if (!engine_.Init(rtc::Thread::Current())) {
@ -398,10 +397,8 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
cricket::FakeWebRtcVoiceEngine voe_;
cricket::WebRtcVoiceEngine engine_;
cricket::VoiceMediaChannel* channel_;
cricket::AudioSendParameters send_parameters_;
cricket::AudioRecvParameters recv_parameters_;
cricket::AudioOptions options_adjust_agc_;
};
// Tests that our stub library "works".
@ -2161,96 +2158,17 @@ TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
EXPECT_FALSE(voe_.GetPlayout(channel_num1));
}
// Test that we can set the devices to use.
TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
EXPECT_TRUE(SetupEngineWithSendStream());
int send_channel = voe_.GetLastChannel();
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
int recv_channel = voe_.GetLastChannel();
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
cricket::kFakeDefaultDeviceId);
cricket::Device dev(cricket::kFakeDeviceName,
cricket::kFakeDeviceId);
// Test SetDevices() while not sending or playing.
EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
// Test SetDevices() while sending and playing.
EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
EXPECT_TRUE(channel_->SetPlayout(true));
EXPECT_TRUE(voe_.GetSend(send_channel));
EXPECT_TRUE(voe_.GetPlayout(recv_channel));
EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
EXPECT_TRUE(voe_.GetSend(send_channel));
EXPECT_TRUE(voe_.GetPlayout(recv_channel));
// Test that failure to open newly selected devices does not prevent opening
// ones after that.
voe_.set_playout_fail_channel(recv_channel);
voe_.set_send_fail_channel(send_channel);
EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
EXPECT_FALSE(voe_.GetSend(send_channel));
EXPECT_FALSE(voe_.GetPlayout(recv_channel));
voe_.set_playout_fail_channel(-1);
voe_.set_send_fail_channel(-1);
EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
EXPECT_TRUE(voe_.GetSend(send_channel));
EXPECT_TRUE(voe_.GetPlayout(recv_channel));
}
// Test that we can set the devices to use even if we failed to
// open the initial ones.
TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
EXPECT_TRUE(SetupEngineWithSendStream());
int send_channel = voe_.GetLastChannel();
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
int recv_channel = voe_.GetLastChannel();
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
cricket::kFakeDefaultDeviceId);
cricket::Device dev(cricket::kFakeDeviceName,
cricket::kFakeDeviceId);
// Test that failure to open devices selected before starting
// send/play does not prevent opening newly selected ones after that.
voe_.set_playout_fail_channel(recv_channel);
voe_.set_send_fail_channel(send_channel);
EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
EXPECT_FALSE(channel_->SetPlayout(true));
EXPECT_FALSE(voe_.GetSend(send_channel));
EXPECT_FALSE(voe_.GetPlayout(recv_channel));
voe_.set_playout_fail_channel(-1);
voe_.set_send_fail_channel(-1);
EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
EXPECT_TRUE(voe_.GetSend(send_channel));
EXPECT_TRUE(voe_.GetPlayout(recv_channel));
}
// Test that we can create a channel configured for Codian bridges,
// and start sending on it.
TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
EXPECT_TRUE(SetupEngineWithSendStream());
cricket::AudioOptions options_adjust_agc;
options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
int channel_num = voe_.GetLastChannel();
webrtc::AgcConfig agc_config;
EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
EXPECT_EQ(0, agc_config.targetLeveldBOv);
send_parameters_.options = options_adjust_agc_;
send_parameters_.options = options_adjust_agc;
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
EXPECT_TRUE(voe_.GetSend(channel_num));
@ -2259,7 +2177,6 @@ TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
EXPECT_FALSE(voe_.GetSend(channel_num));
EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
}
TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
@ -2267,14 +2184,12 @@ TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
webrtc::AgcConfig agc_config;
EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
EXPECT_EQ(0, agc_config.targetLeveldBOv);
cricket::AudioOptions options;
options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
options.tx_agc_digital_compression_gain = rtc::Optional<uint16_t>(9);
options.tx_agc_limiter = rtc::Optional<bool>(true);
options.auto_gain_control = rtc::Optional<bool>(true);
EXPECT_TRUE(engine_.SetOptions(options));
send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
send_parameters_.options.tx_agc_digital_compression_gain =
rtc::Optional<uint16_t>(9);
send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
EXPECT_EQ(3, agc_config.targetLeveldBOv);
EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
@ -2282,19 +2197,18 @@ TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
// Check interaction with adjust_agc_delta. Both should be respected, for
// backwards compatibility.
options.adjust_agc_delta = rtc::Optional<int>(-10);
EXPECT_TRUE(engine_.SetOptions(options));
send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
EXPECT_EQ(13, agc_config.targetLeveldBOv);
}
TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
EXPECT_TRUE(SetupEngineWithSendStream());
cricket::AudioOptions options;
options.recording_sample_rate = rtc::Optional<uint32_t>(48000);
options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
EXPECT_TRUE(engine_.SetOptions(options));
send_parameters_.options.recording_sample_rate =
rtc::Optional<uint32_t>(48000);
send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
unsigned int recording_sample_rate, playout_sample_rate;
EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
@ -2638,10 +2552,12 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(typing_detection_enabled);
EXPECT_EQ(ec_mode, webrtc::kEcConference);
EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
EXPECT_EQ(50, voe_.GetNetEqCapacity());
EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
// Nothing set, so all ignored.
cricket::AudioOptions options;
ASSERT_TRUE(engine_.SetOptions(options));
// Nothing set in AudioOptions, so everything should be as default.
send_parameters_.options = cricket::AudioOptions();
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAecmMode(aecm_mode, cng_enabled);
voe_.GetAgcStatus(agc_enabled, agc_mode);
@ -2661,20 +2577,19 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(typing_detection_enabled);
EXPECT_EQ(ec_mode, webrtc::kEcConference);
EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
EXPECT_EQ(50, voe_.GetNetEqCapacity()); // From GetDefaultEngineOptions().
EXPECT_FALSE(
voe_.GetNetEqFastAccelerate()); // From GetDefaultEngineOptions().
EXPECT_EQ(50, voe_.GetNetEqCapacity());
EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
// Turn echo cancellation off
options.echo_cancellation = rtc::Optional<bool>(false);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
EXPECT_FALSE(ec_enabled);
// Turn echo cancellation back on, with settings, and make sure
// nothing else changed.
options.echo_cancellation = rtc::Optional<bool>(true);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAecmMode(aecm_mode, cng_enabled);
voe_.GetAgcStatus(agc_enabled, agc_mode);
@ -2696,8 +2611,8 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
// Turn on delay agnostic aec and make sure nothing change w.r.t. echo
// control.
options.delay_agnostic_aec = rtc::Optional<bool>(true);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAecmMode(aecm_mode, cng_enabled);
EXPECT_TRUE(ec_enabled);
@ -2705,41 +2620,41 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_EQ(ec_mode, webrtc::kEcConference);
// Turn off echo cancellation and delay agnostic aec.
options.delay_agnostic_aec = rtc::Optional<bool>(false);
options.extended_filter_aec = rtc::Optional<bool>(false);
options.echo_cancellation = rtc::Optional<bool>(false);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
EXPECT_FALSE(ec_enabled);
// Turning delay agnostic aec back on should also turn on echo cancellation.
options.delay_agnostic_aec = rtc::Optional<bool>(true);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
EXPECT_TRUE(ec_enabled);
EXPECT_TRUE(voe_.ec_metrics_enabled());
EXPECT_EQ(ec_mode, webrtc::kEcConference);
// Turn off AGC
options.auto_gain_control = rtc::Optional<bool>(false);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetAgcStatus(agc_enabled, agc_mode);
EXPECT_FALSE(agc_enabled);
// Turn AGC back on
options.auto_gain_control = rtc::Optional<bool>(true);
options.adjust_agc_delta = rtc::Optional<int>();
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetAgcStatus(agc_enabled, agc_mode);
EXPECT_TRUE(agc_enabled);
voe_.GetAgcConfig(agc_config);
EXPECT_EQ(0, agc_config.targetLeveldBOv);
// Turn off other options (and stereo swapping on).
options.noise_suppression = rtc::Optional<bool>(false);
options.highpass_filter = rtc::Optional<bool>(false);
options.typing_detection = rtc::Optional<bool>(false);
options.stereo_swapping = rtc::Optional<bool>(true);
ASSERT_TRUE(engine_.SetOptions(options));
send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetNsStatus(ns_enabled, ns_mode);
highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
@ -2750,7 +2665,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(stereo_swapping_enabled);
// Set options again to ensure it has no impact.
ASSERT_TRUE(engine_.SetOptions(options));
EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetNsStatus(ns_enabled, ns_mode);
EXPECT_TRUE(ec_enabled);
@ -2850,7 +2765,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
expected_options.noise_suppression = rtc::Optional<bool>(true);
EXPECT_EQ(expected_options, channel2->options());
ASSERT_TRUE(engine_.SetOptions(parameters_options_all.options));
ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
bool ec_enabled;
webrtc::EcModes ec_mode;
bool agc_enabled;
@ -2872,14 +2787,6 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
EXPECT_TRUE(agc_enabled);
EXPECT_FALSE(ns_enabled);
channel1->SetSend(cricket::SEND_NOTHING);
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAgcStatus(agc_enabled, agc_mode);
voe_.GetNsStatus(ns_enabled, ns_mode);
EXPECT_TRUE(ec_enabled);
EXPECT_TRUE(agc_enabled);
EXPECT_TRUE(ns_enabled);
channel2->SetSend(cricket::SEND_MICROPHONE);
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAgcStatus(agc_enabled, agc_mode);
@ -2888,16 +2795,8 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
EXPECT_FALSE(agc_enabled);
EXPECT_TRUE(ns_enabled);
channel2->SetSend(cricket::SEND_NOTHING);
voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAgcStatus(agc_enabled, agc_mode);
voe_.GetNsStatus(ns_enabled, ns_mode);
EXPECT_TRUE(ec_enabled);
EXPECT_TRUE(agc_enabled);
EXPECT_TRUE(ns_enabled);
// Make sure settings take effect while we are sending.
ASSERT_TRUE(engine_.SetOptions(parameters_options_all.options));
ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
send_parameters_;
parameters_options_no_agc_nor_ns.options.auto_gain_control =
@ -3072,13 +2971,12 @@ TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
static const uint32_t kSsrcs[] = {1, 2, 3, 4};
for (unsigned int i = 0; i < arraysize(kSsrcs); ++i) {
for (uint32_t ssrc : kSsrcs4) {
EXPECT_TRUE(media_channel->AddRecvStream(
cricket::StreamParams::CreateLegacy(kSsrcs[i])));
EXPECT_NE(nullptr, call_.GetAudioReceiveStream(kSsrcs[i]));
cricket::StreamParams::CreateLegacy(ssrc)));
EXPECT_NE(nullptr, call_.GetAudioReceiveStream(ssrc));
}
EXPECT_EQ(arraysize(kSsrcs), call_.GetAudioReceiveStreams().size());
EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioReceiveStreams().size());
}
// TODO(solenberg): Remove, once recv streams are configured through Call.
@ -3207,18 +3105,6 @@ TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
}
// Tests for the actual WebRtc VoE library.
TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
cricket::WebRtcVoiceEngine engine;
cricket::AudioOptions options = engine.GetOptions();
// The default options should have at least a few things set. We purposefully
// don't check the option values here, though.
EXPECT_TRUE(options.echo_cancellation);
EXPECT_TRUE(options.auto_gain_control);
EXPECT_TRUE(options.noise_suppression);
}
// Tests that the library initializes and shuts down properly.
TEST(WebRtcVoiceEngineTest, StartupShutdown) {
cricket::WebRtcVoiceEngine engine;

View File

@ -101,8 +101,6 @@ void ChannelManager::Construct(MediaEngineInterface* me,
initialized_ = false;
main_thread_ = rtc::Thread::Current();
worker_thread_ = worker_thread;
// Get the default audio options from the media engine.
audio_options_ = media_engine_->GetAudioOptions();
audio_output_volume_ = kNotSetOutputVolume;
local_renderer_ = NULL;
capturing_ = false;
@ -205,11 +203,6 @@ bool ChannelManager::Init() {
return false;
}
if (!SetAudioOptions(audio_options_)) {
LOG(LS_WARNING) << "Failed to SetAudioOptions with options: "
<< audio_options_.ToString();
}
// If audio_output_volume_ has been set via SetOutputVolume(), set the
// audio output volume of the engine.
if (kNotSetOutputVolume != audio_output_volume_ &&
@ -427,43 +420,6 @@ void ChannelManager::DestroyDataChannel_w(DataChannel* data_channel) {
delete data_channel;
}
bool ChannelManager::SetAudioOptions(const AudioOptions& options) {
// "Get device ids from DeviceManager" - these are the defaults returned.
Device in_dev("", -1);
Device out_dev("", -1);
// If we're initialized, pass the settings to the media engine.
bool ret = true;
if (initialized_) {
ret = worker_thread_->Invoke<bool>(
Bind(&ChannelManager::SetAudioOptions_w, this,
options, &in_dev, &out_dev));
}
// If all worked well, save the values for use in GetAudioOptions.
if (ret) {
audio_options_ = options;
}
return ret;
}
bool ChannelManager::SetAudioOptions_w(
const AudioOptions& options,
const Device* in_dev, const Device* out_dev) {
ASSERT(worker_thread_ == rtc::Thread::Current());
ASSERT(initialized_);
// Set audio options
bool ret = media_engine_->SetAudioOptions(options);
// Set the audio devices
if (ret) {
ret = media_engine_->SetSoundDevices(in_dev, out_dev);
}
return ret;
}
bool ChannelManager::GetOutputVolume(int* level) {
if (!initialized_) {
return false;

View File

@ -177,11 +177,6 @@ class ChannelManager : public rtc::MessageHandler,
sigslot::signal2<VideoCapturer*, CaptureState> SignalVideoCaptureStateChange;
protected:
// Adds non-transient parameters which can only be changed through the
// options store.
bool SetAudioOptions(const AudioOptions& options);
private:
typedef std::vector<VoiceChannel*> VoiceChannels;
typedef std::vector<VideoChannel*> VideoChannels;
@ -213,8 +208,6 @@ class ChannelManager : public rtc::MessageHandler,
bool rtcp,
DataChannelType data_channel_type);
void DestroyDataChannel_w(DataChannel* data_channel);
bool SetAudioOptions_w(const AudioOptions& options,
const Device* in_dev, const Device* out_dev);
void OnVideoCaptureStateChange(VideoCapturer* capturer,
CaptureState result);
void GetSupportedFormats_w(
@ -234,7 +227,6 @@ class ChannelManager : public rtc::MessageHandler,
VideoChannels video_channels_;
DataChannels data_channels_;
AudioOptions audio_options_;
int audio_output_volume_;
VideoEncoderConfig default_video_encoder_config_;
VideoRenderer* local_renderer_;