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

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

Issue 1806313003: Pass task runners to AudioManager constructor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/audio_manager_pulse.h" 5 #include "media/audio/pulse/audio_manager_pulse.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/environment.h" 8 #include "base/environment.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 29 matching lines...) Expand all
40 static const int kMaximumOutputBufferSize = 8192; 40 static const int kMaximumOutputBufferSize = 8192;
41 41
42 // Default input buffer size. 42 // Default input buffer size.
43 static const int kDefaultInputBufferSize = 1024; 43 static const int kDefaultInputBufferSize = 1024;
44 44
45 #if defined(DLOPEN_PULSEAUDIO) 45 #if defined(DLOPEN_PULSEAUDIO)
46 static const base::FilePath::CharType kPulseLib[] = 46 static const base::FilePath::CharType kPulseLib[] =
47 FILE_PATH_LITERAL("libpulse.so.0"); 47 FILE_PATH_LITERAL("libpulse.so.0");
48 #endif 48 #endif
49 49
50 // static 50 AudioManagerPulse::AudioManagerPulse(
51 AudioManager* AudioManagerPulse::Create(AudioLogFactory* audio_log_factory) { 51 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
52 scoped_ptr<AudioManagerPulse> ret(new AudioManagerPulse(audio_log_factory)); 52 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
53 if (ret->Init()) 53 AudioLogFactory* audio_log_factory)
54 return ret.release(); 54 : AudioManagerBase(std::move(task_runner),
55 55 std::move(worker_task_runner),
56 DVLOG(1) << "PulseAudio is not available on the OS"; 56 audio_log_factory),
57 return NULL;
58 }
59
60 AudioManagerPulse::AudioManagerPulse(AudioLogFactory* audio_log_factory)
61 : AudioManagerBase(audio_log_factory),
62 input_mainloop_(NULL), 57 input_mainloop_(NULL),
63 input_context_(NULL), 58 input_context_(NULL),
64 devices_(NULL), 59 devices_(NULL),
65 native_input_sample_rate_(0) { 60 native_input_sample_rate_(0) {
66 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 61 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
67 } 62 }
68 63
69 AudioManagerPulse::~AudioManagerPulse() { 64 AudioManagerPulse::~AudioManagerPulse() {
70 Shutdown(); 65 Shutdown();
71 66
72 // The Pulse objects are the last things to be destroyed since Shutdown() 67 // The Pulse objects are the last things to be destroyed since Shutdown()
73 // needs them. 68 // needs them.
74 DestroyPulse(); 69 DestroyPulse();
alokp 2016/04/05 23:57:40 I think we need to Shutdown AudioManagerBase, whic
DaleCurtis 2016/04/06 01:22:29 Can we just post a task to a static DestroyPulse m
alokp 2016/04/06 02:03:44 Yup.. thats exactly what I am doing..
75 } 70 }
76 71
72 bool AudioManagerPulse::Init() {
73 DCHECK(!input_mainloop_);
74
75 #if defined(DLOPEN_PULSEAUDIO)
76 StubPathMap paths;
77
78 // Check if the pulse library is avialbale.
79 paths[kModulePulse].push_back(kPulseLib);
80 if (!InitializeStubs(paths)) {
81 VLOG(1) << "Failed on loading the Pulse library and symbols";
82 return false;
83 }
84 #endif // defined(DLOPEN_PULSEAUDIO)
85
86 // Create a mainloop API and connect to the default server.
87 // The mainloop is the internal asynchronous API event loop.
88 input_mainloop_ = pa_threaded_mainloop_new();
89 if (!input_mainloop_)
90 return false;
91
92 // Start the threaded mainloop.
93 if (pa_threaded_mainloop_start(input_mainloop_))
94 return false;
95
96 // Lock the event loop object, effectively blocking the event loop thread
97 // from processing events. This is necessary.
98 AutoPulseLock auto_lock(input_mainloop_);
99
100 pa_mainloop_api* pa_mainloop_api =
101 pa_threaded_mainloop_get_api(input_mainloop_);
102 input_context_ = pa_context_new(pa_mainloop_api, "Chrome input");
103 if (!input_context_)
104 return false;
105
106 pa_context_set_state_callback(input_context_, &pulse::ContextStateCallback,
107 input_mainloop_);
108 if (pa_context_connect(input_context_, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) {
109 VLOG(1) << "Failed to connect to the context. Error: "
110 << pa_strerror(pa_context_errno(input_context_));
111 return false;
112 }
113
114 // Wait until |input_context_| is ready. pa_threaded_mainloop_wait() must be
115 // called after pa_context_get_state() in case the context is already ready,
116 // otherwise pa_threaded_mainloop_wait() will hang indefinitely.
117 while (true) {
118 pa_context_state_t context_state = pa_context_get_state(input_context_);
119 if (!PA_CONTEXT_IS_GOOD(context_state))
120 return false;
121 if (context_state == PA_CONTEXT_READY)
122 break;
123 pa_threaded_mainloop_wait(input_mainloop_);
124 }
125
126 return true;
127 }
128
77 // Implementation of AudioManager. 129 // Implementation of AudioManager.
78 bool AudioManagerPulse::HasAudioOutputDevices() { 130 bool AudioManagerPulse::HasAudioOutputDevices() {
79 AudioDeviceNames devices; 131 AudioDeviceNames devices;
80 GetAudioOutputDeviceNames(&devices); 132 GetAudioOutputDeviceNames(&devices);
81 return !devices.empty(); 133 return !devices.empty();
82 } 134 }
83 135
84 bool AudioManagerPulse::HasAudioInputDevices() { 136 bool AudioManagerPulse::HasAudioInputDevices() {
85 AudioDeviceNames devices; 137 AudioDeviceNames devices;
86 GetAudioInputDeviceNames(&devices); 138 GetAudioInputDeviceNames(&devices);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 DCHECK(input_mainloop_); 262 DCHECK(input_mainloop_);
211 DCHECK(input_context_); 263 DCHECK(input_context_);
212 AutoPulseLock auto_lock(input_mainloop_); 264 AutoPulseLock auto_lock(input_mainloop_);
213 pa_operation* operation = pa_context_get_server_info( 265 pa_operation* operation = pa_context_get_server_info(
214 input_context_, SampleRateInfoCallback, this); 266 input_context_, SampleRateInfoCallback, this);
215 WaitForOperationCompletion(input_mainloop_, operation); 267 WaitForOperationCompletion(input_mainloop_, operation);
216 268
217 return native_input_sample_rate_; 269 return native_input_sample_rate_;
218 } 270 }
219 271
220 bool AudioManagerPulse::Init() {
221 DCHECK(!input_mainloop_);
222
223 #if defined(DLOPEN_PULSEAUDIO)
224 StubPathMap paths;
225
226 // Check if the pulse library is avialbale.
227 paths[kModulePulse].push_back(kPulseLib);
228 if (!InitializeStubs(paths)) {
229 VLOG(1) << "Failed on loading the Pulse library and symbols";
230 return false;
231 }
232 #endif // defined(DLOPEN_PULSEAUDIO)
233
234 // Create a mainloop API and connect to the default server.
235 // The mainloop is the internal asynchronous API event loop.
236 input_mainloop_ = pa_threaded_mainloop_new();
237 if (!input_mainloop_)
238 return false;
239
240 // Start the threaded mainloop.
241 if (pa_threaded_mainloop_start(input_mainloop_))
242 return false;
243
244 // Lock the event loop object, effectively blocking the event loop thread
245 // from processing events. This is necessary.
246 AutoPulseLock auto_lock(input_mainloop_);
247
248 pa_mainloop_api* pa_mainloop_api =
249 pa_threaded_mainloop_get_api(input_mainloop_);
250 input_context_ = pa_context_new(pa_mainloop_api, "Chrome input");
251 if (!input_context_)
252 return false;
253
254 pa_context_set_state_callback(input_context_, &pulse::ContextStateCallback,
255 input_mainloop_);
256 if (pa_context_connect(input_context_, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) {
257 VLOG(1) << "Failed to connect to the context. Error: "
258 << pa_strerror(pa_context_errno(input_context_));
259 return false;
260 }
261
262 // Wait until |input_context_| is ready. pa_threaded_mainloop_wait() must be
263 // called after pa_context_get_state() in case the context is already ready,
264 // otherwise pa_threaded_mainloop_wait() will hang indefinitely.
265 while (true) {
266 pa_context_state_t context_state = pa_context_get_state(input_context_);
267 if (!PA_CONTEXT_IS_GOOD(context_state))
268 return false;
269 if (context_state == PA_CONTEXT_READY)
270 break;
271 pa_threaded_mainloop_wait(input_mainloop_);
272 }
273
274 return true;
275 }
276
277 void AudioManagerPulse::DestroyPulse() { 272 void AudioManagerPulse::DestroyPulse() {
278 if (!input_mainloop_) { 273 if (!input_mainloop_) {
279 DCHECK(!input_context_); 274 DCHECK(!input_context_);
280 return; 275 return;
281 } 276 }
282 277
283 { 278 {
284 AutoPulseLock auto_lock(input_mainloop_); 279 AutoPulseLock auto_lock(input_mainloop_);
285 if (input_context_) { 280 if (input_context_) {
286 // Clear our state callback. 281 // Clear our state callback.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 void AudioManagerPulse::SampleRateInfoCallback(pa_context* context, 327 void AudioManagerPulse::SampleRateInfoCallback(pa_context* context,
333 const pa_server_info* info, 328 const pa_server_info* info,
334 void* user_data) { 329 void* user_data) {
335 AudioManagerPulse* manager = reinterpret_cast<AudioManagerPulse*>(user_data); 330 AudioManagerPulse* manager = reinterpret_cast<AudioManagerPulse*>(user_data);
336 331
337 manager->native_input_sample_rate_ = info->sample_spec.rate; 332 manager->native_input_sample_rate_ = info->sample_spec.rate;
338 pa_threaded_mainloop_signal(manager->input_mainloop_, 0); 333 pa_threaded_mainloop_signal(manager->input_mainloop_, 0);
339 } 334 }
340 335
341 } // namespace media 336 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698