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

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: Undid overzealous clang-format Created 7 years, 5 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) {}
brettw 2013/06/24 21:18:29 I liked the old way better.
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(
brettw 2013/06/24 21:18:29 Old way was better
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) {
brettw 2013/06/24 21:18:29 Old way was better.
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 24 matching lines...) Expand all
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())
352 return; 344 return;
353 345
354 AttemptRead_Locked(); 346 AttemptRead_Locked();
355 } 347 }
356 348
357 bool AudioRendererImpl::HandleSplicerBuffer( 349 bool AudioRendererImpl::HandleSplicerBuffer(
358 const scoped_refptr<DataBuffer>& buffer) { 350 const scoped_refptr<DataBuffer>& buffer) {
359 if (buffer->IsEndOfStream()) { 351 if (buffer->end_of_stream()) {
360 received_end_of_stream_ = true; 352 received_end_of_stream_ = true;
361 353
362 // Transition to kPlaying if we are currently handling an underflow since 354 // Transition to kPlaying if we are currently handling an underflow since
363 // no more data will be arriving. 355 // no more data will be arriving.
364 if (state_ == kUnderflow || state_ == kRebuffering) 356 if (state_ == kUnderflow || state_ == kRebuffering)
365 state_ = kPlaying; 357 state_ = kPlaying;
366 } 358 }
367 359
368 switch (state_) { 360 switch (state_) {
369 case kUninitialized: 361 case kUninitialized:
370 NOTREACHED(); 362 NOTREACHED();
371 return false; 363 return false;
372 case kPaused: 364 case kPaused:
373 if (!buffer->IsEndOfStream()) 365 if (!buffer->end_of_stream()) algorithm_->EnqueueBuffer(buffer);
374 algorithm_->EnqueueBuffer(buffer);
375 DCHECK(!pending_read_); 366 DCHECK(!pending_read_);
376 base::ResetAndReturn(&pause_cb_).Run(); 367 base::ResetAndReturn(&pause_cb_).Run();
377 return false; 368 return false;
378 case kPrerolling: 369 case kPrerolling:
379 if (IsBeforePrerollTime(buffer)) 370 if (IsBeforePrerollTime(buffer))
380 return true; 371 return true;
381 372
382 if (!buffer->IsEndOfStream()) { 373 if (!buffer->end_of_stream()) {
383 algorithm_->EnqueueBuffer(buffer); 374 algorithm_->EnqueueBuffer(buffer);
384 if (!algorithm_->IsQueueFull()) 375 if (!algorithm_->IsQueueFull())
385 return false; 376 return false;
386 } 377 }
387 state_ = kPaused; 378 state_ = kPaused;
388 base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK); 379 base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK);
389 return false; 380 return false;
390 case kPlaying: 381 case kPlaying:
391 case kUnderflow: 382 case kUnderflow:
392 case kRebuffering: 383 case kRebuffering:
393 if (!buffer->IsEndOfStream()) 384 if (!buffer->end_of_stream())
394 algorithm_->EnqueueBuffer(buffer); 385 algorithm_->EnqueueBuffer(buffer);
395 return false; 386 return false;
396 case kStopped: 387 case kStopped:
397 return false; 388 return false;
398 } 389 }
399 return false; 390 return false;
400 } 391 }
401 392
402 void AudioRendererImpl::AttemptRead() { 393 void AudioRendererImpl::AttemptRead() {
403 base::AutoLock auto_lock(lock_); 394 base::AutoLock auto_lock(lock_);
(...skipping 21 matching lines...) Expand all
425 return false; 416 return false;
426 417
427 case kPrerolling: 418 case kPrerolling:
428 case kPlaying: 419 case kPlaying:
429 case kUnderflow: 420 case kUnderflow:
430 case kRebuffering: 421 case kRebuffering:
431 break; 422 break;
432 } 423 }
433 424
434 return !pending_read_ && !received_end_of_stream_ && 425 return !pending_read_ && !received_end_of_stream_ &&
435 !algorithm_->IsQueueFull(); 426 !algorithm_->IsQueueFull();
436 } 427 }
437 428
438 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { 429 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
439 DCHECK(message_loop_->BelongsToCurrentThread()); 430 DCHECK(message_loop_->BelongsToCurrentThread());
440 DCHECK_GE(playback_rate, 0); 431 DCHECK_GE(playback_rate, 0);
441 DCHECK(sink_.get()); 432 DCHECK(sink_.get());
442 433
443 // We have two cases here: 434 // We have two cases here:
444 // Play: current_playback_rate == 0 && playback_rate != 0 435 // Play: current_playback_rate == 0 && playback_rate != 0
445 // Pause: current_playback_rate != 0 && playback_rate == 0 436 // Pause: current_playback_rate != 0 && playback_rate == 0
446 float current_playback_rate = algorithm_->playback_rate(); 437 float current_playback_rate = algorithm_->playback_rate();
447 if (current_playback_rate == 0 && playback_rate != 0) 438 if (current_playback_rate == 0 && playback_rate != 0)
448 DoPlay(); 439 DoPlay();
449 else if (current_playback_rate != 0 && playback_rate == 0) 440 else if (current_playback_rate != 0 && playback_rate == 0)
450 DoPause(); 441 DoPause();
451 442
452 base::AutoLock auto_lock(lock_); 443 base::AutoLock auto_lock(lock_);
453 algorithm_->SetPlaybackRate(playback_rate); 444 algorithm_->SetPlaybackRate(playback_rate);
454 } 445 }
455 446
456 bool AudioRendererImpl::IsBeforePrerollTime( 447 bool AudioRendererImpl::IsBeforePrerollTime(
457 const scoped_refptr<DataBuffer>& buffer) { 448 const scoped_refptr<DataBuffer>& buffer) {
458 return (state_ == kPrerolling) && buffer.get() && !buffer->IsEndOfStream() && 449 return (state_ == kPrerolling) && buffer.get() &&
459 (buffer->GetTimestamp() + buffer->GetDuration()) < preroll_timestamp_; 450 !buffer->end_of_stream() &&
451 (buffer->timestamp() + buffer->duration()) <
452 preroll_timestamp_;
460 } 453 }
461 454
462 int AudioRendererImpl::Render(AudioBus* audio_bus, 455 int AudioRendererImpl::Render(AudioBus* audio_bus,
463 int audio_delay_milliseconds) { 456 int audio_delay_milliseconds) {
464 if (actual_frames_per_buffer_ != audio_bus->frames()) { 457 if (actual_frames_per_buffer_ != audio_bus->frames()) {
465 audio_buffer_.reset( 458 audio_buffer_.reset(
466 new uint8[audio_bus->frames() * audio_parameters_.GetBytesPerFrame()]); 459 new uint8[audio_bus->frames() * audio_parameters_.GetBytesPerFrame()]);
467 actual_frames_per_buffer_ = audio_bus->frames(); 460 actual_frames_per_buffer_ = audio_bus->frames();
468 } 461 }
469 462
470 int frames_filled = FillBuffer( 463 int frames_filled = FillBuffer(audio_buffer_.get(), audio_bus->frames(),
471 audio_buffer_.get(), audio_bus->frames(), audio_delay_milliseconds); 464 audio_delay_milliseconds);
472 DCHECK_LE(frames_filled, actual_frames_per_buffer_); 465 DCHECK_LE(frames_filled, actual_frames_per_buffer_);
473 466
474 // Deinterleave audio data into the output bus. 467 // Deinterleave audio data into the output bus.
475 audio_bus->FromInterleaved( 468 audio_bus->FromInterleaved(audio_buffer_.get(), frames_filled,
476 audio_buffer_.get(), frames_filled, 469 audio_parameters_.bits_per_sample() / 8);
477 audio_parameters_.bits_per_sample() / 8);
478 470
479 return frames_filled; 471 return frames_filled;
480 } 472 }
481 473
482 uint32 AudioRendererImpl::FillBuffer(uint8* dest, 474 uint32 AudioRendererImpl::FillBuffer(uint8* dest, uint32 requested_frames,
483 uint32 requested_frames,
484 int audio_delay_milliseconds) { 475 int audio_delay_milliseconds) {
485 base::TimeDelta current_time = kNoTimestamp(); 476 base::TimeDelta current_time = kNoTimestamp();
486 base::TimeDelta max_time = kNoTimestamp(); 477 base::TimeDelta max_time = kNoTimestamp();
487 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds( 478 base::TimeDelta playback_delay =
488 audio_delay_milliseconds); 479 base::TimeDelta::FromMilliseconds(audio_delay_milliseconds);
489 480
490 size_t frames_written = 0; 481 size_t frames_written = 0;
491 base::Closure underflow_cb; 482 base::Closure underflow_cb;
492 { 483 {
493 base::AutoLock auto_lock(lock_); 484 base::AutoLock auto_lock(lock_);
494 485
495 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. 486 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
496 if (!algorithm_) 487 if (!algorithm_)
497 return 0; 488 return 0;
498 489
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 state_ = kUnderflow; 526 state_ = kUnderflow;
536 underflow_cb = underflow_cb_; 527 underflow_cb = underflow_cb_;
537 } else { 528 } else {
538 // We can't write any data this cycle. For example, we may have 529 // 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 530 // sent all available data to the audio device while not reaching
540 // |earliest_end_time_|. 531 // |earliest_end_time_|.
541 } 532 }
542 } 533 }
543 534
544 if (CanRead_Locked()) { 535 if (CanRead_Locked()) {
545 message_loop_->PostTask(FROM_HERE, base::Bind( 536 message_loop_->PostTask(
546 &AudioRendererImpl::AttemptRead, weak_this_)); 537 FROM_HERE, base::Bind(&AudioRendererImpl::AttemptRead, weak_this_));
547 } 538 }
548 539
549 // The |audio_time_buffered_| is the ending timestamp of the last frame 540 // 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 541 // 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 542 // buffered at the audio device. The current time can be computed by their
552 // difference. 543 // difference.
553 if (audio_time_buffered_ != kNoTimestamp()) { 544 if (audio_time_buffered_ != kNoTimestamp()) {
554 // Adjust the delay according to playback rate. 545 // Adjust the delay according to playback rate.
555 base::TimeDelta adjusted_playback_delay = 546 base::TimeDelta adjusted_playback_delay =
556 base::TimeDelta::FromMicroseconds(ceil( 547 base::TimeDelta::FromMicroseconds(
557 playback_delay.InMicroseconds() * playback_rate)); 548 ceil(playback_delay.InMicroseconds() * playback_rate));
558 549
559 base::TimeDelta previous_time = current_time_; 550 base::TimeDelta previous_time = current_time_;
560 current_time_ = audio_time_buffered_ - adjusted_playback_delay; 551 current_time_ = audio_time_buffered_ - adjusted_playback_delay;
561 552
562 // Time can change in one of two ways: 553 // Time can change in one of two ways:
563 // 1) The time of the audio data at the audio device changed, or 554 // 1) The time of the audio data at the audio device changed, or
564 // 2) The playback delay value has changed 555 // 2) The playback delay value has changed
565 // 556 //
566 // We only want to set |current_time| (and thus execute |time_cb_|) if 557 // 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. 558 // time has progressed and we haven't signaled end of stream yet.
568 // 559 //
569 // Why? The current latency of the system results in getting the last call 560 // 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' 561 // to FillBuffer() later than we'd like, which delays firing the 'ended'
571 // event, which delays the looping/trigging performance of short sound 562 // event, which delays the looping/trigging performance of short sound
572 // effects. 563 // effects.
573 // 564 //
574 // TODO(scherkus): revisit this and switch back to relying on playback 565 // TODO(scherkus): revisit this and switch back to relying on playback
575 // delay after we've revamped our audio IPC subsystem. 566 // delay after we've revamped our audio IPC subsystem.
576 if (current_time_ > previous_time && !rendered_end_of_stream_) { 567 if (current_time_ > previous_time && !rendered_end_of_stream_) {
577 current_time = current_time_; 568 current_time = current_time_;
578 } 569 }
579 } 570 }
580 571
581 // The call to FillBuffer() on |algorithm_| has increased the amount of 572 // The call to FillBuffer() on |algorithm_| has increased the amount of
582 // buffered audio data. Update the new amount of time buffered. 573 // buffered audio data. Update the new amount of time buffered.
583 max_time = algorithm_->GetTime(); 574 max_time = algorithm_->GetTime();
584 audio_time_buffered_ = max_time; 575 audio_time_buffered_ = max_time;
585 576
586 UpdateEarliestEndTime_Locked( 577 UpdateEarliestEndTime_Locked(frames_written, playback_delay, now_cb_.Run());
587 frames_written, playback_delay, now_cb_.Run());
588 } 578 }
589 579
590 if (current_time != kNoTimestamp() && max_time != kNoTimestamp()) { 580 if (current_time != kNoTimestamp() && max_time != kNoTimestamp()) {
591 time_cb_.Run(current_time, max_time); 581 time_cb_.Run(current_time, max_time);
592 } 582 }
593 583
594 if (!underflow_cb.is_null()) 584 if (!underflow_cb.is_null())
595 underflow_cb.Run(); 585 underflow_cb.Run();
596 586
597 return frames_written; 587 return frames_written;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 case kUnderflow: 632 case kUnderflow:
643 case kRebuffering: 633 case kRebuffering:
644 case kStopped: 634 case kStopped:
645 if (status != PIPELINE_OK) 635 if (status != PIPELINE_OK)
646 error_cb_.Run(status); 636 error_cb_.Run(status);
647 return; 637 return;
648 } 638 }
649 } 639 }
650 640
651 } // namespace media 641 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698