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