Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: media/audio/win/audio_low_latency_output_win.cc

Issue 367923004: Turn audio ducking on by default on Windows again. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/win/audio_low_latency_output_win.h" 5 #include "media/audio/win/audio_low_latency_output_win.h"
6 6
7 #include <Functiondiscoverykeys_devpkey.h> 7 #include <Functiondiscoverykeys_devpkey.h>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 packet_size_frames_(0), 64 packet_size_frames_(0),
65 packet_size_bytes_(0), 65 packet_size_bytes_(0),
66 endpoint_buffer_size_frames_(0), 66 endpoint_buffer_size_frames_(0),
67 device_id_(device_id), 67 device_id_(device_id),
68 device_role_(device_role), 68 device_role_(device_role),
69 share_mode_(GetShareMode()), 69 share_mode_(GetShareMode()),
70 num_written_frames_(0), 70 num_written_frames_(0),
71 source_(NULL), 71 source_(NULL),
72 audio_bus_(AudioBus::Create(params)) { 72 audio_bus_(AudioBus::Create(params)) {
73 DCHECK(manager_); 73 DCHECK(manager_);
74
74 VLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()"; 75 VLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()";
75 VLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE) 76 VLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE)
76 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled."; 77 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled.";
77 78
78 // Load the Avrt DLL if not already loaded. Required to support MMCSS. 79 // Load the Avrt DLL if not already loaded. Required to support MMCSS.
79 bool avrt_init = avrt::Initialize(); 80 bool avrt_init = avrt::Initialize();
80 DCHECK(avrt_init) << "Failed to load the avrt.dll"; 81 DCHECK(avrt_init) << "Failed to load the avrt.dll";
81 82
82 // Set up the desired render format specified by the client. We use the 83 // Set up the desired render format specified by the client. We use the
83 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering 84 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering
(...skipping 29 matching lines...) Expand all
113 // Create the event which the audio engine will signal each time 114 // Create the event which the audio engine will signal each time
114 // a buffer becomes ready to be processed by the client. 115 // a buffer becomes ready to be processed by the client.
115 audio_samples_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL)); 116 audio_samples_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL));
116 DCHECK(audio_samples_render_event_.IsValid()); 117 DCHECK(audio_samples_render_event_.IsValid());
117 118
118 // Create the event which will be set in Stop() when capturing shall stop. 119 // Create the event which will be set in Stop() when capturing shall stop.
119 stop_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL)); 120 stop_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL));
120 DCHECK(stop_render_event_.IsValid()); 121 DCHECK(stop_render_event_.IsValid());
121 } 122 }
122 123
123 WASAPIAudioOutputStream::~WASAPIAudioOutputStream() {} 124 WASAPIAudioOutputStream::~WASAPIAudioOutputStream() {
125 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_);
126 }
124 127
125 bool WASAPIAudioOutputStream::Open() { 128 bool WASAPIAudioOutputStream::Open() {
126 VLOG(1) << "WASAPIAudioOutputStream::Open()"; 129 VLOG(1) << "WASAPIAudioOutputStream::Open()";
127 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_); 130 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_);
128 if (opened_) 131 if (opened_)
129 return true; 132 return true;
130 133
134 DCHECK(!audio_client_);
135 DCHECK(!audio_render_client_);
136
137 // Will be set to true if we ended up opening the default communications
138 // device.
139 bool communications_device = false;
140
131 // Create an IAudioClient interface for the default rendering IMMDevice. 141 // Create an IAudioClient interface for the default rendering IMMDevice.
132 ScopedComPtr<IAudioClient> audio_client; 142 ScopedComPtr<IAudioClient> audio_client;
133 if (device_id_.empty() || 143 if (device_id_.empty() ||
134 CoreAudioUtil::DeviceIsDefault(eRender, device_role_, device_id_)) { 144 CoreAudioUtil::DeviceIsDefault(eRender, device_role_, device_id_)) {
135 audio_client = CoreAudioUtil::CreateDefaultClient(eRender, device_role_); 145 audio_client = CoreAudioUtil::CreateDefaultClient(eRender, device_role_);
146 communications_device = (device_role_ == eCommunications);
136 } else { 147 } else {
137 ScopedComPtr<IMMDevice> device(CoreAudioUtil::CreateDevice(device_id_)); 148 ScopedComPtr<IMMDevice> device(CoreAudioUtil::CreateDevice(device_id_));
138 DLOG_IF(ERROR, !device) << "Failed to open device: " << device_id_; 149 DLOG_IF(ERROR, !device) << "Failed to open device: " << device_id_;
139 if (device) 150 if (device)
140 audio_client = CoreAudioUtil::CreateClient(device); 151 audio_client = CoreAudioUtil::CreateClient(device);
141 } 152 }
142 153
143 if (!audio_client) 154 if (!audio_client)
144 return false; 155 return false;
145 156
146 // Extra sanity to ensure that the provided device format is still valid. 157 // Extra sanity to ensure that the provided device format is still valid.
147 if (!CoreAudioUtil::IsFormatSupported(audio_client, 158 if (!CoreAudioUtil::IsFormatSupported(audio_client,
148 share_mode_, 159 share_mode_,
149 &format_)) { 160 &format_)) {
150 LOG(ERROR) << "Audio parameters are not supported."; 161 LOG(ERROR) << "Audio parameters are not supported.";
151 return false; 162 return false;
152 } 163 }
153 164
154 HRESULT hr = S_FALSE; 165 HRESULT hr = S_FALSE;
155 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) { 166 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) {
156 // Initialize the audio stream between the client and the device in shared 167 // Initialize the audio stream between the client and the device in shared
157 // mode and using event-driven buffer handling. 168 // mode and using event-driven buffer handling.
158 hr = CoreAudioUtil::SharedModeInitialize( 169 hr = CoreAudioUtil::SharedModeInitialize(
159 audio_client, &format_, audio_samples_render_event_.Get(), 170 audio_client, &format_, audio_samples_render_event_.Get(),
160 &endpoint_buffer_size_frames_); 171 &endpoint_buffer_size_frames_,
172 communications_device ? &kCommunicationsSessionId : NULL);
161 if (FAILED(hr)) 173 if (FAILED(hr))
162 return false; 174 return false;
163 175
164 // We know from experience that the best possible callback sequence is 176 // We know from experience that the best possible callback sequence is
165 // achieved when the packet size (given by the native device period) 177 // achieved when the packet size (given by the native device period)
166 // is an even divisor of the endpoint buffer size. 178 // is an even divisor of the endpoint buffer size.
167 // Examples: 48kHz => 960 % 480, 44.1kHz => 896 % 448 or 882 % 441. 179 // Examples: 48kHz => 960 % 480, 44.1kHz => 896 % 448 or 882 % 441.
168 if (endpoint_buffer_size_frames_ % packet_size_frames_ != 0) { 180 if (endpoint_buffer_size_frames_ % packet_size_frames_ != 0) {
169 LOG(ERROR) 181 LOG(ERROR)
170 << "Bailing out due to non-perfect timing. Buffer size of " 182 << "Bailing out due to non-perfect timing. Buffer size of "
(...skipping 20 matching lines...) Expand all
191 } 203 }
192 204
193 // Create an IAudioRenderClient client for an initialized IAudioClient. 205 // Create an IAudioRenderClient client for an initialized IAudioClient.
194 // The IAudioRenderClient interface enables us to write output data to 206 // The IAudioRenderClient interface enables us to write output data to
195 // a rendering endpoint buffer. 207 // a rendering endpoint buffer.
196 ScopedComPtr<IAudioRenderClient> audio_render_client = 208 ScopedComPtr<IAudioRenderClient> audio_render_client =
197 CoreAudioUtil::CreateRenderClient(audio_client); 209 CoreAudioUtil::CreateRenderClient(audio_client);
198 if (!audio_render_client) 210 if (!audio_render_client)
199 return false; 211 return false;
200 212
201 // Store valid COM interfaces. 213 // Store valid COM interfaces.
202 audio_client_ = audio_client; 214 audio_client_ = audio_client;
203 audio_render_client_ = audio_render_client; 215 audio_render_client_ = audio_render_client;
204 216
205 hr = audio_client_->GetService(__uuidof(IAudioClock), 217 hr = audio_client_->GetService(__uuidof(IAudioClock),
206 audio_clock_.ReceiveVoid()); 218 audio_clock_.ReceiveVoid());
207 if (FAILED(hr)) { 219 if (FAILED(hr)) {
208 LOG(ERROR) << "Failed to get IAudioClock service."; 220 LOG(ERROR) << "Failed to get IAudioClock service.";
209 return false; 221 return false;
210 } 222 }
211 223
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 620
609 // Ensure that we don't quit the main thread loop immediately next 621 // Ensure that we don't quit the main thread loop immediately next
610 // time Start() is called. 622 // time Start() is called.
611 ResetEvent(stop_render_event_.Get()); 623 ResetEvent(stop_render_event_.Get());
612 } 624 }
613 625
614 source_ = NULL; 626 source_ = NULL;
615 } 627 }
616 628
617 } // namespace media 629 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698