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

Side by Side Diff: media/base/pipeline.cc

Issue 10796074: Move VideoRenderer out of Filter heirarchy. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: Created 8 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
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/base/pipeline.h" 5 #include "media/base/pipeline.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/string_util.h" 16 #include "base/string_util.h"
17 #include "base/synchronization/condition_variable.h" 17 #include "base/synchronization/condition_variable.h"
18 #include "media/base/audio_decoder.h" 18 #include "media/base/audio_decoder.h"
19 #include "media/base/audio_renderer.h" 19 #include "media/base/audio_renderer.h"
20 #include "media/base/callback_util.h" 20 #include "media/base/callback_util.h"
21 #include "media/base/clock.h" 21 #include "media/base/clock.h"
22 #include "media/base/composite_filter.h"
23 #include "media/base/filter_collection.h" 22 #include "media/base/filter_collection.h"
24 #include "media/base/media_log.h" 23 #include "media/base/media_log.h"
25 #include "media/base/video_decoder.h" 24 #include "media/base/video_decoder.h"
26 #include "media/base/video_renderer.h" 25 #include "media/base/video_renderer.h"
27 26
28 using base::TimeDelta; 27 using base::TimeDelta;
29 28
30 namespace media { 29 namespace media {
31 30
32 PipelineStatusNotification::PipelineStatusNotification() 31 PipelineStatusNotification::PipelineStatusNotification()
(...skipping 25 matching lines...) Expand all
58 57
59 media::PipelineStatus PipelineStatusNotification::status() { 58 media::PipelineStatus PipelineStatusNotification::status() {
60 base::AutoLock auto_lock(lock_); 59 base::AutoLock auto_lock(lock_);
61 DCHECK(notified_); 60 DCHECK(notified_);
62 return status_; 61 return status_;
63 } 62 }
64 63
65 struct Pipeline::PipelineInitState { 64 struct Pipeline::PipelineInitState {
66 scoped_refptr<AudioDecoder> audio_decoder; 65 scoped_refptr<AudioDecoder> audio_decoder;
67 scoped_refptr<VideoDecoder> video_decoder; 66 scoped_refptr<VideoDecoder> video_decoder;
68 scoped_refptr<VideoRenderer> video_renderer;
69 scoped_refptr<CompositeFilter> composite;
70 }; 67 };
71 68
72 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) 69 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log)
73 : message_loop_(message_loop->message_loop_proxy()), 70 : message_loop_(message_loop->message_loop_proxy()),
74 media_log_(media_log), 71 media_log_(media_log),
75 clock_(new Clock(&base::Time::Now)), 72 clock_(new Clock(&base::Time::Now)),
76 waiting_for_clock_update_(false), 73 waiting_for_clock_update_(false),
77 state_(kCreated), 74 state_(kCreated),
78 creation_time_(base::Time::Now()) { 75 creation_time_(base::Time::Now()) {
79 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); 76 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 DCHECK(IsRunning()); 371 DCHECK(IsRunning());
375 DCHECK_NE(PIPELINE_OK, error); 372 DCHECK_NE(PIPELINE_OK, error);
376 VLOG(1) << "Media pipeline error: " << error; 373 VLOG(1) << "Media pipeline error: " << error;
377 374
378 message_loop_->PostTask(FROM_HERE, base::Bind( 375 message_loop_->PostTask(FROM_HERE, base::Bind(
379 &Pipeline::ErrorChangedTask, this, error)); 376 &Pipeline::ErrorChangedTask, this, error));
380 377
381 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); 378 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error));
382 } 379 }
383 380
384 TimeDelta Pipeline::GetTime() const {
385 DCHECK(IsRunning());
386 return GetCurrentTime();
387 }
388
389 TimeDelta Pipeline::GetDuration() const {
390 DCHECK(IsRunning());
391 return GetMediaDuration();
392 }
393
394 void Pipeline::OnAudioDisabled() { 381 void Pipeline::OnAudioDisabled() {
395 DCHECK(IsRunning()); 382 DCHECK(IsRunning());
396 message_loop_->PostTask(FROM_HERE, base::Bind( 383 message_loop_->PostTask(FROM_HERE, base::Bind(
397 &Pipeline::AudioDisabledTask, this)); 384 &Pipeline::AudioDisabledTask, this));
398 media_log_->AddEvent( 385 media_log_->AddEvent(
399 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); 386 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED));
400 } 387 }
401 388
402 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { 389 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) {
403 DCHECK(time <= max_time); 390 DCHECK(time <= max_time);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 return time_offset; 456 return time_offset;
470 } 457 }
471 458
472 void Pipeline::DoPause(const base::Closure& done_cb) { 459 void Pipeline::DoPause(const base::Closure& done_cb) {
473 DCHECK(message_loop_->BelongsToCurrentThread()); 460 DCHECK(message_loop_->BelongsToCurrentThread());
474 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 461 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
475 462
476 if (audio_renderer_) 463 if (audio_renderer_)
477 closures->push(base::Bind(&AudioRenderer::Pause, audio_renderer_)); 464 closures->push(base::Bind(&AudioRenderer::Pause, audio_renderer_));
478 465
479 if (pipeline_filter_) 466 if (video_renderer_)
480 closures->push(base::Bind(&Filter::Pause, pipeline_filter_)); 467 closures->push(base::Bind(&VideoRenderer::Pause, video_renderer_));
481 468
482 RunInSeries(closures.Pass(), done_cb); 469 RunInSeries(closures.Pass(), done_cb);
483 } 470 }
484 471
485 void Pipeline::DoFlush(const base::Closure& done_cb) { 472 void Pipeline::DoFlush(const base::Closure& done_cb) {
486 DCHECK(message_loop_->BelongsToCurrentThread()); 473 DCHECK(message_loop_->BelongsToCurrentThread());
487 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 474 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
488 475
489 if (audio_renderer_) 476 if (audio_renderer_)
490 closures->push(base::Bind(&AudioRenderer::Flush, audio_renderer_)); 477 closures->push(base::Bind(&AudioRenderer::Flush, audio_renderer_));
491 478
492 if (pipeline_filter_) 479 if (video_renderer_)
493 closures->push(base::Bind(&Filter::Flush, pipeline_filter_)); 480 closures->push(base::Bind(&VideoRenderer::Flush, video_renderer_));
494 481
495 RunInParallel(closures.Pass(), done_cb); 482 RunInParallel(closures.Pass(), done_cb);
496 } 483 }
497 484
498 void Pipeline::DoPlay(const base::Closure& done_cb) { 485 void Pipeline::DoPlay(const base::Closure& done_cb) {
499 DCHECK(message_loop_->BelongsToCurrentThread()); 486 DCHECK(message_loop_->BelongsToCurrentThread());
500 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 487 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
501 488
502 if (audio_renderer_) 489 if (audio_renderer_)
503 closures->push(base::Bind(&AudioRenderer::Play, audio_renderer_)); 490 closures->push(base::Bind(&AudioRenderer::Play, audio_renderer_));
504 491
505 if (pipeline_filter_) 492 if (video_renderer_)
506 closures->push(base::Bind(&Filter::Play, pipeline_filter_)); 493 closures->push(base::Bind(&VideoRenderer::Play, video_renderer_));
507 494
508 RunInSeries(closures.Pass(), done_cb); 495 RunInSeries(closures.Pass(), done_cb);
509 } 496 }
510 497
511 void Pipeline::DoStop(const base::Closure& done_cb) { 498 void Pipeline::DoStop(const base::Closure& done_cb) {
512 DCHECK(message_loop_->BelongsToCurrentThread()); 499 DCHECK(message_loop_->BelongsToCurrentThread());
513 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 500 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
514 501
515 if (demuxer_) 502 if (demuxer_)
516 closures->push(base::Bind(&Demuxer::Stop, demuxer_)); 503 closures->push(base::Bind(&Demuxer::Stop, demuxer_));
517 504
518 if (audio_renderer_) 505 if (audio_renderer_)
519 closures->push(base::Bind(&AudioRenderer::Stop, audio_renderer_)); 506 closures->push(base::Bind(&AudioRenderer::Stop, audio_renderer_));
520 507
521 if (pipeline_filter_) 508 if (video_renderer_)
522 closures->push(base::Bind(&Filter::Stop, pipeline_filter_)); 509 closures->push(base::Bind(&VideoRenderer::Stop, video_renderer_));
523 510
524 RunInSeries(closures.Pass(), done_cb); 511 RunInSeries(closures.Pass(), done_cb);
525 } 512 }
526 513
527 void Pipeline::AddBufferedByteRange(int64 start, int64 end) { 514 void Pipeline::AddBufferedByteRange(int64 start, int64 end) {
528 DCHECK(IsRunning()); 515 DCHECK(IsRunning());
529 base::AutoLock auto_lock(lock_); 516 base::AutoLock auto_lock(lock_);
530 buffered_byte_ranges_.Add(start, end); 517 buffered_byte_ranges_.Add(start, end);
531 did_loading_progress_ = true; 518 did_loading_progress_ = true;
532 } 519 }
533 520
534 void Pipeline::AddBufferedTimeRange(base::TimeDelta start, 521 void Pipeline::AddBufferedTimeRange(base::TimeDelta start,
535 base::TimeDelta end) { 522 base::TimeDelta end) {
536 DCHECK(IsRunning()); 523 DCHECK(IsRunning());
537 base::AutoLock auto_lock(lock_); 524 base::AutoLock auto_lock(lock_);
538 buffered_time_ranges_.Add(start, end); 525 buffered_time_ranges_.Add(start, end);
539 did_loading_progress_ = true; 526 did_loading_progress_ = true;
540 } 527 }
541 528
542 void Pipeline::SetNaturalVideoSize(const gfx::Size& size) { 529 void Pipeline::OnNaturalVideoSizeChanged(const gfx::Size& size) {
543 DCHECK(IsRunning()); 530 DCHECK(IsRunning());
544 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( 531 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent(
545 size.width(), size.height())); 532 size.width(), size.height()));
546 533
547 base::AutoLock auto_lock(lock_); 534 base::AutoLock auto_lock(lock_);
548 natural_size_ = size; 535 natural_size_ = size;
549 } 536 }
550 537
551 void Pipeline::NotifyEnded() { 538 void Pipeline::OnRendererEnded() {
552 DCHECK(IsRunning()); 539 DCHECK(IsRunning());
553 message_loop_->PostTask(FROM_HERE, base::Bind( 540 message_loop_->PostTask(FROM_HERE, base::Bind(
554 &Pipeline::NotifyEndedTask, this)); 541 &Pipeline::OnRendererEndedTask, this));
555 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); 542 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED));
556 } 543 }
557 544
558 // Called from any thread. 545 // Called from any thread.
559 void Pipeline::OnFilterInitialize(PipelineStatus status) { 546 void Pipeline::OnFilterInitialize(PipelineStatus status) {
560 // Continue the initialize task by proceeding to the next stage. 547 // Continue the initialize task by proceeding to the next stage.
561 message_loop_->PostTask(FROM_HERE, base::Bind( 548 message_loop_->PostTask(FROM_HERE, base::Bind(
562 &Pipeline::InitializeTask, this, status)); 549 &Pipeline::InitializeTask, this, status));
563 } 550 }
564 551
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 const PipelineStatusCB& start_cb) { 588 const PipelineStatusCB& start_cb) {
602 DCHECK(message_loop_->BelongsToCurrentThread()); 589 DCHECK(message_loop_->BelongsToCurrentThread());
603 DCHECK_EQ(kCreated, state_); 590 DCHECK_EQ(kCreated, state_);
604 filter_collection_ = filter_collection.Pass(); 591 filter_collection_ = filter_collection.Pass();
605 ended_cb_ = ended_cb; 592 ended_cb_ = ended_cb;
606 error_cb_ = error_cb; 593 error_cb_ = error_cb;
607 seek_cb_ = start_cb; 594 seek_cb_ = start_cb;
608 595
609 // Kick off initialization. 596 // Kick off initialization.
610 pipeline_init_state_.reset(new PipelineInitState()); 597 pipeline_init_state_.reset(new PipelineInitState());
611 pipeline_init_state_->composite = new CompositeFilter(message_loop_);
612 pipeline_init_state_->composite->SetHost(this);
613 598
614 SetState(kInitDemuxer); 599 SetState(kInitDemuxer);
615 InitializeDemuxer(); 600 InitializeDemuxer();
616 } 601 }
617 602
618 // Main initialization method called on the pipeline thread. This code attempts 603 // Main initialization method called on the pipeline thread. This code attempts
619 // to use the specified filter factory to build a pipeline. 604 // to use the specified filter factory to build a pipeline.
620 // Initialization step performed in this method depends on current state of this 605 // Initialization step performed in this method depends on current state of this
621 // object, indicated by |state_|. After each step of initialization, this 606 // object, indicated by |state_|. After each step of initialization, this
622 // object transits to the next stage. It starts by creating a Demuxer, and then 607 // object transits to the next stage. It starts by creating a Demuxer, and then
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 return; 677 return;
693 } 678 }
694 } 679 }
695 680
696 if (state_ == kInitVideoRenderer) { 681 if (state_ == kInitVideoRenderer) {
697 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) { 682 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) {
698 SetError(PIPELINE_ERROR_COULD_NOT_RENDER); 683 SetError(PIPELINE_ERROR_COULD_NOT_RENDER);
699 return; 684 return;
700 } 685 }
701 686
702 // Clear the collection of filters. 687 // Clear initialization state now that we're done.
703 filter_collection_->Clear(); 688 filter_collection_.reset();
704
705 pipeline_filter_ = pipeline_init_state_->composite;
706
707 // Clear init state since we're done initializing.
708 pipeline_init_state_.reset(); 689 pipeline_init_state_.reset();
709 690
710 // Initialization was successful, we are now considered paused, so it's safe 691 // Initialization was successful, we are now considered paused, so it's safe
711 // to set the initial playback rate and volume. 692 // to set the initial playback rate and volume.
712 PlaybackRateChangedTask(GetPlaybackRate()); 693 PlaybackRateChangedTask(GetPlaybackRate());
713 VolumeChangedTask(GetVolume()); 694 VolumeChangedTask(GetVolume());
714 695
715 // Fire a seek request to get the renderers to preroll. We can skip a seek 696 // Fire a seek request to get the renderers to preroll. We can skip a seek
716 // here as the demuxer should be at the start of the stream. 697 // here as the demuxer should be at the start of the stream.
717 seek_pending_ = true; 698 seek_pending_ = true;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 pending_playback_rate_ = playback_rate; 777 pending_playback_rate_ = playback_rate;
797 playback_rate_change_pending_ = true; 778 playback_rate_change_pending_ = true;
798 return; 779 return;
799 } 780 }
800 781
801 { 782 {
802 base::AutoLock auto_lock(lock_); 783 base::AutoLock auto_lock(lock_);
803 clock_->SetPlaybackRate(playback_rate); 784 clock_->SetPlaybackRate(playback_rate);
804 } 785 }
805 786
806 // Notify |pipeline_filter_| if it has been initialized. If initialization 787 // These will get set after initialization completes in case playback rate is
807 // hasn't completed yet, the playback rate will be set when initialization 788 // set prior to initialization.
808 // completes. 789 if (demuxer_)
809 if (pipeline_filter_) {
810 demuxer_->SetPlaybackRate(playback_rate); 790 demuxer_->SetPlaybackRate(playback_rate);
811 pipeline_filter_->SetPlaybackRate(playback_rate); 791 if (audio_renderer_)
812 792 audio_renderer_->SetPlaybackRate(playback_rate_);
813 if (audio_renderer_) 793 if (video_renderer_)
814 audio_renderer_->SetPlaybackRate(playback_rate_); 794 video_renderer_->SetPlaybackRate(playback_rate_);
815 }
816 } 795 }
817 796
818 void Pipeline::VolumeChangedTask(float volume) { 797 void Pipeline::VolumeChangedTask(float volume) {
819 DCHECK(message_loop_->BelongsToCurrentThread()); 798 DCHECK(message_loop_->BelongsToCurrentThread());
820 if (!running_ || tearing_down_) 799 if (!running_ || tearing_down_)
821 return; 800 return;
822 801
823 if (audio_renderer_) 802 if (audio_renderer_)
824 audio_renderer_->SetVolume(volume); 803 audio_renderer_->SetVolume(volume);
825 } 804 }
(...skipping 27 matching lines...) Expand all
853 832
854 // Kick off seeking! 833 // Kick off seeking!
855 { 834 {
856 base::AutoLock auto_lock(lock_); 835 base::AutoLock auto_lock(lock_);
857 if (clock_->IsPlaying()) 836 if (clock_->IsPlaying())
858 clock_->Pause(); 837 clock_->Pause();
859 } 838 }
860 DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this)); 839 DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this));
861 } 840 }
862 841
863 void Pipeline::NotifyEndedTask() { 842 void Pipeline::OnRendererEndedTask() {
864 DCHECK(message_loop_->BelongsToCurrentThread()); 843 DCHECK(message_loop_->BelongsToCurrentThread());
865 844
866 // We can only end if we were actually playing. 845 // We can only end if we were actually playing.
867 if (state_ != kStarted) { 846 if (state_ != kStarted) {
868 return; 847 return;
869 } 848 }
870 849
871 DCHECK(audio_renderer_ || video_renderer_); 850 DCHECK(audio_renderer_ || video_renderer_);
872 851
873 // Make sure every extant renderer has ended. 852 // Make sure every extant renderer has ended.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 break; 999 break;
1021 // default: intentionally left out to force new states to cause compiler 1000 // default: intentionally left out to force new states to cause compiler
1022 // errors. 1001 // errors.
1023 }; 1002 };
1024 } 1003 }
1025 1004
1026 void Pipeline::FinishDestroyingFiltersTask() { 1005 void Pipeline::FinishDestroyingFiltersTask() {
1027 DCHECK(message_loop_->BelongsToCurrentThread()); 1006 DCHECK(message_loop_->BelongsToCurrentThread());
1028 DCHECK(IsPipelineStopped()); 1007 DCHECK(IsPipelineStopped());
1029 1008
1030 // Clear filter references.
1031 audio_renderer_ = NULL; 1009 audio_renderer_ = NULL;
1032 video_renderer_ = NULL; 1010 video_renderer_ = NULL;
1033 demuxer_ = NULL; 1011 demuxer_ = NULL;
1034 1012
1035 pipeline_filter_ = NULL;
1036
1037 if (error_caused_teardown_ && !IsPipelineOk() && !error_cb_.is_null()) 1013 if (error_caused_teardown_ && !IsPipelineOk() && !error_cb_.is_null())
1038 error_cb_.Run(status_); 1014 error_cb_.Run(status_);
1039 1015
1040 if (stop_pending_) { 1016 if (stop_pending_) {
1041 stop_pending_ = false; 1017 stop_pending_ = false;
1042 ResetState(); 1018 ResetState();
1043 // Notify the client that stopping has finished. 1019 // Notify the client that stopping has finished.
1044 base::ResetAndReturn(&stop_cb_).Run(); 1020 base::ResetAndReturn(&stop_cb_).Run();
1045 } 1021 }
1046 1022
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 if (!audio_renderer_) { 1125 if (!audio_renderer_) {
1150 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1126 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1151 return false; 1127 return false;
1152 } 1128 }
1153 1129
1154 audio_renderer_->Initialize( 1130 audio_renderer_->Initialize(
1155 decoder, 1131 decoder,
1156 base::Bind(&Pipeline::OnFilterInitialize, this), 1132 base::Bind(&Pipeline::OnFilterInitialize, this),
1157 base::Bind(&Pipeline::OnAudioUnderflow, this), 1133 base::Bind(&Pipeline::OnAudioUnderflow, this),
1158 base::Bind(&Pipeline::OnAudioTimeUpdate, this), 1134 base::Bind(&Pipeline::OnAudioTimeUpdate, this),
1159 base::Bind(&Pipeline::NotifyEnded, this), 1135 base::Bind(&Pipeline::OnRendererEnded, this),
1160 base::Bind(&Pipeline::OnAudioDisabled, this), 1136 base::Bind(&Pipeline::OnAudioDisabled, this),
1161 base::Bind(&Pipeline::SetError, this)); 1137 base::Bind(&Pipeline::SetError, this));
1162 return true; 1138 return true;
1163 } 1139 }
1164 1140
1165 bool Pipeline::InitializeVideoRenderer( 1141 bool Pipeline::InitializeVideoRenderer(
1166 const scoped_refptr<VideoDecoder>& decoder) { 1142 const scoped_refptr<VideoDecoder>& decoder) {
1167 DCHECK(message_loop_->BelongsToCurrentThread()); 1143 DCHECK(message_loop_->BelongsToCurrentThread());
1168 DCHECK(IsPipelineOk()); 1144 DCHECK(IsPipelineOk());
1169 1145
1170 if (!decoder) 1146 if (!decoder)
1171 return false; 1147 return false;
1172 1148
1173 filter_collection_->SelectVideoRenderer( 1149 filter_collection_->SelectVideoRenderer(
Ami GONE FROM CHROMIUM 2012/07/21 05:02:35 single line
scherkus (not reviewing) 2012/07/23 03:21:12 Done.
1174 &pipeline_init_state_->video_renderer); 1150 &video_renderer_);
1175 if (!pipeline_init_state_->video_renderer) { 1151 if (!video_renderer_) {
1176 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1152 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1177 return false; 1153 return false;
1178 } 1154 }
1179 1155
1180 pipeline_init_state_->composite->AddFilter( 1156 video_renderer_->Initialize(
1181 pipeline_init_state_->video_renderer);
1182
1183 pipeline_init_state_->video_renderer->Initialize(
1184 decoder, 1157 decoder,
1185 base::Bind(&Pipeline::OnFilterInitialize, this), 1158 base::Bind(&Pipeline::OnFilterInitialize, this),
1186 base::Bind(&Pipeline::OnUpdateStatistics, this), 1159 base::Bind(&Pipeline::OnUpdateStatistics, this),
1187 base::Bind(&Pipeline::OnVideoTimeUpdate, this)); 1160 base::Bind(&Pipeline::OnVideoTimeUpdate, this),
1188 1161 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this),
1189 video_renderer_ = pipeline_init_state_->video_renderer; 1162 base::Bind(&Pipeline::OnRendererEnded, this),
1163 base::Bind(&Pipeline::SetError, this),
1164 base::Bind(&Pipeline::GetCurrentTime, this),
1165 base::Bind(&Pipeline::GetMediaDuration, this));
1190 return true; 1166 return true;
1191 } 1167 }
1192 1168
1193 void Pipeline::TearDownPipeline() { 1169 void Pipeline::TearDownPipeline() {
1194 DCHECK(message_loop_->BelongsToCurrentThread()); 1170 DCHECK(message_loop_->BelongsToCurrentThread());
1195 DCHECK_NE(kStopped, state_); 1171 DCHECK_NE(kStopped, state_);
1196 1172
1197 DCHECK(!tearing_down_ || // Teardown on Stop(). 1173 DCHECK(!tearing_down_ || // Teardown on Stop().
1198 (tearing_down_ && error_caused_teardown_) || // Teardown on error. 1174 (tearing_down_ && error_caused_teardown_) || // Teardown on error.
1199 (tearing_down_ && stop_pending_)); // Stop during teardown by error. 1175 (tearing_down_ && stop_pending_)); // Stop during teardown by error.
(...skipping 10 matching lines...) Expand all
1210 message_loop_->PostTask(FROM_HERE, base::Bind( 1186 message_loop_->PostTask(FROM_HERE, base::Bind(
1211 &Pipeline::FinishDestroyingFiltersTask, this)); 1187 &Pipeline::FinishDestroyingFiltersTask, this));
1212 break; 1188 break;
1213 1189
1214 case kInitDemuxer: 1190 case kInitDemuxer:
1215 case kInitAudioDecoder: 1191 case kInitAudioDecoder:
1216 case kInitAudioRenderer: 1192 case kInitAudioRenderer:
1217 case kInitVideoDecoder: 1193 case kInitVideoDecoder:
1218 case kInitVideoRenderer: 1194 case kInitVideoRenderer:
1219 // Make it look like initialization was successful. 1195 // Make it look like initialization was successful.
1220 pipeline_filter_ = pipeline_init_state_->composite; 1196 filter_collection_.reset();
1221 pipeline_init_state_.reset(); 1197 pipeline_init_state_.reset();
1222 filter_collection_.reset();
1223 1198
1224 SetState(kStopping); 1199 SetState(kStopping);
1225 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); 1200 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
1226 1201
1227 FinishInitialization(); 1202 FinishInitialization();
1228 break; 1203 break;
1229 1204
1230 case kPausing: 1205 case kPausing:
1231 case kSeeking: 1206 case kSeeking:
1232 case kFlushing: 1207 case kFlushing:
(...skipping 30 matching lines...) Expand all
1263 scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs( 1238 scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs(
1264 new std::queue<PipelineStatusCBFunc>()); 1239 new std::queue<PipelineStatusCBFunc>());
1265 1240
1266 if (!skip_demuxer_seek) 1241 if (!skip_demuxer_seek)
1267 status_cbs->push(base::Bind(&Demuxer::Seek, demuxer_, seek_timestamp)); 1242 status_cbs->push(base::Bind(&Demuxer::Seek, demuxer_, seek_timestamp));
1268 1243
1269 if (audio_renderer_) 1244 if (audio_renderer_)
1270 status_cbs->push(base::Bind( 1245 status_cbs->push(base::Bind(
1271 &AudioRenderer::Seek, audio_renderer_, seek_timestamp)); 1246 &AudioRenderer::Seek, audio_renderer_, seek_timestamp));
1272 1247
1273 if (pipeline_filter_) 1248 if (video_renderer_)
1274 status_cbs->push(base::Bind( 1249 status_cbs->push(base::Bind(
1275 &Filter::Seek, pipeline_filter_, seek_timestamp)); 1250 &VideoRenderer::Seek, video_renderer_, seek_timestamp));
1276 1251
1277 RunInSeriesWithStatus(status_cbs.Pass(), base::Bind( 1252 RunInSeriesWithStatus(status_cbs.Pass(), base::Bind(
1278 &Pipeline::ReportStatus, this, done_cb)); 1253 &Pipeline::ReportStatus, this, done_cb));
1279 } 1254 }
1280 1255
1281 void Pipeline::OnAudioUnderflow() { 1256 void Pipeline::OnAudioUnderflow() {
1282 if (!message_loop_->BelongsToCurrentThread()) { 1257 if (!message_loop_->BelongsToCurrentThread()) {
1283 message_loop_->PostTask(FROM_HERE, base::Bind( 1258 message_loop_->PostTask(FROM_HERE, base::Bind(
1284 &Pipeline::OnAudioUnderflow, this)); 1259 &Pipeline::OnAudioUnderflow, this));
1285 return; 1260 return;
1286 } 1261 }
1287 1262
1288 if (state_ != kStarted) 1263 if (state_ != kStarted)
1289 return; 1264 return;
1290 1265
1291 if (audio_renderer_) 1266 if (audio_renderer_)
1292 audio_renderer_->ResumeAfterUnderflow(true); 1267 audio_renderer_->ResumeAfterUnderflow(true);
1293 } 1268 }
1294 1269
1295 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 1270 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
1296 lock_.AssertAcquired(); 1271 lock_.AssertAcquired();
1297 if (!waiting_for_clock_update_) 1272 if (!waiting_for_clock_update_)
1298 return; 1273 return;
1299 1274
1300 waiting_for_clock_update_ = false; 1275 waiting_for_clock_update_ = false;
1301 clock_->Play(); 1276 clock_->Play();
1302 } 1277 }
1303 1278
1304 } // namespace media 1279 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698