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 |