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

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: Comments. Split out base/ changes. Created 7 years, 3 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
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/audio_util.h" 14 #include "media/audio/audio_util.h"
15 #include "media/audio/shared_memory_util.h"
16 #include "media/base/scoped_histogram_timer.h" 15 #include "media/base/scoped_histogram_timer.h"
17 16
18 using base::Time; 17 using base::Time;
19 using base::TimeDelta; 18 using base::TimeDelta;
20 19
21 namespace media { 20 namespace media {
22 21
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.
25 static const int kPowerMeasurementTimeConstantMillis = 10; 24 static const int kPowerMeasurementTimeConstantMillis = 10;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 204
206 void AudioOutputController::DoPause() { 205 void AudioOutputController::DoPause() {
207 DCHECK(message_loop_->BelongsToCurrentThread()); 206 DCHECK(message_loop_->BelongsToCurrentThread());
208 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); 207 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime");
209 208
210 StopStream(); 209 StopStream();
211 210
212 if (state_ != kPaused) 211 if (state_ != kPaused)
213 return; 212 return;
214 213
215 // Send a special pause mark to the low-latency audio thread. 214 // Let the renderer know we've stopped. Necessary to let PPAPI clients know
216 sync_reader_->UpdatePendingBytes(kPauseMark); 215 // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have
216 // a better way to know when it should exit PPB_Audio_Shared::Run().
217 sync_reader_->UpdatePendingBytes(-1);
217 218
218 // Paused means silence follows. 219 // Paused means silence follows.
219 handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false); 220 handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false);
220 221
221 handler_->OnPaused(); 222 handler_->OnPaused();
222 } 223 }
223 224
224 void AudioOutputController::DoClose() { 225 void AudioOutputController::DoClose() {
225 DCHECK(message_loop_->BelongsToCurrentThread()); 226 DCHECK(message_loop_->BelongsToCurrentThread());
226 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime"); 227 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime");
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 AudioBuffersState buffers_state) { 261 AudioBuffersState buffers_state) {
261 return OnMoreIOData(NULL, dest, buffers_state); 262 return OnMoreIOData(NULL, dest, buffers_state);
262 } 263 }
263 264
264 int AudioOutputController::OnMoreIOData(AudioBus* source, 265 int AudioOutputController::OnMoreIOData(AudioBus* source,
265 AudioBus* dest, 266 AudioBus* dest,
266 AudioBuffersState buffers_state) { 267 AudioBuffersState buffers_state) {
267 DisallowEntryToOnMoreIOData(); 268 DisallowEntryToOnMoreIOData();
268 TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData"); 269 TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData");
269 270
270 // The OS level audio APIs on Linux and Windows all have problems requesting 271 sync_reader_->Read(source, dest);
271 // data on a fixed interval. Sometimes they will issue calls back to back
272 // which can cause glitching, so wait until the renderer is ready.
273 //
274 // We also need to wait when diverting since the virtual stream will call this
275 // multiple times without waiting.
276 //
277 // NEVER wait on OSX unless a virtual stream is connected, otherwise we can
278 // end up hanging the entire OS.
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 const bool kShouldBlock = true;
284 #else
285 const bool kShouldBlock = diverting_to_stream_ != NULL;
286 #endif
287 272
288 const int frames = sync_reader_->Read(kShouldBlock, source, dest); 273 const int frames = dest->frames();
289 DCHECK_LE(0, frames);
290 sync_reader_->UpdatePendingBytes( 274 sync_reader_->UpdatePendingBytes(
291 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); 275 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame());
292 276
293 power_monitor_.Scan(*dest, frames); 277 power_monitor_.Scan(*dest, frames);
294 278
295 AllowEntryToOnMoreIOData(); 279 AllowEntryToOnMoreIOData();
296 return frames; 280 return frames;
297 } 281 }
298 282
299 void AudioOutputController::OnError(AudioOutputStream* stream) { 283 void AudioOutputController::OnError(AudioOutputStream* stream) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_)); 381 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_));
398 base::AtomicRefCountInc(&num_allowed_io_); 382 base::AtomicRefCountInc(&num_allowed_io_);
399 } 383 }
400 384
401 void AudioOutputController::DisallowEntryToOnMoreIOData() { 385 void AudioOutputController::DisallowEntryToOnMoreIOData() {
402 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_); 386 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_);
403 DCHECK(is_zero); 387 DCHECK(is_zero);
404 } 388 }
405 389
406 } // namespace media 390 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698