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

Side by Side Diff: media/filters/audio_renderer_impl.cc

Issue 17315021: Refactored DataBuffer to use unix_hacker style methods. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed accidental renaming of test cases. Created 7 years, 6 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
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/filters/audio_renderer_impl.h" 5 #include "media/filters/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 22 matching lines...) Expand all
33 }; 33 };
34 34
35 void HistogramRendererEvent(AudioRendererEvent event) { 35 void HistogramRendererEvent(AudioRendererEvent event) {
36 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS); 36 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS);
37 } 37 }
38 38
39 } // namespace 39 } // namespace
40 40
41 AudioRendererImpl::AudioRendererImpl( 41 AudioRendererImpl::AudioRendererImpl(
42 const scoped_refptr<base::MessageLoopProxy>& message_loop, 42 const scoped_refptr<base::MessageLoopProxy>& message_loop,
43 media::AudioRendererSink* sink, 43 media::AudioRendererSink* sink, ScopedVector<AudioDecoder> decoders,
44 ScopedVector<AudioDecoder> decoders,
45 const SetDecryptorReadyCB& set_decryptor_ready_cb, 44 const SetDecryptorReadyCB& set_decryptor_ready_cb,
46 bool increase_preroll_on_underflow) 45 bool increase_preroll_on_underflow)
47 : message_loop_(message_loop), 46 : message_loop_(message_loop),
48 weak_factory_(this), 47 weak_factory_(this),
49 sink_(sink), 48 sink_(sink),
50 decoder_selector_(new AudioDecoderSelector( 49 decoder_selector_(new AudioDecoderSelector(message_loop, decoders.Pass(),
51 message_loop, decoders.Pass(), set_decryptor_ready_cb)), 50 set_decryptor_ready_cb)),
52 now_cb_(base::Bind(&base::TimeTicks::Now)), 51 now_cb_(base::Bind(&base::TimeTicks::Now)),
53 state_(kUninitialized), 52 state_(kUninitialized),
54 sink_playing_(false), 53 sink_playing_(false),
55 pending_read_(false), 54 pending_read_(false),
56 received_end_of_stream_(false), 55 received_end_of_stream_(false),
57 rendered_end_of_stream_(false), 56 rendered_end_of_stream_(false),
58 audio_time_buffered_(kNoTimestamp()), 57 audio_time_buffered_(kNoTimestamp()),
59 current_time_(kNoTimestamp()), 58 current_time_(kNoTimestamp()),
60 underflow_disabled_(false), 59 underflow_disabled_(false),
61 increase_preroll_on_underflow_(increase_preroll_on_underflow), 60 increase_preroll_on_underflow_(increase_preroll_on_underflow),
62 preroll_aborted_(false), 61 preroll_aborted_(false),
63 actual_frames_per_buffer_(0) { 62 actual_frames_per_buffer_(0) {}
64 }
65 63
66 AudioRendererImpl::~AudioRendererImpl() { 64 AudioRendererImpl::~AudioRendererImpl() {
67 // Stop() should have been called and |algorithm_| should have been destroyed. 65 // Stop() should have been called and |algorithm_| should have been destroyed.
68 DCHECK(state_ == kUninitialized || state_ == kStopped); 66 DCHECK(state_ == kUninitialized || state_ == kStopped);
69 DCHECK(!algorithm_.get()); 67 DCHECK(!algorithm_.get());
70 } 68 }
71 69
72 void AudioRendererImpl::Play(const base::Closure& callback) { 70 void AudioRendererImpl::Play(const base::Closure& callback) {
73 DCHECK(message_loop_->BelongsToCurrentThread()); 71 DCHECK(message_loop_->BelongsToCurrentThread());
74 72
(...skipping 22 matching lines...) Expand all
97 sink_->Play(); 95 sink_->Play();
98 sink_playing_ = true; 96 sink_playing_ = true;
99 } 97 }
100 } 98 }
101 99
102 void AudioRendererImpl::Pause(const base::Closure& callback) { 100 void AudioRendererImpl::Pause(const base::Closure& callback) {
103 DCHECK(message_loop_->BelongsToCurrentThread()); 101 DCHECK(message_loop_->BelongsToCurrentThread());
104 102
105 { 103 {
106 base::AutoLock auto_lock(lock_); 104 base::AutoLock auto_lock(lock_);
107 DCHECK(state_ == kPlaying || state_ == kUnderflow || 105 DCHECK(state_ == kPlaying || state_ == kUnderflow || state_ == kRebuffering)
108 state_ == kRebuffering) << "state_ == " << state_; 106 << "state_ == " << state_;
109 pause_cb_ = callback; 107 pause_cb_ = callback;
110 state_ = kPaused; 108 state_ = kPaused;
111 109
112 // Pause only when we've completed our pending read. 110 // Pause only when we've completed our pending read.
113 if (!pending_read_) 111 if (!pending_read_) base::ResetAndReturn(&pause_cb_).Run();
114 base::ResetAndReturn(&pause_cb_).Run();
115 } 112 }
116 113
117 DoPause(); 114 DoPause();
118 } 115 }
119 116
120 void AudioRendererImpl::DoPause() { 117 void AudioRendererImpl::DoPause() {
121 DCHECK(message_loop_->BelongsToCurrentThread()); 118 DCHECK(message_loop_->BelongsToCurrentThread());
122 if (sink_playing_) { 119 if (sink_playing_) {
123 sink_->Pause(); 120 sink_->Pause();
124 sink_playing_ = false; 121 sink_playing_ = false;
125 } 122 }
126 } 123 }
127 124
128 void AudioRendererImpl::Flush(const base::Closure& callback) { 125 void AudioRendererImpl::Flush(const base::Closure& callback) {
129 DCHECK(message_loop_->BelongsToCurrentThread()); 126 DCHECK(message_loop_->BelongsToCurrentThread());
130 127
131 if (decrypting_demuxer_stream_) { 128 if (decrypting_demuxer_stream_) {
132 decrypting_demuxer_stream_->Reset(base::Bind( 129 decrypting_demuxer_stream_->Reset(
133 &AudioRendererImpl::ResetDecoder, weak_this_, callback)); 130 base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_, callback));
134 return; 131 return;
135 } 132 }
136 133
137 decoder_->Reset(callback); 134 decoder_->Reset(callback);
138 } 135 }
139 136
140 void AudioRendererImpl::ResetDecoder(const base::Closure& callback) { 137 void AudioRendererImpl::ResetDecoder(const base::Closure& callback) {
141 DCHECK(message_loop_->BelongsToCurrentThread()); 138 DCHECK(message_loop_->BelongsToCurrentThread());
142 decoder_->Reset(callback); 139 decoder_->Reset(callback);
143 } 140 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 rendered_end_of_stream_ = false; 185 rendered_end_of_stream_ = false;
189 preroll_aborted_ = false; 186 preroll_aborted_ = false;
190 187
191 splicer_->Reset(); 188 splicer_->Reset();
192 algorithm_->FlushBuffers(); 189 algorithm_->FlushBuffers();
193 earliest_end_time_ = now_cb_.Run(); 190 earliest_end_time_ = now_cb_.Run();
194 191
195 AttemptRead_Locked(); 192 AttemptRead_Locked();
196 } 193 }
197 194
198 void AudioRendererImpl::Initialize(DemuxerStream* stream, 195 void AudioRendererImpl::Initialize(
199 const PipelineStatusCB& init_cb, 196 DemuxerStream* stream, const PipelineStatusCB& init_cb,
200 const StatisticsCB& statistics_cb, 197 const StatisticsCB& statistics_cb, const base::Closure& underflow_cb,
201 const base::Closure& underflow_cb, 198 const TimeCB& time_cb, const base::Closure& ended_cb,
202 const TimeCB& time_cb, 199 const base::Closure& disabled_cb, const PipelineStatusCB& error_cb) {
203 const base::Closure& ended_cb,
204 const base::Closure& disabled_cb,
205 const PipelineStatusCB& error_cb) {
206 DCHECK(message_loop_->BelongsToCurrentThread()); 200 DCHECK(message_loop_->BelongsToCurrentThread());
207 DCHECK(stream); 201 DCHECK(stream);
208 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); 202 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
209 DCHECK(!init_cb.is_null()); 203 DCHECK(!init_cb.is_null());
210 DCHECK(!statistics_cb.is_null()); 204 DCHECK(!statistics_cb.is_null());
211 DCHECK(!underflow_cb.is_null()); 205 DCHECK(!underflow_cb.is_null());
212 DCHECK(!time_cb.is_null()); 206 DCHECK(!time_cb.is_null());
213 DCHECK(!ended_cb.is_null()); 207 DCHECK(!ended_cb.is_null());
214 DCHECK(!disabled_cb.is_null()); 208 DCHECK(!disabled_cb.is_null());
215 DCHECK(!error_cb.is_null()); 209 DCHECK(!error_cb.is_null());
216 DCHECK_EQ(kUninitialized, state_); 210 DCHECK_EQ(kUninitialized, state_);
217 DCHECK(sink_.get()); 211 DCHECK(sink_.get());
218 212
219 weak_this_ = weak_factory_.GetWeakPtr(); 213 weak_this_ = weak_factory_.GetWeakPtr();
220 init_cb_ = init_cb; 214 init_cb_ = init_cb;
221 statistics_cb_ = statistics_cb; 215 statistics_cb_ = statistics_cb;
222 underflow_cb_ = underflow_cb; 216 underflow_cb_ = underflow_cb;
223 time_cb_ = time_cb; 217 time_cb_ = time_cb;
224 ended_cb_ = ended_cb; 218 ended_cb_ = ended_cb;
225 disabled_cb_ = disabled_cb; 219 disabled_cb_ = disabled_cb;
226 error_cb_ = error_cb; 220 error_cb_ = error_cb;
227 221
228 decoder_selector_->SelectAudioDecoder( 222 decoder_selector_->SelectAudioDecoder(
229 stream, 223 stream, statistics_cb,
230 statistics_cb,
231 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); 224 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_));
232 } 225 }
233 226
234 void AudioRendererImpl::OnDecoderSelected( 227 void AudioRendererImpl::OnDecoderSelected(
235 scoped_ptr<AudioDecoder> decoder, 228 scoped_ptr<AudioDecoder> decoder,
236 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 229 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
237 DCHECK(message_loop_->BelongsToCurrentThread()); 230 DCHECK(message_loop_->BelongsToCurrentThread());
238 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); 231 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass());
239 232
240 if (state_ == kStopped) { 233 if (state_ == kStopped) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 } 296 }
304 } 297 }
305 298
306 void AudioRendererImpl::SetVolume(float volume) { 299 void AudioRendererImpl::SetVolume(float volume) {
307 DCHECK(message_loop_->BelongsToCurrentThread()); 300 DCHECK(message_loop_->BelongsToCurrentThread());
308 DCHECK(sink_.get()); 301 DCHECK(sink_.get());
309 sink_->SetVolume(volume); 302 sink_->SetVolume(volume);
310 } 303 }
311 304
312 void AudioRendererImpl::DecodedAudioReady( 305 void AudioRendererImpl::DecodedAudioReady(
313 AudioDecoder::Status status, 306 AudioDecoder::Status status, const scoped_refptr<DataBuffer>& buffer) {
314 const scoped_refptr<DataBuffer>& buffer) {
315 DCHECK(message_loop_->BelongsToCurrentThread()); 307 DCHECK(message_loop_->BelongsToCurrentThread());
316 308
317 base::AutoLock auto_lock(lock_); 309 base::AutoLock auto_lock(lock_);
318 DCHECK(state_ == kPaused || state_ == kPrerolling || state_ == kPlaying || 310 DCHECK(state_ == kPaused || state_ == kPrerolling || state_ == kPlaying ||
319 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); 311 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped);
320 312
321 CHECK(pending_read_); 313 CHECK(pending_read_);
322 pending_read_ = false; 314 pending_read_ = false;
323 315
324 if (status == AudioDecoder::kAborted) { 316 if (status == AudioDecoder::kAborted) {
(...skipping 16 matching lines...) Expand all
341 333
342 if (!splicer_->HasNextBuffer()) { 334 if (!splicer_->HasNextBuffer()) {
343 AttemptRead_Locked(); 335 AttemptRead_Locked();
344 return; 336 return;
345 } 337 }
346 338
347 bool need_another_buffer = false; 339 bool need_another_buffer = false;
348 while (splicer_->HasNextBuffer()) 340 while (splicer_->HasNextBuffer())
349 need_another_buffer = HandleSplicerBuffer(splicer_->GetNextBuffer()); 341 need_another_buffer = HandleSplicerBuffer(splicer_->GetNextBuffer());
350 342
351 if (!need_another_buffer && !CanRead_Locked()) 343 if (!need_another_buffer && !CanRead_Locked()) return;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
352 return;
353 344
354 AttemptRead_Locked(); 345 AttemptRead_Locked();
355 } 346 }
356 347
357 bool AudioRendererImpl::HandleSplicerBuffer( 348 bool AudioRendererImpl::HandleSplicerBuffer(
358 const scoped_refptr<DataBuffer>& buffer) { 349 const scoped_refptr<DataBuffer>& buffer) {
359 if (buffer->IsEndOfStream()) { 350 if (buffer->end_of_stream()) {
360 received_end_of_stream_ = true; 351 received_end_of_stream_ = true;
361 352
362 // Transition to kPlaying if we are currently handling an underflow since 353 // Transition to kPlaying if we are currently handling an underflow since
363 // no more data will be arriving. 354 // no more data will be arriving.
364 if (state_ == kUnderflow || state_ == kRebuffering) 355 if (state_ == kUnderflow || state_ == kRebuffering) state_ = kPlaying;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
365 state_ = kPlaying;
366 } 356 }
367 357
368 switch (state_) { 358 switch (state_) {
369 case kUninitialized: 359 case kUninitialized:
370 NOTREACHED(); 360 NOTREACHED();
371 return false; 361 return false;
372 case kPaused: 362 case kPaused:
373 if (!buffer->IsEndOfStream()) 363 if (!buffer->end_of_stream()) algorithm_->EnqueueBuffer(buffer);
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
374 algorithm_->EnqueueBuffer(buffer);
375 DCHECK(!pending_read_); 364 DCHECK(!pending_read_);
376 base::ResetAndReturn(&pause_cb_).Run(); 365 base::ResetAndReturn(&pause_cb_).Run();
377 return false; 366 return false;
378 case kPrerolling: 367 case kPrerolling:
379 if (IsBeforePrerollTime(buffer)) 368 if (IsBeforePrerollTime(buffer)) return true;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
380 return true;
381 369
382 if (!buffer->IsEndOfStream()) { 370 if (!buffer->end_of_stream()) {
383 algorithm_->EnqueueBuffer(buffer); 371 algorithm_->EnqueueBuffer(buffer);
384 if (!algorithm_->IsQueueFull()) 372 if (!algorithm_->IsQueueFull()) return false;
385 return false;
386 } 373 }
387 state_ = kPaused; 374 state_ = kPaused;
388 base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK); 375 base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK);
389 return false; 376 return false;
390 case kPlaying: 377 case kPlaying:
391 case kUnderflow: 378 case kUnderflow:
392 case kRebuffering: 379 case kRebuffering:
393 if (!buffer->IsEndOfStream()) 380 if (!buffer->end_of_stream()) algorithm_->EnqueueBuffer(buffer);
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
394 algorithm_->EnqueueBuffer(buffer);
395 return false; 381 return false;
396 case kStopped: 382 case kStopped:
397 return false; 383 return false;
398 } 384 }
399 return false; 385 return false;
400 } 386 }
401 387
402 void AudioRendererImpl::AttemptRead() { 388 void AudioRendererImpl::AttemptRead() {
403 base::AutoLock auto_lock(lock_); 389 base::AutoLock auto_lock(lock_);
404 AttemptRead_Locked(); 390 AttemptRead_Locked();
405 } 391 }
406 392
407 void AudioRendererImpl::AttemptRead_Locked() { 393 void AudioRendererImpl::AttemptRead_Locked() {
408 DCHECK(message_loop_->BelongsToCurrentThread()); 394 DCHECK(message_loop_->BelongsToCurrentThread());
409 lock_.AssertAcquired(); 395 lock_.AssertAcquired();
410 396
411 if (!CanRead_Locked()) 397 if (!CanRead_Locked()) return;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
412 return;
413 398
414 pending_read_ = true; 399 pending_read_ = true;
415 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); 400 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_));
416 } 401 }
417 402
418 bool AudioRendererImpl::CanRead_Locked() { 403 bool AudioRendererImpl::CanRead_Locked() {
419 lock_.AssertAcquired(); 404 lock_.AssertAcquired();
420 405
421 switch (state_) { 406 switch (state_) {
422 case kUninitialized: 407 case kUninitialized:
423 case kPaused: 408 case kPaused:
424 case kStopped: 409 case kStopped:
425 return false; 410 return false;
426 411
427 case kPrerolling: 412 case kPrerolling:
428 case kPlaying: 413 case kPlaying:
429 case kUnderflow: 414 case kUnderflow:
430 case kRebuffering: 415 case kRebuffering:
431 break; 416 break;
432 } 417 }
433 418
434 return !pending_read_ && !received_end_of_stream_ && 419 return !pending_read_ && !received_end_of_stream_ &&
435 !algorithm_->IsQueueFull(); 420 !algorithm_->IsQueueFull();
436 } 421 }
437 422
438 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { 423 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
439 DCHECK(message_loop_->BelongsToCurrentThread()); 424 DCHECK(message_loop_->BelongsToCurrentThread());
440 DCHECK_GE(playback_rate, 0); 425 DCHECK_GE(playback_rate, 0);
441 DCHECK(sink_.get()); 426 DCHECK(sink_.get());
442 427
443 // We have two cases here: 428 // We have two cases here:
444 // Play: current_playback_rate == 0 && playback_rate != 0 429 // Play: current_playback_rate == 0 && playback_rate != 0
445 // Pause: current_playback_rate != 0 && playback_rate == 0 430 // Pause: current_playback_rate != 0 && playback_rate == 0
446 float current_playback_rate = algorithm_->playback_rate(); 431 float current_playback_rate = algorithm_->playback_rate();
447 if (current_playback_rate == 0 && playback_rate != 0) 432 if (current_playback_rate == 0 && playback_rate != 0)
448 DoPlay(); 433 DoPlay();
449 else if (current_playback_rate != 0 && playback_rate == 0) 434 else if (current_playback_rate != 0 && playback_rate == 0)
450 DoPause(); 435 DoPause();
451 436
452 base::AutoLock auto_lock(lock_); 437 base::AutoLock auto_lock(lock_);
453 algorithm_->SetPlaybackRate(playback_rate); 438 algorithm_->SetPlaybackRate(playback_rate);
454 } 439 }
455 440
456 bool AudioRendererImpl::IsBeforePrerollTime( 441 bool AudioRendererImpl::IsBeforePrerollTime(
457 const scoped_refptr<DataBuffer>& buffer) { 442 const scoped_refptr<DataBuffer>& buffer) {
458 return (state_ == kPrerolling) && buffer.get() && !buffer->IsEndOfStream() && 443 return (state_ == kPrerolling) && buffer.get() &&
459 (buffer->GetTimestamp() + buffer->GetDuration()) < preroll_timestamp_; 444 !buffer->end_of_stream() &&
445 (buffer->timestamp() + buffer->duration()) <
446 preroll_timestamp_;
460 } 447 }
461 448
462 int AudioRendererImpl::Render(AudioBus* audio_bus, 449 int AudioRendererImpl::Render(AudioBus* audio_bus,
463 int audio_delay_milliseconds) { 450 int audio_delay_milliseconds) {
464 if (actual_frames_per_buffer_ != audio_bus->frames()) { 451 if (actual_frames_per_buffer_ != audio_bus->frames()) {
465 audio_buffer_.reset( 452 audio_buffer_.reset(
466 new uint8[audio_bus->frames() * audio_parameters_.GetBytesPerFrame()]); 453 new uint8[audio_bus->frames() * audio_parameters_.GetBytesPerFrame()]);
467 actual_frames_per_buffer_ = audio_bus->frames(); 454 actual_frames_per_buffer_ = audio_bus->frames();
468 } 455 }
469 456
470 int frames_filled = FillBuffer( 457 int frames_filled = FillBuffer(audio_buffer_.get(), audio_bus->frames(),
471 audio_buffer_.get(), audio_bus->frames(), audio_delay_milliseconds); 458 audio_delay_milliseconds);
472 DCHECK_LE(frames_filled, actual_frames_per_buffer_); 459 DCHECK_LE(frames_filled, actual_frames_per_buffer_);
473 460
474 // Deinterleave audio data into the output bus. 461 // Deinterleave audio data into the output bus.
475 audio_bus->FromInterleaved( 462 audio_bus->FromInterleaved(audio_buffer_.get(), frames_filled,
476 audio_buffer_.get(), frames_filled, 463 audio_parameters_.bits_per_sample() / 8);
477 audio_parameters_.bits_per_sample() / 8);
478 464
479 return frames_filled; 465 return frames_filled;
480 } 466 }
481 467
482 uint32 AudioRendererImpl::FillBuffer(uint8* dest, 468 uint32 AudioRendererImpl::FillBuffer(uint8* dest, uint32 requested_frames,
483 uint32 requested_frames,
484 int audio_delay_milliseconds) { 469 int audio_delay_milliseconds) {
485 base::TimeDelta current_time = kNoTimestamp(); 470 base::TimeDelta current_time = kNoTimestamp();
486 base::TimeDelta max_time = kNoTimestamp(); 471 base::TimeDelta max_time = kNoTimestamp();
487 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds( 472 base::TimeDelta playback_delay =
488 audio_delay_milliseconds); 473 base::TimeDelta::FromMilliseconds(audio_delay_milliseconds);
489 474
490 size_t frames_written = 0; 475 size_t frames_written = 0;
491 base::Closure underflow_cb; 476 base::Closure underflow_cb;
492 { 477 {
493 base::AutoLock auto_lock(lock_); 478 base::AutoLock auto_lock(lock_);
494 479
495 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. 480 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
496 if (!algorithm_) 481 if (!algorithm_) return 0;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
497 return 0;
498 482
499 float playback_rate = algorithm_->playback_rate(); 483 float playback_rate = algorithm_->playback_rate();
500 if (playback_rate == 0) 484 if (playback_rate == 0) return 0;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
501 return 0;
502 485
503 if (state_ == kRebuffering && algorithm_->IsQueueFull()) 486 if (state_ == kRebuffering && algorithm_->IsQueueFull()) state_ = kPlaying;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
504 state_ = kPlaying;
505 487
506 // Mute audio by returning 0 when not playing. 488 // Mute audio by returning 0 when not playing.
507 if (state_ != kPlaying) 489 if (state_ != kPlaying) return 0;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
508 return 0;
509 490
510 // We use the following conditions to determine end of playback: 491 // We use the following conditions to determine end of playback:
511 // 1) Algorithm can not fill the audio callback buffer 492 // 1) Algorithm can not fill the audio callback buffer
512 // 2) We received an end of stream buffer 493 // 2) We received an end of stream buffer
513 // 3) We haven't already signalled that we've ended 494 // 3) We haven't already signalled that we've ended
514 // 4) Our estimated earliest end time has expired 495 // 4) Our estimated earliest end time has expired
515 // 496 //
516 // TODO(enal): we should replace (4) with a check that the browser has no 497 // TODO(enal): we should replace (4) with a check that the browser has no
517 // more audio data or at least use a delayed callback. 498 // more audio data or at least use a delayed callback.
518 // 499 //
(...skipping 16 matching lines...) Expand all
535 state_ = kUnderflow; 516 state_ = kUnderflow;
536 underflow_cb = underflow_cb_; 517 underflow_cb = underflow_cb_;
537 } else { 518 } else {
538 // We can't write any data this cycle. For example, we may have 519 // We can't write any data this cycle. For example, we may have
539 // sent all available data to the audio device while not reaching 520 // sent all available data to the audio device while not reaching
540 // |earliest_end_time_|. 521 // |earliest_end_time_|.
541 } 522 }
542 } 523 }
543 524
544 if (CanRead_Locked()) { 525 if (CanRead_Locked()) {
545 message_loop_->PostTask(FROM_HERE, base::Bind( 526 message_loop_->PostTask(
546 &AudioRendererImpl::AttemptRead, weak_this_)); 527 FROM_HERE, base::Bind(&AudioRendererImpl::AttemptRead, weak_this_));
547 } 528 }
548 529
549 // The |audio_time_buffered_| is the ending timestamp of the last frame 530 // The |audio_time_buffered_| is the ending timestamp of the last frame
550 // buffered at the audio device. |playback_delay| is the amount of time 531 // buffered at the audio device. |playback_delay| is the amount of time
551 // buffered at the audio device. The current time can be computed by their 532 // buffered at the audio device. The current time can be computed by their
552 // difference. 533 // difference.
553 if (audio_time_buffered_ != kNoTimestamp()) { 534 if (audio_time_buffered_ != kNoTimestamp()) {
554 // Adjust the delay according to playback rate. 535 // Adjust the delay according to playback rate.
555 base::TimeDelta adjusted_playback_delay = 536 base::TimeDelta adjusted_playback_delay =
556 base::TimeDelta::FromMicroseconds(ceil( 537 base::TimeDelta::FromMicroseconds(
557 playback_delay.InMicroseconds() * playback_rate)); 538 ceil(playback_delay.InMicroseconds() * playback_rate));
558 539
559 base::TimeDelta previous_time = current_time_; 540 base::TimeDelta previous_time = current_time_;
560 current_time_ = audio_time_buffered_ - adjusted_playback_delay; 541 current_time_ = audio_time_buffered_ - adjusted_playback_delay;
561 542
562 // Time can change in one of two ways: 543 // Time can change in one of two ways:
563 // 1) The time of the audio data at the audio device changed, or 544 // 1) The time of the audio data at the audio device changed, or
564 // 2) The playback delay value has changed 545 // 2) The playback delay value has changed
565 // 546 //
566 // We only want to set |current_time| (and thus execute |time_cb_|) if 547 // We only want to set |current_time| (and thus execute |time_cb_|) if
567 // time has progressed and we haven't signaled end of stream yet. 548 // time has progressed and we haven't signaled end of stream yet.
568 // 549 //
569 // Why? The current latency of the system results in getting the last call 550 // Why? The current latency of the system results in getting the last call
570 // to FillBuffer() later than we'd like, which delays firing the 'ended' 551 // to FillBuffer() later than we'd like, which delays firing the 'ended'
571 // event, which delays the looping/trigging performance of short sound 552 // event, which delays the looping/trigging performance of short sound
572 // effects. 553 // effects.
573 // 554 //
574 // TODO(scherkus): revisit this and switch back to relying on playback 555 // TODO(scherkus): revisit this and switch back to relying on playback
575 // delay after we've revamped our audio IPC subsystem. 556 // delay after we've revamped our audio IPC subsystem.
576 if (current_time_ > previous_time && !rendered_end_of_stream_) { 557 if (current_time_ > previous_time && !rendered_end_of_stream_) {
577 current_time = current_time_; 558 current_time = current_time_;
578 } 559 }
579 } 560 }
580 561
581 // The call to FillBuffer() on |algorithm_| has increased the amount of 562 // The call to FillBuffer() on |algorithm_| has increased the amount of
582 // buffered audio data. Update the new amount of time buffered. 563 // buffered audio data. Update the new amount of time buffered.
583 max_time = algorithm_->GetTime(); 564 max_time = algorithm_->GetTime();
584 audio_time_buffered_ = max_time; 565 audio_time_buffered_ = max_time;
585 566
586 UpdateEarliestEndTime_Locked( 567 UpdateEarliestEndTime_Locked(frames_written, playback_delay, now_cb_.Run());
587 frames_written, playback_delay, now_cb_.Run());
588 } 568 }
589 569
590 if (current_time != kNoTimestamp() && max_time != kNoTimestamp()) { 570 if (current_time != kNoTimestamp() && max_time != kNoTimestamp()) {
591 time_cb_.Run(current_time, max_time); 571 time_cb_.Run(current_time, max_time);
592 } 572 }
593 573
594 if (!underflow_cb.is_null()) 574 if (!underflow_cb.is_null()) underflow_cb.Run();
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
595 underflow_cb.Run();
596 575
597 return frames_written; 576 return frames_written;
598 } 577 }
599 578
600 void AudioRendererImpl::UpdateEarliestEndTime_Locked( 579 void AudioRendererImpl::UpdateEarliestEndTime_Locked(
601 int frames_filled, const base::TimeDelta& playback_delay, 580 int frames_filled, const base::TimeDelta& playback_delay,
602 const base::TimeTicks& time_now) { 581 const base::TimeTicks& time_now) {
603 if (frames_filled <= 0) 582 if (frames_filled <= 0) return;
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
604 return;
605 583
606 base::TimeDelta predicted_play_time = base::TimeDelta::FromMicroseconds( 584 base::TimeDelta predicted_play_time = base::TimeDelta::FromMicroseconds(
607 static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond / 585 static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond /
608 audio_parameters_.sample_rate()); 586 audio_parameters_.sample_rate());
609 587
610 lock_.AssertAcquired(); 588 lock_.AssertAcquired();
611 earliest_end_time_ = std::max( 589 earliest_end_time_ = std::max(
612 earliest_end_time_, time_now + playback_delay + predicted_play_time); 590 earliest_end_time_, time_now + playback_delay + predicted_play_time);
613 } 591 }
614 592
615 void AudioRendererImpl::OnRenderError() { 593 void AudioRendererImpl::OnRenderError() {
616 HistogramRendererEvent(RENDER_ERROR); 594 HistogramRendererEvent(RENDER_ERROR);
617 disabled_cb_.Run(); 595 disabled_cb_.Run();
618 } 596 }
619 597
620 void AudioRendererImpl::DisableUnderflowForTesting() { 598 void AudioRendererImpl::DisableUnderflowForTesting() {
621 underflow_disabled_ = true; 599 underflow_disabled_ = true;
622 } 600 }
623 601
624 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) { 602 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) {
625 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK; 603 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK;
626 switch (state_) { 604 switch (state_) {
627 case kUninitialized: 605 case kUninitialized:
628 NOTREACHED(); 606 NOTREACHED();
629 return; 607 return;
630 case kPaused: 608 case kPaused:
631 if (status != PIPELINE_OK) 609 if (status != PIPELINE_OK) error_cb_.Run(status);
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
632 error_cb_.Run(status);
633 base::ResetAndReturn(&pause_cb_).Run(); 610 base::ResetAndReturn(&pause_cb_).Run();
634 return; 611 return;
635 case kPrerolling: 612 case kPrerolling:
636 // This is a signal for abort if it's not an error. 613 // This is a signal for abort if it's not an error.
637 preroll_aborted_ = !is_decode_error; 614 preroll_aborted_ = !is_decode_error;
638 state_ = kPaused; 615 state_ = kPaused;
639 base::ResetAndReturn(&preroll_cb_).Run(status); 616 base::ResetAndReturn(&preroll_cb_).Run(status);
640 return; 617 return;
641 case kPlaying: 618 case kPlaying:
642 case kUnderflow: 619 case kUnderflow:
643 case kRebuffering: 620 case kRebuffering:
644 case kStopped: 621 case kStopped:
645 if (status != PIPELINE_OK) 622 if (status != PIPELINE_OK) error_cb_.Run(status);
scherkus (not reviewing) 2013/06/21 19:48:38 revert this change -- we don't do single-line ifs
646 error_cb_.Run(status);
647 return; 623 return;
648 } 624 }
649 } 625 }
650 626
651 } // namespace media 627 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698