| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 #include "base/stl_util-inl.h" | 81 #include "base/stl_util-inl.h" |
| 82 #include "base/time.h" | 82 #include "base/time.h" |
| 83 #include "media/audio/audio_util.h" | 83 #include "media/audio/audio_util.h" |
| 84 #include "media/audio/linux/alsa_wrapper.h" | 84 #include "media/audio/linux/alsa_wrapper.h" |
| 85 #include "media/audio/linux/audio_manager_linux.h" | 85 #include "media/audio/linux/audio_manager_linux.h" |
| 86 | 86 |
| 87 // Amount of time to wait if we've exhausted the data source. This is to avoid | 87 // Amount of time to wait if we've exhausted the data source. This is to avoid |
| 88 // busy looping. | 88 // busy looping. |
| 89 static const int kNoDataSleepMilliseconds = 10; | 89 static const int kNoDataSleepMilliseconds = 10; |
| 90 | 90 |
| 91 // According to the linux nanosleep manpage, nanosleep on linux can miss the |
| 92 // deadline by up to 10ms because the kernel timeslice is 10ms. Give a 2x |
| 93 // buffer to compensate for the timeslice, and any additional slowdowns. |
| 94 static const int kSleepErrorMilliseconds = 20; |
| 95 |
| 91 // Set to 0 during debugging if you want error messages due to underrun | 96 // Set to 0 during debugging if you want error messages due to underrun |
| 92 // events or other recoverable errors. | 97 // events or other recoverable errors. |
| 93 #if defined(NDEBUG) | 98 #if defined(NDEBUG) |
| 94 static const int kPcmRecoverIsSilent = 1; | 99 static const int kPcmRecoverIsSilent = 1; |
| 95 #else | 100 #else |
| 96 static const int kPcmRecoverIsSilent = 0; | 101 static const int kPcmRecoverIsSilent = 0; |
| 97 #endif | 102 #endif |
| 98 | 103 |
| 99 const char AlsaPcmOutputStream::kDefaultDevice[] = "default"; | 104 const char AlsaPcmOutputStream::kDefaultDevice[] = "default"; |
| 100 | 105 |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 } | 498 } |
| 494 | 499 |
| 495 // Calculate when we should have enough buffer for another packet of data. | 500 // Calculate when we should have enough buffer for another packet of data. |
| 496 int frames_leftover = FramesInPacket(*current_packet, bytes_per_frame_); | 501 int frames_leftover = FramesInPacket(*current_packet, bytes_per_frame_); |
| 497 int frames_needed = | 502 int frames_needed = |
| 498 frames_leftover > 0 ? frames_leftover : frames_per_packet_; | 503 frames_leftover > 0 ? frames_leftover : frames_per_packet_; |
| 499 int frames_until_empty_enough = frames_needed - GetAvailableFrames(); | 504 int frames_until_empty_enough = frames_needed - GetAvailableFrames(); |
| 500 int next_fill_time_ms = | 505 int next_fill_time_ms = |
| 501 FramesToMillis(frames_until_empty_enough, sample_rate_); | 506 FramesToMillis(frames_until_empty_enough, sample_rate_); |
| 502 | 507 |
| 508 // Adjust for timer resolution issues. |
| 509 if (next_fill_time_ms > kSleepErrorMilliseconds) { |
| 510 next_fill_time_ms -= kSleepErrorMilliseconds; |
| 511 } |
| 512 |
| 503 // Avoid busy looping if the data source is exhausted. | 513 // Avoid busy looping if the data source is exhausted. |
| 504 if (current_packet->size == 0) { | 514 if (current_packet->size == 0) { |
| 505 next_fill_time_ms = std::max(next_fill_time_ms, kNoDataSleepMilliseconds); | 515 next_fill_time_ms = std::max(next_fill_time_ms, kNoDataSleepMilliseconds); |
| 506 } | 516 } |
| 507 | 517 |
| 508 // Only schedule more reads/writes if we are still in the playing state. | 518 // Only schedule more reads/writes if we are still in the playing state. |
| 509 if (shared_data_.state() == kIsPlaying) { | 519 if (shared_data_.state() == kIsPlaying) { |
| 510 if (next_fill_time_ms <= 0) { | 520 if (next_fill_time_ms <= 0) { |
| 511 message_loop_->PostTask( | 521 message_loop_->PostTask( |
| 512 FROM_HERE, | 522 FROM_HERE, |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 } | 684 } |
| 675 | 685 |
| 676 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to | 686 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to |
| 677 // release ownership of the currently registered callback. | 687 // release ownership of the currently registered callback. |
| 678 void AlsaPcmOutputStream::SharedData::set_source_callback( | 688 void AlsaPcmOutputStream::SharedData::set_source_callback( |
| 679 AudioSourceCallback* callback) { | 689 AudioSourceCallback* callback) { |
| 680 DCHECK_EQ(MessageLoop::current(), state_transition_loop_); | 690 DCHECK_EQ(MessageLoop::current(), state_transition_loop_); |
| 681 AutoLock l(lock_); | 691 AutoLock l(lock_); |
| 682 source_callback_ = callback; | 692 source_callback_ = callback; |
| 683 } | 693 } |
| OLD | NEW |