| 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();
|
| }
|
| }
|
|
|