OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/pulse/audio_manager_pulse.h" | 5 #include "media/audio/pulse/audio_manager_pulse.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/environment.h" | 8 #include "base/environment.h" |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 AudioManagerPulse::AudioManagerPulse( | 51 AudioManagerPulse::AudioManagerPulse( |
52 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 52 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
53 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, | 53 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
54 AudioLogFactory* audio_log_factory) | 54 AudioLogFactory* audio_log_factory) |
55 : AudioManagerBase(std::move(task_runner), | 55 : AudioManagerBase(std::move(task_runner), |
56 std::move(worker_task_runner), | 56 std::move(worker_task_runner), |
57 audio_log_factory), | 57 audio_log_factory), |
58 input_mainloop_(NULL), | 58 input_mainloop_(NULL), |
59 input_context_(NULL), | 59 input_context_(NULL), |
60 devices_(NULL), | 60 devices_(NULL), |
61 native_input_sample_rate_(0) { | 61 native_input_sample_rate_(0), |
| 62 native_channel_count_(0) { |
62 SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 63 SetMaxOutputStreamsAllowed(kMaxOutputStreams); |
63 } | 64 } |
64 | 65 |
65 AudioManagerPulse::~AudioManagerPulse() { | 66 AudioManagerPulse::~AudioManagerPulse() { |
66 Shutdown(); | 67 Shutdown(); |
67 // The Pulse objects are the last things to be destroyed since Shutdown() | 68 // The Pulse objects are the last things to be destroyed since Shutdown() |
68 // needs them. | 69 // needs them. |
69 DestroyPulse(); | 70 DestroyPulse(); |
70 } | 71 } |
71 | 72 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 GetAudioDeviceNames(false, device_names); | 130 GetAudioDeviceNames(false, device_names); |
130 } | 131 } |
131 | 132 |
132 AudioParameters AudioManagerPulse::GetInputStreamParameters( | 133 AudioParameters AudioManagerPulse::GetInputStreamParameters( |
133 const std::string& device_id) { | 134 const std::string& device_id) { |
134 int user_buffer_size = GetUserBufferSize(); | 135 int user_buffer_size = GetUserBufferSize(); |
135 int buffer_size = user_buffer_size ? | 136 int buffer_size = user_buffer_size ? |
136 user_buffer_size : kDefaultInputBufferSize; | 137 user_buffer_size : kDefaultInputBufferSize; |
137 | 138 |
138 // TODO(xians): add support for querying native channel layout for pulse. | 139 // TODO(xians): add support for querying native channel layout for pulse. |
| 140 UpdateNativeAudioHardwareInfo(); |
139 return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 141 return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
140 CHANNEL_LAYOUT_STEREO, GetNativeSampleRate(), 16, | 142 CHANNEL_LAYOUT_STEREO, native_input_sample_rate_, 16, |
141 buffer_size); | 143 buffer_size); |
142 } | 144 } |
143 | 145 |
144 AudioOutputStream* AudioManagerPulse::MakeLinearOutputStream( | 146 AudioOutputStream* AudioManagerPulse::MakeLinearOutputStream( |
145 const AudioParameters& params, | 147 const AudioParameters& params, |
146 const LogCallback& log_callback) { | 148 const LogCallback& log_callback) { |
147 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 149 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); |
148 return MakeOutputStream(params, AudioDeviceDescription::kDefaultDeviceId); | 150 return MakeOutputStream(params, AudioDeviceDescription::kDefaultDeviceId); |
149 } | 151 } |
150 | 152 |
(...skipping 22 matching lines...) Expand all Loading... |
173 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); | 175 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); |
174 return MakeInputStream(params, device_id); | 176 return MakeInputStream(params, device_id); |
175 } | 177 } |
176 | 178 |
177 AudioParameters AudioManagerPulse::GetPreferredOutputStreamParameters( | 179 AudioParameters AudioManagerPulse::GetPreferredOutputStreamParameters( |
178 const std::string& output_device_id, | 180 const std::string& output_device_id, |
179 const AudioParameters& input_params) { | 181 const AudioParameters& input_params) { |
180 // TODO(tommi): Support |output_device_id|. | 182 // TODO(tommi): Support |output_device_id|. |
181 VLOG_IF(0, !output_device_id.empty()) << "Not implemented!"; | 183 VLOG_IF(0, !output_device_id.empty()) << "Not implemented!"; |
182 | 184 |
183 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; | |
184 int buffer_size = kMinimumOutputBufferSize; | 185 int buffer_size = kMinimumOutputBufferSize; |
185 int bits_per_sample = 16; | 186 int bits_per_sample = 16; |
186 int sample_rate = GetNativeSampleRate(); | 187 |
| 188 // Query native parameters where applicable; Pulse does not require these to |
| 189 // be respected though, so prefer the input parameters for channel count. |
| 190 UpdateNativeAudioHardwareInfo(); |
| 191 int sample_rate = native_input_sample_rate_; |
| 192 ChannelLayout channel_layout = GuessChannelLayout(native_channel_count_); |
| 193 |
187 if (input_params.IsValid()) { | 194 if (input_params.IsValid()) { |
188 bits_per_sample = input_params.bits_per_sample(); | 195 bits_per_sample = input_params.bits_per_sample(); |
189 channel_layout = input_params.channel_layout(); | 196 channel_layout = input_params.channel_layout(); |
190 buffer_size = | 197 buffer_size = |
191 std::min(kMaximumOutputBufferSize, | 198 std::min(kMaximumOutputBufferSize, |
192 std::max(buffer_size, input_params.frames_per_buffer())); | 199 std::max(buffer_size, input_params.frames_per_buffer())); |
193 } | 200 } |
194 | 201 |
195 int user_buffer_size = GetUserBufferSize(); | 202 int user_buffer_size = GetUserBufferSize(); |
196 if (user_buffer_size) | 203 if (user_buffer_size) |
197 buffer_size = user_buffer_size; | 204 buffer_size = user_buffer_size; |
198 | 205 |
199 return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, | 206 return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, |
200 sample_rate, bits_per_sample, buffer_size); | 207 sample_rate, bits_per_sample, buffer_size); |
201 } | 208 } |
202 | 209 |
203 AudioOutputStream* AudioManagerPulse::MakeOutputStream( | 210 AudioOutputStream* AudioManagerPulse::MakeOutputStream( |
204 const AudioParameters& params, | 211 const AudioParameters& params, |
205 const std::string& device_id) { | 212 const std::string& device_id) { |
206 DCHECK(!device_id.empty()); | 213 DCHECK(!device_id.empty()); |
207 return new PulseAudioOutputStream(params, device_id, this); | 214 return new PulseAudioOutputStream(params, device_id, this); |
208 } | 215 } |
209 | 216 |
210 AudioInputStream* AudioManagerPulse::MakeInputStream( | 217 AudioInputStream* AudioManagerPulse::MakeInputStream( |
211 const AudioParameters& params, const std::string& device_id) { | 218 const AudioParameters& params, const std::string& device_id) { |
212 return new PulseAudioInputStream(this, device_id, params, | 219 return new PulseAudioInputStream(this, device_id, params, |
213 input_mainloop_, input_context_); | 220 input_mainloop_, input_context_); |
214 } | 221 } |
215 | 222 |
216 int AudioManagerPulse::GetNativeSampleRate() { | 223 void AudioManagerPulse::UpdateNativeAudioHardwareInfo() { |
217 DCHECK(input_mainloop_); | 224 DCHECK(input_mainloop_); |
218 DCHECK(input_context_); | 225 DCHECK(input_context_); |
219 AutoPulseLock auto_lock(input_mainloop_); | 226 AutoPulseLock auto_lock(input_mainloop_); |
220 pa_operation* operation = pa_context_get_server_info( | 227 pa_operation* operation = pa_context_get_server_info( |
221 input_context_, SampleRateInfoCallback, this); | 228 input_context_, AudioHardwareInfoCallback, this); |
222 WaitForOperationCompletion(input_mainloop_, operation); | 229 WaitForOperationCompletion(input_mainloop_, operation); |
223 | |
224 return native_input_sample_rate_; | |
225 } | 230 } |
226 | 231 |
227 bool AudioManagerPulse::InitPulse() { | 232 bool AudioManagerPulse::InitPulse() { |
228 DCHECK(!input_mainloop_); | 233 DCHECK(!input_mainloop_); |
229 | 234 |
230 #if defined(DLOPEN_PULSEAUDIO) | 235 #if defined(DLOPEN_PULSEAUDIO) |
231 StubPathMap paths; | 236 StubPathMap paths; |
232 | 237 |
233 // Check if the pulse library is avialbale. | 238 // Check if the pulse library is avialbale. |
234 paths[kModulePulse].push_back(kPulseLib); | 239 paths[kModulePulse].push_back(kPulseLib); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 if (error) { | 334 if (error) { |
330 // Signal the pulse object that it is done. | 335 // Signal the pulse object that it is done. |
331 pa_threaded_mainloop_signal(manager->input_mainloop_, 0); | 336 pa_threaded_mainloop_signal(manager->input_mainloop_, 0); |
332 return; | 337 return; |
333 } | 338 } |
334 | 339 |
335 manager->devices_->push_back(AudioDeviceName(info->description, | 340 manager->devices_->push_back(AudioDeviceName(info->description, |
336 info->name)); | 341 info->name)); |
337 } | 342 } |
338 | 343 |
339 void AudioManagerPulse::SampleRateInfoCallback(pa_context* context, | 344 void AudioManagerPulse::AudioHardwareInfoCallback(pa_context* context, |
340 const pa_server_info* info, | 345 const pa_server_info* info, |
341 void* user_data) { | 346 void* user_data) { |
342 AudioManagerPulse* manager = reinterpret_cast<AudioManagerPulse*>(user_data); | 347 AudioManagerPulse* manager = reinterpret_cast<AudioManagerPulse*>(user_data); |
343 | 348 |
344 manager->native_input_sample_rate_ = info->sample_spec.rate; | 349 manager->native_input_sample_rate_ = info->sample_spec.rate; |
| 350 manager->native_channel_count_ = info->sample_spec.channels; |
345 pa_threaded_mainloop_signal(manager->input_mainloop_, 0); | 351 pa_threaded_mainloop_signal(manager->input_mainloop_, 0); |
346 } | 352 } |
347 | 353 |
348 } // namespace media | 354 } // namespace media |
OLD | NEW |