Chromium Code Reviews| 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/filters/video_renderer_base.h" | 5 #include "media/filters/video_renderer_base.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 DCHECK(!cb.is_null()); | 105 DCHECK(!cb.is_null()); |
| 106 DCHECK(preroll_cb_.is_null()); | 106 DCHECK(preroll_cb_.is_null()); |
| 107 | 107 |
| 108 state_ = kPrerolling; | 108 state_ = kPrerolling; |
| 109 preroll_cb_ = cb; | 109 preroll_cb_ = cb; |
| 110 preroll_timestamp_ = time; | 110 preroll_timestamp_ = time; |
| 111 prerolling_delayed_frame_ = NULL; | 111 prerolling_delayed_frame_ = NULL; |
| 112 AttemptRead_Locked(); | 112 AttemptRead_Locked(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, | 115 void VideoRendererBase::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| 116 const VideoDecoderList& decoders, | |
| 116 const PipelineStatusCB& init_cb, | 117 const PipelineStatusCB& init_cb, |
| 117 const StatisticsCB& statistics_cb, | 118 const StatisticsCB& statistics_cb, |
| 118 const TimeCB& max_time_cb, | 119 const TimeCB& max_time_cb, |
| 119 const NaturalSizeChangedCB& size_changed_cb, | 120 const NaturalSizeChangedCB& size_changed_cb, |
| 120 const base::Closure& ended_cb, | 121 const base::Closure& ended_cb, |
| 121 const PipelineStatusCB& error_cb, | 122 const PipelineStatusCB& error_cb, |
| 122 const TimeDeltaCB& get_time_cb, | 123 const TimeDeltaCB& get_time_cb, |
| 123 const TimeDeltaCB& get_duration_cb) { | 124 const TimeDeltaCB& get_duration_cb) { |
| 124 base::AutoLock auto_lock(lock_); | 125 base::AutoLock auto_lock(lock_); |
| 125 DCHECK(decoder); | 126 DCHECK(stream); |
| 127 DCHECK(!decoders.empty()); | |
| 128 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); | |
| 126 DCHECK(!init_cb.is_null()); | 129 DCHECK(!init_cb.is_null()); |
| 127 DCHECK(!statistics_cb.is_null()); | 130 DCHECK(!statistics_cb.is_null()); |
| 128 DCHECK(!max_time_cb.is_null()); | 131 DCHECK(!max_time_cb.is_null()); |
| 129 DCHECK(!size_changed_cb.is_null()); | 132 DCHECK(!size_changed_cb.is_null()); |
| 130 DCHECK(!ended_cb.is_null()); | 133 DCHECK(!ended_cb.is_null()); |
| 131 DCHECK(!get_time_cb.is_null()); | 134 DCHECK(!get_time_cb.is_null()); |
| 132 DCHECK(!get_duration_cb.is_null()); | 135 DCHECK(!get_duration_cb.is_null()); |
| 133 DCHECK_EQ(kUninitialized, state_); | 136 DCHECK_EQ(kUninitialized, state_); |
| 134 decoder_ = decoder; | |
| 135 | 137 |
| 138 demuxer_stream_ = stream; | |
| 139 decoders_ = decoders; | |
| 140 init_cb_ = init_cb; | |
| 136 statistics_cb_ = statistics_cb; | 141 statistics_cb_ = statistics_cb; |
| 137 max_time_cb_ = max_time_cb; | 142 max_time_cb_ = max_time_cb; |
| 138 size_changed_cb_ = size_changed_cb; | 143 size_changed_cb_ = size_changed_cb; |
| 139 ended_cb_ = ended_cb; | 144 ended_cb_ = ended_cb; |
| 140 error_cb_ = error_cb; | 145 error_cb_ = error_cb; |
| 141 get_time_cb_ = get_time_cb; | 146 get_time_cb_ = get_time_cb; |
| 142 get_duration_cb_ = get_duration_cb; | 147 get_duration_cb_ = get_duration_cb; |
| 143 | 148 |
| 149 InitializeNextDecoder(); | |
| 150 } | |
| 151 | |
| 152 void VideoRendererBase::InitializeNextDecoder() { | |
| 153 lock_.AssertAcquired(); | |
| 154 DCHECK(!decoders_.empty()); | |
| 155 | |
| 156 scoped_refptr<VideoDecoder> decoder = decoders_.front(); | |
| 157 decoders_.pop_front(); | |
| 158 | |
| 159 DCHECK(decoder); | |
| 160 decoder_ = decoder; | |
| 161 | |
| 162 base::AutoUnlock auto_unlock(lock_); | |
| 163 decoder->Initialize( | |
| 164 demuxer_stream_, | |
| 165 base::Bind(&VideoRendererBase::OnDecoderInitDone, this), | |
| 166 statistics_cb_); | |
| 167 } | |
| 168 | |
| 169 void VideoRendererBase::OnDecoderInitDone(PipelineStatus status) { | |
| 170 base::AutoLock auto_lock(lock_); | |
| 171 if (!decoders_.empty() && status == DECODER_ERROR_NOT_SUPPORTED) { | |
| 172 InitializeNextDecoder(); | |
| 173 return; | |
| 174 } | |
| 175 | |
| 176 if (state_ == kStopped) | |
|
xhwang
2012/08/09 21:38:29
Q: if VBR is already stopped, do we want to Initia
acolwell GONE FROM CHROMIUM
2012/08/09 22:23:32
Good point. Moved this to the top.
| |
| 177 return; | |
| 178 | |
| 179 if (status != PIPELINE_OK) { | |
| 180 state_ = kError; | |
| 181 base::ResetAndReturn(&init_cb_).Run(status); | |
| 182 return; | |
| 183 } | |
| 184 | |
| 144 // We're all good! Consider ourselves flushed. (ThreadMain() should never | 185 // We're all good! Consider ourselves flushed. (ThreadMain() should never |
| 145 // see us in the kUninitialized state). | 186 // see us in the kUninitialized state). |
| 146 // Since we had an initial Preroll(), we consider ourself flushed, because we | 187 // Since we had an initial Preroll(), we consider ourself flushed, because we |
| 147 // have not populated any buffers yet. | 188 // have not populated any buffers yet. |
| 189 | |
| 190 // Clear out remaining decoders since we don't need them now. | |
| 191 decoders_.clear(); | |
| 192 | |
| 148 state_ = kFlushed; | 193 state_ = kFlushed; |
| 149 | 194 |
| 150 set_opaque_cb_.Run(!decoder->HasAlpha()); | 195 set_opaque_cb_.Run(!decoder_->HasAlpha()); |
| 151 set_opaque_cb_.Reset(); | 196 set_opaque_cb_.Reset(); |
| 152 | 197 |
| 153 // Create our video thread. | 198 // Create our video thread. |
| 154 if (!base::PlatformThread::Create(0, this, &thread_)) { | 199 if (!base::PlatformThread::Create(0, this, &thread_)) { |
| 155 NOTREACHED() << "Video thread creation failed"; | 200 NOTREACHED() << "Video thread creation failed"; |
| 156 state_ = kError; | 201 state_ = kError; |
| 157 init_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 202 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| 158 return; | 203 return; |
| 159 } | 204 } |
| 160 | 205 |
| 161 #if defined(OS_WIN) | 206 #if defined(OS_WIN) |
| 162 // Bump up our priority so our sleeping is more accurate. | 207 // Bump up our priority so our sleeping is more accurate. |
| 163 // TODO(scherkus): find out if this is necessary, but it seems to help. | 208 // TODO(scherkus): find out if this is necessary, but it seems to help. |
| 164 ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); | 209 ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); |
| 165 #endif // defined(OS_WIN) | 210 #endif // defined(OS_WIN) |
| 166 init_cb.Run(PIPELINE_OK); | 211 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 167 } | 212 } |
| 168 | 213 |
| 169 bool VideoRendererBase::HasEnded() { | 214 bool VideoRendererBase::HasEnded() { |
| 170 base::AutoLock auto_lock(lock_); | 215 base::AutoLock auto_lock(lock_); |
| 171 return state_ == kEnded; | 216 return state_ == kEnded; |
| 172 } | 217 } |
| 173 | 218 |
| 219 void VideoRendererBase::PrepareForShutdownHack() { | |
| 220 base::AutoLock auto_lock(lock_); | |
| 221 if (decoder_) | |
| 222 decoder_->PrepareForShutdownHack(); | |
| 223 } | |
| 224 | |
| 174 // PlatformThread::Delegate implementation. | 225 // PlatformThread::Delegate implementation. |
| 175 void VideoRendererBase::ThreadMain() { | 226 void VideoRendererBase::ThreadMain() { |
| 176 base::PlatformThread::SetName("CrVideoRenderer"); | 227 base::PlatformThread::SetName("CrVideoRenderer"); |
| 177 | 228 |
| 178 // The number of milliseconds to idle when we do not have anything to do. | 229 // The number of milliseconds to idle when we do not have anything to do. |
| 179 // Nothing special about the value, other than we're being more OS-friendly | 230 // Nothing special about the value, other than we're being more OS-friendly |
| 180 // than sleeping for 1 millisecond. | 231 // than sleeping for 1 millisecond. |
| 181 // | 232 // |
| 182 // TOOD(scherkus): switch to pure event-driven frame timing instead of this | 233 // TOOD(scherkus): switch to pure event-driven frame timing instead of this |
| 183 // kIdleTimeDelta business http://crbug.com/106874 | 234 // kIdleTimeDelta business http://crbug.com/106874 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 | 629 |
| 579 int VideoRendererBase::NumFrames_Locked() const { | 630 int VideoRendererBase::NumFrames_Locked() const { |
| 580 lock_.AssertAcquired(); | 631 lock_.AssertAcquired(); |
| 581 int outstanding_frames = | 632 int outstanding_frames = |
| 582 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + | 633 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + |
| 583 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); | 634 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); |
| 584 return ready_frames_.size() + outstanding_frames; | 635 return ready_frames_.size() + outstanding_frames; |
| 585 } | 636 } |
| 586 | 637 |
| 587 } // namespace media | 638 } // namespace media |
| OLD | NEW |