diff options
Diffstat (limited to 'media/audio/pulse/pulse_input.cc')
-rw-r--r-- | media/audio/pulse/pulse_input.cc | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc index 14ef242..7e2ca22 100644 --- a/media/audio/pulse/pulse_input.cc +++ b/media/audio/pulse/pulse_input.cc @@ -4,8 +4,6 @@ #include "media/audio/pulse/pulse_input.h" -#include <pulse/pulseaudio.h> - #include "base/logging.h" #include "media/audio/pulse/audio_manager_pulse.h" #include "media/audio/pulse/pulse_util.h" @@ -30,6 +28,7 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager, channels_(0), volume_(0.0), stream_started_(false), + muted_(false), fifo_(params.channels(), params.frames_per_buffer(), kNumberOfBlocksBufferInFifo), @@ -185,20 +184,17 @@ double PulseAudioInputStream::GetVolume() { // Return zero and the callback will asynchronously update the |volume_|. return 0.0; } else { - // Called by other thread, put an AutoPulseLock and wait for the operation. - AutoPulseLock auto_lock(pa_mainloop_); - if (!handle_) - return 0.0; - - size_t index = pa_stream_get_device_index(handle_); - pa_operation* operation = pa_context_get_source_info_by_index( - pa_context_, index, &VolumeCallback, this); - WaitForOperationCompletion(pa_mainloop_, operation); - + GetSourceInformation(&VolumeCallback); return volume_; } } +bool PulseAudioInputStream::IsMuted() { + DCHECK(thread_checker_.CalledOnValidThread()); + GetSourceInformation(&MuteCallback); + return muted_; +} + // static, used by pa_stream_set_read_callback. void PulseAudioInputStream::ReadCallback(pa_stream* handle, size_t length, @@ -236,11 +232,32 @@ void PulseAudioInputStream::VolumeCallback(pa_context* context, stream->volume_ = static_cast<double>(volume); } +// static, used by pa_context_get_source_info_by_index. +void PulseAudioInputStream::MuteCallback(pa_context* context, + const pa_source_info* info, + int error, + void* user_data) { + // Runs on PulseAudio callback thread. It might be possible to make this + // method more thread safe by passing a struct (or pair) of a local copy of + // |pa_mainloop_| and |muted_| instead. + PulseAudioInputStream* stream = + reinterpret_cast<PulseAudioInputStream*>(user_data); + + // Avoid infinite wait loop in case of error. + if (error) { + pa_threaded_mainloop_signal(stream->pa_mainloop_, 0); + return; + } + + stream->muted_ = info->mute != 0; +} + // static, used by pa_stream_set_state_callback. void PulseAudioInputStream::StreamNotifyCallback(pa_stream* s, void* user_data) { PulseAudioInputStream* stream = reinterpret_cast<PulseAudioInputStream*>(user_data); + if (s && stream->callback_ && pa_stream_get_state(s) == PA_STREAM_FAILED) { stream->callback_->OnError(stream); @@ -301,4 +318,16 @@ void PulseAudioInputStream::ReadData() { pa_threaded_mainloop_signal(pa_mainloop_, 0); } +bool PulseAudioInputStream::GetSourceInformation(pa_source_info_cb_t callback) { + AutoPulseLock auto_lock(pa_mainloop_); + if (!handle_) + return false; + + size_t index = pa_stream_get_device_index(handle_); + pa_operation* operation = + pa_context_get_source_info_by_index(pa_context_, index, callback, this); + WaitForOperationCompletion(pa_mainloop_, operation); + return true; +} + } // namespace media |