Commit 5dade9ff authored by Per Åhgren's avatar Per Åhgren Committed by Commit Bot

CRAS System AEC: Add support for using AEC group ID in AEC selection

This CL adds the functionality to have an aec group ID, which allow
Chromium to take actions that is specific for the echo canceller
parameter set that is being used in the Chrome Audio Server.

BUG=chromium:907917
CQ-DEPEND=CL:1349280,CL:1349353

Change-Id: I391fd0a65858a2635c8927dc2a8816dfb9cd4221
Reviewed-on: https://chromium-review.googlesource.com/c/1349260Reviewed-by: default avatarJenny Zhang <jennyz@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarMax Morin <maxmorin@chromium.org>
Commit-Queue: Per Åhgren <peah@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612852}
parent 5ed82cdb
...@@ -911,6 +911,7 @@ void CrasAudioHandler::InitializeAudioAfterCrasServiceAvailable( ...@@ -911,6 +911,7 @@ void CrasAudioHandler::InitializeAudioAfterCrasServiceAvailable(
cras_service_available_ = true; cras_service_available_ = true;
GetDefaultOutputBufferSizeInternal(); GetDefaultOutputBufferSizeInternal();
GetSystemAecSupported(); GetSystemAecSupported();
GetSystemAecGroupId();
GetNodes(); GetNodes();
GetNumberOfOutputStreams(); GetNumberOfOutputStreams();
} }
...@@ -1700,4 +1701,29 @@ void CrasAudioHandler::HandleGetSystemAecSupported( ...@@ -1700,4 +1701,29 @@ void CrasAudioHandler::HandleGetSystemAecSupported(
system_aec_supported_ = system_aec_supported.value(); system_aec_supported_ = system_aec_supported.value();
} }
int32_t CrasAudioHandler::system_aec_group_id() const {
DCHECK(main_task_runner_->BelongsToCurrentThread());
return system_aec_group_id_;
}
// GetSystemAecGroupId() is only called in the same thread
// as the CrasAudioHanler constructor. We are safe here without
// thread check, because unittest may not have the task runner
// for the current thread.
void CrasAudioHandler::GetSystemAecGroupId() {
GetCrasAudioClient()->GetSystemAecGroupId(
base::BindOnce(&CrasAudioHandler::HandleGetSystemAecGroupId,
weak_ptr_factory_.GetWeakPtr()));
}
void CrasAudioHandler::HandleGetSystemAecGroupId(
base::Optional<int32_t> system_aec_group_id) {
if (!system_aec_group_id.has_value()) {
// If the group Id is not available, set the ID to reflect that.
system_aec_group_id_ = kSystemAecGroupIdNotAvailable;
return;
}
system_aec_group_id_ = system_aec_group_id.value();
}
} // namespace chromeos } // namespace chromeos
...@@ -44,6 +44,7 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -44,6 +44,7 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
priority_queue<AudioDevice, std::vector<AudioDevice>, AudioDeviceCompare> priority_queue<AudioDevice, std::vector<AudioDevice>, AudioDeviceCompare>
AudioDevicePriorityQueue; AudioDevicePriorityQueue;
typedef std::vector<uint64_t> NodeIdList; typedef std::vector<uint64_t> NodeIdList;
static constexpr int32_t kSystemAecGroupIdNotAvailable = -1;
class AudioObserver { class AudioObserver {
public: public:
...@@ -277,6 +278,10 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -277,6 +278,10 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Returns if system AEC is supported in CRAS. // Returns if system AEC is supported in CRAS.
bool system_aec_supported() const; bool system_aec_supported() const;
// Returns the system AEC group ID. If no group ID is specified, -1 is
// returned.
int32_t system_aec_group_id() const;
protected: protected:
explicit CrasAudioHandler( explicit CrasAudioHandler(
scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler);
...@@ -487,6 +492,15 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -487,6 +492,15 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
// Handle dbus callback for GetSystemAecSupported. // Handle dbus callback for GetSystemAecSupported.
void HandleGetSystemAecSupported(base::Optional<bool> system_aec_supported); void HandleGetSystemAecSupported(base::Optional<bool> system_aec_supported);
// Calling dbus to get the system AEC group id if available.
void GetSystemAecGroupId();
// Calling dbus to get any available system AEC group id on main thread.
void GetSystemAecGroupIdOnMainThread();
// Handle dbus callback for GetSystemAecGroupId.
void HandleGetSystemAecGroupId(base::Optional<int32_t> system_aec_group_id);
void OnVideoCaptureStartedOnMainThread(media::VideoFacingMode facing); void OnVideoCaptureStartedOnMainThread(media::VideoFacingMode facing);
void OnVideoCaptureStoppedOnMainThread(media::VideoFacingMode facing); void OnVideoCaptureStoppedOnMainThread(media::VideoFacingMode facing);
...@@ -534,6 +548,7 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -534,6 +548,7 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
int32_t default_output_buffer_size_; int32_t default_output_buffer_size_;
bool system_aec_supported_ = false; bool system_aec_supported_ = false;
int32_t system_aec_group_id_ = kSystemAecGroupIdNotAvailable;
int num_active_output_streams_ = 0; int num_active_output_streams_ = 0;
......
...@@ -68,6 +68,16 @@ class CrasAudioClientImpl : public CrasAudioClient { ...@@ -68,6 +68,16 @@ class CrasAudioClientImpl : public CrasAudioClient {
weak_ptr_factory_.GetWeakPtr(), std::move(callback))); weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
} }
void GetSystemAecGroupId(DBusMethodCallback<int32_t> callback) override {
dbus::MethodCall method_call(cras::kCrasControlInterface,
cras::kGetSystemAecGroupId);
cras_proxy_->CallMethod(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::BindOnce(&CrasAudioClientImpl::OnGetSystemAecGroupId,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void GetNodes(DBusMethodCallback<AudioNodeList> callback) override { void GetNodes(DBusMethodCallback<AudioNodeList> callback) override {
dbus::MethodCall method_call(cras::kCrasControlInterface, dbus::MethodCall method_call(cras::kCrasControlInterface,
cras::kGetNodes); cras::kGetNodes);
...@@ -462,6 +472,25 @@ class CrasAudioClientImpl : public CrasAudioClient { ...@@ -462,6 +472,25 @@ class CrasAudioClientImpl : public CrasAudioClient {
std::move(callback).Run(system_aec_supported); std::move(callback).Run(system_aec_supported);
} }
void OnGetSystemAecGroupId(DBusMethodCallback<int32_t> callback,
dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Error calling " << cras::kGetSystemAecGroupId;
std::move(callback).Run(base::nullopt);
return;
}
int32_t system_aec_group_id = 0;
dbus::MessageReader reader(response);
if (!reader.PopInt32(&system_aec_group_id)) {
LOG(ERROR) << "Error reading response from cras: "
<< response->ToString();
std::move(callback).Run(base::nullopt);
return;
}
std::move(callback).Run(system_aec_group_id);
}
void OnGetNodes(DBusMethodCallback<AudioNodeList> callback, void OnGetNodes(DBusMethodCallback<AudioNodeList> callback,
dbus::Response* response) { dbus::Response* response) {
if (!response) { if (!response) {
......
...@@ -76,6 +76,9 @@ class CHROMEOS_EXPORT CrasAudioClient : public DBusClient { ...@@ -76,6 +76,9 @@ class CHROMEOS_EXPORT CrasAudioClient : public DBusClient {
// Gets if system AEC is supported. // Gets if system AEC is supported.
virtual void GetSystemAecSupported(DBusMethodCallback<bool> callback) = 0; virtual void GetSystemAecSupported(DBusMethodCallback<bool> callback) = 0;
// Gets any available group ID for the system AEC
virtual void GetSystemAecGroupId(DBusMethodCallback<int32_t> callback) = 0;
// Gets an array of audio input and output nodes. // Gets an array of audio input and output nodes.
virtual void GetNodes(DBusMethodCallback<AudioNodeList> callback) = 0; virtual void GetNodes(DBusMethodCallback<AudioNodeList> callback) = 0;
......
...@@ -111,6 +111,11 @@ void FakeCrasAudioClient::GetSystemAecSupported( ...@@ -111,6 +111,11 @@ void FakeCrasAudioClient::GetSystemAecSupported(
std::move(callback).Run(false); std::move(callback).Run(false);
} }
void FakeCrasAudioClient::GetSystemAecGroupId(
DBusMethodCallback<int32_t> callback) {
std::move(callback).Run(1);
}
void FakeCrasAudioClient::GetNodes(DBusMethodCallback<AudioNodeList> callback) { void FakeCrasAudioClient::GetNodes(DBusMethodCallback<AudioNodeList> callback) {
std::move(callback).Run(node_list_); std::move(callback).Run(node_list_);
} }
......
...@@ -29,6 +29,7 @@ class CHROMEOS_EXPORT FakeCrasAudioClient : public CrasAudioClient { ...@@ -29,6 +29,7 @@ class CHROMEOS_EXPORT FakeCrasAudioClient : public CrasAudioClient {
void GetVolumeState(DBusMethodCallback<VolumeState> callback) override; void GetVolumeState(DBusMethodCallback<VolumeState> callback) override;
void GetDefaultOutputBufferSize(DBusMethodCallback<int> callback) override; void GetDefaultOutputBufferSize(DBusMethodCallback<int> callback) override;
void GetSystemAecSupported(DBusMethodCallback<bool> callback) override; void GetSystemAecSupported(DBusMethodCallback<bool> callback) override;
void GetSystemAecGroupId(DBusMethodCallback<int32_t> callback) override;
void GetNodes(DBusMethodCallback<AudioNodeList> callback) override; void GetNodes(DBusMethodCallback<AudioNodeList> callback) override;
void GetNumberOfActiveOutputStreams( void GetNumberOfActiveOutputStreams(
DBusMethodCallback<int> callback) override; DBusMethodCallback<int> callback) override;
......
...@@ -13,6 +13,8 @@ const base::Feature kEnumerateAudioDevices{"EnumerateAudioDevices", ...@@ -13,6 +13,8 @@ const base::Feature kEnumerateAudioDevices{"EnumerateAudioDevices",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kCrOSSystemAEC{"CrOSSystemAEC", const base::Feature kCrOSSystemAEC{"CrOSSystemAEC",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kCrOSSystemAECDeactivatedGroups{
"CrOSSystemAECDeactivatedGroups", base::FEATURE_ENABLED_BY_DEFAULT};
#endif #endif
#if defined(OS_WIN) #if defined(OS_WIN)
......
...@@ -14,6 +14,7 @@ namespace features { ...@@ -14,6 +14,7 @@ namespace features {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
MEDIA_EXPORT extern const base::Feature kEnumerateAudioDevices; MEDIA_EXPORT extern const base::Feature kEnumerateAudioDevices;
MEDIA_EXPORT extern const base::Feature kCrOSSystemAEC; MEDIA_EXPORT extern const base::Feature kCrOSSystemAEC;
MEDIA_EXPORT extern const base::Feature kCrOSSystemAECDeactivatedGroups;
#endif #endif
#if defined(OS_WIN) #if defined(OS_WIN)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/environment.h" #include "base/environment.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/field_trial_params.h"
#include "base/nix/xdg_util.h" #include "base/nix/xdg_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -192,9 +193,21 @@ AudioParameters AudioManagerCras::GetInputStreamParameters( ...@@ -192,9 +193,21 @@ AudioParameters AudioManagerCras::GetInputStreamParameters(
// but enable it by default on devices that actually support it. // but enable it by default on devices that actually support it.
params.set_effects(params.effects() | params.set_effects(params.effects() |
AudioParameters::EXPERIMENTAL_ECHO_CANCELLER); AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
if (base::FeatureList::IsEnabled(features::kCrOSSystemAEC) && if (base::FeatureList::IsEnabled(features::kCrOSSystemAEC)) {
GetSystemAecSupportedPerBoard()) { if (GetSystemAecSupportedPerBoard()) {
params.set_effects(params.effects() | AudioParameters::ECHO_CANCELLER); const int32_t aec_group_id = GetSystemAecGroupIdPerBoard();
// Check if the system AEC has a group ID which is flagged to be
// deactivated by the field trial.
const bool system_aec_deactivated =
base::GetFieldTrialParamByFeatureAsBool(
features::kCrOSSystemAECDeactivatedGroups,
std::to_string(aec_group_id), false);
if (!system_aec_deactivated) {
params.set_effects(params.effects() | AudioParameters::ECHO_CANCELLER);
}
}
} }
return params; return params;
...@@ -342,6 +355,27 @@ bool AudioManagerCras::GetSystemAecSupportedPerBoard() { ...@@ -342,6 +355,27 @@ bool AudioManagerCras::GetSystemAecSupportedPerBoard() {
return system_aec_supported; return system_aec_supported;
} }
int32_t AudioManagerCras::GetSystemAecGroupIdPerBoard() {
DCHECK(GetTaskRunner()->BelongsToCurrentThread());
int32_t group_id = chromeos::CrasAudioHandler::kSystemAecGroupIdNotAvailable;
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
if (main_task_runner_->BelongsToCurrentThread()) {
// Unittest may use the same thread for audio thread.
GetSystemAecGroupIdOnMainThread(&group_id, &event);
} else {
// Using base::Unretained is safe here because we wait for callback be
// executed in main thread before local variables are destructed.
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AudioManagerCras::GetSystemAecGroupIdOnMainThread,
weak_this_, base::Unretained(&group_id),
base::Unretained(&event)));
}
WaitEventOrShutdown(&event);
return group_id;
}
AudioParameters AudioManagerCras::GetPreferredOutputStreamParameters( AudioParameters AudioManagerCras::GetPreferredOutputStreamParameters(
const std::string& output_device_id, const std::string& output_device_id,
const AudioParameters& input_params) { const AudioParameters& input_params) {
...@@ -514,6 +548,16 @@ void AudioManagerCras::GetSystemAecSupportedOnMainThread( ...@@ -514,6 +548,16 @@ void AudioManagerCras::GetSystemAecSupportedOnMainThread(
event->Signal(); event->Signal();
} }
void AudioManagerCras::GetSystemAecGroupIdOnMainThread(
int32_t* group_id,
base::WaitableEvent* event) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
if (chromeos::CrasAudioHandler::IsInitialized()) {
*group_id = chromeos::CrasAudioHandler::Get()->system_aec_group_id();
}
event->Signal();
}
void AudioManagerCras::WaitEventOrShutdown(base::WaitableEvent* event) { void AudioManagerCras::WaitEventOrShutdown(base::WaitableEvent* event) {
base::WaitableEvent* waitables[] = {event, &on_shutdown_}; base::WaitableEvent* waitables[] = {event, &on_shutdown_};
base::WaitableEvent::WaitMany(waitables, arraysize(waitables)); base::WaitableEvent::WaitMany(waitables, arraysize(waitables));
......
...@@ -82,6 +82,9 @@ class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase { ...@@ -82,6 +82,9 @@ class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase {
// Get if system AEC is supported or not for this board. // Get if system AEC is supported or not for this board.
bool GetSystemAecSupportedPerBoard(); bool GetSystemAecSupportedPerBoard();
// Get what the system AEC group ID is for this board.
int32_t GetSystemAecGroupIdPerBoard();
void GetAudioDeviceNamesImpl(bool is_input, AudioDeviceNames* device_names); void GetAudioDeviceNamesImpl(bool is_input, AudioDeviceNames* device_names);
std::string GetHardwareDeviceFromDeviceId( std::string GetHardwareDeviceFromDeviceId(
...@@ -102,6 +105,8 @@ class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase { ...@@ -102,6 +105,8 @@ class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase {
base::WaitableEvent* event); base::WaitableEvent* event);
void GetSystemAecSupportedOnMainThread(bool* system_aec_supported, void GetSystemAecSupportedOnMainThread(bool* system_aec_supported,
base::WaitableEvent* event); base::WaitableEvent* event);
void GetSystemAecGroupIdOnMainThread(int32_t* group_id,
base::WaitableEvent* event);
void WaitEventOrShutdown(base::WaitableEvent* event); void WaitEventOrShutdown(base::WaitableEvent* event);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment