| Index: media/audio/pulse/pulse_input.cc
|
| diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc
|
| index 6f241fbaff761ce50298bb382876a0184f730f73..3e6e5580bbc4bd910ed5d331c4a14872a41540c7 100644
|
| --- a/media/audio/pulse/pulse_input.cc
|
| +++ b/media/audio/pulse/pulse_input.cc
|
| @@ -217,16 +217,33 @@ void PulseAudioInputStream::SetVolume(double volume) {
|
| }
|
|
|
| double PulseAudioInputStream::GetVolume() {
|
| - AutoPulseLock auto_lock(pa_mainloop_);
|
| - if (!handle_)
|
| + if (pa_threaded_mainloop_in_thread(pa_mainloop_)) {
|
| + // When being called by the pulse thread, GetVolume() is asynchronous and
|
| + // called under AutoPulseLock.
|
| + 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);
|
| + // Do not wait for the operation since we can't block the pulse thread.
|
| + pa_operation_unref(operation);
|
| +
|
| + // 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);
|
| + 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);
|
|
|
| - return volume_;
|
| + return volume_;
|
| + }
|
| }
|
|
|
| // static, used by pa_stream_set_read_callback.
|
| @@ -261,6 +278,8 @@ void PulseAudioInputStream::VolumeCallback(pa_context* context,
|
| volume = info->volume.values[i];
|
| }
|
|
|
| + // It is safe to access |volume_| here since VolumeCallback() is running
|
| + // under PulseLock.
|
| stream->volume_ = static_cast<double>(volume);
|
| }
|
|
|
| @@ -284,8 +303,12 @@ void PulseAudioInputStream::ReadData() {
|
| // Update the AGC volume level once every second. Note that,
|
| // |volume| is also updated each time SetVolume() is called
|
| // through IPC by the render-side AGC.
|
| + // QueryAgcVolume() will trigger a callback to asynchronously update the
|
| + // |volume_|, we disregard the |normalized_volume| from QueryAgcVolume()
|
| + // and use the value calculated by |volume_|.
|
| double normalized_volume = 0.0;
|
| QueryAgcVolume(&normalized_volume);
|
| + normalized_volume = volume_ / GetMaxVolume();
|
|
|
| do {
|
| size_t length = 0;
|
|
|