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 |