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

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

Issue 6625059: Implementing preload=metadata for video (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix indent Created 9 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 | Annotate | Revision Log
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/filters/adaptive_demuxer.h » ('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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names,
6 // potential deadlocks, etc... 6 // potential deadlocks, etc...
7 7
8 #include "media/base/pipeline_impl.h" 8 #include "media/base/pipeline_impl.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 } 48 }
49 49
50 media::PipelineStatus PipelineStatusNotification::status() { 50 media::PipelineStatus PipelineStatusNotification::status() {
51 base::AutoLock auto_lock(lock_); 51 base::AutoLock auto_lock(lock_);
52 DCHECK(notified_); 52 DCHECK(notified_);
53 return status_; 53 return status_;
54 } 54 }
55 55
56 class PipelineImpl::PipelineInitState { 56 class PipelineImpl::PipelineInitState {
57 public: 57 public:
58 scoped_refptr<Demuxer> demuxer_;
59 scoped_refptr<AudioDecoder> audio_decoder_; 58 scoped_refptr<AudioDecoder> audio_decoder_;
60 scoped_refptr<VideoDecoder> video_decoder_; 59 scoped_refptr<VideoDecoder> video_decoder_;
61 scoped_refptr<CompositeFilter> composite_; 60 scoped_refptr<CompositeFilter> composite_;
62 }; 61 };
63 62
64 PipelineImpl::PipelineImpl(MessageLoop* message_loop) 63 PipelineImpl::PipelineImpl(MessageLoop* message_loop)
65 : message_loop_(message_loop), 64 : message_loop_(message_loop),
66 clock_(new Clock(&base::Time::Now)), 65 clock_(new Clock(&base::Time::Now)),
67 waiting_for_clock_update_(false), 66 waiting_for_clock_update_(false),
68 state_(kCreated), 67 state_(kCreated),
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 211
213 base::AutoLock auto_lock(lock_); 212 base::AutoLock auto_lock(lock_);
214 volume_ = volume; 213 volume_ = volume;
215 if (running_) { 214 if (running_) {
216 message_loop_->PostTask(FROM_HERE, 215 message_loop_->PostTask(FROM_HERE,
217 NewRunnableMethod(this, &PipelineImpl::VolumeChangedTask, 216 NewRunnableMethod(this, &PipelineImpl::VolumeChangedTask,
218 volume)); 217 volume));
219 } 218 }
220 } 219 }
221 220
221 Preload PipelineImpl::GetPreload() const {
222 base::AutoLock auto_lock(lock_);
223 return preload_;
224 }
225
226 void PipelineImpl::SetPreload(Preload preload) {
227 base::AutoLock auto_lock(lock_);
228 preload_ = preload;
229 if (running_) {
230 message_loop_->PostTask(FROM_HERE,
231 NewRunnableMethod(this, &PipelineImpl::PreloadChangedTask,
232 preload));
233 }
234 }
235
222 base::TimeDelta PipelineImpl::GetCurrentTime() const { 236 base::TimeDelta PipelineImpl::GetCurrentTime() const {
223 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that 237 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that
224 // is set/get under the lock, because this is breaching the contract that 238 // is set/get under the lock, because this is breaching the contract that
225 // |state_| is only accessed on |message_loop_|. 239 // |state_| is only accessed on |message_loop_|.
226 base::AutoLock auto_lock(lock_); 240 base::AutoLock auto_lock(lock_);
227 return GetCurrentTime_Locked(); 241 return GetCurrentTime_Locked();
228 } 242 }
229 243
230 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { 244 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const {
231 base::TimeDelta elapsed = clock_->Elapsed(); 245 base::TimeDelta elapsed = clock_->Elapsed();
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 state_ == kInitAudioDecoder || 637 state_ == kInitAudioDecoder ||
624 state_ == kInitAudioRenderer || 638 state_ == kInitAudioRenderer ||
625 state_ == kInitVideoDecoder || 639 state_ == kInitVideoDecoder ||
626 state_ == kInitVideoRenderer); 640 state_ == kInitVideoRenderer);
627 641
628 642
629 // Demuxer created, create audio decoder. 643 // Demuxer created, create audio decoder.
630 if (state_ == kInitDemuxer) { 644 if (state_ == kInitDemuxer) {
631 set_state(kInitAudioDecoder); 645 set_state(kInitAudioDecoder);
632 // If this method returns false, then there's no audio stream. 646 // If this method returns false, then there's no audio stream.
633 if (InitializeAudioDecoder(pipeline_init_state_->demuxer_)) 647 if (InitializeAudioDecoder(demuxer_))
634 return; 648 return;
635 } 649 }
636 650
637 // Assuming audio decoder was created, create audio renderer. 651 // Assuming audio decoder was created, create audio renderer.
638 if (state_ == kInitAudioDecoder) { 652 if (state_ == kInitAudioDecoder) {
639 set_state(kInitAudioRenderer); 653 set_state(kInitAudioRenderer);
640 // Returns false if there's no audio stream. 654 // Returns false if there's no audio stream.
641 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder_)) { 655 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder_)) {
642 base::AutoLock auto_lock(lock_); 656 base::AutoLock auto_lock(lock_);
643 has_audio_ = true; 657 has_audio_ = true;
644 return; 658 return;
645 } 659 }
646 } 660 }
647 661
648 // Assuming audio renderer was created, create video decoder. 662 // Assuming audio renderer was created, create video decoder.
649 if (state_ == kInitAudioRenderer) { 663 if (state_ == kInitAudioRenderer) {
650 // Then perform the stage of initialization, i.e. initialize video decoder. 664 // Then perform the stage of initialization, i.e. initialize video decoder.
651 set_state(kInitVideoDecoder); 665 set_state(kInitVideoDecoder);
652 if (InitializeVideoDecoder(pipeline_init_state_->demuxer_)) 666 if (InitializeVideoDecoder(demuxer_))
653 return; 667 return;
654 } 668 }
655 669
656 // Assuming video decoder was created, create video renderer. 670 // Assuming video decoder was created, create video renderer.
657 if (state_ == kInitVideoDecoder) { 671 if (state_ == kInitVideoDecoder) {
658 set_state(kInitVideoRenderer); 672 set_state(kInitVideoRenderer);
659 if (InitializeVideoRenderer(pipeline_init_state_->video_decoder_)) { 673 if (InitializeVideoRenderer(pipeline_init_state_->video_decoder_)) {
660 base::AutoLock auto_lock(lock_); 674 base::AutoLock auto_lock(lock_);
661 has_video_ = true; 675 has_video_ = true;
662 return; 676 return;
(...skipping 15 matching lines...) Expand all
678 pipeline_init_state_.reset(); 692 pipeline_init_state_.reset();
679 693
680 if (audio_disabled_) { 694 if (audio_disabled_) {
681 // Audio was disabled at some point during initialization. Notify 695 // Audio was disabled at some point during initialization. Notify
682 // the pipeline filter now that it has been initialized. 696 // the pipeline filter now that it has been initialized.
683 pipeline_filter_->OnAudioRendererDisabled(); 697 pipeline_filter_->OnAudioRendererDisabled();
684 } 698 }
685 699
686 // Initialization was successful, we are now considered paused, so it's safe 700 // Initialization was successful, we are now considered paused, so it's safe
687 // to set the initial playback rate and volume. 701 // to set the initial playback rate and volume.
702 PreloadChangedTask(GetPreload());
688 PlaybackRateChangedTask(GetPlaybackRate()); 703 PlaybackRateChangedTask(GetPlaybackRate());
689 VolumeChangedTask(GetVolume()); 704 VolumeChangedTask(GetVolume());
690 705
691 // Fire the seek request to get the filters to preroll. 706 // Fire the seek request to get the filters to preroll.
692 seek_pending_ = true; 707 seek_pending_ = true;
693 set_state(kSeeking); 708 set_state(kSeeking);
694 seek_timestamp_ = base::TimeDelta(); 709 seek_timestamp_ = base::TimeDelta();
695 pipeline_filter_->Seek(seek_timestamp_, 710 pipeline_filter_->Seek(seek_timestamp_,
696 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); 711 NewCallback(this, &PipelineImpl::OnFilterStateTransition));
697 } 712 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 } 793 }
779 794
780 void PipelineImpl::VolumeChangedTask(float volume) { 795 void PipelineImpl::VolumeChangedTask(float volume) {
781 DCHECK_EQ(MessageLoop::current(), message_loop_); 796 DCHECK_EQ(MessageLoop::current(), message_loop_);
782 797
783 if (audio_renderer_) { 798 if (audio_renderer_) {
784 audio_renderer_->SetVolume(volume); 799 audio_renderer_->SetVolume(volume);
785 } 800 }
786 } 801 }
787 802
803 void PipelineImpl::PreloadChangedTask(Preload preload) {
804 DCHECK_EQ(MessageLoop::current(), message_loop_);
805 if (demuxer_)
806 demuxer_->SetPreload(preload);
807 }
808
788 void PipelineImpl::SeekTask(base::TimeDelta time, 809 void PipelineImpl::SeekTask(base::TimeDelta time,
789 PipelineStatusCallback* seek_callback) { 810 PipelineStatusCallback* seek_callback) {
790 DCHECK_EQ(MessageLoop::current(), message_loop_); 811 DCHECK_EQ(MessageLoop::current(), message_loop_);
791 DCHECK(!IsPipelineStopPending()); 812 DCHECK(!IsPipelineStopPending());
792 813
793 // Suppress seeking if we're not fully started. 814 // Suppress seeking if we're not fully started.
794 if (state_ != kStarted && state_ != kEnded) { 815 if (state_ != kStarted && state_ != kEnded) {
795 // TODO(scherkus): should we run the callback? I'm tempted to say the API 816 // TODO(scherkus): should we run the callback? I'm tempted to say the API
796 // will only execute the first Seek() request. 817 // will only execute the first Seek() request.
797 VLOG(1) << "Media pipeline has not started, ignoring seek to " 818 VLOG(1) << "Media pipeline has not started, ignoring seek to "
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 break; 1008 break;
988 // default: intentionally left out to force new states to cause compiler 1009 // default: intentionally left out to force new states to cause compiler
989 // errors. 1010 // errors.
990 }; 1011 };
991 } 1012 }
992 1013
993 void PipelineImpl::FinishDestroyingFiltersTask() { 1014 void PipelineImpl::FinishDestroyingFiltersTask() {
994 DCHECK_EQ(MessageLoop::current(), message_loop_); 1015 DCHECK_EQ(MessageLoop::current(), message_loop_);
995 DCHECK(IsPipelineStopped()); 1016 DCHECK(IsPipelineStopped());
996 1017
997 // Clear renderer references. 1018 // Clear filter references.
998 audio_renderer_ = NULL; 1019 audio_renderer_ = NULL;
999 video_renderer_ = NULL; 1020 video_renderer_ = NULL;
1021 demuxer_ = NULL;
1000 1022
1001 pipeline_filter_ = NULL; 1023 pipeline_filter_ = NULL;
1002 1024
1003 if (error_caused_teardown_ && !IsPipelineOk() && error_callback_.get()) 1025 if (error_caused_teardown_ && !IsPipelineOk() && error_callback_.get())
1004 error_callback_->Run(status_); 1026 error_callback_->Run(status_);
1005 1027
1006 if (stop_pending_) { 1028 if (stop_pending_) {
1007 stop_pending_ = false; 1029 stop_pending_ = false;
1008 ResetState(); 1030 ResetState();
1009 scoped_ptr<PipelineStatusCallback> stop_callback(stop_callback_.release()); 1031 scoped_ptr<PipelineStatusCallback> stop_callback(stop_callback_.release());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 1072 }
1051 1073
1052 if (!demuxer) { 1074 if (!demuxer) {
1053 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1075 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1054 return; 1076 return;
1055 } 1077 }
1056 1078
1057 if (!PrepareFilter(demuxer)) 1079 if (!PrepareFilter(demuxer))
1058 return; 1080 return;
1059 1081
1060 pipeline_init_state_->demuxer_ = demuxer; 1082 demuxer_ = demuxer;
1061 OnFilterInitialize(); 1083 OnFilterInitialize();
1062 } 1084 }
1063 1085
1064 bool PipelineImpl::InitializeAudioDecoder( 1086 bool PipelineImpl::InitializeAudioDecoder(
1065 const scoped_refptr<Demuxer>& demuxer) { 1087 const scoped_refptr<Demuxer>& demuxer) {
1066 DCHECK_EQ(MessageLoop::current(), message_loop_); 1088 DCHECK_EQ(MessageLoop::current(), message_loop_);
1067 DCHECK(IsPipelineOk()); 1089 DCHECK(IsPipelineOk());
1068 1090
1069 scoped_refptr<DemuxerStream> stream = 1091 scoped_refptr<DemuxerStream> stream =
1070 demuxer->GetStream(DemuxerStream::AUDIO); 1092 demuxer->GetStream(DemuxerStream::AUDIO);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 case kStopping: 1255 case kStopping:
1234 case kStopped: 1256 case kStopped:
1235 NOTREACHED() << "Unexpected state for teardown: " << state_; 1257 NOTREACHED() << "Unexpected state for teardown: " << state_;
1236 break; 1258 break;
1237 // default: intentionally left out to force new states to cause compiler 1259 // default: intentionally left out to force new states to cause compiler
1238 // errors. 1260 // errors.
1239 }; 1261 };
1240 } 1262 }
1241 1263
1242 } // namespace media 1264 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/filters/adaptive_demuxer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698