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

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

Issue 384543002: Move bulk of media::AudioRendererImpl::Render() logic to media thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: use time_since_writing Created 6 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_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/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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/time/default_tick_clock.h"
17 #include "media/base/audio_buffer.h" 18 #include "media/base/audio_buffer.h"
18 #include "media/base/audio_buffer_converter.h" 19 #include "media/base/audio_buffer_converter.h"
19 #include "media/base/audio_hardware_config.h" 20 #include "media/base/audio_hardware_config.h"
20 #include "media/base/audio_splicer.h" 21 #include "media/base/audio_splicer.h"
21 #include "media/base/bind_to_current_loop.h" 22 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/demuxer_stream.h" 23 #include "media/base/demuxer_stream.h"
23 #include "media/filters/audio_clock.h" 24 #include "media/filters/audio_clock.h"
24 #include "media/filters/decrypting_demuxer_stream.h" 25 #include "media/filters/decrypting_demuxer_stream.h"
25 26
26 namespace media { 27 namespace media {
27 28
28 namespace { 29 namespace {
29 30
30 enum AudioRendererEvent { 31 enum AudioRendererEvent {
31 INITIALIZED, 32 INITIALIZED,
32 RENDER_ERROR, 33 RENDER_ERROR,
33 RENDER_EVENT_MAX = RENDER_ERROR, 34 RENDER_EVENT_MAX = RENDER_ERROR,
34 }; 35 };
35 36
36 void HistogramRendererEvent(AudioRendererEvent event) { 37 void HistogramRendererEvent(AudioRendererEvent event) {
37 UMA_HISTOGRAM_ENUMERATION( 38 UMA_HISTOGRAM_ENUMERATION(
38 "Media.AudioRendererEvents", event, RENDER_EVENT_MAX + 1); 39 "Media.AudioRendererEvents", event, RENDER_EVENT_MAX + 1);
39 } 40 }
40 41
41 } // namespace 42 } // namespace
42 43
44 AudioRendererImpl::RenderResult::RenderResult()
45 : requested_frames(0),
46 delay_frames(0),
47 frames_written(0),
48 playback_rate(0),
49 endpoint_timestamp(kNoTimestamp()) {
50 }
51
43 AudioRendererImpl::AudioRendererImpl( 52 AudioRendererImpl::AudioRendererImpl(
44 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 53 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
45 media::AudioRendererSink* sink, 54 media::AudioRendererSink* sink,
46 ScopedVector<AudioDecoder> decoders, 55 ScopedVector<AudioDecoder> decoders,
47 const SetDecryptorReadyCB& set_decryptor_ready_cb, 56 const SetDecryptorReadyCB& set_decryptor_ready_cb,
48 AudioHardwareConfig* hardware_config) 57 AudioHardwareConfig* hardware_config)
49 : task_runner_(task_runner), 58 : task_runner_(task_runner),
50 sink_(sink), 59 sink_(sink),
51 audio_buffer_stream_(task_runner, 60 audio_buffer_stream_(task_runner,
52 decoders.Pass(), 61 decoders.Pass(),
53 set_decryptor_ready_cb), 62 set_decryptor_ready_cb),
54 hardware_config_(hardware_config), 63 hardware_config_(hardware_config),
55 now_cb_(base::Bind(&base::TimeTicks::Now)), 64 tick_clock_(new base::DefaultTickClock()),
56 state_(kUninitialized), 65 state_(kUninitialized),
57 buffering_state_(BUFFERING_HAVE_NOTHING), 66 buffering_state_(BUFFERING_HAVE_NOTHING),
58 rendering_(false), 67 rendering_(false),
59 sink_playing_(false), 68 sink_playing_(false),
60 pending_read_(false), 69 pending_read_(false),
61 received_end_of_stream_(false), 70 received_end_of_stream_(false),
62 rendered_end_of_stream_(false), 71 rendered_end_of_stream_(false),
63 weak_factory_(this) { 72 weak_factory_(this) {
64 audio_buffer_stream_.set_splice_observer(base::Bind( 73 audio_buffer_stream_.set_splice_observer(base::Bind(
65 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); 74 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 178
170 DCHECK_EQ(state_, kFlushed); 179 DCHECK_EQ(state_, kFlushed);
171 DCHECK(!flush_cb_.is_null()); 180 DCHECK(!flush_cb_.is_null());
172 181
173 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); 182 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
174 received_end_of_stream_ = false; 183 received_end_of_stream_ = false;
175 rendered_end_of_stream_ = false; 184 rendered_end_of_stream_ = false;
176 185
177 // Flush() may have been called while underflowed/not fully buffered. 186 // Flush() may have been called while underflowed/not fully buffered.
178 if (buffering_state_ != BUFFERING_HAVE_NOTHING) 187 if (buffering_state_ != BUFFERING_HAVE_NOTHING)
179 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); 188 SetBufferingState(BUFFERING_HAVE_NOTHING);
180 189
181 splicer_->Reset(); 190 splicer_->Reset();
182 if (buffer_converter_) 191 if (buffer_converter_)
183 buffer_converter_->Reset(); 192 buffer_converter_->Reset();
184 algorithm_->FlushBuffers(); 193 algorithm_->FlushBuffers();
185 } 194 }
186 195
187 // Changes in buffering state are always posted. Flush callback must only be 196 // Changes in buffering state are always posted. Flush callback must only be
188 // run after buffering state has been set back to nothing. 197 // run after buffering state has been set back to nothing.
189 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_)); 198 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 362
354 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 363 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
355 } 364 }
356 365
357 void AudioRendererImpl::SetVolume(float volume) { 366 void AudioRendererImpl::SetVolume(float volume) {
358 DCHECK(task_runner_->BelongsToCurrentThread()); 367 DCHECK(task_runner_->BelongsToCurrentThread());
359 DCHECK(sink_); 368 DCHECK(sink_);
360 sink_->SetVolume(volume); 369 sink_->SetVolume(volume);
361 } 370 }
362 371
372 void AudioRendererImpl::SetTickClockForTesting(
373 scoped_ptr<base::TickClock> tick_clock) {
374 tick_clock_.swap(tick_clock);
375 }
376
363 void AudioRendererImpl::DecodedAudioReady( 377 void AudioRendererImpl::DecodedAudioReady(
364 AudioBufferStream::Status status, 378 AudioBufferStream::Status status,
365 const scoped_refptr<AudioBuffer>& buffer) { 379 const scoped_refptr<AudioBuffer>& buffer) {
366 DVLOG(2) << __FUNCTION__ << "(" << status << ")"; 380 DVLOG(2) << __FUNCTION__ << "(" << status << ")";
367 DCHECK(task_runner_->BelongsToCurrentThread()); 381 DCHECK(task_runner_->BelongsToCurrentThread());
368 382
369 base::AutoLock auto_lock(lock_); 383 base::AutoLock auto_lock(lock_);
370 DCHECK(state_ != kUninitialized); 384 DCHECK(state_ != kUninitialized);
371 385
372 CHECK(pending_read_); 386 CHECK(pending_read_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 424
411 if (!splicer_->HasNextBuffer()) { 425 if (!splicer_->HasNextBuffer()) {
412 AttemptRead_Locked(); 426 AttemptRead_Locked();
413 return; 427 return;
414 } 428 }
415 429
416 bool need_another_buffer = false; 430 bool need_another_buffer = false;
417 while (splicer_->HasNextBuffer()) 431 while (splicer_->HasNextBuffer())
418 need_another_buffer = HandleSplicerBuffer_Locked(splicer_->GetNextBuffer()); 432 need_another_buffer = HandleSplicerBuffer_Locked(splicer_->GetNextBuffer());
419 433
420 if (!need_another_buffer && !CanRead_Locked()) 434 if (!need_another_buffer)
421 return; 435 return;
422 436
423 AttemptRead_Locked(); 437 AttemptRead_Locked();
424 } 438 }
425 439
426 bool AudioRendererImpl::HandleSplicerBuffer_Locked( 440 bool AudioRendererImpl::HandleSplicerBuffer_Locked(
427 const scoped_refptr<AudioBuffer>& buffer) { 441 const scoped_refptr<AudioBuffer>& buffer) {
428 lock_.AssertAcquired(); 442 lock_.AssertAcquired();
429 if (buffer->end_of_stream()) { 443 if (buffer->end_of_stream()) {
430 received_end_of_stream_ = true; 444 received_end_of_stream_ = true;
(...skipping 25 matching lines...) Expand all
456 NOTREACHED(); 470 NOTREACHED();
457 return false; 471 return false;
458 472
459 case kFlushed: 473 case kFlushed:
460 DCHECK(!pending_read_); 474 DCHECK(!pending_read_);
461 return false; 475 return false;
462 476
463 case kPlaying: 477 case kPlaying:
464 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) { 478 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) {
465 if (buffering_state_ == BUFFERING_HAVE_NOTHING) 479 if (buffering_state_ == BUFFERING_HAVE_NOTHING)
466 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH); 480 SetBufferingState(BUFFERING_HAVE_ENOUGH);
467 return false; 481 return false;
468 } 482 }
469 return true; 483 return true;
470 484
471 case kStopped: 485 case kStopped:
472 return false; 486 return false;
473 } 487 }
474 return false; 488 return false;
475 } 489 }
476 490
477 void AudioRendererImpl::AttemptRead() {
478 base::AutoLock auto_lock(lock_);
479 AttemptRead_Locked();
480 }
481
482 void AudioRendererImpl::AttemptRead_Locked() { 491 void AudioRendererImpl::AttemptRead_Locked() {
483 DCHECK(task_runner_->BelongsToCurrentThread()); 492 DCHECK(task_runner_->BelongsToCurrentThread());
484 lock_.AssertAcquired(); 493 lock_.AssertAcquired();
485 494
486 if (!CanRead_Locked())
487 return;
488
489 pending_read_ = true;
490 audio_buffer_stream_.Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
491 weak_factory_.GetWeakPtr()));
492 }
493
494 bool AudioRendererImpl::CanRead_Locked() {
495 lock_.AssertAcquired();
496
497 switch (state_) { 495 switch (state_) {
498 case kUninitialized: 496 case kUninitialized:
499 case kInitializing: 497 case kInitializing:
500 case kFlushing: 498 case kFlushing:
501 case kFlushed: 499 case kFlushed:
502 case kStopped: 500 case kStopped:
503 return false; 501 return;
504 502
505 case kPlaying: 503 case kPlaying:
506 break; 504 break;
507 } 505 }
508 506
509 return !pending_read_ && !received_end_of_stream_ && 507 if (pending_read_ || received_end_of_stream_ || algorithm_->IsQueueFull())
510 !algorithm_->IsQueueFull(); 508 return;
509
510 pending_read_ = true;
511 audio_buffer_stream_.Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
512 weak_factory_.GetWeakPtr()));
511 } 513 }
512 514
513 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { 515 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
514 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; 516 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
515 DCHECK(task_runner_->BelongsToCurrentThread()); 517 DCHECK(task_runner_->BelongsToCurrentThread());
516 DCHECK_GE(playback_rate, 0); 518 DCHECK_GE(playback_rate, 0);
517 DCHECK(sink_); 519 DCHECK(sink_);
518 520
519 base::AutoLock auto_lock(lock_); 521 base::AutoLock auto_lock(lock_);
520 522
(...skipping 19 matching lines...) Expand all
540 542
541 bool AudioRendererImpl::IsBeforeStartTime( 543 bool AudioRendererImpl::IsBeforeStartTime(
542 const scoped_refptr<AudioBuffer>& buffer) { 544 const scoped_refptr<AudioBuffer>& buffer) {
543 DCHECK_EQ(state_, kPlaying); 545 DCHECK_EQ(state_, kPlaying);
544 return buffer && !buffer->end_of_stream() && 546 return buffer && !buffer->end_of_stream() &&
545 (buffer->timestamp() + buffer->duration()) < start_timestamp_; 547 (buffer->timestamp() + buffer->duration()) < start_timestamp_;
546 } 548 }
547 549
548 int AudioRendererImpl::Render(AudioBus* audio_bus, 550 int AudioRendererImpl::Render(AudioBus* audio_bus,
549 int audio_delay_milliseconds) { 551 int audio_delay_milliseconds) {
550 const int requested_frames = audio_bus->frames(); 552 DVLOG(2) << __FUNCTION__;
551 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds( 553 base::TimeDelta playback_delay =
552 audio_delay_milliseconds); 554 base::TimeDelta::FromMilliseconds(audio_delay_milliseconds);
553 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() * 555
554 audio_parameters_.sample_rate()); 556 RenderResult result;
555 int frames_written = 0; 557 result.ticks = tick_clock_->NowTicks();
556 base::Closure time_cb; 558 result.requested_frames = audio_bus->frames();
559 result.delay_frames = static_cast<int>(playback_delay.InSecondsF() *
560 audio_parameters_.sample_rate());
561
557 { 562 {
558 base::AutoLock auto_lock(lock_); 563 base::AutoLock auto_lock(lock_);
559 564 if (state_ == kPlaying && algorithm_->frames_buffered() > 0) {
560 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. 565 result.frames_written =
561 if (!algorithm_) { 566 algorithm_->FillBuffer(audio_bus, result.requested_frames);
562 audio_clock_->WroteSilence(requested_frames, delay_frames); 567 result.playback_rate = algorithm_->playback_rate();
563 return 0; 568 result.endpoint_timestamp = algorithm_->GetTime();
564 }
565
566 float playback_rate = algorithm_->playback_rate();
567 if (playback_rate == 0) {
568 audio_clock_->WroteSilence(requested_frames, delay_frames);
569 return 0;
570 }
571
572 // Mute audio by returning 0 when not playing.
573 if (state_ != kPlaying) {
574 audio_clock_->WroteSilence(requested_frames, delay_frames);
575 return 0;
576 }
577
578 // We use the following conditions to determine end of playback:
579 // 1) Algorithm can not fill the audio callback buffer
580 // 2) We received an end of stream buffer
581 // 3) We haven't already signalled that we've ended
582 // 4) We've played all known audio data sent to hardware
583 //
584 // We use the following conditions to determine underflow:
585 // 1) Algorithm can not fill the audio callback buffer
586 // 2) We have NOT received an end of stream buffer
587 // 3) We are in the kPlaying state
588 //
589 // Otherwise the buffer has data we can send to the device.
590 const base::TimeDelta media_timestamp_before_filling =
591 audio_clock_->CurrentMediaTimestamp(base::TimeDelta());
592 if (algorithm_->frames_buffered() > 0) {
593 frames_written = algorithm_->FillBuffer(audio_bus, requested_frames);
594 audio_clock_->WroteAudio(
595 frames_written, delay_frames, playback_rate, algorithm_->GetTime());
596 }
597 audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames);
598
599 if (frames_written == 0) {
600 if (received_end_of_stream_ && !rendered_end_of_stream_ &&
601 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) ==
602 audio_clock_->last_endpoint_timestamp()) {
603 rendered_end_of_stream_ = true;
604 ended_cb_.Run();
605 } else if (!received_end_of_stream_ && state_ == kPlaying) {
606 if (buffering_state_ != BUFFERING_HAVE_NOTHING) {
607 algorithm_->IncreaseQueueCapacity();
608 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
609 }
610 }
611 }
612
613 if (CanRead_Locked()) {
614 task_runner_->PostTask(FROM_HERE,
615 base::Bind(&AudioRendererImpl::AttemptRead,
616 weak_factory_.GetWeakPtr()));
617 }
618
619 // We only want to execute |time_cb_| if time has progressed and we haven't
620 // signaled end of stream yet.
621 if (media_timestamp_before_filling !=
622 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) &&
623 !rendered_end_of_stream_) {
624 time_cb =
625 base::Bind(time_cb_,
626 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()),
627 audio_clock_->last_endpoint_timestamp());
628 } 569 }
629 } 570 }
630 571
631 if (!time_cb.is_null()) 572 task_runner_->PostTask(
632 task_runner_->PostTask(FROM_HERE, time_cb); 573 FROM_HERE,
574 base::Bind(
575 &AudioRendererImpl::DidRender, weak_factory_.GetWeakPtr(), result));
633 576
634 DCHECK_LE(frames_written, requested_frames); 577 return result.frames_written;
635 return frames_written; 578 }
579
580 void AudioRendererImpl::DidRender(RenderResult result) {
581 DCHECK(task_runner_->BelongsToCurrentThread());
582 DVLOG(2) << __FUNCTION__;
583
584 base::AutoLock auto_lock(lock_);
585 if (state_ == kStopped)
586 return;
587
588 if (result.frames_written > 0) {
589 audio_clock_->WroteAudio(result.frames_written,
590 result.delay_frames,
591 result.playback_rate,
592 result.endpoint_timestamp);
593 }
594 audio_clock_->WroteSilence(result.requested_frames - result.frames_written,
595 result.delay_frames);
596
597 // We use the following conditions to determine end of playback:
598 // 1) Algorithm can not fill the audio callback buffer
599 // 2) We received an end of stream buffer
600 // 3) We haven't already signalled that we've ended
601 // 4) We've played all known audio data sent to hardware
602 //
603 // We use the following conditions to determine underflow:
604 // 1) Algorithm can not fill the audio callback buffer
605 // 2) We have NOT received an end of stream buffer
606 // 3) We are in the kPlaying state
607 if (result.frames_written == 0) {
608 if (received_end_of_stream_ && !rendered_end_of_stream_ &&
609 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) ==
DaleCurtis 2014/07/15 19:25:28 Shouldn't this be using the time since writing?
scherkus (not reviewing) 2014/07/15 20:14:22 Maybe ... I'm still thinking what the right option
610 audio_clock_->last_endpoint_timestamp()) {
611 rendered_end_of_stream_ = true;
612 ended_cb_.Run();
613 } else if (!received_end_of_stream_ && state_ == kPlaying) {
614 if (buffering_state_ != BUFFERING_HAVE_NOTHING) {
615 algorithm_->IncreaseQueueCapacity();
616 SetBufferingState(BUFFERING_HAVE_NOTHING);
617 }
618 }
619 }
620
621 // Use adjusted media timestamp that takes time since writing into account.
622 if (!rendered_end_of_stream_) {
623 base::TimeDelta time_since_writing = tick_clock_->NowTicks() - result.ticks;
624 time_cb_.Run(audio_clock_->CurrentMediaTimestamp(time_since_writing),
625 audio_clock_->last_endpoint_timestamp());
626 }
627
628 AttemptRead_Locked();
636 } 629 }
637 630
638 void AudioRendererImpl::OnRenderError() { 631 void AudioRendererImpl::OnRenderError() {
639 // UMA data tells us this happens ~0.01% of the time. Trigger an error instead 632 // UMA data tells us this happens ~0.01% of the time. Trigger an error instead
640 // of trying to gracefully fall back to a fake sink. It's very likely 633 // of trying to gracefully fall back to a fake sink. It's very likely
641 // OnRenderError() should be removed and the audio stack handle errors without 634 // OnRenderError() should be removed and the audio stack handle errors without
642 // notifying clients. See http://crbug.com/234708 for details. 635 // notifying clients. See http://crbug.com/234708 for details.
643 HistogramRendererEvent(RENDER_ERROR); 636 HistogramRendererEvent(RENDER_ERROR);
644 error_cb_.Run(PIPELINE_ERROR_DECODE); 637 error_cb_.Run(PIPELINE_ERROR_DECODE);
645 } 638 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 DCHECK(task_runner_->BelongsToCurrentThread()); 681 DCHECK(task_runner_->BelongsToCurrentThread());
689 DCHECK(expecting_config_changes_); 682 DCHECK(expecting_config_changes_);
690 buffer_converter_->ResetTimestampState(); 683 buffer_converter_->ResetTimestampState();
691 // Drain flushed buffers from the converter so the AudioSplicer receives all 684 // Drain flushed buffers from the converter so the AudioSplicer receives all
692 // data ahead of any OnNewSpliceBuffer() calls. Since discontinuities should 685 // data ahead of any OnNewSpliceBuffer() calls. Since discontinuities should
693 // only appear after config changes, AddInput() should never fail here. 686 // only appear after config changes, AddInput() should never fail here.
694 while (buffer_converter_->HasNextBuffer()) 687 while (buffer_converter_->HasNextBuffer())
695 CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer())); 688 CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer()));
696 } 689 }
697 690
698 void AudioRendererImpl::SetBufferingState_Locked( 691 void AudioRendererImpl::SetBufferingState(BufferingState buffering_state) {
699 BufferingState buffering_state) {
700 DVLOG(1) << __FUNCTION__ << " : " << buffering_state_ << " -> " 692 DVLOG(1) << __FUNCTION__ << " : " << buffering_state_ << " -> "
701 << buffering_state; 693 << buffering_state;
694 DCHECK(task_runner_->BelongsToCurrentThread());
702 DCHECK_NE(buffering_state_, buffering_state); 695 DCHECK_NE(buffering_state_, buffering_state);
703 lock_.AssertAcquired();
704 buffering_state_ = buffering_state; 696 buffering_state_ = buffering_state;
705 697
706 task_runner_->PostTask(FROM_HERE, 698 task_runner_->PostTask(FROM_HERE,
707 base::Bind(buffering_state_cb_, buffering_state_)); 699 base::Bind(buffering_state_cb_, buffering_state_));
708 } 700 }
709 701
710 } // namespace media 702 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698