Index: media/audio/audio_output_controller.cc |
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc |
index 9990389e0ccf2aabf7b0d4190411f019e64a4941..9120706eed3763b6313d4b5aced45abfda6301ff 100644 |
--- a/media/audio/audio_output_controller.cc |
+++ b/media/audio/audio_output_controller.cc |
@@ -273,6 +273,16 @@ int AudioOutputController::OnMoreIOData(AudioBus* source, |
DisallowEntryToOnMoreIOData(); |
TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData"); |
+ // The OS level audio APIs on Linux and Windows all have problems requesting |
+ // data on a fixed interval. Sometimes they will issue calls back to back |
+ // which can cause glitching, so wait until the renderer is ready for Read(). |
+ // |
+ // See many bugs for context behind this decision: http://crbug.com/170498, |
+ // http://crbug.com/171651, http://crbug.com/174985, and more. |
+#if defined(OS_WIN) || defined(OS_LINUX) |
+ WaitTillDataReady(); |
+#endif |
+ |
const int frames = sync_reader_->Read(source, dest); |
DCHECK_LE(0, frames); |
sync_reader_->UpdatePendingBytes( |
@@ -284,13 +294,12 @@ int AudioOutputController::OnMoreIOData(AudioBus* source, |
void AudioOutputController::WaitTillDataReady() { |
base::Time start = base::Time::Now(); |
- // Wait for up to 1.5 seconds for DataReady(). 1.5 seconds was chosen because |
- // it's larger than the playback time of the WaveOut buffer size using the |
- // minimum supported sample rate: 4096 / 3000 = ~1.4 seconds. Even a client |
- // expecting real time playout should be able to fill in this time. |
- const base::TimeDelta max_wait = base::TimeDelta::FromMilliseconds(1500); |
+ // Wait for up to 683ms for DataReady(). 683ms was chosen because it's larger |
+ // than the playback time of the WaveOut buffer size using the minimum |
+ // supported sample rate: 2048 / 3000 = ~683ms. |
+ const base::TimeDelta kMaxWait = base::TimeDelta::FromMilliseconds(683); |
while (!sync_reader_->DataReady() && |
- ((base::Time::Now() - start) < max_wait)) { |
+ ((base::Time::Now() - start) < kMaxWait)) { |
base::PlatformThread::YieldCurrentThread(); |
} |
} |