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 |