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

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

Issue 1487983002: Forward the number of skipped frames by the OS in audio playout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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
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/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/numerics/safe_conversions.h" 9 #include "base/numerics/safe_conversions.h"
10 #include "base/task_runner_util.h" 10 #include "base/task_runner_util.h"
(...skipping 18 matching lines...) Expand all
29 stream_(NULL), 29 stream_(NULL),
30 diverting_to_stream_(NULL), 30 diverting_to_stream_(NULL),
31 volume_(1.0), 31 volume_(1.0),
32 state_(kEmpty), 32 state_(kEmpty),
33 sync_reader_(sync_reader), 33 sync_reader_(sync_reader),
34 message_loop_(audio_manager->GetTaskRunner()), 34 message_loop_(audio_manager->GetTaskRunner()),
35 power_monitor_( 35 power_monitor_(
36 params.sample_rate(), 36 params.sample_rate(),
37 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)), 37 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)),
38 on_more_io_data_called_(0), 38 on_more_io_data_called_(0),
39 ignore_errors_during_stop_close_(false) { 39 ignore_errors_during_stop_close_(false),
40 frames_skipped_(0) {
40 DCHECK(audio_manager); 41 DCHECK(audio_manager);
41 DCHECK(handler_); 42 DCHECK(handler_);
42 DCHECK(sync_reader_); 43 DCHECK(sync_reader_);
43 DCHECK(message_loop_.get()); 44 DCHECK(message_loop_.get());
44 } 45 }
45 46
46 AudioOutputController::~AudioOutputController() { 47 AudioOutputController::~AudioOutputController() {
47 DCHECK_EQ(kClosed, state_); 48 DCHECK_EQ(kClosed, state_);
48 } 49 }
49 50
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 void AudioOutputController::DoPlay() { 154 void AudioOutputController::DoPlay() {
154 DCHECK(message_loop_->BelongsToCurrentThread()); 155 DCHECK(message_loop_->BelongsToCurrentThread());
155 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime"); 156 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime");
156 TRACE_EVENT0("audio", "AudioOutputController::DoPlay"); 157 TRACE_EVENT0("audio", "AudioOutputController::DoPlay");
157 158
158 // We can start from created or paused state. 159 // We can start from created or paused state.
159 if (state_ != kCreated && state_ != kPaused) 160 if (state_ != kCreated && state_ != kPaused)
160 return; 161 return;
161 162
162 // Ask for first packet. 163 // Ask for first packet.
163 sync_reader_->UpdatePendingBytes(0); 164 sync_reader_->UpdatePendingBytes(0, 0);
164 165
165 state_ = kPlaying; 166 state_ = kPlaying;
166 167
167 stream_->Start(this); 168 stream_->Start(this);
168 169
169 // For UMA tracking purposes, start the wedge detection timer. This allows us 170 // For UMA tracking purposes, start the wedge detection timer. This allows us
170 // to record statistics about the number of wedged playbacks in the field. 171 // to record statistics about the number of wedged playbacks in the field.
171 // 172 //
172 // WedgeCheck() will look to see if |on_more_io_data_called_| is true after 173 // WedgeCheck() will look to see if |on_more_io_data_called_| is true after
173 // the timeout expires. Care must be taken to ensure the wedge check delay is 174 // the timeout expires. Care must be taken to ensure the wedge check delay is
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 TRACE_EVENT0("audio", "AudioOutputController::DoPause"); 207 TRACE_EVENT0("audio", "AudioOutputController::DoPause");
207 208
208 StopStream(); 209 StopStream();
209 210
210 if (state_ != kPaused) 211 if (state_ != kPaused)
211 return; 212 return;
212 213
213 // Let the renderer know we've stopped. Necessary to let PPAPI clients know 214 // Let the renderer know we've stopped. Necessary to let PPAPI clients know
214 // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have 215 // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have
215 // a better way to know when it should exit PPB_Audio_Shared::Run(). 216 // a better way to know when it should exit PPB_Audio_Shared::Run().
216 sync_reader_->UpdatePendingBytes(kuint32max); 217 sync_reader_->UpdatePendingBytes(kuint32max, 0);
217 218
218 handler_->OnPaused(); 219 handler_->OnPaused();
219 } 220 }
220 221
221 void AudioOutputController::DoClose() { 222 void AudioOutputController::DoClose() {
222 DCHECK(message_loop_->BelongsToCurrentThread()); 223 DCHECK(message_loop_->BelongsToCurrentThread());
223 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime"); 224 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime");
224 TRACE_EVENT0("audio", "AudioOutputController::DoClose"); 225 TRACE_EVENT0("audio", "AudioOutputController::DoClose");
225 226
226 if (state_ != kClosed) { 227 if (state_ != kClosed) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 // Indicate that we haven't wedged (at least not indefinitely, WedgeCheck() 287 // Indicate that we haven't wedged (at least not indefinitely, WedgeCheck()
287 // may have already fired if OnMoreData() took an abnormal amount of time). 288 // may have already fired if OnMoreData() took an abnormal amount of time).
288 // Since this thread is the only writer of |on_more_io_data_called_| once the 289 // Since this thread is the only writer of |on_more_io_data_called_| once the
289 // thread starts, its safe to compare and then increment. 290 // thread starts, its safe to compare and then increment.
290 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) 291 if (base::AtomicRefCountIsZero(&on_more_io_data_called_))
291 base::AtomicRefCountInc(&on_more_io_data_called_); 292 base::AtomicRefCountInc(&on_more_io_data_called_);
292 293
293 sync_reader_->Read(dest); 294 sync_reader_->Read(dest);
294 295
295 const int frames = dest->frames(); 296 const int frames = dest->frames();
296 sync_reader_->UpdatePendingBytes(base::saturated_cast<uint32>( 297 sync_reader_->UpdatePendingBytes(
297 total_bytes_delay + frames * params_.GetBytesPerFrame())); 298 base::saturated_cast<uint32>(total_bytes_delay +
tommi (sloooow) - chröme 2015/12/01 13:34:25 this saturated cast looks like a hack. :-/ Can we
Henrik Grunell 2015/12/03 17:01:07 Agree, I don't know why we would fear it overflowi
299 frames * params_.GetBytesPerFrame()),
300 frames_skipped_);
301 frames_skipped_ = 0;
298 302
299 if (will_monitor_audio_levels()) 303 if (will_monitor_audio_levels())
300 power_monitor_.Scan(*dest, frames); 304 power_monitor_.Scan(*dest, frames);
301 305
302 return frames; 306 return frames;
303 } 307 }
304 308
309 void AudioOutputController::OnSkippedData(uint32 frames_skipped) {
tommi (sloooow) - chröme 2015/12/01 13:34:25 thread check
Henrik Grunell 2015/12/03 17:01:06 Done.
310 // Store the number of skipped frames, will be passed to the provider in
311 // OnMoreData().
312 frames_skipped_ += frames_skipped;
313 }
314
305 void AudioOutputController::OnError(AudioOutputStream* stream) { 315 void AudioOutputController::OnError(AudioOutputStream* stream) {
306 { 316 {
307 base::AutoLock auto_lock(error_lock_); 317 base::AutoLock auto_lock(error_lock_);
308 if (ignore_errors_during_stop_close_) 318 if (ignore_errors_during_stop_close_)
309 return; 319 return;
310 } 320 }
311 321
312 // Handle error on the audio controller thread. 322 // Handle error on the audio controller thread.
313 message_loop_->PostTask(FROM_HERE, base::Bind( 323 message_loop_->PostTask(FROM_HERE, base::Bind(
314 &AudioOutputController::DoReportError, this)); 324 &AudioOutputController::DoReportError, this));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 DCHECK(message_loop_->BelongsToCurrentThread()); 433 DCHECK(message_loop_->BelongsToCurrentThread());
424 434
425 // If we should be playing and we haven't, that's a wedge. 435 // If we should be playing and we haven't, that's a wedge.
426 if (state_ == kPlaying) { 436 if (state_ == kPlaying) {
427 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", 437 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess",
428 base::AtomicRefCountIsOne(&on_more_io_data_called_)); 438 base::AtomicRefCountIsOne(&on_more_io_data_called_));
429 } 439 }
430 } 440 }
431 441
432 } // namespace media 442 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698