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

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

Issue 10332119: Fix PulseAudio compile failures when use_pulseaudio=1. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: Created 8 years, 7 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 | « no previous file | 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_output.h" 5 #include "media/audio/pulse/pulse_output.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "media/audio/audio_parameters.h" 9 #include "media/audio/audio_parameters.h"
10 #include "media/audio/audio_util.h" 10 #include "media/audio/audio_util.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 *state = pa_context_get_state(context); 121 *state = pa_context_get_state(context);
122 } 122 }
123 123
124 // static 124 // static
125 void PulseAudioOutputStream::WriteRequestCallback(pa_stream* playback_handle, 125 void PulseAudioOutputStream::WriteRequestCallback(pa_stream* playback_handle,
126 size_t length, 126 size_t length,
127 void* stream_addr) { 127 void* stream_addr) {
128 PulseAudioOutputStream* stream = 128 PulseAudioOutputStream* stream =
129 reinterpret_cast<PulseAudioOutputStream*>(stream_addr); 129 reinterpret_cast<PulseAudioOutputStream*>(stream_addr);
130 130
131 DCHECK_EQ(stream->manager_->GetMessageLoop(), MessageLoop::current()); 131 DCHECK(stream->manager_->GetMessageLoop()->BelongsToCurrentThread());
132 132
133 stream->write_callback_handled_ = true; 133 stream->write_callback_handled_ = true;
134 134
135 // Fulfill write request. 135 // Fulfill write request.
136 stream->FulfillWriteRequest(length); 136 stream->FulfillWriteRequest(length);
137 } 137 }
138 138
139 PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params, 139 PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params,
140 AudioManagerPulse* manager) 140 AudioManagerPulse* manager)
141 : channel_layout_(params.channel_layout), 141 : channel_layout_(params.channel_layout()),
142 channel_count_(ChannelLayoutToChannelCount(channel_layout_)), 142 channel_count_(ChannelLayoutToChannelCount(channel_layout_)),
143 sample_format_(BitsToPASampleFormat(params.bits_per_sample)), 143 sample_format_(BitsToPASampleFormat(params.bits_per_sample())),
144 sample_rate_(params.sample_rate), 144 sample_rate_(params.sample_rate()),
145 bytes_per_frame_(params.channels * params.bits_per_sample / 8), 145 bytes_per_frame_(params.GetBytesPerFrame()),
146 manager_(manager), 146 manager_(manager),
147 pa_context_(NULL), 147 pa_context_(NULL),
148 pa_mainloop_(NULL), 148 pa_mainloop_(NULL),
149 playback_handle_(NULL), 149 playback_handle_(NULL),
150 packet_size_(params.GetPacketSize()), 150 packet_size_(params.GetBytesPerBuffer()),
151 frames_per_packet_(packet_size_ / bytes_per_frame_), 151 frames_per_packet_(packet_size_ / bytes_per_frame_),
152 client_buffer_(NULL), 152 client_buffer_(NULL),
153 volume_(1.0f), 153 volume_(1.0f),
154 stream_stopped_(true), 154 stream_stopped_(true),
155 write_callback_handled_(false), 155 write_callback_handled_(false),
156 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 156 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
157 source_callback_(NULL) { 157 source_callback_(NULL) {
158 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 158 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
159 159
160 // TODO(slock): Sanity check input values. 160 // TODO(slock): Sanity check input values.
161 } 161 }
162 162
163 PulseAudioOutputStream::~PulseAudioOutputStream() { 163 PulseAudioOutputStream::~PulseAudioOutputStream() {
164 // All internal structures should already have been freed in Close(), 164 // All internal structures should already have been freed in Close(),
165 // which calls AudioManagerPulse::Release which deletes this object. 165 // which calls AudioManagerPulse::Release which deletes this object.
166 DCHECK(!playback_handle_); 166 DCHECK(!playback_handle_);
167 DCHECK(!pa_context_); 167 DCHECK(!pa_context_);
168 DCHECK(!pa_mainloop_); 168 DCHECK(!pa_mainloop_);
169 } 169 }
170 170
171 bool PulseAudioOutputStream::Open() { 171 bool PulseAudioOutputStream::Open() {
172 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 172 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
173 173
174 // TODO(slock): Possibly move most of this to an OpenPlaybackDevice function 174 // TODO(slock): Possibly move most of this to an OpenPlaybackDevice function
175 // in a new class 'pulse_util', like alsa_util. 175 // in a new class 'pulse_util', like alsa_util.
176 176
177 // Create a mainloop API and connect to the default server. 177 // Create a mainloop API and connect to the default server.
178 pa_mainloop_ = pa_mainloop_new(); 178 pa_mainloop_ = pa_mainloop_new();
179 pa_mainloop_api* pa_mainloop_api = pa_mainloop_get_api(pa_mainloop_); 179 pa_mainloop_api* pa_mainloop_api = pa_mainloop_get_api(pa_mainloop_);
180 pa_context_ = pa_context_new(pa_mainloop_api, "Chromium"); 180 pa_context_ = pa_context_new(pa_mainloop_api, "Chromium");
181 pa_context_state_t pa_context_state = PA_CONTEXT_UNCONNECTED; 181 pa_context_state_t pa_context_state = PA_CONTEXT_UNCONNECTED;
182 pa_context_connect(pa_context_, NULL, PA_CONTEXT_NOFLAGS, NULL); 182 pa_context_connect(pa_context_, NULL, PA_CONTEXT_NOFLAGS, NULL);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 if (pa_mainloop_) { 265 if (pa_mainloop_) {
266 pa_mainloop_free(pa_mainloop_); 266 pa_mainloop_free(pa_mainloop_);
267 pa_mainloop_ = NULL; 267 pa_mainloop_ = NULL;
268 } 268 }
269 269
270 // Release internal buffer. 270 // Release internal buffer.
271 client_buffer_.reset(); 271 client_buffer_.reset();
272 } 272 }
273 273
274 void PulseAudioOutputStream::Close() { 274 void PulseAudioOutputStream::Close() {
275 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 275 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
276 276
277 Reset(); 277 Reset();
278 278
279 // Signal to the manager that we're closed and can be removed. 279 // Signal to the manager that we're closed and can be removed.
280 // This should be the last call in the function as it deletes "this". 280 // This should be the last call in the function as it deletes "this".
281 manager_->ReleaseOutputStream(this); 281 manager_->ReleaseOutputStream(this);
282 } 282 }
283 283
284 void PulseAudioOutputStream::WaitForWriteRequest() { 284 void PulseAudioOutputStream::WaitForWriteRequest() {
285 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 285 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
286 286
287 if (stream_stopped_) 287 if (stream_stopped_)
288 return; 288 return;
289 289
290 // Iterate the PulseAudio mainloop. If PulseAudio doesn't request a write, 290 // Iterate the PulseAudio mainloop. If PulseAudio doesn't request a write,
291 // post a task to iterate the mainloop again. 291 // post a task to iterate the mainloop again.
292 write_callback_handled_ = false; 292 write_callback_handled_ = false;
293 pa_mainloop_iterate(pa_mainloop_, 1, NULL); 293 pa_mainloop_iterate(pa_mainloop_, 1, NULL);
294 if (!write_callback_handled_) { 294 if (!write_callback_handled_) {
295 manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( 295 manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 } 330 }
331 331
332 void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) { 332 void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) {
333 // If we have enough data to fulfill the request, we can finish the write. 333 // If we have enough data to fulfill the request, we can finish the write.
334 if (stream_stopped_) 334 if (stream_stopped_)
335 return; 335 return;
336 336
337 // Request more data from the source until we can fulfill the request or 337 // Request more data from the source until we can fulfill the request or
338 // fail to receive anymore data. 338 // fail to receive anymore data.
339 bool buffering_successful = true; 339 bool buffering_successful = true;
340 while (client_buffer_->forward_bytes() < requested_bytes && 340 size_t forward_bytes = static_cast<size_t>(client_buffer_->forward_bytes());
341 buffering_successful) { 341 while (forward_bytes < requested_bytes && buffering_successful) {
342 buffering_successful = BufferPacketFromSource(); 342 buffering_successful = BufferPacketFromSource();
343 } 343 }
344 344
345 size_t bytes_written = 0; 345 size_t bytes_written = 0;
346 if (client_buffer_->forward_bytes() > 0) { 346 if (client_buffer_->forward_bytes() > 0) {
347 // Try to fulfill the request by writing as many of the requested bytes to 347 // Try to fulfill the request by writing as many of the requested bytes to
348 // the stream as we can. 348 // the stream as we can.
349 WriteToStream(requested_bytes, &bytes_written); 349 WriteToStream(requested_bytes, &bytes_written);
350 } 350 }
351 351
(...skipping 10 matching lines...) Expand all
362 &PulseAudioOutputStream::WaitForWriteRequest, 362 &PulseAudioOutputStream::WaitForWriteRequest,
363 weak_factory_.GetWeakPtr())); 363 weak_factory_.GetWeakPtr()));
364 } 364 }
365 } 365 }
366 366
367 void PulseAudioOutputStream::WriteToStream(size_t bytes_to_write, 367 void PulseAudioOutputStream::WriteToStream(size_t bytes_to_write,
368 size_t* bytes_written) { 368 size_t* bytes_written) {
369 *bytes_written = 0; 369 *bytes_written = 0;
370 while (*bytes_written < bytes_to_write) { 370 while (*bytes_written < bytes_to_write) {
371 const uint8* chunk; 371 const uint8* chunk;
372 size_t chunk_size; 372 int chunk_size;
373 373
374 // Stop writing if there is no more data available. 374 // Stop writing if there is no more data available.
375 if (!client_buffer_->GetCurrentChunk(&chunk, &chunk_size)) 375 if (!client_buffer_->GetCurrentChunk(&chunk, &chunk_size))
376 break; 376 break;
377 377
378 // Write data to stream. 378 // Write data to stream.
379 pa_stream_write(playback_handle_, chunk, chunk_size, 379 pa_stream_write(playback_handle_, chunk, chunk_size,
380 NULL, 0LL, PA_SEEK_RELATIVE); 380 NULL, 0LL, PA_SEEK_RELATIVE);
381 client_buffer_->Seek(chunk_size); 381 client_buffer_->Seek(chunk_size);
382 *bytes_written += chunk_size; 382 *bytes_written += chunk_size;
383 } 383 }
384 } 384 }
385 385
386 void PulseAudioOutputStream::Start(AudioSourceCallback* callback) { 386 void PulseAudioOutputStream::Start(AudioSourceCallback* callback) {
387 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 387 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
388 CHECK(callback); 388 CHECK(callback);
389 DLOG_IF(ERROR, !playback_handle_) 389 DLOG_IF(ERROR, !playback_handle_)
390 << "Open() has not been called successfully"; 390 << "Open() has not been called successfully";
391 if (!playback_handle_) 391 if (!playback_handle_)
392 return; 392 return;
393 393
394 source_callback_ = callback; 394 source_callback_ = callback;
395 395
396 // Clear buffer, it might still have data in it. 396 // Clear buffer, it might still have data in it.
397 client_buffer_->Clear(); 397 client_buffer_->Clear();
398 stream_stopped_ = false; 398 stream_stopped_ = false;
399 399
400 // Start playback. 400 // Start playback.
401 manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( 401 manager_->GetMessageLoop()->PostTask(FROM_HERE, base::Bind(
402 &PulseAudioOutputStream::WaitForWriteRequest, 402 &PulseAudioOutputStream::WaitForWriteRequest,
403 weak_factory_.GetWeakPtr())); 403 weak_factory_.GetWeakPtr()));
404 } 404 }
405 405
406 void PulseAudioOutputStream::Stop() { 406 void PulseAudioOutputStream::Stop() {
407 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 407 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
408 408
409 stream_stopped_ = true; 409 stream_stopped_ = true;
410 } 410 }
411 411
412 void PulseAudioOutputStream::SetVolume(double volume) { 412 void PulseAudioOutputStream::SetVolume(double volume) {
413 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 413 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
414 414
415 volume_ = static_cast<float>(volume); 415 volume_ = static_cast<float>(volume);
416 } 416 }
417 417
418 void PulseAudioOutputStream::GetVolume(double* volume) { 418 void PulseAudioOutputStream::GetVolume(double* volume) {
419 DCHECK_EQ(manager_->GetMessageLoop(), MessageLoop::current()); 419 DCHECK(manager_->GetMessageLoop()->BelongsToCurrentThread());
420 420
421 *volume = volume_; 421 *volume = volume_;
422 } 422 }
423 423
424 uint32 PulseAudioOutputStream::RunDataCallback( 424 uint32 PulseAudioOutputStream::RunDataCallback(
425 uint8* dest, uint32 max_size, AudioBuffersState buffers_state) { 425 uint8* dest, uint32 max_size, AudioBuffersState buffers_state) {
426 if (source_callback_) 426 if (source_callback_)
427 return source_callback_->OnMoreData(dest, max_size, buffers_state); 427 return source_callback_->OnMoreData(dest, max_size, buffers_state);
428 428
429 return 0; 429 return 0;
430 } 430 }
431 431
432 } // namespace media 432 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698