Chromium Code Reviews| 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/pulse/pulse_input.h" | 5 #include "media/audio/pulse/pulse_input.h" |
| 6 | 6 |
| 7 #include <pulse/pulseaudio.h> | 7 #include <pulse/pulseaudio.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 pa_cvolume pa_volume; | 210 pa_cvolume pa_volume; |
| 211 pa_cvolume_set(&pa_volume, channels_, volume); | 211 pa_cvolume_set(&pa_volume, channels_, volume); |
| 212 operation = pa_context_set_source_volume_by_index( | 212 operation = pa_context_set_source_volume_by_index( |
| 213 pa_context_, index, &pa_volume, NULL, NULL); | 213 pa_context_, index, &pa_volume, NULL, NULL); |
| 214 | 214 |
| 215 // Don't need to wait for this task to complete. | 215 // Don't need to wait for this task to complete. |
| 216 pa_operation_unref(operation); | 216 pa_operation_unref(operation); |
| 217 } | 217 } |
| 218 | 218 |
| 219 double PulseAudioInputStream::GetVolume() { | 219 double PulseAudioInputStream::GetVolume() { |
| 220 AutoPulseLock auto_lock(pa_mainloop_); | 220 if (pa_threaded_mainloop_in_thread(pa_mainloop_)) { |
| 221 if (!handle_) | 221 // When being called by the pulse thread, GetVolume() is asynchronous and |
| 222 // called under AutoPulseLock. | |
| 223 if (!handle_) | |
| 224 return 0.0; | |
| 225 | |
| 226 size_t index = pa_stream_get_device_index(handle_); | |
| 227 pa_operation* operation = pa_context_get_source_info_by_index( | |
| 228 pa_context_, index, &VolumeCallback, this); | |
| 229 // Do not wait for the operation since we can't block the pulse thread. | |
| 230 pa_operation_unref(operation); | |
| 231 | |
| 232 // Return zero and the callback will asynchronously update the |volume_|. | |
| 222 return 0.0; | 233 return 0.0; |
| 234 } else { | |
| 235 // Called by other thread, put an AutoPulseLock and wait for the operation. | |
| 236 AutoPulseLock auto_lock(pa_mainloop_); | |
| 237 if (!handle_) | |
| 238 return 0.0; | |
| 223 | 239 |
| 224 size_t index = pa_stream_get_device_index(handle_); | 240 size_t index = pa_stream_get_device_index(handle_); |
| 225 pa_operation* operation = pa_context_get_source_info_by_index( | 241 pa_operation* operation = pa_context_get_source_info_by_index( |
| 226 pa_context_, index, &VolumeCallback, this); | 242 pa_context_, index, &VolumeCallback, this); |
| 227 WaitForOperationCompletion(pa_mainloop_, operation); | 243 WaitForOperationCompletion(pa_mainloop_, operation); |
| 228 | 244 |
| 229 return volume_; | 245 return volume_; |
| 246 } | |
| 230 } | 247 } |
| 231 | 248 |
| 232 // static, used by pa_stream_set_read_callback. | 249 // static, used by pa_stream_set_read_callback. |
| 233 void PulseAudioInputStream::ReadCallback(pa_stream* handle, | 250 void PulseAudioInputStream::ReadCallback(pa_stream* handle, |
| 234 size_t length, | 251 size_t length, |
| 235 void* user_data) { | 252 void* user_data) { |
| 236 PulseAudioInputStream* stream = | 253 PulseAudioInputStream* stream = |
| 237 reinterpret_cast<PulseAudioInputStream*>(user_data); | 254 reinterpret_cast<PulseAudioInputStream*>(user_data); |
| 238 | 255 |
| 239 stream->ReadData(); | 256 stream->ReadData(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 254 if (stream->channels_ != info->channel_map.channels) | 271 if (stream->channels_ != info->channel_map.channels) |
| 255 stream->channels_ = info->channel_map.channels; | 272 stream->channels_ = info->channel_map.channels; |
| 256 | 273 |
| 257 pa_volume_t volume = PA_VOLUME_MUTED; // Minimum possible value. | 274 pa_volume_t volume = PA_VOLUME_MUTED; // Minimum possible value. |
| 258 // Use the max volume of any channel as the volume. | 275 // Use the max volume of any channel as the volume. |
| 259 for (int i = 0; i < stream->channels_; ++i) { | 276 for (int i = 0; i < stream->channels_; ++i) { |
| 260 if (volume < info->volume.values[i]) | 277 if (volume < info->volume.values[i]) |
| 261 volume = info->volume.values[i]; | 278 volume = info->volume.values[i]; |
| 262 } | 279 } |
| 263 | 280 |
| 264 stream->volume_ = static_cast<double>(volume); | 281 stream->volume_ = static_cast<double>(volume); |
|
DaleCurtis
2013/02/25 18:52:18
I'd add a comment here that this is thread safe be
no longer working on chromium
2013/02/26 12:02:51
Done.
| |
| 265 } | 282 } |
| 266 | 283 |
| 267 // static, used by pa_stream_set_state_callback. | 284 // static, used by pa_stream_set_state_callback. |
| 268 void PulseAudioInputStream::StreamNotifyCallback(pa_stream* s, | 285 void PulseAudioInputStream::StreamNotifyCallback(pa_stream* s, |
| 269 void* user_data) { | 286 void* user_data) { |
| 270 PulseAudioInputStream* stream = | 287 PulseAudioInputStream* stream = |
| 271 reinterpret_cast<PulseAudioInputStream*>(user_data); | 288 reinterpret_cast<PulseAudioInputStream*>(user_data); |
| 272 if (s && stream->callback_ && | 289 if (s && stream->callback_ && |
| 273 pa_stream_get_state(s) == PA_STREAM_FAILED) { | 290 pa_stream_get_state(s) == PA_STREAM_FAILED) { |
| 274 stream->callback_->OnError(stream, pa_context_errno(stream->pa_context_)); | 291 stream->callback_->OnError(stream, pa_context_errno(stream->pa_context_)); |
| 275 } | 292 } |
| 276 | 293 |
| 277 pa_threaded_mainloop_signal(stream->pa_mainloop_, 0); | 294 pa_threaded_mainloop_signal(stream->pa_mainloop_, 0); |
| 278 } | 295 } |
| 279 | 296 |
| 280 void PulseAudioInputStream::ReadData() { | 297 void PulseAudioInputStream::ReadData() { |
| 281 uint32 hardware_delay = pulse::GetHardwareLatencyInBytes( | 298 uint32 hardware_delay = pulse::GetHardwareLatencyInBytes( |
| 282 handle_, params_.sample_rate(), params_.GetBytesPerFrame()); | 299 handle_, params_.sample_rate(), params_.GetBytesPerFrame()); |
| 283 | 300 |
| 284 // Update the AGC volume level once every second. Note that, | 301 // Update the AGC volume level once every second. Note that, |
| 285 // |volume| is also updated each time SetVolume() is called | 302 // |volume| is also updated each time SetVolume() is called |
| 286 // through IPC by the render-side AGC. | 303 // through IPC by the render-side AGC. |
| 304 // QueryAgcVolume() will trigger a callback to asynchronously update the | |
| 305 // |volume_|. | |
|
DaleCurtis
2013/02/25 18:52:18
This needs some mention of the fact that the |norm
no longer working on chromium
2013/02/26 12:02:51
Done.
| |
| 287 double normalized_volume = 0.0; | 306 double normalized_volume = 0.0; |
| 288 QueryAgcVolume(&normalized_volume); | 307 QueryAgcVolume(&normalized_volume); |
| 308 normalized_volume = volume_ / GetMaxVolume(); | |
| 289 | 309 |
| 290 do { | 310 do { |
| 291 size_t length = 0; | 311 size_t length = 0; |
| 292 const void* data = NULL; | 312 const void* data = NULL; |
| 293 pa_stream_peek(handle_, &data, &length); | 313 pa_stream_peek(handle_, &data, &length); |
| 294 if (!data || length == 0) | 314 if (!data || length == 0) |
| 295 break; | 315 break; |
| 296 | 316 |
| 297 buffer_->Append(reinterpret_cast<const uint8*>(data), length); | 317 buffer_->Append(reinterpret_cast<const uint8*>(data), length); |
| 298 | 318 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 314 DLOG(WARNING) << "OnData is being called consecutively, sleep 5ms to " | 334 DLOG(WARNING) << "OnData is being called consecutively, sleep 5ms to " |
| 315 << "wait until render consumes the data"; | 335 << "wait until render consumes the data"; |
| 316 base::PlatformThread::Sleep( | 336 base::PlatformThread::Sleep( |
| 317 base::TimeDelta::FromMilliseconds(5)); | 337 base::TimeDelta::FromMilliseconds(5)); |
| 318 } | 338 } |
| 319 | 339 |
| 320 pa_threaded_mainloop_signal(pa_mainloop_, 0); | 340 pa_threaded_mainloop_signal(pa_mainloop_, 0); |
| 321 } | 341 } |
| 322 | 342 |
| 323 } // namespace media | 343 } // namespace media |
| OLD | NEW |