OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/condition_variable.h" | 10 #include "base/condition_variable.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 return "DemuxerThread"; | 50 return "DemuxerThread"; |
51 case FILTER_AUDIO_DECODER: | 51 case FILTER_AUDIO_DECODER: |
52 return "AudioDecoderThread"; | 52 return "AudioDecoderThread"; |
53 case FILTER_VIDEO_DECODER: | 53 case FILTER_VIDEO_DECODER: |
54 return "VideoDecoderThread"; | 54 return "VideoDecoderThread"; |
55 default: | 55 default: |
56 return "FilterThread"; | 56 return "FilterThread"; |
57 } | 57 } |
58 } | 58 } |
59 | 59 |
60 // Helper function used with NewRunnableMethod to implement a (very) crude | |
61 // blocking counter. | |
62 // | |
63 // TODO(scherkus): remove this as soon as Stop() is made asynchronous. | |
64 void DecrementCounter(Lock* lock, ConditionVariable* cond_var, int* count) { | |
65 AutoLock auto_lock(*lock); | |
66 --(*count); | |
67 CHECK(*count >= 0); | |
68 if (*count == 0) { | |
69 cond_var->Signal(); | |
70 } | |
71 } | |
72 | |
73 } // namespace | 60 } // namespace |
74 | 61 |
75 PipelineImpl::PipelineImpl(MessageLoop* message_loop) | 62 PipelineImpl::PipelineImpl(MessageLoop* message_loop) |
76 : message_loop_(message_loop), | 63 : message_loop_(message_loop), |
77 clock_(&base::Time::Now), | 64 clock_(&base::Time::Now), |
78 waiting_for_clock_update_(false), | 65 waiting_for_clock_update_(false), |
79 state_(kCreated), | 66 state_(kCreated), |
80 remaining_transitions_(0), | 67 remaining_transitions_(0), |
81 current_bytes_(0) { | 68 current_bytes_(0) { |
82 ResetState(); | 69 ResetState(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 return running_; | 129 return running_; |
143 } | 130 } |
144 | 131 |
145 bool PipelineImpl::IsInitialized() const { | 132 bool PipelineImpl::IsInitialized() const { |
146 // TODO(scherkus): perhaps replace this with a bool that is set/get under the | 133 // 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 | 134 // lock, because this is breaching the contract that |state_| is only accessed |
148 // on |message_loop_|. | 135 // on |message_loop_|. |
149 AutoLock auto_lock(lock_); | 136 AutoLock auto_lock(lock_); |
150 switch (state_) { | 137 switch (state_) { |
151 case kPausing: | 138 case kPausing: |
| 139 case kFlushing: |
152 case kSeeking: | 140 case kSeeking: |
153 case kStarting: | 141 case kStarting: |
154 case kStarted: | 142 case kStarted: |
155 case kEnded: | 143 case kEnded: |
156 return true; | 144 return true; |
157 default: | 145 default: |
158 return false; | 146 return false; |
159 } | 147 } |
160 } | 148 } |
161 | 149 |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 if (seek_callback_.get()) { | 363 if (seek_callback_.get()) { |
376 seek_callback_->Run(); | 364 seek_callback_->Run(); |
377 seek_callback_.reset(); | 365 seek_callback_.reset(); |
378 } | 366 } |
379 filter_factory_ = NULL; | 367 filter_factory_ = NULL; |
380 } | 368 } |
381 | 369 |
382 // static | 370 // static |
383 bool PipelineImpl::TransientState(State state) { | 371 bool PipelineImpl::TransientState(State state) { |
384 return state == kPausing || | 372 return state == kPausing || |
| 373 state == kFlushing || |
385 state == kSeeking || | 374 state == kSeeking || |
386 state == kStarting || | 375 state == kStarting || |
387 state == kStopping; | 376 state == kStopping; |
388 } | 377 } |
389 | 378 |
390 // static | 379 // static |
391 PipelineImpl::State PipelineImpl::FindNextState(State current) { | 380 PipelineImpl::State PipelineImpl::FindNextState(State current) { |
392 // TODO(scherkus): refactor InitializeTask() to make use of this function. | 381 // TODO(scherkus): refactor InitializeTask() to make use of this function. |
393 if (current == kPausing) | 382 if (current == kPausing) |
| 383 return kFlushing; |
| 384 if (current == kFlushing) |
394 return kSeeking; | 385 return kSeeking; |
395 if (current == kSeeking) | 386 if (current == kSeeking) |
396 return kStarting; | 387 return kStarting; |
397 if (current == kStarting) | 388 if (current == kStarting) |
398 return kStarted; | 389 return kStarted; |
399 if (current == kStopping) | 390 if (current == kStopping) |
400 return kStopped; | 391 return kStopped; |
401 return current; | 392 return current; |
402 } | 393 } |
403 | 394 |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 if (TransientState(state_)) { | 826 if (TransientState(state_)) { |
836 remaining_transitions_ = filters_.size(); | 827 remaining_transitions_ = filters_.size(); |
837 } | 828 } |
838 } | 829 } |
839 | 830 |
840 // Carry out the action for the current state. | 831 // Carry out the action for the current state. |
841 if (TransientState(state_)) { | 832 if (TransientState(state_)) { |
842 MediaFilter* filter = filters_[filters_.size() - remaining_transitions_]; | 833 MediaFilter* filter = filters_[filters_.size() - remaining_transitions_]; |
843 if (state_ == kPausing) { | 834 if (state_ == kPausing) { |
844 filter->Pause(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 835 filter->Pause(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
| 836 } else if (state_ == kFlushing) { |
| 837 filter->Flush(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
845 } else if (state_ == kSeeking) { | 838 } else if (state_ == kSeeking) { |
846 filter->Seek(seek_timestamp_, | 839 filter->Seek(seek_timestamp_, |
847 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 840 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
848 } else if (state_ == kStarting) { | 841 } else if (state_ == kStarting) { |
849 filter->Play(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 842 filter->Play(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
850 } else if (state_ == kStopping) { | 843 } else if (state_ == kStopping) { |
851 filter->Stop(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 844 filter->Stop(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
852 } else { | 845 } else { |
853 NOTREACHED(); | 846 NOTREACHED(); |
854 } | 847 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 filters_.front()->Stop(NewCallback( | 1031 filters_.front()->Stop(NewCallback( |
1039 this, &PipelineImpl::OnFilterStateTransition)); | 1032 this, &PipelineImpl::OnFilterStateTransition)); |
1040 } else { | 1033 } else { |
1041 state_ = kStopped; | 1034 state_ = kStopped; |
1042 message_loop_->PostTask(FROM_HERE, | 1035 message_loop_->PostTask(FROM_HERE, |
1043 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1036 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
1044 } | 1037 } |
1045 } | 1038 } |
1046 | 1039 |
1047 } // namespace media | 1040 } // namespace media |
OLD | NEW |