| OLD | NEW |
| 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> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.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/clock.h" | 18 #include "media/base/clock.h" |
| 19 #include "media/base/filter_collection.h" | 19 #include "media/base/filter_collection.h" |
| 20 #include "media/base/media_log.h" |
| 20 | 21 |
| 21 namespace media { | 22 namespace media { |
| 22 | 23 |
| 23 const char kRawMediaScheme[] = "x-raw-media"; | 24 const char kRawMediaScheme[] = "x-raw-media"; |
| 24 | 25 |
| 25 PipelineStatusNotification::PipelineStatusNotification() | 26 PipelineStatusNotification::PipelineStatusNotification() |
| 26 : cv_(&lock_), status_(PIPELINE_OK), notified_(false) { | 27 : cv_(&lock_), status_(PIPELINE_OK), notified_(false) { |
| 27 callback_.reset(NewCallback(this, &PipelineStatusNotification::Notify)); | 28 callback_.reset(NewCallback(this, &PipelineStatusNotification::Notify)); |
| 28 } | 29 } |
| 29 | 30 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 55 return status_; | 56 return status_; |
| 56 } | 57 } |
| 57 | 58 |
| 58 class PipelineImpl::PipelineInitState { | 59 class PipelineImpl::PipelineInitState { |
| 59 public: | 60 public: |
| 60 scoped_refptr<AudioDecoder> audio_decoder_; | 61 scoped_refptr<AudioDecoder> audio_decoder_; |
| 61 scoped_refptr<VideoDecoder> video_decoder_; | 62 scoped_refptr<VideoDecoder> video_decoder_; |
| 62 scoped_refptr<CompositeFilter> composite_; | 63 scoped_refptr<CompositeFilter> composite_; |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 PipelineImpl::PipelineImpl(MessageLoop* message_loop) | 66 PipelineImpl::PipelineImpl(MessageLoop* message_loop, MediaLog* media_log) |
| 66 : message_loop_(message_loop), | 67 : message_loop_(message_loop), |
| 68 media_log_(media_log), |
| 67 clock_(new Clock(&base::Time::Now)), | 69 clock_(new Clock(&base::Time::Now)), |
| 68 waiting_for_clock_update_(false), | 70 waiting_for_clock_update_(false), |
| 69 state_(kCreated), | 71 state_(kCreated), |
| 70 current_bytes_(0) { | 72 current_bytes_(0) { |
| 73 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); |
| 71 ResetState(); | 74 ResetState(); |
| 75 media_log_->AddEvent( |
| 76 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); |
| 72 } | 77 } |
| 73 | 78 |
| 74 PipelineImpl::~PipelineImpl() { | 79 PipelineImpl::~PipelineImpl() { |
| 75 base::AutoLock auto_lock(lock_); | 80 base::AutoLock auto_lock(lock_); |
| 76 DCHECK(!running_) << "Stop() must complete before destroying object"; | 81 DCHECK(!running_) << "Stop() must complete before destroying object"; |
| 77 DCHECK(!stop_pending_); | 82 DCHECK(!stop_pending_); |
| 78 DCHECK(!seek_pending_); | 83 DCHECK(!seek_pending_); |
| 84 |
| 85 media_log_->AddEvent( |
| 86 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); |
| 79 } | 87 } |
| 80 | 88 |
| 81 void PipelineImpl::Init(PipelineStatusCallback* ended_callback, | 89 void PipelineImpl::Init(PipelineStatusCallback* ended_callback, |
| 82 PipelineStatusCallback* error_callback, | 90 PipelineStatusCallback* error_callback, |
| 83 PipelineStatusCallback* network_callback) { | 91 PipelineStatusCallback* network_callback) { |
| 84 DCHECK(!IsRunning()) | 92 DCHECK(!IsRunning()) |
| 85 << "Init() should be called before the pipeline has started"; | 93 << "Init() should be called before the pipeline has started"; |
| 86 ended_callback_.reset(ended_callback); | 94 ended_callback_.reset(ended_callback); |
| 87 error_callback_.reset(error_callback); | 95 error_callback_.reset(error_callback); |
| 88 network_callback_.reset(network_callback); | 96 network_callback_.reset(network_callback); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 playback_rate_ = 0.0f; | 382 playback_rate_ = 0.0f; |
| 375 pending_playback_rate_ = 0.0f; | 383 pending_playback_rate_ = 0.0f; |
| 376 status_ = PIPELINE_OK; | 384 status_ = PIPELINE_OK; |
| 377 has_audio_ = false; | 385 has_audio_ = false; |
| 378 has_video_ = false; | 386 has_video_ = false; |
| 379 waiting_for_clock_update_ = false; | 387 waiting_for_clock_update_ = false; |
| 380 audio_disabled_ = false; | 388 audio_disabled_ = false; |
| 381 clock_->SetTime(kZero); | 389 clock_->SetTime(kZero); |
| 382 } | 390 } |
| 383 | 391 |
| 384 void PipelineImpl::set_state(State next_state) { | 392 void PipelineImpl::SetState(State next_state) { |
| 385 state_ = next_state; | 393 state_ = next_state; |
| 394 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); |
| 386 } | 395 } |
| 387 | 396 |
| 388 bool PipelineImpl::IsPipelineOk() { | 397 bool PipelineImpl::IsPipelineOk() { |
| 389 base::AutoLock auto_lock(lock_); | 398 base::AutoLock auto_lock(lock_); |
| 390 return status_ == PIPELINE_OK; | 399 return status_ == PIPELINE_OK; |
| 391 } | 400 } |
| 392 | 401 |
| 393 bool PipelineImpl::IsPipelineStopped() { | 402 bool PipelineImpl::IsPipelineStopped() { |
| 394 DCHECK_EQ(MessageLoop::current(), message_loop_); | 403 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 395 return state_ == kStopped || state_ == kError; | 404 return state_ == kStopped || state_ == kError; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 seek_callback_.reset(start_callback); | 623 seek_callback_.reset(start_callback); |
| 615 | 624 |
| 616 // Kick off initialization. | 625 // Kick off initialization. |
| 617 pipeline_init_state_.reset(new PipelineInitState()); | 626 pipeline_init_state_.reset(new PipelineInitState()); |
| 618 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); | 627 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); |
| 619 pipeline_init_state_->composite_->set_host(this); | 628 pipeline_init_state_->composite_->set_host(this); |
| 620 | 629 |
| 621 bool raw_media = (base::strncasecmp(url.c_str(), kRawMediaScheme, | 630 bool raw_media = (base::strncasecmp(url.c_str(), kRawMediaScheme, |
| 622 strlen(kRawMediaScheme)) == 0); | 631 strlen(kRawMediaScheme)) == 0); |
| 623 if (raw_media) { | 632 if (raw_media) { |
| 624 set_state(kInitVideoDecoder); | 633 SetState(kInitVideoDecoder); |
| 625 InitializeVideoDecoder(NULL); | 634 InitializeVideoDecoder(NULL); |
| 626 } else { | 635 } else { |
| 627 set_state(kInitDemuxer); | 636 SetState(kInitDemuxer); |
| 628 InitializeDemuxer(); | 637 InitializeDemuxer(); |
| 629 } | 638 } |
| 630 } | 639 } |
| 631 | 640 |
| 632 // Main initialization method called on the pipeline thread. This code attempts | 641 // Main initialization method called on the pipeline thread. This code attempts |
| 633 // to use the specified filter factory to build a pipeline. | 642 // to use the specified filter factory to build a pipeline. |
| 634 // Initialization step performed in this method depends on current state of this | 643 // Initialization step performed in this method depends on current state of this |
| 635 // object, indicated by |state_|. After each step of initialization, this | 644 // object, indicated by |state_|. After each step of initialization, this |
| 636 // object transits to the next stage. It starts by creating a Demuxer, and then | 645 // object transits to the next stage. It starts by creating a Demuxer, and then |
| 637 // connects the Demuxer's audio stream to an AudioDecoder which is then | 646 // connects the Demuxer's audio stream to an AudioDecoder which is then |
| (...skipping 17 matching lines...) Expand all Loading... |
| 655 | 664 |
| 656 DCHECK(state_ == kInitDemuxer || | 665 DCHECK(state_ == kInitDemuxer || |
| 657 state_ == kInitAudioDecoder || | 666 state_ == kInitAudioDecoder || |
| 658 state_ == kInitAudioRenderer || | 667 state_ == kInitAudioRenderer || |
| 659 state_ == kInitVideoDecoder || | 668 state_ == kInitVideoDecoder || |
| 660 state_ == kInitVideoRenderer); | 669 state_ == kInitVideoRenderer); |
| 661 | 670 |
| 662 | 671 |
| 663 // Demuxer created, create audio decoder. | 672 // Demuxer created, create audio decoder. |
| 664 if (state_ == kInitDemuxer) { | 673 if (state_ == kInitDemuxer) { |
| 665 set_state(kInitAudioDecoder); | 674 SetState(kInitAudioDecoder); |
| 666 // If this method returns false, then there's no audio stream. | 675 // If this method returns false, then there's no audio stream. |
| 667 if (InitializeAudioDecoder(demuxer_)) | 676 if (InitializeAudioDecoder(demuxer_)) |
| 668 return; | 677 return; |
| 669 } | 678 } |
| 670 | 679 |
| 671 // Assuming audio decoder was created, create audio renderer. | 680 // Assuming audio decoder was created, create audio renderer. |
| 672 if (state_ == kInitAudioDecoder) { | 681 if (state_ == kInitAudioDecoder) { |
| 673 set_state(kInitAudioRenderer); | 682 SetState(kInitAudioRenderer); |
| 683 |
| 674 // Returns false if there's no audio stream. | 684 // Returns false if there's no audio stream. |
| 675 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder_)) { | 685 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder_)) { |
| 676 base::AutoLock auto_lock(lock_); | 686 base::AutoLock auto_lock(lock_); |
| 677 has_audio_ = true; | 687 has_audio_ = true; |
| 678 return; | 688 return; |
| 679 } | 689 } |
| 680 } | 690 } |
| 681 | 691 |
| 682 // Assuming audio renderer was created, create video decoder. | 692 // Assuming audio renderer was created, create video decoder. |
| 683 if (state_ == kInitAudioRenderer) { | 693 if (state_ == kInitAudioRenderer) { |
| 684 // Then perform the stage of initialization, i.e. initialize video decoder. | 694 // Then perform the stage of initialization, i.e. initialize video decoder. |
| 685 set_state(kInitVideoDecoder); | 695 SetState(kInitVideoDecoder); |
| 686 if (InitializeVideoDecoder(demuxer_)) | 696 if (InitializeVideoDecoder(demuxer_)) |
| 687 return; | 697 return; |
| 688 } | 698 } |
| 689 | 699 |
| 690 // Assuming video decoder was created, create video renderer. | 700 // Assuming video decoder was created, create video renderer. |
| 691 if (state_ == kInitVideoDecoder) { | 701 if (state_ == kInitVideoDecoder) { |
| 692 set_state(kInitVideoRenderer); | 702 SetState(kInitVideoRenderer); |
| 693 if (InitializeVideoRenderer(pipeline_init_state_->video_decoder_)) { | 703 if (InitializeVideoRenderer(pipeline_init_state_->video_decoder_)) { |
| 694 base::AutoLock auto_lock(lock_); | 704 base::AutoLock auto_lock(lock_); |
| 695 has_video_ = true; | 705 has_video_ = true; |
| 696 return; | 706 return; |
| 697 } | 707 } |
| 698 } | 708 } |
| 699 | 709 |
| 700 if (state_ == kInitVideoRenderer) { | 710 if (state_ == kInitVideoRenderer) { |
| 701 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) { | 711 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) { |
| 702 SetError(PIPELINE_ERROR_COULD_NOT_RENDER); | 712 SetError(PIPELINE_ERROR_COULD_NOT_RENDER); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 718 } | 728 } |
| 719 | 729 |
| 720 // Initialization was successful, we are now considered paused, so it's safe | 730 // Initialization was successful, we are now considered paused, so it's safe |
| 721 // to set the initial playback rate and volume. | 731 // to set the initial playback rate and volume. |
| 722 PreloadChangedTask(GetPreload()); | 732 PreloadChangedTask(GetPreload()); |
| 723 PlaybackRateChangedTask(GetPlaybackRate()); | 733 PlaybackRateChangedTask(GetPlaybackRate()); |
| 724 VolumeChangedTask(GetVolume()); | 734 VolumeChangedTask(GetVolume()); |
| 725 | 735 |
| 726 // Fire the seek request to get the filters to preroll. | 736 // Fire the seek request to get the filters to preroll. |
| 727 seek_pending_ = true; | 737 seek_pending_ = true; |
| 728 set_state(kSeeking); | 738 SetState(kSeeking); |
| 729 if (demuxer_) | 739 if (demuxer_) |
| 730 seek_timestamp_ = demuxer_->GetStartTime(); | 740 seek_timestamp_ = demuxer_->GetStartTime(); |
| 731 else | 741 else |
| 732 seek_timestamp_ = base::TimeDelta(); | 742 seek_timestamp_ = base::TimeDelta(); |
| 733 | 743 |
| 734 pipeline_filter_->Seek( | 744 pipeline_filter_->Seek( |
| 735 seek_timestamp_, | 745 seek_timestamp_, |
| 736 base::Bind(&PipelineImpl::OnFilterStateTransitionWithStatus, this)); | 746 base::Bind(&PipelineImpl::OnFilterStateTransitionWithStatus, this)); |
| 737 } | 747 } |
| 738 } | 748 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 DCHECK(!seek_pending_); | 867 DCHECK(!seek_pending_); |
| 858 seek_pending_ = true; | 868 seek_pending_ = true; |
| 859 | 869 |
| 860 // We'll need to pause every filter before seeking. The state transition | 870 // We'll need to pause every filter before seeking. The state transition |
| 861 // is as follows: | 871 // is as follows: |
| 862 // kStarted/kEnded | 872 // kStarted/kEnded |
| 863 // kPausing (for each filter) | 873 // kPausing (for each filter) |
| 864 // kSeeking (for each filter) | 874 // kSeeking (for each filter) |
| 865 // kStarting (for each filter) | 875 // kStarting (for each filter) |
| 866 // kStarted | 876 // kStarted |
| 867 set_state(kPausing); | 877 SetState(kPausing); |
| 868 seek_timestamp_ = time; | 878 seek_timestamp_ = time; |
| 869 seek_callback_.reset(seek_callback); | 879 seek_callback_.reset(seek_callback); |
| 870 | 880 |
| 871 // Kick off seeking! | 881 // Kick off seeking! |
| 872 { | 882 { |
| 873 base::AutoLock auto_lock(lock_); | 883 base::AutoLock auto_lock(lock_); |
| 874 // If we are waiting for a clock update, the clock hasn't been played yet. | 884 // If we are waiting for a clock update, the clock hasn't been played yet. |
| 875 if (!waiting_for_clock_update_) | 885 if (!waiting_for_clock_update_) |
| 876 clock_->Pause(); | 886 clock_->Pause(); |
| 877 } | 887 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 901 waiting_for_clock_update_ = false; | 911 waiting_for_clock_update_ = false; |
| 902 clock_->Play(); | 912 clock_->Play(); |
| 903 } | 913 } |
| 904 } | 914 } |
| 905 | 915 |
| 906 if (video_renderer_ && !video_renderer_->HasEnded()) { | 916 if (video_renderer_ && !video_renderer_->HasEnded()) { |
| 907 return; | 917 return; |
| 908 } | 918 } |
| 909 | 919 |
| 910 // Transition to ended, executing the callback if present. | 920 // Transition to ended, executing the callback if present. |
| 911 set_state(kEnded); | 921 SetState(kEnded); |
| 912 if (ended_callback_.get()) { | 922 if (ended_callback_.get()) { |
| 913 ended_callback_->Run(status_); | 923 ended_callback_->Run(status_); |
| 914 } | 924 } |
| 915 } | 925 } |
| 916 | 926 |
| 917 void PipelineImpl::NotifyNetworkEventTask() { | 927 void PipelineImpl::NotifyNetworkEventTask() { |
| 918 DCHECK_EQ(MessageLoop::current(), message_loop_); | 928 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 919 if (network_callback_.get()) { | 929 if (network_callback_.get()) { |
| 920 network_callback_->Run(status_); | 930 network_callback_->Run(status_); |
| 921 } | 931 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 951 } | 961 } |
| 952 | 962 |
| 953 if (!TransientState(state_)) { | 963 if (!TransientState(state_)) { |
| 954 NOTREACHED() << "Invalid current state: " << state_; | 964 NOTREACHED() << "Invalid current state: " << state_; |
| 955 SetError(PIPELINE_ERROR_ABORT); | 965 SetError(PIPELINE_ERROR_ABORT); |
| 956 return; | 966 return; |
| 957 } | 967 } |
| 958 | 968 |
| 959 // Decrement the number of remaining transitions, making sure to transition | 969 // Decrement the number of remaining transitions, making sure to transition |
| 960 // to the next state if needed. | 970 // to the next state if needed. |
| 961 set_state(FindNextState(state_)); | 971 SetState(FindNextState(state_)); |
| 962 if (state_ == kSeeking) { | 972 if (state_ == kSeeking) { |
| 963 base::AutoLock auto_lock(lock_); | 973 base::AutoLock auto_lock(lock_); |
| 964 clock_->SetTime(seek_timestamp_); | 974 clock_->SetTime(seek_timestamp_); |
| 965 } | 975 } |
| 966 | 976 |
| 967 // Carry out the action for the current state. | 977 // Carry out the action for the current state. |
| 968 if (TransientState(state_)) { | 978 if (TransientState(state_)) { |
| 969 if (state_ == kPausing) { | 979 if (state_ == kPausing) { |
| 970 pipeline_filter_->Pause( | 980 pipeline_filter_->Pause( |
| 971 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 981 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 } | 1021 } |
| 1012 } else { | 1022 } else { |
| 1013 NOTREACHED() << "Unexpected state: " << state_; | 1023 NOTREACHED() << "Unexpected state: " << state_; |
| 1014 } | 1024 } |
| 1015 } | 1025 } |
| 1016 | 1026 |
| 1017 void PipelineImpl::TeardownStateTransitionTask() { | 1027 void PipelineImpl::TeardownStateTransitionTask() { |
| 1018 DCHECK(IsPipelineTearingDown()); | 1028 DCHECK(IsPipelineTearingDown()); |
| 1019 switch (state_) { | 1029 switch (state_) { |
| 1020 case kStopping: | 1030 case kStopping: |
| 1021 set_state(error_caused_teardown_ ? kError : kStopped); | 1031 SetState(error_caused_teardown_ ? kError : kStopped); |
| 1022 FinishDestroyingFiltersTask(); | 1032 FinishDestroyingFiltersTask(); |
| 1023 break; | 1033 break; |
| 1024 case kPausing: | 1034 case kPausing: |
| 1025 set_state(kFlushing); | 1035 SetState(kFlushing); |
| 1026 pipeline_filter_->Flush( | 1036 pipeline_filter_->Flush( |
| 1027 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 1037 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 1028 break; | 1038 break; |
| 1029 case kFlushing: | 1039 case kFlushing: |
| 1030 set_state(kStopping); | 1040 SetState(kStopping); |
| 1031 pipeline_filter_->Stop( | 1041 pipeline_filter_->Stop( |
| 1032 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 1042 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 1033 break; | 1043 break; |
| 1034 | 1044 |
| 1035 case kCreated: | 1045 case kCreated: |
| 1036 case kError: | 1046 case kError: |
| 1037 case kInitDemuxer: | 1047 case kInitDemuxer: |
| 1038 case kInitAudioDecoder: | 1048 case kInitAudioDecoder: |
| 1039 case kInitAudioRenderer: | 1049 case kInitAudioRenderer: |
| 1040 case kInitVideoDecoder: | 1050 case kInitVideoDecoder: |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 DCHECK(!tearing_down_ || // Teardown on Stop(). | 1257 DCHECK(!tearing_down_ || // Teardown on Stop(). |
| 1248 (tearing_down_ && error_caused_teardown_) || // Teardown on error. | 1258 (tearing_down_ && error_caused_teardown_) || // Teardown on error. |
| 1249 (tearing_down_ && stop_pending_)); // Stop during teardown by error. | 1259 (tearing_down_ && stop_pending_)); // Stop during teardown by error. |
| 1250 | 1260 |
| 1251 // Mark that we already start tearing down operation. | 1261 // Mark that we already start tearing down operation. |
| 1252 tearing_down_ = true; | 1262 tearing_down_ = true; |
| 1253 | 1263 |
| 1254 switch (state_) { | 1264 switch (state_) { |
| 1255 case kCreated: | 1265 case kCreated: |
| 1256 case kError: | 1266 case kError: |
| 1257 set_state(kStopped); | 1267 SetState(kStopped); |
| 1258 // Need to put this in the message loop to make sure that it comes | 1268 // Need to put this in the message loop to make sure that it comes |
| 1259 // after any pending callback tasks that are already queued. | 1269 // after any pending callback tasks that are already queued. |
| 1260 message_loop_->PostTask(FROM_HERE, | 1270 message_loop_->PostTask(FROM_HERE, |
| 1261 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1271 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
| 1262 break; | 1272 break; |
| 1263 | 1273 |
| 1264 case kInitDemuxer: | 1274 case kInitDemuxer: |
| 1265 case kInitAudioDecoder: | 1275 case kInitAudioDecoder: |
| 1266 case kInitAudioRenderer: | 1276 case kInitAudioRenderer: |
| 1267 case kInitVideoDecoder: | 1277 case kInitVideoDecoder: |
| 1268 case kInitVideoRenderer: | 1278 case kInitVideoRenderer: |
| 1269 // Make it look like initialization was successful. | 1279 // Make it look like initialization was successful. |
| 1270 pipeline_filter_ = pipeline_init_state_->composite_; | 1280 pipeline_filter_ = pipeline_init_state_->composite_; |
| 1271 pipeline_init_state_.reset(); | 1281 pipeline_init_state_.reset(); |
| 1272 filter_collection_.reset(); | 1282 filter_collection_.reset(); |
| 1273 | 1283 |
| 1274 set_state(kStopping); | 1284 SetState(kStopping); |
| 1275 pipeline_filter_->Stop( | 1285 pipeline_filter_->Stop( |
| 1276 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 1286 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 1277 | 1287 |
| 1278 FinishInitialization(); | 1288 FinishInitialization(); |
| 1279 break; | 1289 break; |
| 1280 | 1290 |
| 1281 case kPausing: | 1291 case kPausing: |
| 1282 case kSeeking: | 1292 case kSeeking: |
| 1283 case kFlushing: | 1293 case kFlushing: |
| 1284 case kStarting: | 1294 case kStarting: |
| 1285 set_state(kStopping); | 1295 SetState(kStopping); |
| 1286 pipeline_filter_->Stop( | 1296 pipeline_filter_->Stop( |
| 1287 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 1297 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 1288 | 1298 |
| 1289 if (seek_pending_) { | 1299 if (seek_pending_) { |
| 1290 seek_pending_ = false; | 1300 seek_pending_ = false; |
| 1291 FinishInitialization(); | 1301 FinishInitialization(); |
| 1292 } | 1302 } |
| 1293 | 1303 |
| 1294 break; | 1304 break; |
| 1295 | 1305 |
| 1296 case kStarted: | 1306 case kStarted: |
| 1297 case kEnded: | 1307 case kEnded: |
| 1298 set_state(kPausing); | 1308 SetState(kPausing); |
| 1299 pipeline_filter_->Pause( | 1309 pipeline_filter_->Pause( |
| 1300 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 1310 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 1301 break; | 1311 break; |
| 1302 | 1312 |
| 1303 case kStopping: | 1313 case kStopping: |
| 1304 case kStopped: | 1314 case kStopped: |
| 1305 NOTREACHED() << "Unexpected state for teardown: " << state_; | 1315 NOTREACHED() << "Unexpected state for teardown: " << state_; |
| 1306 break; | 1316 break; |
| 1307 // default: intentionally left out to force new states to cause compiler | 1317 // default: intentionally left out to force new states to cause compiler |
| 1308 // errors. | 1318 // errors. |
| 1309 }; | 1319 }; |
| 1310 } | 1320 } |
| 1311 | 1321 |
| 1312 } // namespace media | 1322 } // namespace media |
| OLD | NEW |