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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 frame_available_.TimedWait(kIdleTimeDelta); | 202 frame_available_.TimedWait(kIdleTimeDelta); |
203 continue; | 203 continue; |
204 } | 204 } |
205 | 205 |
206 // Remain idle until we have the next frame ready for rendering. | 206 // Remain idle until we have the next frame ready for rendering. |
207 if (ready_frames_.empty()) { | 207 if (ready_frames_.empty()) { |
208 frame_available_.TimedWait(kIdleTimeDelta); | 208 frame_available_.TimedWait(kIdleTimeDelta); |
209 continue; | 209 continue; |
210 } | 210 } |
211 | 211 |
212 // If the next frame is end of stream then we are truly at the end of the | |
213 // video stream. | |
214 if (ready_frames_.front()->IsEndOfStream()) { | |
DaleCurtis
2012/08/06 21:44:35
Not super familiar with this code, but won't this
scherkus (not reviewing)
2012/08/06 23:36:46
I wondered about that in acolwell's previous chang
| |
215 state_ = kEnded; | |
216 ended_cb_.Run(); | |
217 ready_frames_.clear(); | |
218 | |
219 // No need to sleep here as we idle when |state_ != kPlaying|. | |
220 continue; | |
221 } | |
222 | |
212 // Remain idle until we've initialized |current_frame_| via prerolling. | 223 // Remain idle until we've initialized |current_frame_| via prerolling. |
213 if (!current_frame_) { | 224 if (!current_frame_) { |
214 // This can happen if our preroll only contains end of stream frames. | |
215 if (ready_frames_.front()->IsEndOfStream()) { | |
216 state_ = kEnded; | |
217 ended_cb_.Run(); | |
218 ready_frames_.clear(); | |
219 | |
220 // No need to sleep here as we idle when |state_ != kPlaying|. | |
221 continue; | |
222 } | |
223 | |
224 frame_available_.TimedWait(kIdleTimeDelta); | 225 frame_available_.TimedWait(kIdleTimeDelta); |
225 continue; | 226 continue; |
226 } | 227 } |
227 | 228 |
228 // Calculate how long until we should advance the frame, which is | 229 // Calculate how long until we should advance the frame, which is |
229 // typically negative but for playback rates < 1.0f may be long enough | 230 // typically negative but for playback rates < 1.0f may be long enough |
230 // that it makes more sense to idle and check again. | 231 // that it makes more sense to idle and check again. |
231 base::TimeDelta remaining_time = | 232 base::TimeDelta remaining_time = |
232 CalculateSleepDuration(ready_frames_.front(), playback_rate_); | 233 CalculateSleepDuration(ready_frames_.front(), playback_rate_); |
233 | 234 |
234 // Sleep up to a maximum of our idle time until we're within the time to | 235 // Sleep up to a maximum of our idle time until we're within the time to |
235 // render the next frame. | 236 // render the next frame. |
236 if (remaining_time.InMicroseconds() > 0) { | 237 if (remaining_time.InMicroseconds() > 0) { |
237 remaining_time = std::min(remaining_time, kIdleTimeDelta); | 238 remaining_time = std::min(remaining_time, kIdleTimeDelta); |
238 frame_available_.TimedWait(remaining_time); | 239 frame_available_.TimedWait(remaining_time); |
239 continue; | 240 continue; |
240 } | 241 } |
241 | 242 |
242 | 243 |
243 // We're almost there! | 244 // We're almost there! |
244 // | 245 // |
245 // At this point we've rendered |current_frame_| for the proper amount | 246 // At this point we've rendered |current_frame_| for the proper amount |
246 // of time and also have the next frame that ready for rendering. | 247 // of time and also have the next frame that ready for rendering. |
247 | 248 |
248 | |
249 // If the next frame is end of stream then we are truly at the end of the | |
250 // video stream. | |
251 // | |
252 // TODO(scherkus): deduplicate this end of stream check after we get rid of | |
253 // |current_frame_|. | |
254 if (ready_frames_.front()->IsEndOfStream()) { | |
255 state_ = kEnded; | |
256 ended_cb_.Run(); | |
257 ready_frames_.clear(); | |
258 | |
259 // No need to sleep here as we idle when |state_ != kPlaying|. | |
260 continue; | |
261 } | |
262 | |
263 // We cannot update |current_frame_| until we've completed the pending | 249 // We cannot update |current_frame_| until we've completed the pending |
264 // paint. Furthermore, the pending paint might be really slow: check to | 250 // paint. Furthermore, the pending paint might be really slow: check to |
265 // see if we have any ready frames that we can drop if they've already | 251 // see if we have any ready frames that we can drop if they've already |
266 // expired. | 252 // expired. |
267 if (pending_paint_) { | 253 if (pending_paint_) { |
268 while (!ready_frames_.empty()) { | 254 while (!ready_frames_.empty()) { |
269 // Can't drop anything if we're at the end. | 255 // Can't drop anything if we're at the end. |
270 if (ready_frames_.front()->IsEndOfStream()) | 256 if (ready_frames_.front()->IsEndOfStream()) |
271 break; | 257 break; |
272 | 258 |
(...skipping 10 matching lines...) Expand all Loading... | |
283 // Frame dropped: read again. | 269 // Frame dropped: read again. |
284 ++frames_dropped; | 270 ++frames_dropped; |
285 ready_frames_.pop_front(); | 271 ready_frames_.pop_front(); |
286 AttemptRead_Locked(); | 272 AttemptRead_Locked(); |
287 } | 273 } |
288 // Continue waiting for the current paint to finish. | 274 // Continue waiting for the current paint to finish. |
289 frame_available_.TimedWait(kIdleTimeDelta); | 275 frame_available_.TimedWait(kIdleTimeDelta); |
290 continue; | 276 continue; |
291 } | 277 } |
292 | 278 |
293 | |
294 // Congratulations! You've made it past the video frame timing gauntlet. | 279 // Congratulations! You've made it past the video frame timing gauntlet. |
295 // | 280 // |
296 // We can now safely update the current frame, request another frame, and | 281 // We can now safely update the current frame, request another frame, and |
297 // signal to the client that a new frame is available. | 282 // signal to the client that a new frame is available. |
298 DCHECK(!pending_paint_); | 283 DCHECK(!pending_paint_); |
299 DCHECK(!ready_frames_.empty()); | 284 DCHECK(!ready_frames_.empty()); |
300 SetCurrentFrameToNextReadyFrame(); | 285 SetCurrentFrameToNextReadyFrame(); |
301 AttemptRead_Locked(); | 286 AttemptRead_Locked(); |
302 | 287 |
303 base::AutoUnlock auto_unlock(lock_); | 288 base::AutoUnlock auto_unlock(lock_); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 | 542 |
558 int VideoRendererBase::NumFrames_Locked() const { | 543 int VideoRendererBase::NumFrames_Locked() const { |
559 lock_.AssertAcquired(); | 544 lock_.AssertAcquired(); |
560 int outstanding_frames = | 545 int outstanding_frames = |
561 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + | 546 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + |
562 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); | 547 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); |
563 return ready_frames_.size() + outstanding_frames; | 548 return ready_frames_.size() + outstanding_frames; |
564 } | 549 } |
565 | 550 |
566 } // namespace media | 551 } // namespace media |
OLD | NEW |