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