| 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/core_audio_util_win.h" | 5 #include "media/audio/win/core_audio_util_win.h" |
| 6 | 6 |
| 7 #include <audioclient.h> | 7 #include <audioclient.h> |
| 8 #include <devicetopology.h> | 8 #include <devicetopology.h> |
| 9 #include <functiondiscoverykeys_devpkey.h> | 9 #include <functiondiscoverykeys_devpkey.h> |
| 10 | 10 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 161 |
| 162 if (friendly_name_pv.get().vt == VT_LPWSTR && | 162 if (friendly_name_pv.get().vt == VT_LPWSTR && |
| 163 friendly_name_pv.get().pwszVal) { | 163 friendly_name_pv.get().pwszVal) { |
| 164 base::WideToUTF8(friendly_name_pv.get().pwszVal, | 164 base::WideToUTF8(friendly_name_pv.get().pwszVal, |
| 165 wcslen(friendly_name_pv.get().pwszVal), friendly_name); | 165 wcslen(friendly_name_pv.get().pwszVal), friendly_name); |
| 166 } | 166 } |
| 167 | 167 |
| 168 return hr; | 168 return hr; |
| 169 } | 169 } |
| 170 | 170 |
| 171 static ScopedComPtr<IMMDeviceEnumerator> CreateDeviceEnumeratorInternal() { | 171 static ScopedComPtr<IMMDeviceEnumerator> CreateDeviceEnumeratorInternal( |
| 172 bool allow_reinitialize) { |
| 172 ScopedComPtr<IMMDeviceEnumerator> device_enumerator; | 173 ScopedComPtr<IMMDeviceEnumerator> device_enumerator; |
| 173 HRESULT hr = device_enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), | 174 HRESULT hr = device_enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), |
| 174 NULL, CLSCTX_INPROC_SERVER); | 175 NULL, CLSCTX_INPROC_SERVER); |
| 175 if (hr == CO_E_NOTINITIALIZED) { | 176 if (hr == CO_E_NOTINITIALIZED && allow_reinitialize) { |
| 176 LOG(ERROR) << "CoCreateInstance fails with CO_E_NOTINITIALIZED"; | 177 LOG(ERROR) << "CoCreateInstance fails with CO_E_NOTINITIALIZED"; |
| 177 // We have seen crashes which indicates that this method can in fact | 178 // We have seen crashes which indicates that this method can in fact |
| 178 // fail with CO_E_NOTINITIALIZED in combination with certain 3rd party | 179 // fail with CO_E_NOTINITIALIZED in combination with certain 3rd party |
| 179 // modules. Calling CoInitializeEx is an attempt to resolve the reported | 180 // modules. Calling CoInitializeEx is an attempt to resolve the reported |
| 180 // issues. See http://crbug.com/378465 for details. | 181 // issues. See http://crbug.com/378465 for details. |
| 181 hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); | 182 hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); |
| 182 if (SUCCEEDED(hr)) { | 183 if (SUCCEEDED(hr)) { |
| 183 hr = device_enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), | 184 hr = device_enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), |
| 184 NULL, CLSCTX_INPROC_SERVER); | 185 NULL, CLSCTX_INPROC_SERVER); |
| 185 } | 186 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 208 // See http://crbug.com/166397 why this extra step is required to guarantee | 209 // See http://crbug.com/166397 why this extra step is required to guarantee |
| 209 // Core Audio support. | 210 // Core Audio support. |
| 210 if (!LoadAudiosesDll()) | 211 if (!LoadAudiosesDll()) |
| 211 return false; | 212 return false; |
| 212 | 213 |
| 213 // Being able to load the Audioses.dll does not seem to be sufficient for | 214 // Being able to load the Audioses.dll does not seem to be sufficient for |
| 214 // all devices to guarantee Core Audio support. To be 100%, we also verify | 215 // all devices to guarantee Core Audio support. To be 100%, we also verify |
| 215 // that it is possible to a create the IMMDeviceEnumerator interface. If this | 216 // that it is possible to a create the IMMDeviceEnumerator interface. If this |
| 216 // works as well we should be home free. | 217 // works as well we should be home free. |
| 217 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = | 218 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
| 218 CreateDeviceEnumeratorInternal(); | 219 CreateDeviceEnumeratorInternal(false); |
| 219 if (!device_enumerator) { | 220 if (!device_enumerator) { |
| 220 LOG(ERROR) | 221 LOG(ERROR) |
| 221 << "Failed to create Core Audio device enumerator on thread with ID " | 222 << "Failed to create Core Audio device enumerator on thread with ID " |
| 222 << GetCurrentThreadId(); | 223 << GetCurrentThreadId(); |
| 223 return false; | 224 return false; |
| 224 } | 225 } |
| 225 | 226 |
| 226 return true; | 227 return true; |
| 227 } | 228 } |
| 228 | 229 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 UINT number_of_active_devices = 0; | 268 UINT number_of_active_devices = 0; |
| 268 collection->GetCount(&number_of_active_devices); | 269 collection->GetCount(&number_of_active_devices); |
| 269 DVLOG(2) << ((data_flow == eCapture) ? "[in ] " : "[out] ") | 270 DVLOG(2) << ((data_flow == eCapture) ? "[in ] " : "[out] ") |
| 270 << "number of devices: " << number_of_active_devices; | 271 << "number of devices: " << number_of_active_devices; |
| 271 return static_cast<int>(number_of_active_devices); | 272 return static_cast<int>(number_of_active_devices); |
| 272 } | 273 } |
| 273 | 274 |
| 274 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { | 275 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { |
| 275 DCHECK(IsSupported()); | 276 DCHECK(IsSupported()); |
| 276 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = | 277 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
| 277 CreateDeviceEnumeratorInternal(); | 278 CreateDeviceEnumeratorInternal(true); |
| 278 CHECK(device_enumerator); | 279 CHECK(device_enumerator); |
| 279 return device_enumerator; | 280 return device_enumerator; |
| 280 } | 281 } |
| 281 | 282 |
| 282 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, | 283 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, |
| 283 ERole role) { | 284 ERole role) { |
| 284 DCHECK(IsSupported()); | 285 DCHECK(IsSupported()); |
| 285 ScopedComPtr<IMMDevice> endpoint_device; | 286 ScopedComPtr<IMMDevice> endpoint_device; |
| 286 | 287 |
| 287 // Create the IMMDeviceEnumerator interface. | 288 // Create the IMMDeviceEnumerator interface. |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 return false; | 864 return false; |
| 864 | 865 |
| 865 // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to | 866 // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to |
| 866 // explicitly write silence data to the rendering buffer. | 867 // explicitly write silence data to the rendering buffer. |
| 867 DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; | 868 DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; |
| 868 return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill, | 869 return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill, |
| 869 AUDCLNT_BUFFERFLAGS_SILENT)); | 870 AUDCLNT_BUFFERFLAGS_SILENT)); |
| 870 } | 871 } |
| 871 | 872 |
| 872 } // namespace media | 873 } // namespace media |
| OLD | NEW |