summaryrefslogtreecommitdiffstats
path: root/media/audio/pulse/pulse_input.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/audio/pulse/pulse_input.cc')
-rw-r--r--media/audio/pulse/pulse_input.cc53
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