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/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
14 #include "media/audio/shared_memory_util.h" | |
15 #include "media/base/scoped_histogram_timer.h" | 14 #include "media/base/scoped_histogram_timer.h" |
16 | 15 |
17 using base::Time; | 16 using base::Time; |
18 using base::TimeDelta; | 17 using base::TimeDelta; |
19 | 18 |
20 namespace media { | 19 namespace media { |
21 | 20 |
22 #if defined(AUDIO_POWER_MONITORING) | 21 #if defined(AUDIO_POWER_MONITORING) |
23 // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for | 22 // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for |
24 // semantics. This value was arbitrarily chosen, but seems to work well. | 23 // semantics. This value was arbitrarily chosen, but seems to work well. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 213 |
215 void AudioOutputController::DoPause() { | 214 void AudioOutputController::DoPause() { |
216 DCHECK(message_loop_->BelongsToCurrentThread()); | 215 DCHECK(message_loop_->BelongsToCurrentThread()); |
217 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); | 216 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); |
218 | 217 |
219 StopStream(); | 218 StopStream(); |
220 | 219 |
221 if (state_ != kPaused) | 220 if (state_ != kPaused) |
222 return; | 221 return; |
223 | 222 |
224 // Send a special pause mark to the low-latency audio thread. | 223 // Let the renderer know we've stopped. Necessary to let PPAPI clients know |
225 sync_reader_->UpdatePendingBytes(kPauseMark); | 224 // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have |
| 225 // a better way to know when it should exit PPB_Audio_Shared::Run(). |
| 226 sync_reader_->UpdatePendingBytes(-1); |
226 | 227 |
227 #if defined(AUDIO_POWER_MONITORING) | 228 #if defined(AUDIO_POWER_MONITORING) |
228 // Paused means silence follows. | 229 // Paused means silence follows. |
229 handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false); | 230 handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false); |
230 #endif | 231 #endif |
231 | 232 |
232 handler_->OnPaused(); | 233 handler_->OnPaused(); |
233 } | 234 } |
234 | 235 |
235 void AudioOutputController::DoClose() { | 236 void AudioOutputController::DoClose() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 AudioBuffersState buffers_state) { | 272 AudioBuffersState buffers_state) { |
272 return OnMoreIOData(NULL, dest, buffers_state); | 273 return OnMoreIOData(NULL, dest, buffers_state); |
273 } | 274 } |
274 | 275 |
275 int AudioOutputController::OnMoreIOData(AudioBus* source, | 276 int AudioOutputController::OnMoreIOData(AudioBus* source, |
276 AudioBus* dest, | 277 AudioBus* dest, |
277 AudioBuffersState buffers_state) { | 278 AudioBuffersState buffers_state) { |
278 DisallowEntryToOnMoreIOData(); | 279 DisallowEntryToOnMoreIOData(); |
279 TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData"); | 280 TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData"); |
280 | 281 |
281 // The OS level audio APIs on Linux and Windows all have problems requesting | 282 sync_reader_->Read(source, dest); |
282 // data on a fixed interval. Sometimes they will issue calls back to back | |
283 // which can cause glitching, so wait until the renderer is ready. | |
284 // | |
285 // We also need to wait when diverting since the virtual stream will call this | |
286 // multiple times without waiting. | |
287 // | |
288 // NEVER wait on OSX unless a virtual stream is connected, otherwise we can | |
289 // end up hanging the entire OS. | |
290 // | |
291 // See many bugs for context behind this decision: http://crbug.com/170498, | |
292 // http://crbug.com/171651, http://crbug.com/174985, and more. | |
293 #if defined(OS_WIN) || defined(OS_LINUX) | |
294 const bool kShouldBlock = true; | |
295 #else | |
296 const bool kShouldBlock = diverting_to_stream_ != NULL; | |
297 #endif | |
298 | 283 |
299 const int frames = sync_reader_->Read(kShouldBlock, source, dest); | 284 const int frames = dest->frames(); |
300 DCHECK_LE(0, frames); | |
301 sync_reader_->UpdatePendingBytes( | 285 sync_reader_->UpdatePendingBytes( |
302 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); | 286 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); |
303 | 287 |
304 #if defined(AUDIO_POWER_MONITORING) | 288 #if defined(AUDIO_POWER_MONITORING) |
305 power_monitor_.Scan(*dest, frames); | 289 power_monitor_.Scan(*dest, frames); |
306 #endif | 290 #endif |
307 | 291 |
308 AllowEntryToOnMoreIOData(); | 292 AllowEntryToOnMoreIOData(); |
309 return frames; | 293 return frames; |
310 } | 294 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_)); | 394 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_)); |
411 base::AtomicRefCountInc(&num_allowed_io_); | 395 base::AtomicRefCountInc(&num_allowed_io_); |
412 } | 396 } |
413 | 397 |
414 void AudioOutputController::DisallowEntryToOnMoreIOData() { | 398 void AudioOutputController::DisallowEntryToOnMoreIOData() { |
415 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_); | 399 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_); |
416 DCHECK(is_zero); | 400 DCHECK(is_zero); |
417 } | 401 } |
418 | 402 |
419 } // namespace media | 403 } // namespace media |
OLD | NEW |