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

Side by Side Diff: chrome/browser/chromeos/audio_mixer_pulse.cc

Issue 5859003: Add ALSA support to volume keys (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/chrome/browser/chromeos
Patch Set: fix comment Created 9 years, 11 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 | « chrome/browser/chromeos/audio_mixer_pulse.h ('k') | chrome/chrome_browser.gypi » ('j') | 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/chromeos/pulse_audio_mixer.h" 5 #include "chrome/browser/chromeos/audio_mixer_pulse.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/task.h" 10 #include "base/task.h"
11 11
12 namespace chromeos { 12 namespace chromeos {
13 13
14 // Using asynchronous versions of the threaded PulseAudio API, as well 14 // Using asynchronous versions of the threaded PulseAudio API, as well
15 // as a worker thread so gets, sets, and the init sequence do not block the 15 // as a worker thread so gets, sets, and the init sequence do not block the
16 // calling thread. GetVolume() and IsMute() can still be called synchronously 16 // calling thread. GetVolume() and IsMute() can still be called synchronously
17 // if needed, but take a bit longer (~2ms vs ~0.3ms). 17 // if needed, but take a bit longer (~2ms vs ~0.3ms).
18 // 18 //
19 // Set calls just return without waiting. If you must guarantee the value has 19 // Set calls just return without waiting. If you must guarantee the value has
20 // been set before continuing, immediately call the blocking Get version to 20 // been set before continuing, immediately call the blocking Get version to
21 // synchronously get the value back. 21 // synchronously get the value back.
22 // 22 //
23 // TODO(davej): Serialize volume/mute to preserve settings when restarting? 23 // TODO(davej): Serialize volume/mute to preserve settings when restarting?
24 24
25 namespace { 25 namespace {
26 26
27 const int kInvalidDeviceId = -1; 27 const int kInvalidDeviceId = -1;
28 28
29 const double kMinVolumeDb = -90.0;
30 // Choosing 6.0dB here instead of 0dB to give user chance to amplify audio some
31 // in case sounds or their setup is too quiet for them.
32 const double kMaxVolumeDb = 6.0;
33
29 // Used for passing custom data to the PulseAudio callbacks. 34 // Used for passing custom data to the PulseAudio callbacks.
30 struct CallbackWrapper { 35 struct CallbackWrapper {
31 PulseAudioMixer* instance; 36 AudioMixerPulse* instance;
32 bool done; 37 bool done;
33 void* userdata; 38 void* userdata;
34 }; 39 };
35 40
36 } // namespace 41 } // namespace
37 42
38 // AudioInfo contains all the values we care about when getting info for a 43 // AudioInfo contains all the values we care about when getting info for a
39 // Sink (output device) used by GetAudioInfo(). 44 // Sink (output device) used by GetAudioInfo().
40 struct PulseAudioMixer::AudioInfo { 45 struct AudioMixerPulse::AudioInfo {
41 pa_cvolume cvolume; 46 pa_cvolume cvolume;
42 bool muted; 47 bool muted;
43 }; 48 };
44 49
45 PulseAudioMixer::PulseAudioMixer() 50 AudioMixerPulse::AudioMixerPulse()
46 : device_id_(kInvalidDeviceId), 51 : device_id_(kInvalidDeviceId),
47 last_channels_(0), 52 last_channels_(0),
48 mainloop_lock_count_(0), 53 mainloop_lock_count_(0),
49 mixer_state_lock_(),
50 mixer_state_(UNINITIALIZED), 54 mixer_state_(UNINITIALIZED),
51 pa_context_(NULL), 55 pa_context_(NULL),
52 pa_mainloop_(NULL), 56 pa_mainloop_(NULL) {
53 thread_(NULL) {
54 } 57 }
55 58
56 PulseAudioMixer::~PulseAudioMixer() { 59 AudioMixerPulse::~AudioMixerPulse() {
57 PulseAudioFree(); 60 PulseAudioFree();
58 thread_->Stop(); 61 if (thread_ != NULL) {
59 thread_.reset(); 62 thread_->Stop();
63 thread_.reset();
64 }
60 } 65 }
61 66
62 bool PulseAudioMixer::Init(InitDoneCallback* callback) { 67 void AudioMixerPulse::Init(InitDoneCallback* callback) {
63 if (!InitThread()) 68 DCHECK(callback);
64 return false; 69 if (!InitThread()) {
70 callback->Run(false);
71 delete callback;
72 return;
73 }
65 74
66 // Post the task of starting up, which can block for 200-500ms, 75 // Post the task of starting up, which can block for 200-500ms,
67 // so best not to do it on the caller's thread. 76 // so best not to do it on the caller's thread.
68 thread_->message_loop()->PostTask(FROM_HERE, 77 thread_->message_loop()->PostTask(FROM_HERE,
69 NewRunnableMethod(this, &PulseAudioMixer::DoInit, callback)); 78 NewRunnableMethod(this, &AudioMixerPulse::DoInit, callback));
70 return true;
71 } 79 }
72 80
73 bool PulseAudioMixer::InitSync() { 81 bool AudioMixerPulse::InitSync() {
74 if (!InitThread()) 82 if (!InitThread())
75 return false; 83 return false;
76 return PulseAudioInit(); 84 return PulseAudioInit();
77 } 85 }
78 86
79 double PulseAudioMixer::GetVolumeDb() const { 87 double AudioMixerPulse::GetVolumeDb() const {
80 if (!MainloopLockIfReady()) 88 if (!MainloopLockIfReady())
81 return pa_sw_volume_to_dB(0); // this returns -inf. 89 return AudioMixer::kSilenceDb;
82 AudioInfo data; 90 AudioInfo data;
83 GetAudioInfo(&data); 91 GetAudioInfo(&data);
84 MainloopUnlock(); 92 MainloopUnlock();
85 return pa_sw_volume_to_dB(data.cvolume.values[0]); 93 return pa_sw_volume_to_dB(data.cvolume.values[0]);
86 } 94 }
87 95
88 bool PulseAudioMixer::GetVolumeDbAsync(GetVolumeCallback* callback, 96 bool AudioMixerPulse::GetVolumeLimits(double* vol_min, double* vol_max) {
89 void* user) { 97 if (vol_min)
90 if (CheckState() != READY) 98 *vol_min = kMinVolumeDb;
91 return false; 99 if (vol_max)
92 thread_->message_loop()->PostTask(FROM_HERE, 100 *vol_max = kMaxVolumeDb;
93 NewRunnableMethod(this,
94 &PulseAudioMixer::DoGetVolume,
95 callback, user));
96 return true; 101 return true;
97 } 102 }
98 103
99 void PulseAudioMixer::SetVolumeDb(double vol_db) { 104 void AudioMixerPulse::SetVolumeDb(double vol_db) {
100 if (!MainloopLockIfReady()) 105 if (!MainloopLockIfReady())
101 return; 106 return;
102 107
103 // last_channels_ determines the number of channels on the main output device, 108 // last_channels_ determines the number of channels on the main output device,
104 // and is used later to set the volume on all channels at once. 109 // and is used later to set the volume on all channels at once.
105 if (!last_channels_) { 110 if (!last_channels_) {
106 AudioInfo data; 111 AudioInfo data;
107 GetAudioInfo(&data); 112 GetAudioInfo(&data);
108 last_channels_ = data.cvolume.channels; 113 last_channels_ = data.cvolume.channels;
109 } 114 }
110 115
111 pa_operation* pa_op; 116 pa_operation* pa_op;
112 pa_cvolume cvolume; 117 pa_cvolume cvolume;
113 pa_cvolume_set(&cvolume, last_channels_, pa_sw_volume_from_dB(vol_db)); 118 pa_cvolume_set(&cvolume, last_channels_, pa_sw_volume_from_dB(vol_db));
114 pa_op = pa_context_set_sink_volume_by_index(pa_context_, device_id_, 119 pa_op = pa_context_set_sink_volume_by_index(pa_context_, device_id_,
115 &cvolume, NULL, NULL); 120 &cvolume, NULL, NULL);
116 pa_operation_unref(pa_op); 121 pa_operation_unref(pa_op);
117 MainloopUnlock(); 122 MainloopUnlock();
123 VLOG(1) << "Set volume to " << vol_db << " dB";
118 } 124 }
119 125
120 bool PulseAudioMixer::IsMute() const { 126 bool AudioMixerPulse::IsMute() const {
121 if (!MainloopLockIfReady()) 127 if (!MainloopLockIfReady())
122 return false; 128 return false;
123 AudioInfo data; 129 AudioInfo data;
124 GetAudioInfo(&data); 130 GetAudioInfo(&data);
125 MainloopUnlock(); 131 MainloopUnlock();
126 return data.muted; 132 return data.muted;
127 } 133 }
128 134
129 void PulseAudioMixer::SetMute(bool mute) { 135 void AudioMixerPulse::SetMute(bool mute) {
130 if (!MainloopLockIfReady()) 136 if (!MainloopLockIfReady())
131 return; 137 return;
132 pa_operation* pa_op; 138 pa_operation* pa_op;
133 pa_op = pa_context_set_sink_mute_by_index(pa_context_, device_id_, 139 pa_op = pa_context_set_sink_mute_by_index(pa_context_, device_id_,
134 mute ? 1 : 0, NULL, NULL); 140 mute ? 1 : 0, NULL, NULL);
135 pa_operation_unref(pa_op); 141 pa_operation_unref(pa_op);
136 MainloopUnlock(); 142 MainloopUnlock();
143 VLOG(1) << "Set mute to " << mute;
137 } 144 }
138 145
139 PulseAudioMixer::State PulseAudioMixer::CheckState() const { 146 AudioMixer::State AudioMixerPulse::GetState() const {
140 AutoLock lock(mixer_state_lock_); 147 AutoLock lock(mixer_state_lock_);
141 // If we think it's ready, verify it is actually so. 148 // If we think it's ready, verify it is actually so.
142 if ((mixer_state_ == READY) && 149 if ((mixer_state_ == READY) &&
143 (pa_context_get_state(pa_context_) != PA_CONTEXT_READY)) 150 (pa_context_get_state(pa_context_) != PA_CONTEXT_READY))
144 mixer_state_ = IN_ERROR; 151 mixer_state_ = IN_ERROR;
145 return mixer_state_; 152 return mixer_state_;
146 } 153 }
147 154
148 //////////////////////////////////////////////////////////////////////////////// 155 ////////////////////////////////////////////////////////////////////////////////
149 // Private functions follow 156 // Private functions follow
150 157
151 void PulseAudioMixer::DoInit(InitDoneCallback* callback) { 158 void AudioMixerPulse::DoInit(InitDoneCallback* callback) {
152 bool success = PulseAudioInit(); 159 bool success = PulseAudioInit();
153 callback->Run(success); 160 callback->Run(success);
154 delete callback; 161 delete callback;
155 } 162 }
156 163
157 void PulseAudioMixer::DoGetVolume(GetVolumeCallback* callback, 164 bool AudioMixerPulse::InitThread() {
158 void* user) {
159 callback->Run(GetVolumeDb(), user);
160 delete callback;
161 }
162
163 bool PulseAudioMixer::InitThread() {
164 AutoLock lock(mixer_state_lock_); 165 AutoLock lock(mixer_state_lock_);
165 166
166 if (mixer_state_ != UNINITIALIZED) 167 if (mixer_state_ != UNINITIALIZED)
167 return false; 168 return false;
169
168 if (thread_ == NULL) { 170 if (thread_ == NULL) {
169 thread_.reset(new base::Thread("PulseAudioMixer")); 171 thread_.reset(new base::Thread("AudioMixerPulse"));
170 if (!thread_->Start()) { 172 if (!thread_->Start()) {
171 thread_.reset(); 173 thread_.reset();
172 return false; 174 return false;
173 } 175 }
174 } 176 }
175 mixer_state_ = INITIALIZING; 177 mixer_state_ = INITIALIZING;
176 return true; 178 return true;
177 } 179 }
178 180
179 // static 181 // static
180 void PulseAudioMixer::ConnectToPulseCallbackThunk( 182 void AudioMixerPulse::ConnectToPulseCallbackThunk(
181 pa_context* context, void* userdata) { 183 pa_context* context, void* userdata) {
182 CallbackWrapper* data = 184 CallbackWrapper* data =
183 static_cast<CallbackWrapper*>(userdata); 185 static_cast<CallbackWrapper*>(userdata);
184 data->instance->OnConnectToPulseCallback(context, &data->done); 186 data->instance->OnConnectToPulseCallback(context, &data->done);
185 } 187 }
186 188
187 void PulseAudioMixer::OnConnectToPulseCallback( 189 void AudioMixerPulse::OnConnectToPulseCallback(
188 pa_context* context, bool* connect_done) { 190 pa_context* context, bool* connect_done) {
189 pa_context_state_t state = pa_context_get_state(context); 191 pa_context_state_t state = pa_context_get_state(context);
190 if (state == PA_CONTEXT_READY || 192 if (state == PA_CONTEXT_READY ||
191 state == PA_CONTEXT_FAILED || 193 state == PA_CONTEXT_FAILED ||
192 state == PA_CONTEXT_TERMINATED) { 194 state == PA_CONTEXT_TERMINATED) {
193 // Connection process has reached a terminal state. Wake PulseAudioInit(). 195 // Connection process has reached a terminal state. Wake PulseAudioInit().
194 *connect_done = true; 196 *connect_done = true;
195 MainloopSignal(); 197 MainloopSignal();
196 } 198 }
197 } 199 }
198 200
199 bool PulseAudioMixer::PulseAudioInit() { 201 bool AudioMixerPulse::PulseAudioInit() {
200 pa_context_state_t state = PA_CONTEXT_FAILED; 202 pa_context_state_t state = PA_CONTEXT_FAILED;
201 203
202 { 204 {
203 AutoLock lock(mixer_state_lock_); 205 AutoLock lock(mixer_state_lock_);
204 if (mixer_state_ != INITIALIZING) 206 if (mixer_state_ != INITIALIZING)
205 return false; 207 return false;
206 208
207 pa_mainloop_ = pa_threaded_mainloop_new(); 209 pa_mainloop_ = pa_threaded_mainloop_new();
208 if (!pa_mainloop_) { 210 if (!pa_mainloop_) {
209 LOG(ERROR) << "Can't create PulseAudio mainloop"; 211 LOG(ERROR) << "Can't create PulseAudio mainloop";
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 } 293 }
292 294
293 return true; 295 return true;
294 } 296 }
295 297
296 // Failed startup sequence, clean up now. 298 // Failed startup sequence, clean up now.
297 PulseAudioFree(); 299 PulseAudioFree();
298 return false; 300 return false;
299 } 301 }
300 302
301 void PulseAudioMixer::PulseAudioFree() { 303 void AudioMixerPulse::PulseAudioFree() {
302 { 304 {
303 AutoLock lock(mixer_state_lock_); 305 AutoLock lock(mixer_state_lock_);
304 if (!pa_mainloop_) 306 if (!pa_mainloop_)
305 mixer_state_ = UNINITIALIZED; 307 mixer_state_ = UNINITIALIZED;
306 if ((mixer_state_ == UNINITIALIZED) || (mixer_state_ == SHUTTING_DOWN)) 308 if ((mixer_state_ == UNINITIALIZED) || (mixer_state_ == SHUTTING_DOWN))
307 return; 309 return;
310
308 // If still initializing on another thread, this will cause it to exit. 311 // If still initializing on another thread, this will cause it to exit.
309 mixer_state_ = SHUTTING_DOWN; 312 mixer_state_ = SHUTTING_DOWN;
310 } 313 }
311 314
312 DCHECK(pa_mainloop_); 315 DCHECK(pa_mainloop_);
313 316
314 MainloopLock(); 317 MainloopLock();
315 if (pa_context_) { 318 if (pa_context_) {
316 pa_context_disconnect(pa_context_); 319 pa_context_disconnect(pa_context_);
317 pa_context_unref(pa_context_); 320 pa_context_unref(pa_context_);
318 pa_context_ = NULL; 321 pa_context_ = NULL;
319 } 322 }
320 MainloopUnlock(); 323 MainloopUnlock();
321 324
322 pa_threaded_mainloop_stop(pa_mainloop_); 325 pa_threaded_mainloop_stop(pa_mainloop_);
323 pa_threaded_mainloop_free(pa_mainloop_); 326 pa_threaded_mainloop_free(pa_mainloop_);
324 pa_mainloop_ = NULL; 327 pa_mainloop_ = NULL;
325 328
326 { 329 {
327 AutoLock lock(mixer_state_lock_); 330 AutoLock lock(mixer_state_lock_);
328 mixer_state_ = UNINITIALIZED; 331 mixer_state_ = UNINITIALIZED;
329 } 332 }
330 } 333 }
331 334
332 void PulseAudioMixer::CompleteOperation(pa_operation* pa_op, 335 void AudioMixerPulse::CompleteOperation(pa_operation* pa_op,
333 bool* done) const { 336 bool* done) const {
334 // After starting any operation, this helper checks if it started OK, then 337 // After starting any operation, this helper checks if it started OK, then
335 // waits for it to complete by iterating through the mainloop until the 338 // waits for it to complete by iterating through the mainloop until the
336 // operation is not running anymore. 339 // operation is not running anymore.
337 CHECK(pa_op); 340 CHECK(pa_op);
338 341
339 while (pa_operation_get_state(pa_op) == PA_OPERATION_RUNNING) { 342 while (pa_operation_get_state(pa_op) == PA_OPERATION_RUNNING) {
340 // If operation still running, but we got what we needed, cancel it now. 343 // If operation still running, but we got what we needed, cancel it now.
341 if (*done) { 344 if (*done) {
342 pa_operation_cancel(pa_op); 345 pa_operation_cancel(pa_op);
343 break; 346 break;
344 } 347 }
345 MainloopWait(); 348 MainloopWait();
346 } 349 }
347 pa_operation_unref(pa_op); 350 pa_operation_unref(pa_op);
348 } 351 }
349 352
350 // Must be called with mainloop lock held 353 // Must be called with mainloop lock held
351 void PulseAudioMixer::GetDefaultPlaybackDevice() { 354 void AudioMixerPulse::GetDefaultPlaybackDevice() {
352 DCHECK_GT(mainloop_lock_count_, 0); 355 DCHECK_GT(mainloop_lock_count_, 0);
353 DCHECK(pa_context_); 356 DCHECK(pa_context_);
354 DCHECK(pa_context_get_state(pa_context_) == PA_CONTEXT_READY); 357 DCHECK(pa_context_get_state(pa_context_) == PA_CONTEXT_READY);
355 358
356 CallbackWrapper data = {this, false, NULL}; 359 CallbackWrapper data = {this, false, NULL};
357 360
358 pa_operation* pa_op = pa_context_get_sink_info_list(pa_context_, 361 pa_operation* pa_op = pa_context_get_sink_info_list(pa_context_,
359 EnumerateDevicesCallback, 362 EnumerateDevicesCallback,
360 &data); 363 &data);
361 CompleteOperation(pa_op, &data.done); 364 CompleteOperation(pa_op, &data.done);
362 return; 365 return;
363 } 366 }
364 367
365 void PulseAudioMixer::OnEnumerateDevices(const pa_sink_info* sink_info, 368 void AudioMixerPulse::OnEnumerateDevices(const pa_sink_info* sink_info,
366 int eol, bool* done) { 369 int eol, bool* done) {
367 if (device_id_ != kInvalidDeviceId) 370 if (device_id_ != kInvalidDeviceId)
368 return; 371 return;
369 372
370 // TODO(davej): Should we handle cases of more than one output sink device? 373 // TODO(davej): Should we handle cases of more than one output sink device?
371 374
372 // eol is < 0 for error, > 0 for end of list, ==0 while listing. 375 // eol is < 0 for error, > 0 for end of list, ==0 while listing.
373 if (eol == 0) { 376 if (eol == 0) {
374 device_id_ = sink_info->index; 377 device_id_ = sink_info->index;
375 } 378 }
376 *done = true; 379 *done = true;
377 MainloopSignal(); 380 MainloopSignal();
378 } 381 }
379 382
380 // static 383 // static
381 void PulseAudioMixer::EnumerateDevicesCallback(pa_context* unused, 384 void AudioMixerPulse::EnumerateDevicesCallback(pa_context* unused,
382 const pa_sink_info* sink_info, 385 const pa_sink_info* sink_info,
383 int eol, 386 int eol,
384 void* userdata) { 387 void* userdata) {
385 CallbackWrapper* data = 388 CallbackWrapper* data =
386 static_cast<CallbackWrapper*>(userdata); 389 static_cast<CallbackWrapper*>(userdata);
387 data->instance->OnEnumerateDevices(sink_info, eol, &data->done); 390 data->instance->OnEnumerateDevices(sink_info, eol, &data->done);
388 } 391 }
389 392
390 // Must be called with lock held 393 // Must be called with lock held
391 void PulseAudioMixer::GetAudioInfo(AudioInfo* info) const { 394 void AudioMixerPulse::GetAudioInfo(AudioInfo* info) const {
392 DCHECK_GT(mainloop_lock_count_, 0); 395 DCHECK_GT(mainloop_lock_count_, 0);
393 CallbackWrapper data = {const_cast<PulseAudioMixer*>(this), false, info}; 396 CallbackWrapper data = {const_cast<AudioMixerPulse*>(this), false, info};
394 pa_operation* pa_op = pa_context_get_sink_info_by_index(pa_context_, 397 pa_operation* pa_op = pa_context_get_sink_info_by_index(pa_context_,
395 device_id_, 398 device_id_,
396 GetAudioInfoCallback, 399 GetAudioInfoCallback,
397 &data); 400 &data);
398 CompleteOperation(pa_op, &data.done); 401 CompleteOperation(pa_op, &data.done);
399 } 402 }
400 403
401 // static 404 // static
402 void PulseAudioMixer::GetAudioInfoCallback(pa_context* unused, 405 void AudioMixerPulse::GetAudioInfoCallback(pa_context* unused,
403 const pa_sink_info* sink_info, 406 const pa_sink_info* sink_info,
404 int eol, 407 int eol,
405 void* userdata) { 408 void* userdata) {
406 CallbackWrapper* data = static_cast<CallbackWrapper*>(userdata); 409 CallbackWrapper* data = static_cast<CallbackWrapper*>(userdata);
407 AudioInfo* info = static_cast<AudioInfo*>(data->userdata); 410 AudioInfo* info = static_cast<AudioInfo*>(data->userdata);
408 411
409 // Copy just the information we care about. 412 // Copy just the information we care about.
410 if (eol == 0) { 413 if (eol == 0) {
411 info->cvolume = sink_info->volume; 414 info->cvolume = sink_info->volume;
412 info->muted = sink_info->mute ? true : false; 415 info->muted = sink_info->mute ? true : false;
413 data->done = true; 416 data->done = true;
414 } 417 }
415 data->instance->MainloopSignal(); 418 data->instance->MainloopSignal();
416 } 419 }
417 420
418 inline void PulseAudioMixer::MainloopLock() const { 421 inline void AudioMixerPulse::MainloopLock() const {
419 pa_threaded_mainloop_lock(pa_mainloop_); 422 pa_threaded_mainloop_lock(pa_mainloop_);
420 ++mainloop_lock_count_; 423 ++mainloop_lock_count_;
421 } 424 }
422 425
423 inline void PulseAudioMixer::MainloopUnlock() const { 426 inline void AudioMixerPulse::MainloopUnlock() const {
424 --mainloop_lock_count_; 427 --mainloop_lock_count_;
425 pa_threaded_mainloop_unlock(pa_mainloop_); 428 pa_threaded_mainloop_unlock(pa_mainloop_);
426 } 429 }
427 430
428 // Must be called with the lock held. 431 // Must be called with the lock held.
429 inline void PulseAudioMixer::MainloopWait() const { 432 inline void AudioMixerPulse::MainloopWait() const {
430 DCHECK_GT(mainloop_lock_count_, 0); 433 DCHECK_GT(mainloop_lock_count_, 0);
431 pa_threaded_mainloop_wait(pa_mainloop_); 434 pa_threaded_mainloop_wait(pa_mainloop_);
432 } 435 }
433 436
434 // Must be called with the lock held. 437 // Must be called with the lock held.
435 inline void PulseAudioMixer::MainloopSignal() const { 438 inline void AudioMixerPulse::MainloopSignal() const {
436 DCHECK_GT(mainloop_lock_count_, 0); 439 DCHECK_GT(mainloop_lock_count_, 0);
437 pa_threaded_mainloop_signal(pa_mainloop_, 0); 440 pa_threaded_mainloop_signal(pa_mainloop_, 0);
438 } 441 }
439 442
440 inline bool PulseAudioMixer::MainloopSafeLock() const { 443 inline bool AudioMixerPulse::MainloopSafeLock() const {
441 AutoLock lock(mixer_state_lock_); 444 AutoLock lock(mixer_state_lock_);
442 if ((mixer_state_ == SHUTTING_DOWN) || (!pa_mainloop_)) 445 if ((mixer_state_ == SHUTTING_DOWN) || (!pa_mainloop_))
443 return false; 446 return false;
447
444 pa_threaded_mainloop_lock(pa_mainloop_); 448 pa_threaded_mainloop_lock(pa_mainloop_);
445 ++mainloop_lock_count_; 449 ++mainloop_lock_count_;
446 return true; 450 return true;
447 } 451 }
448 452
449 inline bool PulseAudioMixer::MainloopLockIfReady() const { 453 inline bool AudioMixerPulse::MainloopLockIfReady() const {
450 AutoLock lock(mixer_state_lock_); 454 AutoLock lock(mixer_state_lock_);
451 if (mixer_state_ != READY) 455 if (mixer_state_ != READY)
452 return false; 456 return false;
453 if (!pa_mainloop_) 457 if (!pa_mainloop_)
454 return false; 458 return false;
455 pa_threaded_mainloop_lock(pa_mainloop_); 459 pa_threaded_mainloop_lock(pa_mainloop_);
456 ++mainloop_lock_count_; 460 ++mainloop_lock_count_;
457 return true; 461 return true;
458 } 462 }
459 463
460 } // namespace chromeos 464 } // namespace chromeos
461 465
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/audio_mixer_pulse.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698