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

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: GetMediaTime 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
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_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/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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 return; 179 return;
183 180
184 base::AutoLock auto_lock(lock_); 181 base::AutoLock auto_lock(lock_);
185 volume_ = volume; 182 volume_ = volume;
186 if (running_ && !tearing_down_) { 183 if (running_ && !tearing_down_) {
187 message_loop_->PostTask(FROM_HERE, base::Bind( 184 message_loop_->PostTask(FROM_HERE, base::Bind(
188 &Pipeline::VolumeChangedTask, this, volume)); 185 &Pipeline::VolumeChangedTask, this, volume));
189 } 186 }
190 } 187 }
191 188
192 TimeDelta Pipeline::GetCurrentTime() const { 189 TimeDelta Pipeline::GetMediaTime() const {
193 base::AutoLock auto_lock(lock_); 190 base::AutoLock auto_lock(lock_);
194 return GetCurrentTime_Locked();
195 }
196
197 TimeDelta Pipeline::GetCurrentTime_Locked() const {
198 lock_.AssertAcquired();
199 return clock_->Elapsed(); 191 return clock_->Elapsed();
200 } 192 }
201 193
202 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { 194 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() {
203 base::AutoLock auto_lock(lock_); 195 base::AutoLock auto_lock(lock_);
204 Ranges<TimeDelta> time_ranges; 196 Ranges<TimeDelta> time_ranges;
205 for (size_t i = 0; i < buffered_time_ranges_.size(); ++i) { 197 for (size_t i = 0; i < buffered_time_ranges_.size(); ++i) {
206 time_ranges.Add(buffered_time_ranges_.start(i), 198 time_ranges.Add(buffered_time_ranges_.start(i),
207 buffered_time_ranges_.end(i)); 199 buffered_time_ranges_.end(i));
208 } 200 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 DCHECK(IsRunning()); 366 DCHECK(IsRunning());
375 DCHECK_NE(PIPELINE_OK, error); 367 DCHECK_NE(PIPELINE_OK, error);
376 VLOG(1) << "Media pipeline error: " << error; 368 VLOG(1) << "Media pipeline error: " << error;
377 369
378 message_loop_->PostTask(FROM_HERE, base::Bind( 370 message_loop_->PostTask(FROM_HERE, base::Bind(
379 &Pipeline::ErrorChangedTask, this, error)); 371 &Pipeline::ErrorChangedTask, this, error));
380 372
381 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); 373 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error));
382 } 374 }
383 375
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() { 376 void Pipeline::OnAudioDisabled() {
395 DCHECK(IsRunning()); 377 DCHECK(IsRunning());
396 message_loop_->PostTask(FROM_HERE, base::Bind( 378 message_loop_->PostTask(FROM_HERE, base::Bind(
397 &Pipeline::AudioDisabledTask, this)); 379 &Pipeline::AudioDisabledTask, this));
398 media_log_->AddEvent( 380 media_log_->AddEvent(
399 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); 381 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED));
400 } 382 }
401 383
402 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { 384 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) {
403 DCHECK(time <= max_time); 385 DCHECK(time <= max_time);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 return time_offset; 451 return time_offset;
470 } 452 }
471 453
472 void Pipeline::DoPause(const base::Closure& done_cb) { 454 void Pipeline::DoPause(const base::Closure& done_cb) {
473 DCHECK(message_loop_->BelongsToCurrentThread()); 455 DCHECK(message_loop_->BelongsToCurrentThread());
474 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 456 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
475 457
476 if (audio_renderer_) 458 if (audio_renderer_)
477 closures->push(base::Bind(&AudioRenderer::Pause, audio_renderer_)); 459 closures->push(base::Bind(&AudioRenderer::Pause, audio_renderer_));
478 460
479 if (pipeline_filter_) 461 if (video_renderer_)
480 closures->push(base::Bind(&Filter::Pause, pipeline_filter_)); 462 closures->push(base::Bind(&VideoRenderer::Pause, video_renderer_));
481 463
482 RunInSeries(closures.Pass(), done_cb); 464 RunInSeries(closures.Pass(), done_cb);
483 } 465 }
484 466
485 void Pipeline::DoFlush(const base::Closure& done_cb) { 467 void Pipeline::DoFlush(const base::Closure& done_cb) {
486 DCHECK(message_loop_->BelongsToCurrentThread()); 468 DCHECK(message_loop_->BelongsToCurrentThread());
487 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 469 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
488 470
489 if (audio_renderer_) 471 if (audio_renderer_)
490 closures->push(base::Bind(&AudioRenderer::Flush, audio_renderer_)); 472 closures->push(base::Bind(&AudioRenderer::Flush, audio_renderer_));
491 473
492 if (pipeline_filter_) 474 if (video_renderer_)
493 closures->push(base::Bind(&Filter::Flush, pipeline_filter_)); 475 closures->push(base::Bind(&VideoRenderer::Flush, video_renderer_));
494 476
495 RunInParallel(closures.Pass(), done_cb); 477 RunInParallel(closures.Pass(), done_cb);
496 } 478 }
497 479
498 void Pipeline::DoPlay(const base::Closure& done_cb) { 480 void Pipeline::DoPlay(const base::Closure& done_cb) {
499 DCHECK(message_loop_->BelongsToCurrentThread()); 481 DCHECK(message_loop_->BelongsToCurrentThread());
500 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 482 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
501 483
502 if (audio_renderer_) 484 if (audio_renderer_)
503 closures->push(base::Bind(&AudioRenderer::Play, audio_renderer_)); 485 closures->push(base::Bind(&AudioRenderer::Play, audio_renderer_));
504 486
505 if (pipeline_filter_) 487 if (video_renderer_)
506 closures->push(base::Bind(&Filter::Play, pipeline_filter_)); 488 closures->push(base::Bind(&VideoRenderer::Play, video_renderer_));
507 489
508 RunInSeries(closures.Pass(), done_cb); 490 RunInSeries(closures.Pass(), done_cb);
509 } 491 }
510 492
511 void Pipeline::DoStop(const base::Closure& done_cb) { 493 void Pipeline::DoStop(const base::Closure& done_cb) {
512 DCHECK(message_loop_->BelongsToCurrentThread()); 494 DCHECK(message_loop_->BelongsToCurrentThread());
513 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); 495 scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>);
514 496
515 if (demuxer_) 497 if (demuxer_)
516 closures->push(base::Bind(&Demuxer::Stop, demuxer_)); 498 closures->push(base::Bind(&Demuxer::Stop, demuxer_));
517 499
518 if (audio_renderer_) 500 if (audio_renderer_)
519 closures->push(base::Bind(&AudioRenderer::Stop, audio_renderer_)); 501 closures->push(base::Bind(&AudioRenderer::Stop, audio_renderer_));
520 502
521 if (pipeline_filter_) 503 if (video_renderer_)
522 closures->push(base::Bind(&Filter::Stop, pipeline_filter_)); 504 closures->push(base::Bind(&VideoRenderer::Stop, video_renderer_));
523 505
524 RunInSeries(closures.Pass(), done_cb); 506 RunInSeries(closures.Pass(), done_cb);
525 } 507 }
526 508
527 void Pipeline::AddBufferedByteRange(int64 start, int64 end) { 509 void Pipeline::AddBufferedByteRange(int64 start, int64 end) {
528 DCHECK(IsRunning()); 510 DCHECK(IsRunning());
529 base::AutoLock auto_lock(lock_); 511 base::AutoLock auto_lock(lock_);
530 buffered_byte_ranges_.Add(start, end); 512 buffered_byte_ranges_.Add(start, end);
531 did_loading_progress_ = true; 513 did_loading_progress_ = true;
532 } 514 }
533 515
534 void Pipeline::AddBufferedTimeRange(base::TimeDelta start, 516 void Pipeline::AddBufferedTimeRange(base::TimeDelta start,
535 base::TimeDelta end) { 517 base::TimeDelta end) {
536 DCHECK(IsRunning()); 518 DCHECK(IsRunning());
537 base::AutoLock auto_lock(lock_); 519 base::AutoLock auto_lock(lock_);
538 buffered_time_ranges_.Add(start, end); 520 buffered_time_ranges_.Add(start, end);
539 did_loading_progress_ = true; 521 did_loading_progress_ = true;
540 } 522 }
541 523
542 void Pipeline::SetNaturalVideoSize(const gfx::Size& size) { 524 void Pipeline::OnNaturalVideoSizeChanged(const gfx::Size& size) {
543 DCHECK(IsRunning()); 525 DCHECK(IsRunning());
544 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( 526 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent(
545 size.width(), size.height())); 527 size.width(), size.height()));
546 528
547 base::AutoLock auto_lock(lock_); 529 base::AutoLock auto_lock(lock_);
548 natural_size_ = size; 530 natural_size_ = size;
549 } 531 }
550 532
551 void Pipeline::NotifyEnded() { 533 void Pipeline::OnRendererEnded() {
552 DCHECK(IsRunning()); 534 DCHECK(IsRunning());
553 message_loop_->PostTask(FROM_HERE, base::Bind( 535 message_loop_->PostTask(FROM_HERE, base::Bind(
554 &Pipeline::NotifyEndedTask, this)); 536 &Pipeline::OnRendererEndedTask, this));
555 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); 537 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED));
556 } 538 }
557 539
558 // Called from any thread. 540 // Called from any thread.
559 void Pipeline::OnFilterInitialize(PipelineStatus status) { 541 void Pipeline::OnFilterInitialize(PipelineStatus status) {
560 // Continue the initialize task by proceeding to the next stage. 542 // Continue the initialize task by proceeding to the next stage.
561 message_loop_->PostTask(FROM_HERE, base::Bind( 543 message_loop_->PostTask(FROM_HERE, base::Bind(
562 &Pipeline::InitializeTask, this, status)); 544 &Pipeline::InitializeTask, this, status));
563 } 545 }
564 546
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 const PipelineStatusCB& start_cb) { 583 const PipelineStatusCB& start_cb) {
602 DCHECK(message_loop_->BelongsToCurrentThread()); 584 DCHECK(message_loop_->BelongsToCurrentThread());
603 DCHECK_EQ(kCreated, state_); 585 DCHECK_EQ(kCreated, state_);
604 filter_collection_ = filter_collection.Pass(); 586 filter_collection_ = filter_collection.Pass();
605 ended_cb_ = ended_cb; 587 ended_cb_ = ended_cb;
606 error_cb_ = error_cb; 588 error_cb_ = error_cb;
607 seek_cb_ = start_cb; 589 seek_cb_ = start_cb;
608 590
609 // Kick off initialization. 591 // Kick off initialization.
610 pipeline_init_state_.reset(new PipelineInitState()); 592 pipeline_init_state_.reset(new PipelineInitState());
611 pipeline_init_state_->composite = new CompositeFilter(message_loop_);
612 pipeline_init_state_->composite->SetHost(this);
613 593
614 SetState(kInitDemuxer); 594 SetState(kInitDemuxer);
615 InitializeDemuxer(); 595 InitializeDemuxer();
616 } 596 }
617 597
618 // Main initialization method called on the pipeline thread. This code attempts 598 // Main initialization method called on the pipeline thread. This code attempts
619 // to use the specified filter factory to build a pipeline. 599 // to use the specified filter factory to build a pipeline.
620 // Initialization step performed in this method depends on current state of this 600 // Initialization step performed in this method depends on current state of this
621 // object, indicated by |state_|. After each step of initialization, this 601 // 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 602 // 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; 672 return;
693 } 673 }
694 } 674 }
695 675
696 if (state_ == kInitVideoRenderer) { 676 if (state_ == kInitVideoRenderer) {
697 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) { 677 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) {
698 SetError(PIPELINE_ERROR_COULD_NOT_RENDER); 678 SetError(PIPELINE_ERROR_COULD_NOT_RENDER);
699 return; 679 return;
700 } 680 }
701 681
702 // Clear the collection of filters. 682 // Clear initialization state now that we're done.
703 filter_collection_->Clear(); 683 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(); 684 pipeline_init_state_.reset();
709 685
710 // Initialization was successful, we are now considered paused, so it's safe 686 // Initialization was successful, we are now considered paused, so it's safe
711 // to set the initial playback rate and volume. 687 // to set the initial playback rate and volume.
712 PlaybackRateChangedTask(GetPlaybackRate()); 688 PlaybackRateChangedTask(GetPlaybackRate());
713 VolumeChangedTask(GetVolume()); 689 VolumeChangedTask(GetVolume());
714 690
715 // Fire a seek request to get the renderers to preroll. We can skip a seek 691 // 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. 692 // here as the demuxer should be at the start of the stream.
717 seek_pending_ = true; 693 seek_pending_ = true;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 pending_playback_rate_ = playback_rate; 772 pending_playback_rate_ = playback_rate;
797 playback_rate_change_pending_ = true; 773 playback_rate_change_pending_ = true;
798 return; 774 return;
799 } 775 }
800 776
801 { 777 {
802 base::AutoLock auto_lock(lock_); 778 base::AutoLock auto_lock(lock_);
803 clock_->SetPlaybackRate(playback_rate); 779 clock_->SetPlaybackRate(playback_rate);
804 } 780 }
805 781
806 // Notify |pipeline_filter_| if it has been initialized. If initialization 782 // 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 783 // set prior to initialization.
808 // completes. 784 if (demuxer_)
809 if (pipeline_filter_) {
810 demuxer_->SetPlaybackRate(playback_rate); 785 demuxer_->SetPlaybackRate(playback_rate);
811 pipeline_filter_->SetPlaybackRate(playback_rate); 786 if (audio_renderer_)
812 787 audio_renderer_->SetPlaybackRate(playback_rate_);
813 if (audio_renderer_) 788 if (video_renderer_)
814 audio_renderer_->SetPlaybackRate(playback_rate_); 789 video_renderer_->SetPlaybackRate(playback_rate_);
815 }
816 } 790 }
817 791
818 void Pipeline::VolumeChangedTask(float volume) { 792 void Pipeline::VolumeChangedTask(float volume) {
819 DCHECK(message_loop_->BelongsToCurrentThread()); 793 DCHECK(message_loop_->BelongsToCurrentThread());
820 if (!running_ || tearing_down_) 794 if (!running_ || tearing_down_)
821 return; 795 return;
822 796
823 if (audio_renderer_) 797 if (audio_renderer_)
824 audio_renderer_->SetVolume(volume); 798 audio_renderer_->SetVolume(volume);
825 } 799 }
(...skipping 27 matching lines...) Expand all
853 827
854 // Kick off seeking! 828 // Kick off seeking!
855 { 829 {
856 base::AutoLock auto_lock(lock_); 830 base::AutoLock auto_lock(lock_);
857 if (clock_->IsPlaying()) 831 if (clock_->IsPlaying())
858 clock_->Pause(); 832 clock_->Pause();
859 } 833 }
860 DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this)); 834 DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this));
861 } 835 }
862 836
863 void Pipeline::NotifyEndedTask() { 837 void Pipeline::OnRendererEndedTask() {
864 DCHECK(message_loop_->BelongsToCurrentThread()); 838 DCHECK(message_loop_->BelongsToCurrentThread());
865 839
866 // We can only end if we were actually playing. 840 // We can only end if we were actually playing.
867 if (state_ != kStarted) { 841 if (state_ != kStarted) {
868 return; 842 return;
869 } 843 }
870 844
871 DCHECK(audio_renderer_ || video_renderer_); 845 DCHECK(audio_renderer_ || video_renderer_);
872 846
873 // Make sure every extant renderer has ended. 847 // Make sure every extant renderer has ended.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 break; 994 break;
1021 // default: intentionally left out to force new states to cause compiler 995 // default: intentionally left out to force new states to cause compiler
1022 // errors. 996 // errors.
1023 }; 997 };
1024 } 998 }
1025 999
1026 void Pipeline::FinishDestroyingFiltersTask() { 1000 void Pipeline::FinishDestroyingFiltersTask() {
1027 DCHECK(message_loop_->BelongsToCurrentThread()); 1001 DCHECK(message_loop_->BelongsToCurrentThread());
1028 DCHECK(IsPipelineStopped()); 1002 DCHECK(IsPipelineStopped());
1029 1003
1030 // Clear filter references.
1031 audio_renderer_ = NULL; 1004 audio_renderer_ = NULL;
1032 video_renderer_ = NULL; 1005 video_renderer_ = NULL;
1033 demuxer_ = NULL; 1006 demuxer_ = NULL;
1034 1007
1035 pipeline_filter_ = NULL;
1036
1037 if (error_caused_teardown_ && !IsPipelineOk() && !error_cb_.is_null()) 1008 if (error_caused_teardown_ && !IsPipelineOk() && !error_cb_.is_null())
1038 error_cb_.Run(status_); 1009 error_cb_.Run(status_);
1039 1010
1040 if (stop_pending_) { 1011 if (stop_pending_) {
1041 stop_pending_ = false; 1012 stop_pending_ = false;
1042 ResetState(); 1013 ResetState();
1043 // Notify the client that stopping has finished. 1014 // Notify the client that stopping has finished.
1044 base::ResetAndReturn(&stop_cb_).Run(); 1015 base::ResetAndReturn(&stop_cb_).Run();
1045 } 1016 }
1046 1017
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 if (!audio_renderer_) { 1120 if (!audio_renderer_) {
1150 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1121 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1151 return false; 1122 return false;
1152 } 1123 }
1153 1124
1154 audio_renderer_->Initialize( 1125 audio_renderer_->Initialize(
1155 decoder, 1126 decoder,
1156 base::Bind(&Pipeline::OnFilterInitialize, this), 1127 base::Bind(&Pipeline::OnFilterInitialize, this),
1157 base::Bind(&Pipeline::OnAudioUnderflow, this), 1128 base::Bind(&Pipeline::OnAudioUnderflow, this),
1158 base::Bind(&Pipeline::OnAudioTimeUpdate, this), 1129 base::Bind(&Pipeline::OnAudioTimeUpdate, this),
1159 base::Bind(&Pipeline::NotifyEnded, this), 1130 base::Bind(&Pipeline::OnRendererEnded, this),
1160 base::Bind(&Pipeline::OnAudioDisabled, this), 1131 base::Bind(&Pipeline::OnAudioDisabled, this),
1161 base::Bind(&Pipeline::SetError, this)); 1132 base::Bind(&Pipeline::SetError, this));
1162 return true; 1133 return true;
1163 } 1134 }
1164 1135
1165 bool Pipeline::InitializeVideoRenderer( 1136 bool Pipeline::InitializeVideoRenderer(
1166 const scoped_refptr<VideoDecoder>& decoder) { 1137 const scoped_refptr<VideoDecoder>& decoder) {
1167 DCHECK(message_loop_->BelongsToCurrentThread()); 1138 DCHECK(message_loop_->BelongsToCurrentThread());
1168 DCHECK(IsPipelineOk()); 1139 DCHECK(IsPipelineOk());
1169 1140
1170 if (!decoder) 1141 if (!decoder)
1171 return false; 1142 return false;
1172 1143
1173 filter_collection_->SelectVideoRenderer( 1144 filter_collection_->SelectVideoRenderer(&video_renderer_);
1174 &pipeline_init_state_->video_renderer); 1145 if (!video_renderer_) {
1175 if (!pipeline_init_state_->video_renderer) {
1176 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1146 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1177 return false; 1147 return false;
1178 } 1148 }
1179 1149
1180 pipeline_init_state_->composite->AddFilter( 1150 video_renderer_->Initialize(
1181 pipeline_init_state_->video_renderer);
1182
1183 pipeline_init_state_->video_renderer->Initialize(
1184 decoder, 1151 decoder,
1185 base::Bind(&Pipeline::OnFilterInitialize, this), 1152 base::Bind(&Pipeline::OnFilterInitialize, this),
1186 base::Bind(&Pipeline::OnUpdateStatistics, this), 1153 base::Bind(&Pipeline::OnUpdateStatistics, this),
1187 base::Bind(&Pipeline::OnVideoTimeUpdate, this)); 1154 base::Bind(&Pipeline::OnVideoTimeUpdate, this),
1188 1155 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this),
1189 video_renderer_ = pipeline_init_state_->video_renderer; 1156 base::Bind(&Pipeline::OnRendererEnded, this),
1157 base::Bind(&Pipeline::SetError, this),
1158 base::Bind(&Pipeline::GetMediaTime, this),
1159 base::Bind(&Pipeline::GetMediaDuration, this));
1190 return true; 1160 return true;
1191 } 1161 }
1192 1162
1193 void Pipeline::TearDownPipeline() { 1163 void Pipeline::TearDownPipeline() {
1194 DCHECK(message_loop_->BelongsToCurrentThread()); 1164 DCHECK(message_loop_->BelongsToCurrentThread());
1195 DCHECK_NE(kStopped, state_); 1165 DCHECK_NE(kStopped, state_);
1196 1166
1197 DCHECK(!tearing_down_ || // Teardown on Stop(). 1167 DCHECK(!tearing_down_ || // Teardown on Stop().
1198 (tearing_down_ && error_caused_teardown_) || // Teardown on error. 1168 (tearing_down_ && error_caused_teardown_) || // Teardown on error.
1199 (tearing_down_ && stop_pending_)); // Stop during teardown by error. 1169 (tearing_down_ && stop_pending_)); // Stop during teardown by error.
(...skipping 10 matching lines...) Expand all
1210 message_loop_->PostTask(FROM_HERE, base::Bind( 1180 message_loop_->PostTask(FROM_HERE, base::Bind(
1211 &Pipeline::FinishDestroyingFiltersTask, this)); 1181 &Pipeline::FinishDestroyingFiltersTask, this));
1212 break; 1182 break;
1213 1183
1214 case kInitDemuxer: 1184 case kInitDemuxer:
1215 case kInitAudioDecoder: 1185 case kInitAudioDecoder:
1216 case kInitAudioRenderer: 1186 case kInitAudioRenderer:
1217 case kInitVideoDecoder: 1187 case kInitVideoDecoder:
1218 case kInitVideoRenderer: 1188 case kInitVideoRenderer:
1219 // Make it look like initialization was successful. 1189 // Make it look like initialization was successful.
1220 pipeline_filter_ = pipeline_init_state_->composite; 1190 filter_collection_.reset();
1221 pipeline_init_state_.reset(); 1191 pipeline_init_state_.reset();
1222 filter_collection_.reset();
1223 1192
1224 SetState(kStopping); 1193 SetState(kStopping);
1225 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); 1194 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
1226 1195
1227 FinishInitialization(); 1196 FinishInitialization();
1228 break; 1197 break;
1229 1198
1230 case kPausing: 1199 case kPausing:
1231 case kSeeking: 1200 case kSeeking:
1232 case kFlushing: 1201 case kFlushing:
(...skipping 30 matching lines...) Expand all
1263 scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs( 1232 scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs(
1264 new std::queue<PipelineStatusCBFunc>()); 1233 new std::queue<PipelineStatusCBFunc>());
1265 1234
1266 if (!skip_demuxer_seek) 1235 if (!skip_demuxer_seek)
1267 status_cbs->push(base::Bind(&Demuxer::Seek, demuxer_, seek_timestamp)); 1236 status_cbs->push(base::Bind(&Demuxer::Seek, demuxer_, seek_timestamp));
1268 1237
1269 if (audio_renderer_) 1238 if (audio_renderer_)
1270 status_cbs->push(base::Bind( 1239 status_cbs->push(base::Bind(
1271 &AudioRenderer::Seek, audio_renderer_, seek_timestamp)); 1240 &AudioRenderer::Seek, audio_renderer_, seek_timestamp));
1272 1241
1273 if (pipeline_filter_) 1242 if (video_renderer_)
1274 status_cbs->push(base::Bind( 1243 status_cbs->push(base::Bind(
1275 &Filter::Seek, pipeline_filter_, seek_timestamp)); 1244 &VideoRenderer::Seek, video_renderer_, seek_timestamp));
1276 1245
1277 RunInSeriesWithStatus(status_cbs.Pass(), base::Bind( 1246 RunInSeriesWithStatus(status_cbs.Pass(), base::Bind(
1278 &Pipeline::ReportStatus, this, done_cb)); 1247 &Pipeline::ReportStatus, this, done_cb));
1279 } 1248 }
1280 1249
1281 void Pipeline::OnAudioUnderflow() { 1250 void Pipeline::OnAudioUnderflow() {
1282 if (!message_loop_->BelongsToCurrentThread()) { 1251 if (!message_loop_->BelongsToCurrentThread()) {
1283 message_loop_->PostTask(FROM_HERE, base::Bind( 1252 message_loop_->PostTask(FROM_HERE, base::Bind(
1284 &Pipeline::OnAudioUnderflow, this)); 1253 &Pipeline::OnAudioUnderflow, this));
1285 return; 1254 return;
1286 } 1255 }
1287 1256
1288 if (state_ != kStarted) 1257 if (state_ != kStarted)
1289 return; 1258 return;
1290 1259
1291 if (audio_renderer_) 1260 if (audio_renderer_)
1292 audio_renderer_->ResumeAfterUnderflow(true); 1261 audio_renderer_->ResumeAfterUnderflow(true);
1293 } 1262 }
1294 1263
1295 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 1264 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
1296 lock_.AssertAcquired(); 1265 lock_.AssertAcquired();
1297 if (!waiting_for_clock_update_) 1266 if (!waiting_for_clock_update_)
1298 return; 1267 return;
1299 1268
1300 waiting_for_clock_update_ = false; 1269 waiting_for_clock_update_ = false;
1301 clock_->Play(); 1270 clock_->Play();
1302 } 1271 }
1303 1272
1304 } // namespace media 1273 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698