Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "media/base/buffers.h" | 5 #include "media/base/buffers.h" |
| 6 #include "media/base/filter_host.h" | 6 #include "media/base/filter_host.h" |
| 7 #include "media/filters/video_thread.h" | 7 #include "media/filters/video_thread.h" |
| 8 | 8 |
| 9 namespace media { | 9 namespace media { |
| 10 | 10 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 | 156 |
| 157 // Advance |current_frame_| and try to determine |next_frame|. | 157 // Advance |current_frame_| and try to determine |next_frame|. |
| 158 scoped_refptr<VideoFrame> next_frame; | 158 scoped_refptr<VideoFrame> next_frame; |
| 159 { | 159 { |
| 160 AutoLock auto_lock(lock_); | 160 AutoLock auto_lock(lock_); |
| 161 DCHECK(!frames_.empty()); | 161 DCHECK(!frames_.empty()); |
| 162 DCHECK_EQ(current_frame_, frames_.front()); | 162 DCHECK_EQ(current_frame_, frames_.front()); |
| 163 frames_.pop_front(); | 163 frames_.pop_front(); |
| 164 ScheduleRead(); | 164 ScheduleRead(); |
| 165 while (frames_.empty()) { | 165 while (frames_.empty()) { |
| 166 | |
|
scherkus (not reviewing)
2009/06/04 20:11:08
remove empty line
Alpha Left Google
2009/06/04 20:13:34
Done.
| |
| 166 frame_available_.Wait(); | 167 frame_available_.Wait(); |
| 167 | 168 |
| 168 // We have the lock again, check the actual state to see if we're trying | 169 // We have the lock again, check the actual state to see if we're trying |
| 169 // to stop. | 170 // to stop. |
| 170 if (state_ == STOPPED) { | 171 if (state_ == STOPPED) { |
| 171 return; | 172 return; |
| 172 } | 173 } |
| 173 } | 174 } |
| 174 current_frame_ = frames_.front(); | 175 current_frame_ = frames_.front(); |
| 175 if (frames_.size() >= 2) { | 176 if (frames_.size() >= 2) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 | 222 |
| 222 void VideoThread::GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out) { | 223 void VideoThread::GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out) { |
| 223 AutoLock auto_lock(lock_); | 224 AutoLock auto_lock(lock_); |
| 224 // Either we have initialized or we have the current frame. | 225 // Either we have initialized or we have the current frame. |
| 225 DCHECK(state_ != INITIALIZED || current_frame_); | 226 DCHECK(state_ != INITIALIZED || current_frame_); |
| 226 *frame_out = current_frame_; | 227 *frame_out = current_frame_; |
| 227 } | 228 } |
| 228 | 229 |
| 229 void VideoThread::OnReadComplete(VideoFrame* frame) { | 230 void VideoThread::OnReadComplete(VideoFrame* frame) { |
| 230 AutoLock auto_lock(lock_); | 231 AutoLock auto_lock(lock_); |
| 231 frames_.push_back(frame); | 232 // If this is an end of stream frame, don't enqueue it since it has no data. |
| 232 DCHECK_LE(frames_.size(), kMaxFrames); | 233 if (!frame->IsEndOfStream()) { |
| 234 frames_.push_back(frame); | |
| 235 DCHECK_LE(frames_.size(), kMaxFrames); | |
| 236 frame_available_.Signal(); | |
| 237 } | |
| 233 | 238 |
| 234 // Check for our initialization condition. | 239 // Check for our initialization condition. |
| 235 if (state_ == INITIALIZING && frames_.size() == kMaxFrames) { | 240 if (state_ == INITIALIZING && |
| 236 state_ = INITIALIZED; | 241 (frames_.size() == kMaxFrames || frame->IsEndOfStream())) { |
| 237 current_frame_ = frames_.front(); | 242 if (frames_.empty()) { |
| 238 host_->InitializationComplete(); | 243 // We should have initialized but there's no decoded frames in the queue. |
| 244 // Raise an error. | |
| 245 host_->Error(PIPELINE_ERROR_NO_DATA); | |
| 246 } else { | |
| 247 state_ = INITIALIZED; | |
| 248 current_frame_ = frames_.front(); | |
| 249 host_->InitializationComplete(); | |
| 250 } | |
| 239 } | 251 } |
| 240 | |
| 241 frame_available_.Signal(); | |
| 242 } | 252 } |
| 243 | 253 |
| 244 void VideoThread::ScheduleRead() { | 254 void VideoThread::ScheduleRead() { |
| 245 host_->PostTask( | 255 host_->PostTask( |
| 246 NewRunnableMethod(decoder_.get(), &VideoDecoder::Read, | 256 NewRunnableMethod(decoder_.get(), &VideoDecoder::Read, |
| 247 NewCallback(this, &VideoThread::OnReadComplete))); | 257 NewCallback(this, &VideoThread::OnReadComplete))); |
| 248 } | 258 } |
| 249 | 259 |
| 250 bool VideoThread::WaitForInitialized() { | 260 bool VideoThread::WaitForInitialized() { |
| 251 // This loop essentially handles preroll. We wait until we've been fully | 261 // This loop essentially handles preroll. We wait until we've been fully |
| 252 // initialized so we can call OnFrameAvailable() to provide subclasses with | 262 // initialized so we can call OnFrameAvailable() to provide subclasses with |
| 253 // the first frame. | 263 // the first frame. |
| 254 AutoLock auto_lock(lock_); | 264 AutoLock auto_lock(lock_); |
| 255 DCHECK_EQ(state_, INITIALIZING); | 265 DCHECK_EQ(state_, INITIALIZING); |
| 256 while (state_ == INITIALIZING) { | 266 while (state_ == INITIALIZING) { |
| 257 frame_available_.Wait(); | 267 frame_available_.Wait(); |
| 258 if (state_ == STOPPED) { | 268 if (state_ == STOPPED) { |
| 259 return false; | 269 return false; |
| 260 } | 270 } |
| 261 } | 271 } |
| 262 DCHECK_EQ(state_, INITIALIZED); | 272 DCHECK_EQ(state_, INITIALIZED); |
| 263 DCHECK(current_frame_); | 273 DCHECK(current_frame_); |
| 264 return true; | 274 return true; |
| 265 } | 275 } |
| 266 | 276 |
| 267 } // namespace media | 277 } // namespace media |
| OLD | NEW |