OLD | NEW |
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/pulse_unified.h" | 5 #include "media/audio/pulse/pulse_unified.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/single_thread_task_runner.h" |
8 #include "base/time/time.h" | 8 #include "base/time/time.h" |
9 #include "media/audio/audio_manager_base.h" | 9 #include "media/audio/audio_manager_base.h" |
10 #include "media/audio/audio_parameters.h" | 10 #include "media/audio/audio_parameters.h" |
11 #include "media/audio/pulse/pulse_util.h" | 11 #include "media/audio/pulse/pulse_util.h" |
12 #include "media/base/seekable_buffer.h" | 12 #include "media/base/seekable_buffer.h" |
13 | 13 |
14 namespace media { | 14 namespace media { |
15 | 15 |
16 using pulse::AutoPulseLock; | 16 using pulse::AutoPulseLock; |
17 using pulse::WaitForOperationCompletion; | 17 using pulse::WaitForOperationCompletion; |
(...skipping 29 matching lines...) Expand all Loading... |
47 AudioManagerBase* manager) | 47 AudioManagerBase* manager) |
48 : params_(params), | 48 : params_(params), |
49 input_device_id_(input_device_id), | 49 input_device_id_(input_device_id), |
50 manager_(manager), | 50 manager_(manager), |
51 pa_context_(NULL), | 51 pa_context_(NULL), |
52 pa_mainloop_(NULL), | 52 pa_mainloop_(NULL), |
53 input_stream_(NULL), | 53 input_stream_(NULL), |
54 output_stream_(NULL), | 54 output_stream_(NULL), |
55 volume_(1.0f), | 55 volume_(1.0f), |
56 source_callback_(NULL) { | 56 source_callback_(NULL) { |
57 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 57 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
58 CHECK(params_.IsValid()); | 58 CHECK(params_.IsValid()); |
59 input_bus_ = AudioBus::Create(params_); | 59 input_bus_ = AudioBus::Create(params_); |
60 output_bus_ = AudioBus::Create(params_); | 60 output_bus_ = AudioBus::Create(params_); |
61 } | 61 } |
62 | 62 |
63 PulseAudioUnifiedStream::~PulseAudioUnifiedStream() { | 63 PulseAudioUnifiedStream::~PulseAudioUnifiedStream() { |
64 // All internal structures should already have been freed in Close(), which | 64 // All internal structures should already have been freed in Close(), which |
65 // calls AudioManagerBase::ReleaseOutputStream() which deletes this object. | 65 // calls AudioManagerBase::ReleaseOutputStream() which deletes this object. |
66 DCHECK(!input_stream_); | 66 DCHECK(!input_stream_); |
67 DCHECK(!output_stream_); | 67 DCHECK(!output_stream_); |
68 DCHECK(!pa_context_); | 68 DCHECK(!pa_context_); |
69 DCHECK(!pa_mainloop_); | 69 DCHECK(!pa_mainloop_); |
70 } | 70 } |
71 | 71 |
72 bool PulseAudioUnifiedStream::Open() { | 72 bool PulseAudioUnifiedStream::Open() { |
73 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 73 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
74 // Prepare the recording buffers for the callbacks. | 74 // Prepare the recording buffers for the callbacks. |
75 fifo_.reset(new media::SeekableBuffer( | 75 fifo_.reset(new media::SeekableBuffer( |
76 0, kFifoSizeInPackets * params_.GetBytesPerBuffer())); | 76 0, kFifoSizeInPackets * params_.GetBytesPerBuffer())); |
77 input_data_buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); | 77 input_data_buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); |
78 | 78 |
79 if (!pulse::CreateOutputStream(&pa_mainloop_, &pa_context_, &output_stream_, | 79 if (!pulse::CreateOutputStream(&pa_mainloop_, &pa_context_, &output_stream_, |
80 params_, &StreamNotifyCallback, NULL, this)) | 80 params_, &StreamNotifyCallback, NULL, this)) |
81 return false; | 81 return false; |
82 | 82 |
83 if (!pulse::CreateInputStream(pa_mainloop_, pa_context_, &input_stream_, | 83 if (!pulse::CreateInputStream(pa_mainloop_, pa_context_, &input_stream_, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 pa_context_ = NULL; | 131 pa_context_ = NULL; |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 pa_threaded_mainloop_stop(pa_mainloop_); | 135 pa_threaded_mainloop_stop(pa_mainloop_); |
136 pa_threaded_mainloop_free(pa_mainloop_); | 136 pa_threaded_mainloop_free(pa_mainloop_); |
137 pa_mainloop_ = NULL; | 137 pa_mainloop_ = NULL; |
138 } | 138 } |
139 | 139 |
140 void PulseAudioUnifiedStream::Close() { | 140 void PulseAudioUnifiedStream::Close() { |
141 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 141 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
142 Reset(); | 142 Reset(); |
143 | 143 |
144 // Signal to the manager that we're closed and can be removed. | 144 // Signal to the manager that we're closed and can be removed. |
145 // This should be the last call in the function as it deletes "this". | 145 // This should be the last call in the function as it deletes "this". |
146 manager_->ReleaseOutputStream(this); | 146 manager_->ReleaseOutputStream(this); |
147 } | 147 } |
148 | 148 |
149 void PulseAudioUnifiedStream::WriteData(size_t requested_bytes) { | 149 void PulseAudioUnifiedStream::WriteData(size_t requested_bytes) { |
150 CHECK_EQ(requested_bytes, static_cast<size_t>(params_.GetBytesPerBuffer())); | 150 CHECK_EQ(requested_bytes, static_cast<size_t>(params_.GetBytesPerBuffer())); |
151 | 151 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 } | 204 } |
205 | 205 |
206 // Checks if we still have data. | 206 // Checks if we still have data. |
207 pa_stream_drop(input_stream_); | 207 pa_stream_drop(input_stream_); |
208 } while (pa_stream_readable_size(input_stream_) > 0); | 208 } while (pa_stream_readable_size(input_stream_) > 0); |
209 | 209 |
210 pa_threaded_mainloop_signal(pa_mainloop_, 0); | 210 pa_threaded_mainloop_signal(pa_mainloop_, 0); |
211 } | 211 } |
212 | 212 |
213 void PulseAudioUnifiedStream::Start(AudioSourceCallback* callback) { | 213 void PulseAudioUnifiedStream::Start(AudioSourceCallback* callback) { |
214 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 214 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
215 CHECK(callback); | 215 CHECK(callback); |
216 CHECK(input_stream_); | 216 CHECK(input_stream_); |
217 CHECK(output_stream_); | 217 CHECK(output_stream_); |
218 AutoPulseLock auto_lock(pa_mainloop_); | 218 AutoPulseLock auto_lock(pa_mainloop_); |
219 | 219 |
220 // Ensure the context and stream are ready. | 220 // Ensure the context and stream are ready. |
221 if (pa_context_get_state(pa_context_) != PA_CONTEXT_READY && | 221 if (pa_context_get_state(pa_context_) != PA_CONTEXT_READY && |
222 pa_stream_get_state(output_stream_) != PA_STREAM_READY && | 222 pa_stream_get_state(output_stream_) != PA_STREAM_READY && |
223 pa_stream_get_state(input_stream_) != PA_STREAM_READY) { | 223 pa_stream_get_state(input_stream_) != PA_STREAM_READY) { |
224 callback->OnError(this); | 224 callback->OnError(this); |
(...skipping 12 matching lines...) Expand all Loading... |
237 | 237 |
238 // Uncork (resume) the output stream. | 238 // Uncork (resume) the output stream. |
239 // We use the recording stream to drive the playback, so we do not need to | 239 // We use the recording stream to drive the playback, so we do not need to |
240 // register the write callback using pa_stream_set_write_callback(). | 240 // register the write callback using pa_stream_set_write_callback(). |
241 operation = pa_stream_cork(output_stream_, 0, | 241 operation = pa_stream_cork(output_stream_, 0, |
242 &pulse::StreamSuccessCallback, pa_mainloop_); | 242 &pulse::StreamSuccessCallback, pa_mainloop_); |
243 WaitForOperationCompletion(pa_mainloop_, operation); | 243 WaitForOperationCompletion(pa_mainloop_, operation); |
244 } | 244 } |
245 | 245 |
246 void PulseAudioUnifiedStream::Stop() { | 246 void PulseAudioUnifiedStream::Stop() { |
247 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 247 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
248 | 248 |
249 // Cork (pause) the stream. Waiting for the main loop lock will ensure | 249 // Cork (pause) the stream. Waiting for the main loop lock will ensure |
250 // outstanding callbacks have completed. | 250 // outstanding callbacks have completed. |
251 AutoPulseLock auto_lock(pa_mainloop_); | 251 AutoPulseLock auto_lock(pa_mainloop_); |
252 | 252 |
253 // Set |source_callback_| to NULL so all FulfillWriteRequest() calls which may | 253 // Set |source_callback_| to NULL so all FulfillWriteRequest() calls which may |
254 // occur while waiting on the flush and cork exit immediately. | 254 // occur while waiting on the flush and cork exit immediately. |
255 source_callback_ = NULL; | 255 source_callback_ = NULL; |
256 | 256 |
257 // Set the read callback to NULL before flushing the stream, otherwise it | 257 // Set the read callback to NULL before flushing the stream, otherwise it |
(...skipping 13 matching lines...) Expand all Loading... |
271 operation = pa_stream_flush( | 271 operation = pa_stream_flush( |
272 output_stream_, &pulse::StreamSuccessCallback, pa_mainloop_); | 272 output_stream_, &pulse::StreamSuccessCallback, pa_mainloop_); |
273 WaitForOperationCompletion(pa_mainloop_, operation); | 273 WaitForOperationCompletion(pa_mainloop_, operation); |
274 | 274 |
275 operation = pa_stream_cork(output_stream_, 1, &pulse::StreamSuccessCallback, | 275 operation = pa_stream_cork(output_stream_, 1, &pulse::StreamSuccessCallback, |
276 pa_mainloop_); | 276 pa_mainloop_); |
277 WaitForOperationCompletion(pa_mainloop_, operation); | 277 WaitForOperationCompletion(pa_mainloop_, operation); |
278 } | 278 } |
279 | 279 |
280 void PulseAudioUnifiedStream::SetVolume(double volume) { | 280 void PulseAudioUnifiedStream::SetVolume(double volume) { |
281 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 281 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
282 | 282 |
283 volume_ = static_cast<float>(volume); | 283 volume_ = static_cast<float>(volume); |
284 } | 284 } |
285 | 285 |
286 void PulseAudioUnifiedStream::GetVolume(double* volume) { | 286 void PulseAudioUnifiedStream::GetVolume(double* volume) { |
287 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread()); | 287 DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
288 | 288 |
289 *volume = volume_; | 289 *volume = volume_; |
290 } | 290 } |
291 | 291 |
292 } // namespace media | 292 } // namespace media |
OLD | NEW |