Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 } | 388 } |
| 389 } | 389 } |
| 390 | 390 |
| 391 void AlsaPcmOutputStream::StartTask() { | 391 void AlsaPcmOutputStream::StartTask() { |
| 392 DCHECK_EQ(message_loop_, MessageLoop::current()); | 392 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 393 | 393 |
| 394 if (stop_stream_) { | 394 if (stop_stream_) { |
| 395 return; | 395 return; |
| 396 } | 396 } |
| 397 | 397 |
| 398 // Before starting, the buffer might have audio from previous user of this | |
| 399 // device. | |
| 400 buffer_->Clear(); | |
|
Sergey Ulanov
2011/03/31 22:04:46
Does this mean we cut the sound that was playing b
davejcool
2011/04/09 03:10:43
By this time, the previous stream's usage of this
| |
| 401 | |
| 398 // When starting again, drop all packets in the device and prepare it again | 402 // When starting again, drop all packets in the device and prepare it again |
| 399 // incase we are restarting from a pause state and need to flush old data. | 403 // incase we are restarting from a pause state and need to flush old data. |
| 400 int error = wrapper_->PcmDrop(playback_handle_); | 404 int error = wrapper_->PcmDrop(playback_handle_); |
| 401 if (error < 0 && error != -EAGAIN) { | 405 if (error < 0 && error != -EAGAIN) { |
| 402 LOG(ERROR) << "Failure clearing playback device (" | 406 LOG(ERROR) << "Failure clearing playback device (" |
| 403 << wrapper_->PcmName(playback_handle_) << "): " | 407 << wrapper_->PcmName(playback_handle_) << "): " |
| 404 << wrapper_->StrError(error); | 408 << wrapper_->StrError(error); |
| 405 stop_stream_ = true; | 409 stop_stream_ = true; |
| 406 return; | 410 return; |
| 407 } | 411 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 } else { | 576 } else { |
| 573 if (frames_written > frames) { | 577 if (frames_written > frames) { |
| 574 LOG(WARNING) | 578 LOG(WARNING) |
| 575 << "snd_pcm_writei() has written more frame that we asked."; | 579 << "snd_pcm_writei() has written more frame that we asked."; |
| 576 frames_written = frames; | 580 frames_written = frames; |
| 577 } | 581 } |
| 578 | 582 |
| 579 // Seek forward in the buffer after we've written some data to ALSA. | 583 // Seek forward in the buffer after we've written some data to ALSA. |
| 580 buffer_->Seek(frames_written * bytes_per_output_frame_); | 584 buffer_->Seek(frames_written * bytes_per_output_frame_); |
| 581 } | 585 } |
| 586 } else { | |
| 587 // If nothing left to write and playback hasn't started yet, start it now. | |
| 588 // This ensures that shorter sounds will still play. | |
| 589 if ((wrapper_->PcmState(playback_handle_) == SND_PCM_STATE_PREPARED) && | |
| 590 GetCurrentDelay()) { | |
|
scherkus (not reviewing)
2011/03/31 22:08:10
GetCurrentDelay() > 0 ?
davejcool
2011/04/09 03:10:43
Yes, >0 is better, thanks!
| |
| 591 wrapper_->PcmStart(playback_handle_); | |
| 592 } | |
| 582 } | 593 } |
| 583 } | 594 } |
| 584 | 595 |
| 585 void AlsaPcmOutputStream::WriteTask() { | 596 void AlsaPcmOutputStream::WriteTask() { |
| 586 DCHECK_EQ(message_loop_, MessageLoop::current()); | 597 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 587 | 598 |
| 588 if (stop_stream_) { | 599 if (stop_stream_) { |
| 589 return; | 600 return; |
| 590 } | 601 } |
| 591 | 602 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 913 } | 924 } |
| 914 | 925 |
| 915 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to | 926 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to |
| 916 // release ownership of the currently registered callback. | 927 // release ownership of the currently registered callback. |
| 917 void AlsaPcmOutputStream::SharedData::set_source_callback( | 928 void AlsaPcmOutputStream::SharedData::set_source_callback( |
| 918 AudioSourceCallback* callback) { | 929 AudioSourceCallback* callback) { |
| 919 DCHECK_EQ(MessageLoop::current(), state_transition_loop_); | 930 DCHECK_EQ(MessageLoop::current(), state_transition_loop_); |
| 920 base::AutoLock l(lock_); | 931 base::AutoLock l(lock_); |
| 921 source_callback_ = callback; | 932 source_callback_ = callback; |
| 922 } | 933 } |
| OLD | NEW |