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

Side by Side Diff: media/renderers/renderer_impl.cc

Issue 2684103005: Allow media track switching. (Closed)
Patch Set: Fixed comments Created 3 years, 8 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
« no previous file with comments | « media/renderers/renderer_impl.h ('k') | media/renderers/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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/renderers/renderer_impl.h" 5 #include "media/renderers/renderer_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 }; 73 };
74 74
75 RendererImpl::RendererImpl( 75 RendererImpl::RendererImpl(
76 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 76 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
77 std::unique_ptr<AudioRenderer> audio_renderer, 77 std::unique_ptr<AudioRenderer> audio_renderer,
78 std::unique_ptr<VideoRenderer> video_renderer) 78 std::unique_ptr<VideoRenderer> video_renderer)
79 : state_(STATE_UNINITIALIZED), 79 : state_(STATE_UNINITIALIZED),
80 task_runner_(task_runner), 80 task_runner_(task_runner),
81 audio_renderer_(std::move(audio_renderer)), 81 audio_renderer_(std::move(audio_renderer)),
82 video_renderer_(std::move(video_renderer)), 82 video_renderer_(std::move(video_renderer)),
83 current_audio_stream_(nullptr),
84 current_video_stream_(nullptr),
83 time_source_(NULL), 85 time_source_(NULL),
84 time_ticking_(false), 86 time_ticking_(false),
85 playback_rate_(0.0), 87 playback_rate_(0.0),
86 audio_buffering_state_(BUFFERING_HAVE_NOTHING), 88 audio_buffering_state_(BUFFERING_HAVE_NOTHING),
87 video_buffering_state_(BUFFERING_HAVE_NOTHING), 89 video_buffering_state_(BUFFERING_HAVE_NOTHING),
88 audio_ended_(false), 90 audio_ended_(false),
89 video_ended_(false), 91 video_ended_(false),
90 cdm_context_(nullptr), 92 cdm_context_(nullptr),
91 underflow_disabled_for_testing_(false), 93 underflow_disabled_for_testing_(false),
92 clockless_video_playback_enabled_for_testing_(false), 94 clockless_video_playback_enabled_for_testing_(false),
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 192 }
191 193
192 if (state_ != STATE_PLAYING) { 194 if (state_ != STATE_PLAYING) {
193 DCHECK_EQ(state_, STATE_ERROR); 195 DCHECK_EQ(state_, STATE_ERROR);
194 return; 196 return;
195 } 197 }
196 198
197 flush_cb_ = flush_cb; 199 flush_cb_ = flush_cb;
198 state_ = STATE_FLUSHING; 200 state_ = STATE_FLUSHING;
199 201
200 if (time_ticking_) 202 // If we are currently handling a media stream status change, then postpone
201 PausePlayback(); 203 // Flush until after that's done (because stream status changes also flush
204 // audio_renderer_/video_renderer_ and they need to be restarted before they
205 // can be flushed again). OnStreamRestartCompleted will resume Flush
206 // processing after audio/video restart has completed and there are no other
207 // pending stream status changes.
208 if (restarting_audio_ || restarting_video_) {
209 pending_actions_.push_back(
210 base::Bind(&RendererImpl::FlushInternal, weak_this_));
211 return;
212 }
202 213
203 FlushAudioRenderer(); 214 FlushInternal();
204 } 215 }
205 216
206 void RendererImpl::StartPlayingFrom(base::TimeDelta time) { 217 void RendererImpl::StartPlayingFrom(base::TimeDelta time) {
207 DVLOG(1) << __func__; 218 DVLOG(1) << __func__;
208 DCHECK(task_runner_->BelongsToCurrentThread()); 219 DCHECK(task_runner_->BelongsToCurrentThread());
209 220
210 if (state_ != STATE_FLUSHED) { 221 if (state_ != STATE_FLUSHED) {
211 DCHECK_EQ(state_, STATE_ERROR); 222 DCHECK_EQ(state_, STATE_ERROR);
212 return; 223 return;
213 } 224 }
214 225
215 time_source_->SetMediaTime(time); 226 time_source_->SetMediaTime(time);
216 227
217 state_ = STATE_PLAYING; 228 state_ = STATE_PLAYING;
218 if (audio_renderer_) 229 if (audio_renderer_)
219 audio_renderer_->StartPlaying(); 230 audio_renderer_->StartPlaying();
220 if (video_renderer_) 231 if (video_renderer_)
221 video_renderer_->StartPlayingFrom(time); 232 video_renderer_->StartPlayingFrom(time);
222 } 233 }
223 234
224 void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream,
225 bool enabled,
226 base::TimeDelta time) {
227 DCHECK(task_runner_->BelongsToCurrentThread());
228 DCHECK(stream);
229 bool video = (stream->type() == DemuxerStream::VIDEO);
230 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream
231 << " enabled=" << enabled << " time=" << time.InSecondsF();
232 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_))
233 return;
234 if (restarting_audio_ || restarting_video_) {
235 DVLOG(3) << __func__ << ": postponed stream " << stream
236 << " status change handling.";
237 pending_stream_status_notifications_.push_back(
238 base::Bind(&RendererImpl::OnStreamStatusChanged, weak_this_, stream,
239 enabled, time));
240 return;
241 }
242 if (stream->type() == DemuxerStream::VIDEO) {
243 DCHECK(video_renderer_);
244 restarting_video_ = true;
245 video_renderer_->Flush(
246 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time));
247 } else if (stream->type() == DemuxerStream::AUDIO) {
248 DCHECK(audio_renderer_);
249 DCHECK(time_source_);
250 restarting_audio_ = true;
251 // Stop ticking (transition into paused state) in audio renderer before
252 // calling Flush, since after Flush we are going to restart playback by
253 // calling audio renderer StartPlaying which would fail in playing state.
254 if (time_ticking_) {
255 time_ticking_ = false;
256 time_source_->StopTicking();
257 }
258 audio_renderer_->Flush(
259 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time));
260 }
261 }
262
263 void RendererImpl::RestartVideoRenderer(base::TimeDelta time) {
264 DVLOG(3) << __func__;
265 DCHECK(task_runner_->BelongsToCurrentThread());
266 DCHECK(video_renderer_);
267 DCHECK_EQ(state_, STATE_PLAYING);
268 video_ended_ = false;
269 video_renderer_->StartPlayingFrom(time);
270 }
271
272 void RendererImpl::RestartAudioRenderer(base::TimeDelta time) {
273 DVLOG(3) << __func__;
274 DCHECK(task_runner_->BelongsToCurrentThread());
275 DCHECK_EQ(state_, STATE_PLAYING);
276 DCHECK(time_source_);
277 DCHECK(audio_renderer_);
278 audio_ended_ = false;
279 audio_renderer_->StartPlaying();
280 }
281
282 void RendererImpl::SetPlaybackRate(double playback_rate) { 235 void RendererImpl::SetPlaybackRate(double playback_rate) {
283 DVLOG(1) << __func__ << "(" << playback_rate << ")"; 236 DVLOG(1) << __func__ << "(" << playback_rate << ")";
284 DCHECK(task_runner_->BelongsToCurrentThread()); 237 DCHECK(task_runner_->BelongsToCurrentThread());
285 238
286 // Playback rate changes are only carried out while playing. 239 // Playback rate changes are only carried out while playing.
287 if (state_ != STATE_PLAYING && state_ != STATE_FLUSHED) 240 if (state_ != STATE_PLAYING && state_ != STATE_FLUSHED)
288 return; 241 return;
289 242
290 time_source_->SetPlaybackRate(playback_rate); 243 time_source_->SetPlaybackRate(playback_rate);
291 244
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 // TODO(servolk): Implement proper support for multiple streams. But for now 346 // TODO(servolk): Implement proper support for multiple streams. But for now
394 // pick the first enabled stream to preserve the existing behavior. 347 // pick the first enabled stream to preserve the existing behavior.
395 DemuxerStream* audio_stream = 348 DemuxerStream* audio_stream =
396 media_resource_->GetFirstStream(DemuxerStream::AUDIO); 349 media_resource_->GetFirstStream(DemuxerStream::AUDIO);
397 if (!audio_stream) { 350 if (!audio_stream) {
398 audio_renderer_.reset(); 351 audio_renderer_.reset();
399 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 352 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
400 return; 353 return;
401 } 354 }
402 355
356 current_audio_stream_ = audio_stream;
357
403 audio_renderer_client_.reset( 358 audio_renderer_client_.reset(
404 new RendererClientInternal(DemuxerStream::AUDIO, this)); 359 new RendererClientInternal(DemuxerStream::AUDIO, this));
405 // Note: After the initialization of a renderer, error events from it may 360 // Note: After the initialization of a renderer, error events from it may
406 // happen at any time and all future calls must guard against STATE_ERROR. 361 // happen at any time and all future calls must guard against STATE_ERROR.
407 audio_renderer_->Initialize(audio_stream, cdm_context_, 362 audio_renderer_->Initialize(audio_stream, cdm_context_,
408 audio_renderer_client_.get(), done_cb); 363 audio_renderer_client_.get(), done_cb);
409 } 364 }
410 365
411 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { 366 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
412 DVLOG(1) << __func__ << ": " << status; 367 DVLOG(1) << __func__ << ": " << status;
(...skipping 28 matching lines...) Expand all
441 // TODO(servolk): Implement proper support for multiple streams. But for now 396 // TODO(servolk): Implement proper support for multiple streams. But for now
442 // pick the first enabled stream to preserve the existing behavior. 397 // pick the first enabled stream to preserve the existing behavior.
443 DemuxerStream* video_stream = 398 DemuxerStream* video_stream =
444 media_resource_->GetFirstStream(DemuxerStream::VIDEO); 399 media_resource_->GetFirstStream(DemuxerStream::VIDEO);
445 if (!video_stream) { 400 if (!video_stream) {
446 video_renderer_.reset(); 401 video_renderer_.reset();
447 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 402 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
448 return; 403 return;
449 } 404 }
450 405
406 current_video_stream_ = video_stream;
407
451 video_renderer_client_.reset( 408 video_renderer_client_.reset(
452 new RendererClientInternal(DemuxerStream::VIDEO, this)); 409 new RendererClientInternal(DemuxerStream::VIDEO, this));
453 video_renderer_->Initialize( 410 video_renderer_->Initialize(
454 video_stream, cdm_context_, video_renderer_client_.get(), 411 video_stream, cdm_context_, video_renderer_client_.get(),
455 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), 412 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)),
456 done_cb); 413 done_cb);
457 } 414 }
458 415
459 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { 416 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) {
460 DVLOG(1) << __func__ << ": " << status; 417 DVLOG(1) << __func__ << ": " << status;
(...skipping 25 matching lines...) Expand all
486 time_source_ = wall_clock_time_source_.get(); 443 time_source_ = wall_clock_time_source_.get();
487 } 444 }
488 445
489 state_ = STATE_FLUSHED; 446 state_ = STATE_FLUSHED;
490 DCHECK(time_source_); 447 DCHECK(time_source_);
491 DCHECK(audio_renderer_ || video_renderer_); 448 DCHECK(audio_renderer_ || video_renderer_);
492 449
493 FinishInitialization(PIPELINE_OK); 450 FinishInitialization(PIPELINE_OK);
494 } 451 }
495 452
453 void RendererImpl::FlushInternal() {
454 DVLOG(1) << __func__;
455 DCHECK(task_runner_->BelongsToCurrentThread());
456 DCHECK_EQ(state_, STATE_FLUSHING);
457 DCHECK(!flush_cb_.is_null());
458
459 if (time_ticking_)
460 PausePlayback();
461
462 FlushAudioRenderer();
463 }
464
496 void RendererImpl::FlushAudioRenderer() { 465 void RendererImpl::FlushAudioRenderer() {
497 DVLOG(1) << __func__; 466 DVLOG(1) << __func__;
498 DCHECK(task_runner_->BelongsToCurrentThread()); 467 DCHECK(task_runner_->BelongsToCurrentThread());
499 DCHECK_EQ(state_, STATE_FLUSHING); 468 DCHECK_EQ(state_, STATE_FLUSHING);
500 DCHECK(!flush_cb_.is_null()); 469 DCHECK(!flush_cb_.is_null());
501 470
502 if (!audio_renderer_) { 471 if (!audio_renderer_) {
503 OnAudioRendererFlushDone(); 472 OnAudioRendererFlushDone();
504 return; 473 return;
505 } 474 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 return; 522 return;
554 } 523 }
555 524
556 DCHECK_EQ(state_, STATE_FLUSHING); 525 DCHECK_EQ(state_, STATE_FLUSHING);
557 DCHECK(!flush_cb_.is_null()); 526 DCHECK(!flush_cb_.is_null());
558 527
559 DCHECK_EQ(video_buffering_state_, BUFFERING_HAVE_NOTHING); 528 DCHECK_EQ(video_buffering_state_, BUFFERING_HAVE_NOTHING);
560 video_ended_ = false; 529 video_ended_ = false;
561 state_ = STATE_FLUSHED; 530 state_ = STATE_FLUSHED;
562 base::ResetAndReturn(&flush_cb_).Run(); 531 base::ResetAndReturn(&flush_cb_).Run();
532
533 if (!pending_actions_.empty()) {
534 base::Closure closure = pending_actions_.front();
535 pending_actions_.pop_front();
536 closure.Run();
537 }
538 }
539
540 void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream,
541 bool enabled,
542 base::TimeDelta time) {
543 DCHECK(task_runner_->BelongsToCurrentThread());
544 DCHECK(stream);
545 bool video = (stream->type() == DemuxerStream::VIDEO);
546 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream
547 << " enabled=" << enabled << " time=" << time.InSecondsF();
548
549 if ((state_ != STATE_PLAYING && state_ != STATE_FLUSHING &&
550 state_ != STATE_FLUSHED) ||
551 (audio_ended_ && video_ended_))
552 return;
553
554 if (restarting_audio_ || restarting_video_ || state_ == STATE_FLUSHING) {
555 DVLOG(3) << __func__ << ": postponed stream " << stream
556 << " status change handling.";
557 pending_actions_.push_back(base::Bind(&RendererImpl::OnStreamStatusChanged,
558 weak_this_, stream, enabled, time));
559 return;
560 }
561
562 DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHED);
563 if (stream->type() == DemuxerStream::VIDEO) {
564 DCHECK(video_renderer_);
565 restarting_video_ = true;
566 base::Closure handle_track_status_cb =
567 base::Bind(stream == current_video_stream_
568 ? &RendererImpl::RestartVideoRenderer
569 : &RendererImpl::ReinitializeVideoRenderer,
570 weak_this_, stream, time);
571 if (state_ == STATE_FLUSHED)
572 handle_track_status_cb.Run();
573 else
574 video_renderer_->Flush(handle_track_status_cb);
575 } else if (stream->type() == DemuxerStream::AUDIO) {
576 DCHECK(audio_renderer_);
577 DCHECK(time_source_);
578 restarting_audio_ = true;
579 base::Closure handle_track_status_cb =
580 base::Bind(stream == current_audio_stream_
581 ? &RendererImpl::RestartAudioRenderer
582 : &RendererImpl::ReinitializeAudioRenderer,
583 weak_this_, stream, time);
584 if (state_ == STATE_FLUSHED) {
585 handle_track_status_cb.Run();
586 return;
587 }
588 // Stop ticking (transition into paused state) in audio renderer before
589 // calling Flush, since after Flush we are going to restart playback by
590 // calling audio renderer StartPlaying which would fail in playing state.
591 if (time_ticking_) {
592 time_ticking_ = false;
593 time_source_->StopTicking();
594 }
595 audio_renderer_->Flush(handle_track_status_cb);
596 }
597 }
598
599 void RendererImpl::ReinitializeAudioRenderer(DemuxerStream* stream,
600 base::TimeDelta time) {
601 DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
602 DCHECK(task_runner_->BelongsToCurrentThread());
603 DCHECK_NE(stream, current_audio_stream_);
604
605 current_audio_stream_ = stream;
606 audio_renderer_->Initialize(
607 stream, cdm_context_, audio_renderer_client_.get(),
608 base::Bind(&RendererImpl::OnAudioRendererReinitialized, weak_this_,
609 stream, time));
610 }
611
612 void RendererImpl::OnAudioRendererReinitialized(DemuxerStream* stream,
613 base::TimeDelta time,
614 PipelineStatus status) {
615 DVLOG(2) << __func__ << ": status=" << status;
616 DCHECK_EQ(stream, current_audio_stream_);
617
618 if (status != PIPELINE_OK) {
619 OnError(status);
620 return;
621 }
622 RestartAudioRenderer(stream, time);
623 }
624
625 void RendererImpl::ReinitializeVideoRenderer(DemuxerStream* stream,
626 base::TimeDelta time) {
627 DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
628 DCHECK(task_runner_->BelongsToCurrentThread());
629 DCHECK_NE(stream, current_video_stream_);
630
631 current_video_stream_ = stream;
632 video_renderer_->OnTimeStopped();
633 video_renderer_->Initialize(
634 stream, cdm_context_, video_renderer_client_.get(),
635 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)),
636 base::Bind(&RendererImpl::OnVideoRendererReinitialized, weak_this_,
637 stream, time));
638 }
639
640 void RendererImpl::OnVideoRendererReinitialized(DemuxerStream* stream,
641 base::TimeDelta time,
642 PipelineStatus status) {
643 DVLOG(2) << __func__ << ": status=" << status;
644 DCHECK_EQ(stream, current_video_stream_);
645
646 if (status != PIPELINE_OK) {
647 OnError(status);
648 return;
649 }
650 RestartVideoRenderer(stream, time);
651 }
652
653 void RendererImpl::RestartAudioRenderer(DemuxerStream* stream,
654 base::TimeDelta time) {
655 DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
656 DCHECK(task_runner_->BelongsToCurrentThread());
657 DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHED ||
658 state_ == STATE_FLUSHING);
659 DCHECK(time_source_);
660 DCHECK(audio_renderer_);
661 DCHECK_EQ(stream, current_audio_stream_);
662
663 audio_ended_ = false;
664 if (state_ == STATE_FLUSHED) {
665 // If we are in the FLUSHED state, then we are done. The audio renderer will
666 // be restarted by a subsequent RendererImpl::StartPlayingFrom call.
667 OnStreamRestartCompleted();
668 } else {
669 // Stream restart will be completed when the audio renderer decodes enough
670 // data and reports HAVE_ENOUGH to HandleRestartedStreamBufferingChanges.
671 audio_renderer_->StartPlaying();
672 }
673 }
674
675 void RendererImpl::RestartVideoRenderer(DemuxerStream* stream,
676 base::TimeDelta time) {
677 DVLOG(2) << __func__ << " stream=" << stream << " time=" << time.InSecondsF();
678 DCHECK(task_runner_->BelongsToCurrentThread());
679 DCHECK(video_renderer_);
680 DCHECK(state_ == STATE_PLAYING || state_ == STATE_FLUSHED ||
681 state_ == STATE_FLUSHING);
682 DCHECK_EQ(stream, current_video_stream_);
683
684 video_ended_ = false;
685 if (state_ == STATE_FLUSHED) {
686 // If we are in the FLUSHED state, then we are done. The video renderer will
687 // be restarted by a subsequent RendererImpl::StartPlayingFrom call.
688 OnStreamRestartCompleted();
689 } else {
690 // Stream restart will be completed when the video renderer decodes enough
691 // data and reports HAVE_ENOUGH to HandleRestartedStreamBufferingChanges.
692 video_renderer_->StartPlayingFrom(time);
693 }
563 } 694 }
564 695
565 void RendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) { 696 void RendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
566 DCHECK(task_runner_->BelongsToCurrentThread()); 697 DCHECK(task_runner_->BelongsToCurrentThread());
567 client_->OnStatisticsUpdate(stats); 698 client_->OnStatisticsUpdate(stats);
568 } 699 }
569 700
570 bool RendererImpl::HandleRestartedStreamBufferingChanges( 701 bool RendererImpl::HandleRestartedStreamBufferingChanges(
571 DemuxerStream::Type type, 702 DemuxerStream::Type type,
572 BufferingState new_buffering_state) { 703 BufferingState new_buffering_state) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 PausePlayback(); 758 PausePlayback();
628 task_runner_->PostTask( 759 task_runner_->PostTask(
629 FROM_HERE, 760 FROM_HERE,
630 base::Bind(&RendererImpl::OnStreamRestartCompleted, weak_this_)); 761 base::Bind(&RendererImpl::OnStreamRestartCompleted, weak_this_));
631 } 762 }
632 } 763 }
633 return false; 764 return false;
634 } 765 }
635 766
636 void RendererImpl::OnStreamRestartCompleted() { 767 void RendererImpl::OnStreamRestartCompleted() {
768 DVLOG(3) << __func__ << " restarting_audio_=" << restarting_audio_
769 << " restarting_video_=" << restarting_video_;
770 DCHECK(task_runner_->BelongsToCurrentThread());
637 DCHECK(restarting_audio_ || restarting_video_); 771 DCHECK(restarting_audio_ || restarting_video_);
638 restarting_audio_ = false; 772 restarting_audio_ = false;
639 restarting_video_ = false; 773 restarting_video_ = false;
640 if (!pending_stream_status_notifications_.empty()) { 774 if (!pending_actions_.empty()) {
641 pending_stream_status_notifications_.front().Run(); 775 base::Closure closure = pending_actions_.front();
642 pending_stream_status_notifications_.pop_front(); 776 pending_actions_.pop_front();
777 closure.Run();
643 } 778 }
644 } 779 }
645 780
646 void RendererImpl::OnBufferingStateChange(DemuxerStream::Type type, 781 void RendererImpl::OnBufferingStateChange(DemuxerStream::Type type,
647 BufferingState new_buffering_state) { 782 BufferingState new_buffering_state) {
648 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); 783 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO));
649 BufferingState* buffering_state = type == DemuxerStream::AUDIO 784 BufferingState* buffering_state = type == DemuxerStream::AUDIO
650 ? &audio_buffering_state_ 785 ? &audio_buffering_state_
651 : &video_buffering_state_; 786 : &video_buffering_state_;
652 787
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 DCHECK(task_runner_->BelongsToCurrentThread()); 991 DCHECK(task_runner_->BelongsToCurrentThread());
857 client_->OnVideoNaturalSizeChange(size); 992 client_->OnVideoNaturalSizeChange(size);
858 } 993 }
859 994
860 void RendererImpl::OnVideoOpacityChange(bool opaque) { 995 void RendererImpl::OnVideoOpacityChange(bool opaque) {
861 DCHECK(task_runner_->BelongsToCurrentThread()); 996 DCHECK(task_runner_->BelongsToCurrentThread());
862 client_->OnVideoOpacityChange(opaque); 997 client_->OnVideoOpacityChange(opaque);
863 } 998 }
864 999
865 } // namespace media 1000 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/renderer_impl.h ('k') | media/renderers/renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698