Commit 1ac1dd54 authored by Oskar Sundbom's avatar Oskar Sundbom Committed by Commit Bot

Win AEC: Handle SetOutputDeviceForAec being called before Start()

When using APM in Audio Service, the output device for a microphone
with native echo cancellation support may be set before the stream
has started. For the Windows AEC implementation, this would start
the dummy output stream, which is used to ensure a continuous
reverse stream, too early.

Bug: 882420
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I1121cc4b35a0457f006326dfc0340379f9a0e091
Reviewed-on: https://chromium-review.googlesource.com/1243088
Commit-Queue: Oskar Sundbom <ossu@chromium.org>
Reviewed-by: default avatarHenrik Grunell <grunell@chromium.org>
Reviewed-by: default avatarOlga Sharonova <olka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594685}
parent a34b19ef
......@@ -532,38 +532,44 @@ void WASAPIAudioInputStream::SetOutputDeviceForAec(
output_device_id_for_aec_ = output_device_id;
// Set devices.
Microsoft::WRL::ComPtr<IPropertyStore> ps;
HRESULT hr = voice_capture_dmo_->QueryInterface(IID_IPropertyStore, &ps);
if (FAILED(hr) || !ps) {
log_callback_.Run(base::StringPrintf(
"WASAPIAIS:SetOutputDeviceForAec: Getting DMO property store failed."));
return;
}
if (opened_) {
// Set devices.
Microsoft::WRL::ComPtr<IPropertyStore> ps;
HRESULT hr = voice_capture_dmo_->QueryInterface(IID_IPropertyStore, &ps);
if (FAILED(hr) || !ps) {
log_callback_.Run(
base::StringPrintf("WASAPIAIS:SetOutputDeviceForAec: Getting DMO "
"property store failed."));
return;
}
if (!SetDmoDevices(ps.Get())) {
log_callback_.Run(
"WASAPIAIS:SetOutputDeviceForAec: Setting device indices failed.");
return;
if (!SetDmoDevices(ps.Get())) {
log_callback_.Run(
"WASAPIAIS:SetOutputDeviceForAec: Setting device indices failed.");
return;
}
}
// Recreate the dummy render client on the new output.
hr = audio_client_for_render_->Stop();
if (FAILED(hr)) {
DLOG(ERROR) << "Failed to stop output streaming.";
}
if (started_) {
DCHECK(opened_);
// Recreate the dummy render client on the new output.
HRESULT hr = audio_client_for_render_->Stop();
if (FAILED(hr)) {
DLOG(ERROR) << "Failed to stop output streaming.";
}
CreateDummyRenderClientsForDmo();
CreateDummyRenderClientsForDmo();
if (!CoreAudioUtil::FillRenderEndpointBufferWithSilence(
audio_client_for_render_.Get(), audio_render_client_.Get())) {
DLOG(WARNING) << "Failed to pre-fill render buffer with silence.";
}
if (!CoreAudioUtil::FillRenderEndpointBufferWithSilence(
audio_client_for_render_.Get(), audio_render_client_.Get())) {
DLOG(WARNING) << "Failed to pre-fill render buffer with silence.";
}
hr = audio_client_for_render_->Start();
if (FAILED(hr)) {
DLOG(ERROR) << "Failed to start output streaming: " << std::hex << hr
<< ", proceeding without rendering.";
hr = audio_client_for_render_->Start();
if (FAILED(hr)) {
DLOG(ERROR) << "Failed to start output streaming: " << std::hex << hr
<< ", proceeding without rendering.";
}
}
log_callback_.Run(base::StringPrintf(
......
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