| 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/audio_io.h" | 5 #include "media/audio/audio_io.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <objbase.h> // This has to be before initguid.h | 8 #include <objbase.h> // This has to be before initguid.h |
| 9 #include <initguid.h> | 9 #include <initguid.h> |
| 10 #include <mmsystem.h> | 10 #include <mmsystem.h> |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 | 119 |
| 120 // Use 4 buffers for Vista, 3 for everyone else: | 120 // Use 4 buffers for Vista, 3 for everyone else: |
| 121 // - The entire Windows audio stack was rewritten for Windows Vista and wave | 121 // - The entire Windows audio stack was rewritten for Windows Vista and wave |
| 122 // out performance was degraded compared to XP. | 122 // out performance was degraded compared to XP. |
| 123 // - The regression was fixed in Windows 7 and most configurations will work | 123 // - The regression was fixed in Windows 7 and most configurations will work |
| 124 // with 2, but some (e.g., some Sound Blasters) still need 3. | 124 // with 2, but some (e.g., some Sound Blasters) still need 3. |
| 125 // - Some XP configurations (even multi-processor ones) also need 3. | 125 // - Some XP configurations (even multi-processor ones) also need 3. |
| 126 return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3; | 126 return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3; |
| 127 } | 127 } |
| 128 | 128 |
| 129 AudioManagerWin::AudioManagerWin(AudioLogFactory* audio_log_factory) | 129 AudioManagerWin::AudioManagerWin( |
| 130 : AudioManagerBase(audio_log_factory), | 130 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 131 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
| 132 AudioLogFactory* audio_log_factory) |
| 133 : AudioManagerBase(std::move(task_runner), |
| 134 std::move(worker_task_runner), |
| 135 audio_log_factory), |
| 131 // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing | 136 // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing |
| 132 // multiple initializations. This is however not thread safe. | 137 // multiple initializations. This is however not thread safe. |
| 133 // So, here we call it explicitly before we kick off the audio thread | 138 // So, here we call it explicitly before we kick off the audio thread |
| 134 // or do any other work. | 139 // or do any other work. |
| 135 enumeration_type_(CoreAudioUtil::IsSupported() ? | 140 enumeration_type_(CoreAudioUtil::IsSupported() ? kMMDeviceEnumeration |
| 136 kMMDeviceEnumeration : kWaveEnumeration) { | 141 : kWaveEnumeration) { |
| 137 SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 142 SetMaxOutputStreamsAllowed(kMaxOutputStreams); |
| 138 | 143 |
| 139 // WARNING: This is executed on the UI loop, do not add any code here which | 144 // WARNING: This is executed on the UI loop, do not add any code here which |
| 140 // loads libraries or attempts to call out into the OS. Instead add such code | 145 // loads libraries or attempts to call out into the OS. Instead add such code |
| 141 // to the InitializeOnAudioThread() method below. | 146 // to the InitializeOnAudioThread() method below. |
| 142 | 147 |
| 143 // Task must be posted last to avoid races from handing out "this" to the | 148 // Task must be posted last to avoid races from handing out "this" to the |
| 144 // audio thread. | 149 // audio thread. |
| 145 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( | 150 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( |
| 146 &AudioManagerWin::InitializeOnAudioThread, base::Unretained(this))); | 151 &AudioManagerWin::InitializeOnAudioThread, base::Unretained(this))); |
| 147 } | 152 } |
| 148 | 153 |
| 149 AudioManagerWin::~AudioManagerWin() { | 154 AudioManagerWin::~AudioManagerWin() { |
| 150 // It's safe to post a task here since Shutdown() will wait for all tasks to | |
| 151 // complete before returning. | |
| 152 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( | |
| 153 &AudioManagerWin::ShutdownOnAudioThread, base::Unretained(this))); | |
| 154 Shutdown(); | 155 Shutdown(); |
| 155 } | 156 } |
| 156 | 157 |
| 157 bool AudioManagerWin::HasAudioOutputDevices() { | 158 bool AudioManagerWin::HasAudioOutputDevices() { |
| 158 return (::waveOutGetNumDevs() != 0); | 159 return (::waveOutGetNumDevs() != 0); |
| 159 } | 160 } |
| 160 | 161 |
| 161 bool AudioManagerWin::HasAudioInputDevices() { | 162 bool AudioManagerWin::HasAudioInputDevices() { |
| 162 return (::waveInGetNumDevs() != 0); | 163 return (::waveInGetNumDevs() != 0); |
| 163 } | 164 } |
| 164 | 165 |
| 165 void AudioManagerWin::InitializeOnAudioThread() { | 166 void AudioManagerWin::InitializeOnAudioThread() { |
| 166 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 167 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 167 | 168 |
| 168 if (core_audio_supported()) { | 169 if (core_audio_supported()) { |
| 169 // AudioDeviceListenerWin must be initialized on a COM thread and should | 170 // AudioDeviceListenerWin must be initialized on a COM thread and should |
| 170 // only be used if WASAPI / Core Audio is supported. | 171 // only be used if WASAPI / Core Audio is supported. |
| 171 output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop( | 172 output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop( |
| 172 base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners, | 173 base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners, |
| 173 base::Unretained(this))))); | 174 base::Unretained(this))))); |
| 174 } | 175 } |
| 175 } | 176 } |
| 176 | 177 |
| 177 void AudioManagerWin::ShutdownOnAudioThread() { | |
| 178 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | |
| 179 output_device_listener_.reset(); | |
| 180 } | |
| 181 | |
| 182 base::string16 AudioManagerWin::GetAudioInputDeviceModel() { | 178 base::string16 AudioManagerWin::GetAudioInputDeviceModel() { |
| 183 // Get the default audio capture device and its device interface name. | 179 // Get the default audio capture device and its device interface name. |
| 184 DWORD device_id = 0; | 180 DWORD device_id = 0; |
| 185 waveInMessage(reinterpret_cast<HWAVEIN>(WAVE_MAPPER), | 181 waveInMessage(reinterpret_cast<HWAVEIN>(WAVE_MAPPER), |
| 186 DRVM_MAPPER_PREFERRED_GET, | 182 DRVM_MAPPER_PREFERRED_GET, |
| 187 reinterpret_cast<DWORD_PTR>(&device_id), NULL); | 183 reinterpret_cast<DWORD_PTR>(&device_id), NULL); |
| 188 ULONG device_interface_name_size = 0; | 184 ULONG device_interface_name_size = 0; |
| 189 waveInMessage(reinterpret_cast<HWAVEIN>(device_id), | 185 waveInMessage(reinterpret_cast<HWAVEIN>(device_id), |
| 190 DRV_QUERYDEVICEINTERFACESIZE, | 186 DRV_QUERYDEVICEINTERFACESIZE, |
| 191 reinterpret_cast<DWORD_PTR>(&device_interface_name_size), 0); | 187 reinterpret_cast<DWORD_PTR>(&device_interface_name_size), 0); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 << device_id; | 526 << device_id; |
| 531 return NULL; | 527 return NULL; |
| 532 } | 528 } |
| 533 } | 529 } |
| 534 | 530 |
| 535 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers, | 531 return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers, |
| 536 xp_device_id); | 532 xp_device_id); |
| 537 } | 533 } |
| 538 | 534 |
| 539 /// static | 535 /// static |
| 540 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { | 536 ScopedAudioManagerPtr CreateAudioManager( |
| 541 return new AudioManagerWin(audio_log_factory); | 537 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 538 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
| 539 AudioLogFactory* audio_log_factory) { |
| 540 return ScopedAudioManagerPtr( |
| 541 new AudioManagerWin(std::move(task_runner), std::move(worker_task_runner), |
| 542 audio_log_factory)); |
| 542 } | 543 } |
| 543 | 544 |
| 544 } // namespace media | 545 } // namespace media |
| OLD | NEW |