| OLD | NEW |
| 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" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 struct Pipeline::PipelineInitState { | 64 struct Pipeline::PipelineInitState { |
| 65 scoped_refptr<AudioDecoder> audio_decoder; | 65 scoped_refptr<AudioDecoder> audio_decoder; |
| 66 scoped_refptr<VideoDecoder> video_decoder; | 66 scoped_refptr<VideoDecoder> video_decoder; |
| 67 }; | 67 }; |
| 68 | 68 |
| 69 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) | 69 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) |
| 70 : message_loop_(message_loop->message_loop_proxy()), | 70 : message_loop_(message_loop->message_loop_proxy()), |
| 71 media_log_(media_log), | 71 media_log_(media_log), |
| 72 running_(false), | 72 running_(false), |
| 73 seek_pending_(false), | 73 seek_pending_(false), |
| 74 stop_pending_(false), | |
| 75 tearing_down_(false), | 74 tearing_down_(false), |
| 76 error_caused_teardown_(false), | 75 error_caused_teardown_(false), |
| 77 playback_rate_change_pending_(false), | 76 playback_rate_change_pending_(false), |
| 78 did_loading_progress_(false), | 77 did_loading_progress_(false), |
| 79 total_bytes_(0), | 78 total_bytes_(0), |
| 80 natural_size_(0, 0), | 79 natural_size_(0, 0), |
| 81 volume_(1.0f), | 80 volume_(1.0f), |
| 82 playback_rate_(0.0f), | 81 playback_rate_(0.0f), |
| 83 pending_playback_rate_(0.0f), | 82 pending_playback_rate_(0.0f), |
| 84 clock_(new Clock(&base::Time::Now)), | 83 clock_(new Clock(&base::Time::Now)), |
| 85 waiting_for_clock_update_(false), | 84 waiting_for_clock_update_(false), |
| 86 status_(PIPELINE_OK), | 85 status_(PIPELINE_OK), |
| 87 has_audio_(false), | 86 has_audio_(false), |
| 88 has_video_(false), | 87 has_video_(false), |
| 89 state_(kCreated), | 88 state_(kCreated), |
| 90 seek_timestamp_(kNoTimestamp()), | 89 seek_timestamp_(kNoTimestamp()), |
| 91 audio_ended_(false), | 90 audio_ended_(false), |
| 92 video_ended_(false), | 91 video_ended_(false), |
| 93 audio_disabled_(false), | 92 audio_disabled_(false), |
| 94 creation_time_(base::Time::Now()) { | 93 creation_time_(base::Time::Now()) { |
| 95 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); | 94 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); |
| 96 media_log_->AddEvent( | 95 media_log_->AddEvent( |
| 97 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); | 96 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); |
| 98 } | 97 } |
| 99 | 98 |
| 100 Pipeline::~Pipeline() { | 99 Pipeline::~Pipeline() { |
| 101 base::AutoLock auto_lock(lock_); | 100 base::AutoLock auto_lock(lock_); |
| 102 DCHECK(!running_) << "Stop() must complete before destroying object"; | 101 DCHECK(!running_) << "Stop() must complete before destroying object"; |
| 103 DCHECK(!stop_pending_); | 102 DCHECK(stop_cb_.is_null()); |
| 104 DCHECK(!seek_pending_); | 103 DCHECK(!seek_pending_); |
| 105 | 104 |
| 106 media_log_->AddEvent( | 105 media_log_->AddEvent( |
| 107 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); | 106 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); |
| 108 } | 107 } |
| 109 | 108 |
| 110 void Pipeline::Start(scoped_ptr<FilterCollection> collection, | 109 void Pipeline::Start(scoped_ptr<FilterCollection> collection, |
| 111 const PipelineStatusCB& ended_cb, | 110 const PipelineStatusCB& ended_cb, |
| 112 const PipelineStatusCB& error_cb, | 111 const PipelineStatusCB& error_cb, |
| 113 const PipelineStatusCB& start_cb) { | 112 const PipelineStatusCB& start_cb) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 135 | 134 |
| 136 message_loop_->PostTask(FROM_HERE, base::Bind( | 135 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 137 &Pipeline::SeekTask, this, time, seek_cb)); | 136 &Pipeline::SeekTask, this, time, seek_cb)); |
| 138 } | 137 } |
| 139 | 138 |
| 140 bool Pipeline::IsRunning() const { | 139 bool Pipeline::IsRunning() const { |
| 141 base::AutoLock auto_lock(lock_); | 140 base::AutoLock auto_lock(lock_); |
| 142 return running_; | 141 return running_; |
| 143 } | 142 } |
| 144 | 143 |
| 145 bool Pipeline::IsInitialized() const { | |
| 146 // TODO(scherkus): perhaps replace this with a bool that is set/get under the | |
| 147 // lock, because this is breaching the contract that |state_| is only accessed | |
| 148 // on |message_loop_|. | |
| 149 base::AutoLock auto_lock(lock_); | |
| 150 switch (state_) { | |
| 151 case kPausing: | |
| 152 case kFlushing: | |
| 153 case kSeeking: | |
| 154 case kStarting: | |
| 155 case kStarted: | |
| 156 return true; | |
| 157 default: | |
| 158 return false; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 bool Pipeline::HasAudio() const { | 144 bool Pipeline::HasAudio() const { |
| 163 base::AutoLock auto_lock(lock_); | 145 base::AutoLock auto_lock(lock_); |
| 164 return has_audio_; | 146 return has_audio_; |
| 165 } | 147 } |
| 166 | 148 |
| 167 bool Pipeline::HasVideo() const { | 149 bool Pipeline::HasVideo() const { |
| 168 base::AutoLock auto_lock(lock_); | 150 base::AutoLock auto_lock(lock_); |
| 169 return has_video_; | 151 return has_video_; |
| 170 } | 152 } |
| 171 | 153 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 bool ret = did_loading_progress_; | 231 bool ret = did_loading_progress_; |
| 250 did_loading_progress_ = false; | 232 did_loading_progress_ = false; |
| 251 return ret; | 233 return ret; |
| 252 } | 234 } |
| 253 | 235 |
| 254 PipelineStatistics Pipeline::GetStatistics() const { | 236 PipelineStatistics Pipeline::GetStatistics() const { |
| 255 base::AutoLock auto_lock(lock_); | 237 base::AutoLock auto_lock(lock_); |
| 256 return statistics_; | 238 return statistics_; |
| 257 } | 239 } |
| 258 | 240 |
| 241 bool Pipeline::IsInitializedForTesting() { |
| 242 DCHECK(message_loop_->BelongsToCurrentThread()) |
| 243 << "Tests should run on the same thread as Pipeline"; |
| 244 switch (state_) { |
| 245 case kPausing: |
| 246 case kFlushing: |
| 247 case kSeeking: |
| 248 case kStarting: |
| 249 case kStarted: |
| 250 return true; |
| 251 default: |
| 252 return false; |
| 253 } |
| 254 } |
| 255 |
| 259 void Pipeline::SetClockForTesting(Clock* clock) { | 256 void Pipeline::SetClockForTesting(Clock* clock) { |
| 260 clock_.reset(clock); | 257 clock_.reset(clock); |
| 261 } | 258 } |
| 262 | 259 |
| 263 void Pipeline::SetErrorForTesting(PipelineStatus status) { | 260 void Pipeline::SetErrorForTesting(PipelineStatus status) { |
| 264 SetError(status); | 261 SetError(status); |
| 265 } | 262 } |
| 266 | 263 |
| 267 void Pipeline::SetState(State next_state) { | 264 void Pipeline::SetState(State next_state) { |
| 268 if (state_ != kStarted && next_state == kStarted && | 265 if (state_ != kStarted && next_state == kStarted && |
| (...skipping 14 matching lines...) Expand all Loading... |
| 283 bool Pipeline::IsPipelineStopped() { | 280 bool Pipeline::IsPipelineStopped() { |
| 284 DCHECK(message_loop_->BelongsToCurrentThread()); | 281 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 285 return state_ == kStopped || state_ == kError; | 282 return state_ == kStopped || state_ == kError; |
| 286 } | 283 } |
| 287 | 284 |
| 288 bool Pipeline::IsPipelineTearingDown() { | 285 bool Pipeline::IsPipelineTearingDown() { |
| 289 DCHECK(message_loop_->BelongsToCurrentThread()); | 286 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 290 return tearing_down_; | 287 return tearing_down_; |
| 291 } | 288 } |
| 292 | 289 |
| 293 bool Pipeline::IsPipelineStopPending() { | |
| 294 DCHECK(message_loop_->BelongsToCurrentThread()); | |
| 295 return stop_pending_; | |
| 296 } | |
| 297 | |
| 298 bool Pipeline::IsPipelineSeeking() { | 290 bool Pipeline::IsPipelineSeeking() { |
| 299 DCHECK(message_loop_->BelongsToCurrentThread()); | 291 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 300 if (!seek_pending_) | 292 if (!seek_pending_) |
| 301 return false; | 293 return false; |
| 302 DCHECK(kSeeking == state_ || kPausing == state_ || | 294 DCHECK(kSeeking == state_ || kPausing == state_ || |
| 303 kFlushing == state_ || kStarting == state_) | 295 kFlushing == state_ || kStarting == state_) |
| 304 << "Current state : " << state_; | 296 << "Current state : " << state_; |
| 305 return true; | 297 return true; |
| 306 } | 298 } |
| 307 | 299 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 335 | 327 |
| 336 // static | 328 // static |
| 337 Pipeline::State Pipeline::FindNextState(State current) { | 329 Pipeline::State Pipeline::FindNextState(State current) { |
| 338 // TODO(scherkus): refactor InitializeTask() to make use of this function. | 330 // TODO(scherkus): refactor InitializeTask() to make use of this function. |
| 339 if (current == kPausing) { | 331 if (current == kPausing) { |
| 340 return kFlushing; | 332 return kFlushing; |
| 341 } else if (current == kFlushing) { | 333 } else if (current == kFlushing) { |
| 342 // We will always honor Seek() before Stop(). This is based on the | 334 // We will always honor Seek() before Stop(). This is based on the |
| 343 // assumption that we never accept Seek() after Stop(). | 335 // assumption that we never accept Seek() after Stop(). |
| 344 DCHECK(IsPipelineSeeking() || | 336 DCHECK(IsPipelineSeeking() || |
| 345 IsPipelineStopPending() || | 337 !stop_cb_.is_null() || |
| 346 IsPipelineTearingDown()); | 338 IsPipelineTearingDown()); |
| 347 return IsPipelineSeeking() ? kSeeking : kStopping; | 339 return IsPipelineSeeking() ? kSeeking : kStopping; |
| 348 } else if (current == kSeeking) { | 340 } else if (current == kSeeking) { |
| 349 return kStarting; | 341 return kStarting; |
| 350 } else if (current == kStarting) { | 342 } else if (current == kStarting) { |
| 351 return kStarted; | 343 return kStarted; |
| 352 } else if (current == kStopping) { | 344 } else if (current == kStopping) { |
| 353 return error_caused_teardown_ ? kError : kStopped; | 345 return error_caused_teardown_ ? kError : kStopped; |
| 354 } else { | 346 } else { |
| 355 return current; | 347 return current; |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 if (state_ == kInitVideoDecoder && | 617 if (state_ == kInitVideoDecoder && |
| 626 last_stage_status == DECODER_ERROR_NOT_SUPPORTED) { | 618 last_stage_status == DECODER_ERROR_NOT_SUPPORTED) { |
| 627 state_ = kInitAudioRenderer; | 619 state_ = kInitAudioRenderer; |
| 628 } else { | 620 } else { |
| 629 SetError(last_stage_status); | 621 SetError(last_stage_status); |
| 630 return; | 622 return; |
| 631 } | 623 } |
| 632 } | 624 } |
| 633 | 625 |
| 634 // If we have received the stop or error signal, return immediately. | 626 // If we have received the stop or error signal, return immediately. |
| 635 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) | 627 if (!stop_cb_.is_null() || IsPipelineStopped() || !IsPipelineOk()) |
| 636 return; | 628 return; |
| 637 | 629 |
| 638 DCHECK(state_ == kInitDemuxer || | 630 DCHECK(state_ == kInitDemuxer || |
| 639 state_ == kInitAudioDecoder || | 631 state_ == kInitAudioDecoder || |
| 640 state_ == kInitAudioRenderer || | 632 state_ == kInitAudioRenderer || |
| 641 state_ == kInitVideoDecoder || | 633 state_ == kInitVideoDecoder || |
| 642 state_ == kInitVideoRenderer); | 634 state_ == kInitVideoRenderer); |
| 643 | 635 |
| 644 // Demuxer created, create audio decoder. | 636 // Demuxer created, create audio decoder. |
| 645 if (state_ == kInitDemuxer) { | 637 if (state_ == kInitDemuxer) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 | 698 |
| 707 // This method is called as a result of the client calling Pipeline::Stop() or | 699 // This method is called as a result of the client calling Pipeline::Stop() or |
| 708 // as the result of an error condition. | 700 // as the result of an error condition. |
| 709 // We stop the filters in the reverse order. | 701 // We stop the filters in the reverse order. |
| 710 // | 702 // |
| 711 // TODO(scherkus): beware! this can get posted multiple times since we post | 703 // TODO(scherkus): beware! this can get posted multiple times since we post |
| 712 // Stop() tasks even if we've already stopped. Perhaps this should no-op for | 704 // Stop() tasks even if we've already stopped. Perhaps this should no-op for |
| 713 // additional calls, however most of this logic will be changing. | 705 // additional calls, however most of this logic will be changing. |
| 714 void Pipeline::StopTask(const base::Closure& stop_cb) { | 706 void Pipeline::StopTask(const base::Closure& stop_cb) { |
| 715 DCHECK(message_loop_->BelongsToCurrentThread()); | 707 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 716 DCHECK(!IsPipelineStopPending()); | 708 DCHECK(stop_cb_.is_null()); |
| 717 DCHECK_NE(state_, kStopped); | 709 DCHECK_NE(state_, kStopped); |
| 718 | 710 |
| 719 if (video_decoder_) { | 711 if (video_decoder_) { |
| 720 video_decoder_->PrepareForShutdownHack(); | 712 video_decoder_->PrepareForShutdownHack(); |
| 721 video_decoder_ = NULL; | 713 video_decoder_ = NULL; |
| 722 } | 714 } |
| 723 | 715 |
| 724 if (IsPipelineTearingDown() && error_caused_teardown_) { | 716 if (IsPipelineTearingDown() && error_caused_teardown_) { |
| 725 // If we are stopping due to SetError(), stop normally instead of | 717 // If we are stopping due to SetError(), stop normally instead of |
| 726 // going to error state and calling |error_cb_|. This converts | 718 // going to error state and calling |error_cb_|. This converts |
| 727 // the teardown in progress from an error teardown into one that acts | 719 // the teardown in progress from an error teardown into one that acts |
| 728 // like the error never occurred. | 720 // like the error never occurred. |
| 729 base::AutoLock auto_lock(lock_); | 721 base::AutoLock auto_lock(lock_); |
| 730 status_ = PIPELINE_OK; | 722 status_ = PIPELINE_OK; |
| 731 error_caused_teardown_ = false; | 723 error_caused_teardown_ = false; |
| 732 } | 724 } |
| 733 | 725 |
| 734 stop_cb_ = stop_cb; | 726 stop_cb_ = stop_cb; |
| 735 | 727 |
| 736 stop_pending_ = true; | |
| 737 if (!IsPipelineSeeking() && !IsPipelineTearingDown()) { | 728 if (!IsPipelineSeeking() && !IsPipelineTearingDown()) { |
| 738 // We will tear down pipeline immediately when there is no seek operation | 729 // We will tear down pipeline immediately when there is no seek operation |
| 739 // pending and no teardown in progress. This should include the case where | 730 // pending and no teardown in progress. This should include the case where |
| 740 // we are partially initialized. | 731 // we are partially initialized. |
| 741 TearDownPipeline(); | 732 TearDownPipeline(); |
| 742 } | 733 } |
| 743 } | 734 } |
| 744 | 735 |
| 745 void Pipeline::ErrorChangedTask(PipelineStatus error) { | 736 void Pipeline::ErrorChangedTask(PipelineStatus error) { |
| 746 DCHECK(message_loop_->BelongsToCurrentThread()); | 737 DCHECK(message_loop_->BelongsToCurrentThread()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 DCHECK(message_loop_->BelongsToCurrentThread()); | 790 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 800 if (!running_ || tearing_down_) | 791 if (!running_ || tearing_down_) |
| 801 return; | 792 return; |
| 802 | 793 |
| 803 if (audio_renderer_) | 794 if (audio_renderer_) |
| 804 audio_renderer_->SetVolume(volume); | 795 audio_renderer_->SetVolume(volume); |
| 805 } | 796 } |
| 806 | 797 |
| 807 void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) { | 798 void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) { |
| 808 DCHECK(message_loop_->BelongsToCurrentThread()); | 799 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 809 DCHECK(!IsPipelineStopPending()); | 800 DCHECK(stop_cb_.is_null()); |
| 810 | 801 |
| 811 // Suppress seeking if we're not fully started. | 802 // Suppress seeking if we're not fully started. |
| 812 if (state_ != kStarted) { | 803 if (state_ != kStarted) { |
| 813 // TODO(scherkus): should we run the callback? I'm tempted to say the API | 804 // TODO(scherkus): should we run the callback? I'm tempted to say the API |
| 814 // will only execute the first Seek() request. | 805 // will only execute the first Seek() request. |
| 815 DVLOG(1) << "Media pipeline has not started, ignoring seek to " | 806 DVLOG(1) << "Media pipeline has not started, ignoring seek to " |
| 816 << time.InMicroseconds() << " (current state: " << state_ << ")"; | 807 << time.InMicroseconds() << " (current state: " << state_ << ")"; |
| 817 return; | 808 return; |
| 818 } | 809 } |
| 819 | 810 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 | 960 |
| 970 base::AutoLock auto_lock(lock_); | 961 base::AutoLock auto_lock(lock_); |
| 971 // We use audio stream to update the clock. So if there is such a stream, | 962 // We use audio stream to update the clock. So if there is such a stream, |
| 972 // we pause the clock until we receive a valid timestamp. | 963 // we pause the clock until we receive a valid timestamp. |
| 973 waiting_for_clock_update_ = true; | 964 waiting_for_clock_update_ = true; |
| 974 if (!has_audio_) { | 965 if (!has_audio_) { |
| 975 clock_->SetMaxTime(clock_->Duration()); | 966 clock_->SetMaxTime(clock_->Duration()); |
| 976 StartClockIfWaitingForTimeUpdate_Locked(); | 967 StartClockIfWaitingForTimeUpdate_Locked(); |
| 977 } | 968 } |
| 978 | 969 |
| 979 if (IsPipelineStopPending()) { | 970 // Check if we have a pending stop request that needs to be honored. |
| 980 // We had a pending stop request need to be honored right now. | 971 if (!stop_cb_.is_null()) { |
| 981 TearDownPipeline(); | 972 TearDownPipeline(); |
| 982 } | 973 } |
| 983 } else { | 974 } else { |
| 984 NOTREACHED() << "Unexpected state: " << state_; | 975 NOTREACHED() << "Unexpected state: " << state_; |
| 985 } | 976 } |
| 986 } | 977 } |
| 987 | 978 |
| 988 void Pipeline::TeardownStateTransitionTask() { | 979 void Pipeline::TeardownStateTransitionTask() { |
| 989 DCHECK(IsPipelineTearingDown()); | 980 DCHECK(IsPipelineTearingDown()); |
| 990 DCHECK(pending_callbacks_.get()) | 981 DCHECK(pending_callbacks_.get()) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 DCHECK(message_loop_->BelongsToCurrentThread()); | 1018 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 1028 DCHECK(IsPipelineStopped()); | 1019 DCHECK(IsPipelineStopped()); |
| 1029 | 1020 |
| 1030 audio_renderer_ = NULL; | 1021 audio_renderer_ = NULL; |
| 1031 video_renderer_ = NULL; | 1022 video_renderer_ = NULL; |
| 1032 demuxer_ = NULL; | 1023 demuxer_ = NULL; |
| 1033 | 1024 |
| 1034 if (error_caused_teardown_ && !IsPipelineOk() && !error_cb_.is_null()) | 1025 if (error_caused_teardown_ && !IsPipelineOk() && !error_cb_.is_null()) |
| 1035 error_cb_.Run(status_); | 1026 error_cb_.Run(status_); |
| 1036 | 1027 |
| 1037 if (stop_pending_) { | 1028 if (!stop_cb_.is_null()) { |
| 1038 stop_pending_ = false; | |
| 1039 { | 1029 { |
| 1040 base::AutoLock l(lock_); | 1030 base::AutoLock l(lock_); |
| 1041 running_ = false; | 1031 running_ = false; |
| 1042 } | 1032 } |
| 1043 | 1033 |
| 1044 // Notify the client that stopping has finished. | 1034 // Notify the client that stopping has finished. |
| 1045 base::ResetAndReturn(&stop_cb_).Run(); | 1035 base::ResetAndReturn(&stop_cb_).Run(); |
| 1046 } | 1036 } |
| 1047 | 1037 |
| 1048 tearing_down_ = false; | 1038 tearing_down_ = false; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 base::Bind(&Pipeline::SetError, this), | 1177 base::Bind(&Pipeline::SetError, this), |
| 1188 base::Bind(&Pipeline::GetMediaTime, this), | 1178 base::Bind(&Pipeline::GetMediaTime, this), |
| 1189 base::Bind(&Pipeline::GetMediaDuration, this)); | 1179 base::Bind(&Pipeline::GetMediaDuration, this)); |
| 1190 return true; | 1180 return true; |
| 1191 } | 1181 } |
| 1192 | 1182 |
| 1193 void Pipeline::TearDownPipeline() { | 1183 void Pipeline::TearDownPipeline() { |
| 1194 DCHECK(message_loop_->BelongsToCurrentThread()); | 1184 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 1195 DCHECK_NE(kStopped, state_); | 1185 DCHECK_NE(kStopped, state_); |
| 1196 | 1186 |
| 1197 DCHECK(!tearing_down_ || // Teardown on Stop(). | 1187 // We're either... |
| 1198 (tearing_down_ && error_caused_teardown_) || // Teardown on error. | 1188 // 1) ...tearing down due to Stop() (it doesn't set tearing_down_) |
| 1199 (tearing_down_ && stop_pending_)); // Stop during teardown by error. | 1189 // 2) ...tearing down due to an error (it does set tearing_down_) |
| 1190 // 3) ...tearing down due to an error and Stop() was called during that time |
| 1191 DCHECK(!tearing_down_ || |
| 1192 (tearing_down_ && error_caused_teardown_) || |
| 1193 (tearing_down_ && !stop_cb_.is_null())); |
| 1200 | 1194 |
| 1201 // Mark that we already start tearing down operation. | 1195 // Mark that we already start tearing down operation. |
| 1202 tearing_down_ = true; | 1196 tearing_down_ = true; |
| 1203 | 1197 |
| 1204 // Cancel any pending operation so we can proceed with teardown. | 1198 // Cancel any pending operation so we can proceed with teardown. |
| 1205 pending_callbacks_.reset(); | 1199 pending_callbacks_.reset(); |
| 1206 | 1200 |
| 1207 switch (state_) { | 1201 switch (state_) { |
| 1208 case kCreated: | 1202 case kCreated: |
| 1209 case kError: | 1203 case kError: |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 1293 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 1300 lock_.AssertAcquired(); | 1294 lock_.AssertAcquired(); |
| 1301 if (!waiting_for_clock_update_) | 1295 if (!waiting_for_clock_update_) |
| 1302 return; | 1296 return; |
| 1303 | 1297 |
| 1304 waiting_for_clock_update_ = false; | 1298 waiting_for_clock_update_ = false; |
| 1305 clock_->Play(); | 1299 clock_->Play(); |
| 1306 } | 1300 } |
| 1307 | 1301 |
| 1308 } // namespace media | 1302 } // namespace media |
| OLD | NEW |