| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "media/audio/audio_output_controller.h" | 5 #include "media/audio/audio_output_controller.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 AudioBuffersState buffers_state) { | 266 AudioBuffersState buffers_state) { |
| 267 return OnMoreIOData(NULL, dest, buffers_state); | 267 return OnMoreIOData(NULL, dest, buffers_state); |
| 268 } | 268 } |
| 269 | 269 |
| 270 int AudioOutputController::OnMoreIOData(AudioBus* source, | 270 int AudioOutputController::OnMoreIOData(AudioBus* source, |
| 271 AudioBus* dest, | 271 AudioBus* dest, |
| 272 AudioBuffersState buffers_state) { | 272 AudioBuffersState buffers_state) { |
| 273 DisallowEntryToOnMoreIOData(); | 273 DisallowEntryToOnMoreIOData(); |
| 274 TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData"); | 274 TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData"); |
| 275 | 275 |
| 276 // The OS level audio APIs on Linux and Windows all have problems requesting |
| 277 // data on a fixed interval. Sometimes they will issue calls back to back |
| 278 // which can cause glitching, so wait until the renderer is ready for Read(). |
| 279 // |
| 280 // See many bugs for context behind this decision: http://crbug.com/170498, |
| 281 // http://crbug.com/171651, http://crbug.com/174985, and more. |
| 282 #if defined(OS_WIN) || defined(OS_LINUX) |
| 283 WaitTillDataReady(); |
| 284 #endif |
| 285 |
| 276 const int frames = sync_reader_->Read(source, dest); | 286 const int frames = sync_reader_->Read(source, dest); |
| 277 DCHECK_LE(0, frames); | 287 DCHECK_LE(0, frames); |
| 278 sync_reader_->UpdatePendingBytes( | 288 sync_reader_->UpdatePendingBytes( |
| 279 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); | 289 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); |
| 280 | 290 |
| 281 AllowEntryToOnMoreIOData(); | 291 AllowEntryToOnMoreIOData(); |
| 282 return frames; | 292 return frames; |
| 283 } | 293 } |
| 284 | 294 |
| 285 void AudioOutputController::WaitTillDataReady() { | 295 void AudioOutputController::WaitTillDataReady() { |
| 286 base::Time start = base::Time::Now(); | 296 base::Time start = base::Time::Now(); |
| 287 // Wait for up to 1.5 seconds for DataReady(). 1.5 seconds was chosen because | 297 // Wait for up to 683ms for DataReady(). 683ms was chosen because it's larger |
| 288 // it's larger than the playback time of the WaveOut buffer size using the | 298 // than the playback time of the WaveOut buffer size using the minimum |
| 289 // minimum supported sample rate: 4096 / 3000 = ~1.4 seconds. Even a client | 299 // supported sample rate: 2048 / 3000 = ~683ms. |
| 290 // expecting real time playout should be able to fill in this time. | 300 const base::TimeDelta kMaxWait = base::TimeDelta::FromMilliseconds(683); |
| 291 const base::TimeDelta max_wait = base::TimeDelta::FromMilliseconds(1500); | |
| 292 while (!sync_reader_->DataReady() && | 301 while (!sync_reader_->DataReady() && |
| 293 ((base::Time::Now() - start) < max_wait)) { | 302 ((base::Time::Now() - start) < kMaxWait)) { |
| 294 base::PlatformThread::YieldCurrentThread(); | 303 base::PlatformThread::YieldCurrentThread(); |
| 295 } | 304 } |
| 296 } | 305 } |
| 297 | 306 |
| 298 void AudioOutputController::OnError(AudioOutputStream* stream, int code) { | 307 void AudioOutputController::OnError(AudioOutputStream* stream, int code) { |
| 299 // Handle error on the audio controller thread. | 308 // Handle error on the audio controller thread. |
| 300 message_loop_->PostTask(FROM_HERE, base::Bind( | 309 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 301 &AudioOutputController::DoReportError, this, code)); | 310 &AudioOutputController::DoReportError, this, code)); |
| 302 } | 311 } |
| 303 | 312 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_)); | 405 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_)); |
| 397 base::AtomicRefCountInc(&num_allowed_io_); | 406 base::AtomicRefCountInc(&num_allowed_io_); |
| 398 } | 407 } |
| 399 | 408 |
| 400 void AudioOutputController::DisallowEntryToOnMoreIOData() { | 409 void AudioOutputController::DisallowEntryToOnMoreIOData() { |
| 401 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_); | 410 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_); |
| 402 DCHECK(is_zero); | 411 DCHECK(is_zero); |
| 403 } | 412 } |
| 404 | 413 |
| 405 } // namespace media | 414 } // namespace media |
| OLD | NEW |