Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: media/audio/audio_output_controller.cc

Issue 22886005: Switch audio synchronization from sleep() based to select() based. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix DCHECK. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698