Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: media/audio/pulse/pulse_input.cc

Issue 12310102: Change GetVolume() to be asynchronous when being called by pulse thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updated the comments Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/pulse/pulse.sigs ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
281 // It is safe to access |volume_| here since VolumeCallback() is running
282 // under PulseLock.
264 stream->volume_ = static_cast<double>(volume); 283 stream->volume_ = static_cast<double>(volume);
265 } 284 }
266 285
267 // static, used by pa_stream_set_state_callback. 286 // static, used by pa_stream_set_state_callback.
268 void PulseAudioInputStream::StreamNotifyCallback(pa_stream* s, 287 void PulseAudioInputStream::StreamNotifyCallback(pa_stream* s,
269 void* user_data) { 288 void* user_data) {
270 PulseAudioInputStream* stream = 289 PulseAudioInputStream* stream =
271 reinterpret_cast<PulseAudioInputStream*>(user_data); 290 reinterpret_cast<PulseAudioInputStream*>(user_data);
272 if (s && stream->callback_ && 291 if (s && stream->callback_ &&
273 pa_stream_get_state(s) == PA_STREAM_FAILED) { 292 pa_stream_get_state(s) == PA_STREAM_FAILED) {
274 stream->callback_->OnError(stream, pa_context_errno(stream->pa_context_)); 293 stream->callback_->OnError(stream, pa_context_errno(stream->pa_context_));
275 } 294 }
276 295
277 pa_threaded_mainloop_signal(stream->pa_mainloop_, 0); 296 pa_threaded_mainloop_signal(stream->pa_mainloop_, 0);
278 } 297 }
279 298
280 void PulseAudioInputStream::ReadData() { 299 void PulseAudioInputStream::ReadData() {
281 uint32 hardware_delay = pulse::GetHardwareLatencyInBytes( 300 uint32 hardware_delay = pulse::GetHardwareLatencyInBytes(
282 handle_, params_.sample_rate(), params_.GetBytesPerFrame()); 301 handle_, params_.sample_rate(), params_.GetBytesPerFrame());
283 302
284 // Update the AGC volume level once every second. Note that, 303 // Update the AGC volume level once every second. Note that,
285 // |volume| is also updated each time SetVolume() is called 304 // |volume| is also updated each time SetVolume() is called
286 // through IPC by the render-side AGC. 305 // through IPC by the render-side AGC.
306 // QueryAgcVolume() will trigger a callback to asynchronously update the
307 // |volume_|, we disregard the |normalized_volume| from QueryAgcVolume()
308 // and use the value calculated by |volume_|.
287 double normalized_volume = 0.0; 309 double normalized_volume = 0.0;
288 QueryAgcVolume(&normalized_volume); 310 QueryAgcVolume(&normalized_volume);
311 normalized_volume = volume_ / GetMaxVolume();
289 312
290 do { 313 do {
291 size_t length = 0; 314 size_t length = 0;
292 const void* data = NULL; 315 const void* data = NULL;
293 pa_stream_peek(handle_, &data, &length); 316 pa_stream_peek(handle_, &data, &length);
294 if (!data || length == 0) 317 if (!data || length == 0)
295 break; 318 break;
296 319
297 buffer_->Append(reinterpret_cast<const uint8*>(data), length); 320 buffer_->Append(reinterpret_cast<const uint8*>(data), length);
298 321
(...skipping 15 matching lines...) Expand all
314 DLOG(WARNING) << "OnData is being called consecutively, sleep 5ms to " 337 DLOG(WARNING) << "OnData is being called consecutively, sleep 5ms to "
315 << "wait until render consumes the data"; 338 << "wait until render consumes the data";
316 base::PlatformThread::Sleep( 339 base::PlatformThread::Sleep(
317 base::TimeDelta::FromMilliseconds(5)); 340 base::TimeDelta::FromMilliseconds(5));
318 } 341 }
319 342
320 pa_threaded_mainloop_signal(pa_mainloop_, 0); 343 pa_threaded_mainloop_signal(pa_mainloop_, 0);
321 } 344 }
322 345
323 } // namespace media 346 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/pulse/pulse.sigs ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698