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

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: implemented ScopedAudioManagerPtr Created 4 years, 9 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(task_runner, worker_task_runner, audio_log_factory),
55
56 DVLOG(1) << "PulseAudio is not available on the OS";
57 return NULL;
58 }
59
60 AudioManagerPulse::AudioManagerPulse(AudioLogFactory* audio_log_factory)
61 : AudioManagerBase(audio_log_factory),
62 input_mainloop_(NULL), 55 input_mainloop_(NULL),
63 input_context_(NULL), 56 input_context_(NULL),
64 devices_(NULL), 57 devices_(NULL),
65 native_input_sample_rate_(0) { 58 native_input_sample_rate_(0) {
66 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 59 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
67 } 60 }
68 61
69 AudioManagerPulse::~AudioManagerPulse() { 62 AudioManagerPulse::~AudioManagerPulse() {
70 Shutdown(); 63 Shutdown();
71 64
72 // The Pulse objects are the last things to be destroyed since Shutdown() 65 // The Pulse objects are the last things to be destroyed since Shutdown()
73 // needs them. 66 // needs them.
74 DestroyPulse(); 67 DestroyPulse();
75 } 68 }
76 69
70 bool AudioManagerPulse::Init() {
tommi (sloooow) - chröme 2016/03/19 02:32:42 I'm assuming this is all moved code.
alokp 2016/03/22 21:47:07 YES.
71 DCHECK(!input_mainloop_);
72
73 #if defined(DLOPEN_PULSEAUDIO)
74 StubPathMap paths;
75
76 // Check if the pulse library is avialbale.
77 paths[kModulePulse].push_back(kPulseLib);
78 if (!InitializeStubs(paths)) {
79 VLOG(1) << "Failed on loading the Pulse library and symbols";
80 return false;
81 }
82 #endif // defined(DLOPEN_PULSEAUDIO)
83
84 // Create a mainloop API and connect to the default server.
85 // The mainloop is the internal asynchronous API event loop.
86 input_mainloop_ = pa_threaded_mainloop_new();
87 if (!input_mainloop_)
88 return false;
89
90 // Start the threaded mainloop.
91 if (pa_threaded_mainloop_start(input_mainloop_))
92 return false;
93
94 // Lock the event loop object, effectively blocking the event loop thread
95 // from processing events. This is necessary.
96 AutoPulseLock auto_lock(input_mainloop_);
97
98 pa_mainloop_api* pa_mainloop_api =
99 pa_threaded_mainloop_get_api(input_mainloop_);
100 input_context_ = pa_context_new(pa_mainloop_api, "Chrome input");
101 if (!input_context_)
102 return false;
103
104 pa_context_set_state_callback(input_context_, &pulse::ContextStateCallback,
105 input_mainloop_);
106 if (pa_context_connect(input_context_, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) {
107 VLOG(1) << "Failed to connect to the context. Error: "
108 << pa_strerror(pa_context_errno(input_context_));
109 return false;
110 }
111
112 // Wait until |input_context_| is ready. pa_threaded_mainloop_wait() must be
113 // called after pa_context_get_state() in case the context is already ready,
114 // otherwise pa_threaded_mainloop_wait() will hang indefinitely.
115 while (true) {
116 pa_context_state_t context_state = pa_context_get_state(input_context_);
117 if (!PA_CONTEXT_IS_GOOD(context_state))
118 return false;
119 if (context_state == PA_CONTEXT_READY)
120 break;
121 pa_threaded_mainloop_wait(input_mainloop_);
122 }
123
124 return true;
125 }
126
77 // Implementation of AudioManager. 127 // Implementation of AudioManager.
78 bool AudioManagerPulse::HasAudioOutputDevices() { 128 bool AudioManagerPulse::HasAudioOutputDevices() {
79 AudioDeviceNames devices; 129 AudioDeviceNames devices;
80 GetAudioOutputDeviceNames(&devices); 130 GetAudioOutputDeviceNames(&devices);
81 return !devices.empty(); 131 return !devices.empty();
82 } 132 }
83 133
84 bool AudioManagerPulse::HasAudioInputDevices() { 134 bool AudioManagerPulse::HasAudioInputDevices() {
85 AudioDeviceNames devices; 135 AudioDeviceNames devices;
86 GetAudioInputDeviceNames(&devices); 136 GetAudioInputDeviceNames(&devices);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 DCHECK(input_mainloop_); 260 DCHECK(input_mainloop_);
211 DCHECK(input_context_); 261 DCHECK(input_context_);
212 AutoPulseLock auto_lock(input_mainloop_); 262 AutoPulseLock auto_lock(input_mainloop_);
213 pa_operation* operation = pa_context_get_server_info( 263 pa_operation* operation = pa_context_get_server_info(
214 input_context_, SampleRateInfoCallback, this); 264 input_context_, SampleRateInfoCallback, this);
215 WaitForOperationCompletion(input_mainloop_, operation); 265 WaitForOperationCompletion(input_mainloop_, operation);
216 266
217 return native_input_sample_rate_; 267 return native_input_sample_rate_;
218 } 268 }
219 269
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() { 270 void AudioManagerPulse::DestroyPulse() {
278 if (!input_mainloop_) { 271 if (!input_mainloop_) {
279 DCHECK(!input_context_); 272 DCHECK(!input_context_);
280 return; 273 return;
281 } 274 }
282 275
283 { 276 {
284 AutoPulseLock auto_lock(input_mainloop_); 277 AutoPulseLock auto_lock(input_mainloop_);
285 if (input_context_) { 278 if (input_context_) {
286 // Clear our state callback. 279 // Clear our state callback.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 void AudioManagerPulse::SampleRateInfoCallback(pa_context* context, 325 void AudioManagerPulse::SampleRateInfoCallback(pa_context* context,
333 const pa_server_info* info, 326 const pa_server_info* info,
334 void* user_data) { 327 void* user_data) {
335 AudioManagerPulse* manager = reinterpret_cast<AudioManagerPulse*>(user_data); 328 AudioManagerPulse* manager = reinterpret_cast<AudioManagerPulse*>(user_data);
336 329
337 manager->native_input_sample_rate_ = info->sample_spec.rate; 330 manager->native_input_sample_rate_ = info->sample_spec.rate;
338 pa_threaded_mainloop_signal(manager->input_mainloop_, 0); 331 pa_threaded_mainloop_signal(manager->input_mainloop_, 0);
339 } 332 }
340 333
341 } // namespace media 334 } // namespace media
OLDNEW
« media/audio/fake_audio_manager.cc ('K') | « media/audio/pulse/audio_manager_pulse.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698