OLD | NEW |
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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 client = CoreAudioUtil::CreateClient(device); | 123 client = CoreAudioUtil::CreateClient(device); |
124 } | 124 } |
125 | 125 |
126 if (!client || FAILED(CoreAudioUtil::GetSharedModeMixFormat(client, &format))) | 126 if (!client || FAILED(CoreAudioUtil::GetSharedModeMixFormat(client, &format))) |
127 return 0; | 127 return 0; |
128 | 128 |
129 return static_cast<int>(format.Format.nSamplesPerSec); | 129 return static_cast<int>(format.Format.nSamplesPerSec); |
130 } | 130 } |
131 | 131 |
132 WASAPIAudioOutputStream::WASAPIAudioOutputStream(AudioManagerWin* manager, | 132 WASAPIAudioOutputStream::WASAPIAudioOutputStream(AudioManagerWin* manager, |
| 133 const std::string& device_id, |
133 const AudioParameters& params, | 134 const AudioParameters& params, |
134 ERole device_role) | 135 ERole device_role) |
135 : creating_thread_id_(base::PlatformThread::CurrentId()), | 136 : creating_thread_id_(base::PlatformThread::CurrentId()), |
136 manager_(manager), | 137 manager_(manager), |
137 opened_(false), | 138 opened_(false), |
138 audio_parameters_are_valid_(false), | 139 audio_parameters_are_valid_(false), |
139 volume_(1.0), | 140 volume_(1.0), |
140 endpoint_buffer_size_frames_(0), | 141 endpoint_buffer_size_frames_(0), |
| 142 device_id_(device_id), |
141 device_role_(device_role), | 143 device_role_(device_role), |
142 share_mode_(GetShareMode()), | 144 share_mode_(GetShareMode()), |
143 num_written_frames_(0), | 145 num_written_frames_(0), |
144 source_(NULL), | 146 source_(NULL), |
145 audio_bus_(AudioBus::Create(params)) { | 147 audio_bus_(AudioBus::Create(params)) { |
146 DCHECK(manager_); | 148 DCHECK(manager_); |
147 VLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()"; | 149 VLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()"; |
148 VLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE) | 150 VLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE) |
149 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled."; | 151 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled."; |
150 | 152 |
151 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) { | 153 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) { |
152 // Verify that the input audio parameters are identical (bit depth and | 154 // Verify that the input audio parameters are identical (bit depth and |
153 // channel count are excluded) to the preferred (native) audio parameters. | 155 // channel count are excluded) to the preferred (native) audio parameters. |
154 // Open() will fail if this is not the case. | 156 // Open() will fail if this is not the case. |
155 AudioParameters preferred_params; | 157 AudioParameters preferred_params; |
156 HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters( | 158 HRESULT hr = device_id_.empty() ? |
157 eRender, device_role, &preferred_params); | 159 CoreAudioUtil::GetPreferredAudioParameters(eRender, device_role, |
| 160 &preferred_params) : |
| 161 CoreAudioUtil::GetPreferredAudioParameters(device_id_, |
| 162 &preferred_params); |
158 audio_parameters_are_valid_ = SUCCEEDED(hr) && | 163 audio_parameters_are_valid_ = SUCCEEDED(hr) && |
159 CompareAudioParametersNoBitDepthOrChannels(params, preferred_params); | 164 CompareAudioParametersNoBitDepthOrChannels(params, preferred_params); |
160 LOG_IF(WARNING, !audio_parameters_are_valid_) | 165 LOG_IF(WARNING, !audio_parameters_are_valid_) |
161 << "Input and preferred parameters are not identical."; | 166 << "Input and preferred parameters are not identical. " |
| 167 << "Device id: " << device_id_; |
162 } | 168 } |
163 | 169 |
164 // Load the Avrt DLL if not already loaded. Required to support MMCSS. | 170 // Load the Avrt DLL if not already loaded. Required to support MMCSS. |
165 bool avrt_init = avrt::Initialize(); | 171 bool avrt_init = avrt::Initialize(); |
166 DCHECK(avrt_init) << "Failed to load the avrt.dll"; | 172 DCHECK(avrt_init) << "Failed to load the avrt.dll"; |
167 | 173 |
168 // Set up the desired render format specified by the client. We use the | 174 // Set up the desired render format specified by the client. We use the |
169 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering | 175 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering |
170 // and high precision data can be supported. | 176 // and high precision data can be supported. |
171 | 177 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 } | 213 } |
208 | 214 |
209 WASAPIAudioOutputStream::~WASAPIAudioOutputStream() {} | 215 WASAPIAudioOutputStream::~WASAPIAudioOutputStream() {} |
210 | 216 |
211 bool WASAPIAudioOutputStream::Open() { | 217 bool WASAPIAudioOutputStream::Open() { |
212 VLOG(1) << "WASAPIAudioOutputStream::Open()"; | 218 VLOG(1) << "WASAPIAudioOutputStream::Open()"; |
213 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_); | 219 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_); |
214 if (opened_) | 220 if (opened_) |
215 return true; | 221 return true; |
216 | 222 |
217 | |
218 // Audio parameters must be identical to the preferred set of parameters | 223 // Audio parameters must be identical to the preferred set of parameters |
219 // if shared mode (default) is utilized. | 224 // if shared mode (default) is utilized. |
220 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) { | 225 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) { |
221 if (!audio_parameters_are_valid_) { | 226 if (!audio_parameters_are_valid_) { |
222 LOG(ERROR) << "Audio parameters are not valid."; | 227 LOG(ERROR) << "Audio parameters are not valid."; |
223 return false; | 228 return false; |
224 } | 229 } |
225 } | 230 } |
226 | 231 |
227 // Create an IAudioClient interface for the default rendering IMMDevice. | 232 // Create an IAudioClient interface for the default rendering IMMDevice. |
228 ScopedComPtr<IAudioClient> audio_client = | 233 ScopedComPtr<IAudioClient> audio_client; |
229 CoreAudioUtil::CreateDefaultClient(eRender, device_role_); | 234 if (device_id_.empty()) { |
| 235 audio_client = CoreAudioUtil::CreateDefaultClient(eRender, device_role_); |
| 236 } else { |
| 237 ScopedComPtr<IMMDevice> device(CoreAudioUtil::CreateDevice(device_id_)); |
| 238 DLOG_IF(ERROR, !device) << "Failed to open device: " << device_id_; |
| 239 if (device) |
| 240 audio_client = CoreAudioUtil::CreateClient(device); |
| 241 } |
| 242 |
230 if (!audio_client) | 243 if (!audio_client) |
231 return false; | 244 return false; |
232 | 245 |
233 // Extra sanity to ensure that the provided device format is still valid. | 246 // Extra sanity to ensure that the provided device format is still valid. |
234 if (!CoreAudioUtil::IsFormatSupported(audio_client, | 247 if (!CoreAudioUtil::IsFormatSupported(audio_client, |
235 share_mode_, | 248 share_mode_, |
236 &format_)) { | 249 &format_)) { |
237 return false; | 250 return false; |
238 } | 251 } |
239 | 252 |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 VLOG(1) << "IAudioClient::GetBufferSize: " << std::hex << hr; | 700 VLOG(1) << "IAudioClient::GetBufferSize: " << std::hex << hr; |
688 return hr; | 701 return hr; |
689 } | 702 } |
690 | 703 |
691 *endpoint_buffer_size = buffer_size_in_frames; | 704 *endpoint_buffer_size = buffer_size_in_frames; |
692 VLOG(2) << "endpoint buffer size: " << buffer_size_in_frames; | 705 VLOG(2) << "endpoint buffer size: " << buffer_size_in_frames; |
693 return hr; | 706 return hr; |
694 } | 707 } |
695 | 708 |
696 } // namespace media | 709 } // namespace media |
OLD | NEW |