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 |