| 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 |