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 <Functiondiscoverykeys_devpkey.h> | 8 #include <Functiondiscoverykeys_devpkey.h> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 | 69 |
70 bool LoadAudiosesDll() { | 70 bool LoadAudiosesDll() { |
71 static const wchar_t* const kAudiosesDLL = | 71 static const wchar_t* const kAudiosesDLL = |
72 L"%WINDIR%\\system32\\audioses.dll"; | 72 L"%WINDIR%\\system32\\audioses.dll"; |
73 | 73 |
74 wchar_t path[MAX_PATH] = {0}; | 74 wchar_t path[MAX_PATH] = {0}; |
75 ExpandEnvironmentStringsW(kAudiosesDLL, path, arraysize(path)); | 75 ExpandEnvironmentStringsW(kAudiosesDLL, path, arraysize(path)); |
76 return (LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) != NULL); | 76 return (LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) != NULL); |
77 } | 77 } |
78 | 78 |
79 bool CanCreateDeviceEnumerator() { | |
80 ScopedComPtr<IMMDeviceEnumerator> device_enumerator; | |
81 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), | |
82 NULL, | |
83 CLSCTX_INPROC_SERVER, | |
84 __uuidof(IMMDeviceEnumerator), | |
85 device_enumerator.ReceiveVoid()); | |
86 return SUCCEEDED(hr); | |
tommi (sloooow) - chröme
2013/03/05 09:32:10
add a check here:
CHECK_NE(hr, CO_E_NOTINITIALIZED
henrika (OOO until Aug 14)
2013/03/05 09:49:35
Done.
| |
87 } | |
88 | |
79 bool CoreAudioUtil::IsSupported() { | 89 bool CoreAudioUtil::IsSupported() { |
80 // Microsoft does not plan to make the Core Audio APIs available for use | 90 // Microsoft does not plan to make the Core Audio APIs available for use |
81 // with earlier versions of Windows, including Microsoft Windows Server 2003, | 91 // with earlier versions of Windows, including Microsoft Windows Server 2003, |
82 // Windows XP, Windows Millennium Edition, Windows 2000, and Windows 98. | 92 // Windows XP, Windows Millennium Edition, Windows 2000, and Windows 98. |
83 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 93 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
84 return false; | 94 return false; |
85 | 95 |
86 // The audio core APIs are implemented in the Mmdevapi.dll and Audioses.dll | 96 // The audio core APIs are implemented in the Mmdevapi.dll and Audioses.dll |
87 // system components. | 97 // system components. |
88 // Dependency Walker shows that it is enough to verify possibility to load | 98 // Dependency Walker shows that it is enough to verify possibility to load |
89 // the Audioses DLL since it depends on Mmdevapi.dll. | 99 // the Audioses DLL since it depends on Mmdevapi.dll. |
90 // See http://crbug.com/166397 why this extra step is required to guarantee | 100 // See http://crbug.com/166397 why this extra step is required to guarantee |
91 // Core Audio support. | 101 // Core Audio support. |
92 static bool g_audioses_dll_available = LoadAudiosesDll(); | 102 static bool g_audioses_dll_available = LoadAudiosesDll(); |
93 return g_audioses_dll_available; | 103 if (g_audioses_dll_available) |
DaleCurtis
2013/03/04 17:18:26
!g_audioses_dll_available ?
henrika (OOO until Aug 14)
2013/03/05 09:09:11
My bad. Will fix. Thanks!
| |
104 return false; | |
105 | |
106 // Being able to load the Audioses.dll does not seem to be sufficient for | |
107 // all devices to guarantee Core Audio support. To be 100%, we also verify | |
108 // that it is possible to a create the IMMDeviceEnumerator interface. If this | |
109 // works as well we should be home free. | |
110 static bool g_can_create_device_enumerator = CanCreateDeviceEnumerator(); | |
tommi (sloooow) - chröme
2013/03/04 17:29:01
If this function is called on a non-COM initialize
henrika (OOO until Aug 14)
2013/03/05 09:09:11
Tommi, great comments as usual, please see replies
tommi (sloooow) - chröme
2013/03/05 09:32:10
Yes, that sounds OK with me but ask that we add th
henrika (OOO until Aug 14)
2013/03/05 09:49:35
Got it, thanks. Part of my comments above were inv
| |
111 return g_can_create_device_enumerator; | |
94 } | 112 } |
95 | 113 |
96 base::TimeDelta CoreAudioUtil::RefererenceTimeToTimeDelta(REFERENCE_TIME time) { | 114 base::TimeDelta CoreAudioUtil::RefererenceTimeToTimeDelta(REFERENCE_TIME time) { |
97 // Each unit of reference time is 100 nanoseconds <=> 0.1 microsecond. | 115 // Each unit of reference time is 100 nanoseconds <=> 0.1 microsecond. |
98 return base::TimeDelta::FromMicroseconds(0.1 * time + 0.5); | 116 return base::TimeDelta::FromMicroseconds(0.1 * time + 0.5); |
99 } | 117 } |
100 | 118 |
101 AUDCLNT_SHAREMODE CoreAudioUtil::GetShareMode() { | 119 AUDCLNT_SHAREMODE CoreAudioUtil::GetShareMode() { |
102 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 120 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
103 if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) | 121 if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) |
(...skipping 30 matching lines...) Expand all Loading... | |
134 } | 152 } |
135 | 153 |
136 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { | 154 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { |
137 DCHECK(IsSupported()); | 155 DCHECK(IsSupported()); |
138 ScopedComPtr<IMMDeviceEnumerator> device_enumerator; | 156 ScopedComPtr<IMMDeviceEnumerator> device_enumerator; |
139 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), | 157 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), |
140 NULL, | 158 NULL, |
141 CLSCTX_INPROC_SERVER, | 159 CLSCTX_INPROC_SERVER, |
142 __uuidof(IMMDeviceEnumerator), | 160 __uuidof(IMMDeviceEnumerator), |
143 device_enumerator.ReceiveVoid()); | 161 device_enumerator.ReceiveVoid()); |
144 // CO_E_NOTINITIALIZED is the most likely reason for failure and if that | 162 LOG_IF(ERROR, FAILED(hr)) << "IMMDeviceEnumerator::CreateDeviceEnumerator: " |
145 // happens we might as well die here. | 163 << std::hex << hr; |
146 CHECK(SUCCEEDED(hr)); | |
147 return device_enumerator; | 164 return device_enumerator; |
148 } | 165 } |
149 | 166 |
150 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, | 167 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, |
151 ERole role) { | 168 ERole role) { |
152 DCHECK(IsSupported()); | 169 DCHECK(IsSupported()); |
153 ScopedComPtr<IMMDevice> endpoint_device; | 170 ScopedComPtr<IMMDevice> endpoint_device; |
154 | 171 |
155 // Create the IMMDeviceEnumerator interface. | 172 // Create the IMMDeviceEnumerator interface. |
156 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = | 173 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 return false; | 591 return false; |
575 | 592 |
576 // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to | 593 // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to |
577 // explicitly write silence data to the rendering buffer. | 594 // explicitly write silence data to the rendering buffer. |
578 DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; | 595 DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; |
579 return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill, | 596 return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill, |
580 AUDCLNT_BUFFERFLAGS_SILENT)); | 597 AUDCLNT_BUFFERFLAGS_SILENT)); |
581 } | 598 } |
582 | 599 |
583 } // namespace media | 600 } // namespace media |
OLD | NEW |