Index: media/audio/pulse/pulse_input.cc |
diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc |
index 14ef242759a68d48db6da943ebb899b1089c3cf6..7e2ca22a7a51b293a35588996f37c655e0ae2d3b 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 |