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

Side by Side Diff: media/audio/linux/alsa_output.cc

Issue 3192017: Revert 57254 - Share one thread between all AudioOutputControllers instead of... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 3 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 | « media/audio/linux/alsa_output.h ('k') | media/audio/linux/audio_manager_linux.h » ('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 // THREAD SAFETY 5 // THREAD SAFETY
6 // 6 //
7 // The AlsaPcmOutputStream object's internal state is accessed by two threads: 7 // The AlsaPcmOutputStream object's internal state is accessed by two threads:
8 // 8 //
9 // client thread - creates the object and calls the public APIs. 9 // client thread - creates the object and calls the public APIs.
10 // message loop thread - executes all the internal tasks including querying 10 // message loop thread - executes all the internal tasks including querying
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 shared_data_.set_volume(static_cast<float>(volume)); 369 shared_data_.set_volume(static_cast<float>(volume));
370 } 370 }
371 371
372 void AlsaPcmOutputStream::GetVolume(double* volume) { 372 void AlsaPcmOutputStream::GetVolume(double* volume) {
373 DCHECK_EQ(MessageLoop::current(), client_thread_loop_); 373 DCHECK_EQ(MessageLoop::current(), client_thread_loop_);
374 374
375 *volume = shared_data_.volume(); 375 *volume = shared_data_.volume();
376 } 376 }
377 377
378 void AlsaPcmOutputStream::OpenTask(uint32 packet_size) { 378 void AlsaPcmOutputStream::OpenTask(uint32 packet_size) {
379 DCHECK_EQ(message_loop_, MessageLoop::current()); 379 DCHECK_EQ(MessageLoop::current(), message_loop_);
380 380
381 // Initialize the configuration variables. 381 // Initialize the configuration variables.
382 packet_size_ = packet_size; 382 packet_size_ = packet_size;
383 frames_per_packet_ = packet_size_ / bytes_per_frame_; 383 frames_per_packet_ = packet_size_ / bytes_per_frame_;
384 384
385 // Try to open the device. 385 // Try to open the device.
386 micros_per_packet_ = 386 micros_per_packet_ =
387 FramesToMicros(packet_size / bytes_per_frame_, sample_rate_); 387 FramesToMicros(packet_size / bytes_per_frame_, sample_rate_);
388 latency_micros_ = std::max(AlsaPcmOutputStream::kMinLatencyMicros, 388 latency_micros_ = std::max(AlsaPcmOutputStream::kMinLatencyMicros,
389 micros_per_packet_ * 2); 389 micros_per_packet_ * 2);
(...skipping 25 matching lines...) Expand all
415 LOG(ERROR) << "Failed to get playback buffer size from ALSA: " 415 LOG(ERROR) << "Failed to get playback buffer size from ALSA: "
416 << wrapper_->StrError(error); 416 << wrapper_->StrError(error);
417 alsa_buffer_frames_ = frames_per_packet_; 417 alsa_buffer_frames_ = frames_per_packet_;
418 } else { 418 } else {
419 alsa_buffer_frames_ = buffer_size; 419 alsa_buffer_frames_ = buffer_size;
420 } 420 }
421 } 421 }
422 } 422 }
423 423
424 void AlsaPcmOutputStream::StartTask() { 424 void AlsaPcmOutputStream::StartTask() {
425 DCHECK_EQ(message_loop_, MessageLoop::current()); 425 DCHECK_EQ(MessageLoop::current(), message_loop_);
426 426
427 if (stop_stream_) { 427 if (stop_stream_) {
428 return; 428 return;
429 } 429 }
430 430
431 // When starting again, drop all packets in the device and prepare it again 431 // When starting again, drop all packets in the device and prepare it again
432 // incase we are restarting from a pause state and need to flush old data. 432 // incase we are restarting from a pause state and need to flush old data.
433 int error = wrapper_->PcmDrop(playback_handle_); 433 int error = wrapper_->PcmDrop(playback_handle_);
434 if (error < 0 && error != -EAGAIN) { 434 if (error < 0 && error != -EAGAIN) {
435 LOG(ERROR) << "Failure clearing playback device (" 435 LOG(ERROR) << "Failure clearing playback device ("
(...skipping 11 matching lines...) Expand all
447 stop_stream_ = true; 447 stop_stream_ = true;
448 return; 448 return;
449 } 449 }
450 450
451 ScheduleNextWrite(false); 451 ScheduleNextWrite(false);
452 } 452 }
453 453
454 void AlsaPcmOutputStream::CloseTask() { 454 void AlsaPcmOutputStream::CloseTask() {
455 // NOTE: Keep this function idempotent to handle errors that might cause 455 // NOTE: Keep this function idempotent to handle errors that might cause
456 // multiple CloseTasks to be posted. 456 // multiple CloseTasks to be posted.
457 DCHECK_EQ(message_loop_, MessageLoop::current()); 457 DCHECK_EQ(MessageLoop::current(), message_loop_);
458 458
459 // Shutdown the audio device. 459 // Shutdown the audio device.
460 if (playback_handle_ && !CloseDevice(playback_handle_)) { 460 if (playback_handle_ && !CloseDevice(playback_handle_)) {
461 LOG(WARNING) << "Unable to close audio device. Leaking handle."; 461 LOG(WARNING) << "Unable to close audio device. Leaking handle.";
462 } 462 }
463 playback_handle_ = NULL; 463 playback_handle_ = NULL;
464 464
465 // Release the buffer. 465 // Release the buffer.
466 buffer_.reset(); 466 buffer_.reset();
467 467
468 // Signal anything that might already be scheduled to stop. 468 // Signal anything that might already be scheduled to stop.
469 stop_stream_ = true; 469 stop_stream_ = true;
470 } 470 }
471 471
472 void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) { 472 void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) {
473 DCHECK_EQ(message_loop_, MessageLoop::current()); 473 DCHECK_EQ(MessageLoop::current(), message_loop_);
474 474
475 // If stopped, simulate a 0-lengthed packet. 475 // If stopped, simulate a 0-lengthed packet.
476 if (stop_stream_) { 476 if (stop_stream_) {
477 buffer_->Clear(); 477 buffer_->Clear();
478 *source_exhausted = true; 478 *source_exhausted = true;
479 return; 479 return;
480 } 480 }
481 481
482 *source_exhausted = false; 482 *source_exhausted = false;
483 483
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 packet->SetDataSize(packet_size); 551 packet->SetDataSize(packet_size);
552 // Add the packet to the buffer. 552 // Add the packet to the buffer.
553 buffer_->Append(packet); 553 buffer_->Append(packet);
554 } else { 554 } else {
555 *source_exhausted = true; 555 *source_exhausted = true;
556 } 556 }
557 } 557 }
558 } 558 }
559 559
560 void AlsaPcmOutputStream::WritePacket() { 560 void AlsaPcmOutputStream::WritePacket() {
561 DCHECK_EQ(message_loop_, MessageLoop::current()); 561 DCHECK_EQ(MessageLoop::current(), message_loop_);
562 562
563 // If the device is in error, just eat the bytes. 563 // If the device is in error, just eat the bytes.
564 if (stop_stream_) { 564 if (stop_stream_) {
565 buffer_->Clear(); 565 buffer_->Clear();
566 return; 566 return;
567 } 567 }
568 568
569 CHECK_EQ(buffer_->forward_bytes() % bytes_per_output_frame_, 0u); 569 CHECK_EQ(buffer_->forward_bytes() % bytes_per_output_frame_, 0u);
570 570
571 const uint8* buffer_data; 571 const uint8* buffer_data;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 frames_written = frames; 604 frames_written = frames;
605 } 605 }
606 606
607 // Seek forward in the buffer after we've written some data to ALSA. 607 // Seek forward in the buffer after we've written some data to ALSA.
608 buffer_->Seek(frames_written * bytes_per_output_frame_); 608 buffer_->Seek(frames_written * bytes_per_output_frame_);
609 } 609 }
610 } 610 }
611 } 611 }
612 612
613 void AlsaPcmOutputStream::WriteTask() { 613 void AlsaPcmOutputStream::WriteTask() {
614 DCHECK_EQ(message_loop_, MessageLoop::current()); 614 DCHECK_EQ(MessageLoop::current(), message_loop_);
615 615
616 if (stop_stream_) { 616 if (stop_stream_) {
617 return; 617 return;
618 } 618 }
619 619
620 bool source_exhausted; 620 bool source_exhausted;
621 BufferPacket(&source_exhausted); 621 BufferPacket(&source_exhausted);
622 WritePacket(); 622 WritePacket();
623 623
624 ScheduleNextWrite(source_exhausted); 624 ScheduleNextWrite(source_exhausted);
625 } 625 }
626 626
627 void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) { 627 void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) {
628 DCHECK_EQ(message_loop_, MessageLoop::current()); 628 DCHECK_EQ(MessageLoop::current(), message_loop_);
629 629
630 if (stop_stream_) { 630 if (stop_stream_) {
631 return; 631 return;
632 } 632 }
633 633
634 // Next write is scheduled for the moment when half of the buffer is 634 // Next write is scheduled for the moment when half of the buffer is
635 // available. 635 // available.
636 uint32 frames_avail_wanted = alsa_buffer_frames_ / 2; 636 uint32 frames_avail_wanted = alsa_buffer_frames_ / 2;
637 uint32 available_frames = GetAvailableFrames(); 637 uint32 available_frames = GetAvailableFrames();
638 uint32 next_fill_time_ms = 0; 638 uint32 next_fill_time_ms = 0;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 if (error < 0) { 771 if (error < 0) {
772 LOG(ERROR) << "Error closing audio device (" << name << "): " 772 LOG(ERROR) << "Error closing audio device (" << name << "): "
773 << wrapper_->StrError(error); 773 << wrapper_->StrError(error);
774 return false; 774 return false;
775 } 775 }
776 776
777 return true; 777 return true;
778 } 778 }
779 779
780 snd_pcm_sframes_t AlsaPcmOutputStream::GetAvailableFrames() { 780 snd_pcm_sframes_t AlsaPcmOutputStream::GetAvailableFrames() {
781 DCHECK_EQ(message_loop_, MessageLoop::current()); 781 DCHECK_EQ(MessageLoop::current(), message_loop_);
782 782
783 if (stop_stream_) { 783 if (stop_stream_) {
784 return 0; 784 return 0;
785 } 785 }
786 786
787 // Find the number of frames queued in the sound device. 787 // Find the number of frames queued in the sound device.
788 snd_pcm_sframes_t available_frames = 788 snd_pcm_sframes_t available_frames =
789 wrapper_->PcmAvailUpdate(playback_handle_); 789 wrapper_->PcmAvailUpdate(playback_handle_);
790 if (available_frames < 0) { 790 if (available_frames < 0) {
791 available_frames = wrapper_->PcmRecover(playback_handle_, 791 available_frames = wrapper_->PcmRecover(playback_handle_,
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 } 959 }
960 960
961 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to 961 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to
962 // release ownership of the currently registered callback. 962 // release ownership of the currently registered callback.
963 void AlsaPcmOutputStream::SharedData::set_source_callback( 963 void AlsaPcmOutputStream::SharedData::set_source_callback(
964 AudioSourceCallback* callback) { 964 AudioSourceCallback* callback) {
965 DCHECK_EQ(MessageLoop::current(), state_transition_loop_); 965 DCHECK_EQ(MessageLoop::current(), state_transition_loop_);
966 AutoLock l(lock_); 966 AutoLock l(lock_);
967 source_callback_ = callback; 967 source_callback_ = callback;
968 } 968 }
OLDNEW
« no previous file with comments | « media/audio/linux/alsa_output.h ('k') | media/audio/linux/audio_manager_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698