OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_impl.h" | 5 #include "media/filters/video_renderer_impl.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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 // | 287 // |
288 // TODO(scherkus): An improvement over midpoint might be selecting the | 288 // TODO(scherkus): An improvement over midpoint might be selecting the |
289 // minimum and/or maximum between the midpoint and some constants. As a | 289 // minimum and/or maximum between the midpoint and some constants. As a |
290 // thought experiment, consider what would be better than the midpoint | 290 // thought experiment, consider what would be better than the midpoint |
291 // for both the 1fps case and 120fps case. | 291 // for both the 1fps case and 120fps case. |
292 // | 292 // |
293 // TODO(scherkus): This can be vastly improved. Use a histogram to measure | 293 // TODO(scherkus): This can be vastly improved. Use a histogram to measure |
294 // the accuracy of our frame timing code. http://crbug.com/149829 | 294 // the accuracy of our frame timing code. http://crbug.com/149829 |
295 if (drop_frames_ && last_timestamp_ != kNoTimestamp()) { | 295 if (drop_frames_ && last_timestamp_ != kNoTimestamp()) { |
296 base::TimeDelta now = get_time_cb_.Run(); | 296 base::TimeDelta now = get_time_cb_.Run(); |
297 base::TimeDelta deadline = ready_frames_.front()->GetTimestamp() + | 297 base::TimeDelta deadline = ready_frames_.front()->timestamp() + |
298 (ready_frames_.front()->GetTimestamp() - last_timestamp_) / 2; | 298 (ready_frames_.front()->timestamp() - last_timestamp_) / 2; |
299 | 299 |
300 if (now > deadline) { | 300 if (now > deadline) { |
301 DropNextReadyFrame_Locked(); | 301 DropNextReadyFrame_Locked(); |
302 continue; | 302 continue; |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 // Congratulations! You've made it past the video frame timing gauntlet. | 306 // Congratulations! You've made it past the video frame timing gauntlet. |
307 // | 307 // |
308 // At this point enough time has passed that the next frame that ready for | 308 // At this point enough time has passed that the next frame that ready for |
309 // rendering. | 309 // rendering. |
310 PaintNextReadyFrame_Locked(); | 310 PaintNextReadyFrame_Locked(); |
311 } | 311 } |
312 } | 312 } |
313 | 313 |
314 void VideoRendererImpl::PaintNextReadyFrame_Locked() { | 314 void VideoRendererImpl::PaintNextReadyFrame_Locked() { |
315 lock_.AssertAcquired(); | 315 lock_.AssertAcquired(); |
316 | 316 |
317 scoped_refptr<VideoFrame> next_frame = ready_frames_.front(); | 317 scoped_refptr<VideoFrame> next_frame = ready_frames_.front(); |
318 ready_frames_.pop_front(); | 318 ready_frames_.pop_front(); |
319 frames_decoded_++; | 319 frames_decoded_++; |
320 | 320 |
321 last_timestamp_ = next_frame->GetTimestamp(); | 321 last_timestamp_ = next_frame->timestamp(); |
322 | 322 |
323 paint_cb_.Run(next_frame); | 323 paint_cb_.Run(next_frame); |
324 | 324 |
325 task_runner_->PostTask( | 325 task_runner_->PostTask( |
326 FROM_HERE, | 326 FROM_HERE, |
327 base::Bind(&VideoRendererImpl::AttemptRead, weak_factory_.GetWeakPtr())); | 327 base::Bind(&VideoRendererImpl::AttemptRead, weak_factory_.GetWeakPtr())); |
328 } | 328 } |
329 | 329 |
330 void VideoRendererImpl::DropNextReadyFrame_Locked() { | 330 void VideoRendererImpl::DropNextReadyFrame_Locked() { |
331 TRACE_EVENT0("media", "VideoRendererImpl:frameDropped"); | 331 TRACE_EVENT0("media", "VideoRendererImpl:frameDropped"); |
332 | 332 |
333 lock_.AssertAcquired(); | 333 lock_.AssertAcquired(); |
334 | 334 |
335 last_timestamp_ = ready_frames_.front()->GetTimestamp(); | 335 last_timestamp_ = ready_frames_.front()->timestamp(); |
336 ready_frames_.pop_front(); | 336 ready_frames_.pop_front(); |
337 frames_decoded_++; | 337 frames_decoded_++; |
338 frames_dropped_++; | 338 frames_dropped_++; |
339 | 339 |
340 task_runner_->PostTask( | 340 task_runner_->PostTask( |
341 FROM_HERE, | 341 FROM_HERE, |
342 base::Bind(&VideoRendererImpl::AttemptRead, weak_factory_.GetWeakPtr())); | 342 base::Bind(&VideoRendererImpl::AttemptRead, weak_factory_.GetWeakPtr())); |
343 } | 343 } |
344 | 344 |
345 void VideoRendererImpl::FrameReady(VideoFrameStream::Status status, | 345 void VideoRendererImpl::FrameReady(VideoFrameStream::Status status, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 389 |
390 if (state_ == kPrerolling) | 390 if (state_ == kPrerolling) |
391 TransitionToPrerolled_Locked(); | 391 TransitionToPrerolled_Locked(); |
392 | 392 |
393 return; | 393 return; |
394 } | 394 } |
395 | 395 |
396 // Maintain the latest frame decoded so the correct frame is displayed after | 396 // Maintain the latest frame decoded so the correct frame is displayed after |
397 // prerolling has completed. | 397 // prerolling has completed. |
398 if (state_ == kPrerolling && preroll_timestamp_ != kNoTimestamp() && | 398 if (state_ == kPrerolling && preroll_timestamp_ != kNoTimestamp() && |
399 frame->GetTimestamp() <= preroll_timestamp_) { | 399 frame->timestamp() <= preroll_timestamp_) { |
400 ready_frames_.clear(); | 400 ready_frames_.clear(); |
401 } | 401 } |
402 | 402 |
403 AddReadyFrame_Locked(frame); | 403 AddReadyFrame_Locked(frame); |
404 | 404 |
405 if (ShouldTransitionToPrerolled_Locked()) | 405 if (ShouldTransitionToPrerolled_Locked()) |
406 TransitionToPrerolled_Locked(); | 406 TransitionToPrerolled_Locked(); |
407 | 407 |
408 // Always request more decoded video if we have capacity. This serves two | 408 // Always request more decoded video if we have capacity. This serves two |
409 // purposes: | 409 // purposes: |
(...skipping 12 matching lines...) Expand all Loading... |
422 const scoped_refptr<VideoFrame>& frame) { | 422 const scoped_refptr<VideoFrame>& frame) { |
423 lock_.AssertAcquired(); | 423 lock_.AssertAcquired(); |
424 DCHECK(!frame->end_of_stream()); | 424 DCHECK(!frame->end_of_stream()); |
425 | 425 |
426 // Adjust the incoming frame if its rendering stop time is past the duration | 426 // Adjust the incoming frame if its rendering stop time is past the duration |
427 // of the video itself. This is typically the last frame of the video and | 427 // of the video itself. This is typically the last frame of the video and |
428 // occurs if the container specifies a duration that isn't a multiple of the | 428 // occurs if the container specifies a duration that isn't a multiple of the |
429 // frame rate. Another way for this to happen is for the container to state | 429 // frame rate. Another way for this to happen is for the container to state |
430 // a smaller duration than the largest packet timestamp. | 430 // a smaller duration than the largest packet timestamp. |
431 base::TimeDelta duration = get_duration_cb_.Run(); | 431 base::TimeDelta duration = get_duration_cb_.Run(); |
432 if (frame->GetTimestamp() > duration) { | 432 if (frame->timestamp() > duration) { |
433 frame->SetTimestamp(duration); | 433 frame->set_timestamp(duration); |
434 } | 434 } |
435 | 435 |
436 ready_frames_.push_back(frame); | 436 ready_frames_.push_back(frame); |
437 DCHECK_LE(ready_frames_.size(), | 437 DCHECK_LE(ready_frames_.size(), |
438 static_cast<size_t>(limits::kMaxVideoFrames)); | 438 static_cast<size_t>(limits::kMaxVideoFrames)); |
439 | 439 |
440 max_time_cb_.Run(frame->GetTimestamp()); | 440 max_time_cb_.Run(frame->timestamp()); |
441 | 441 |
442 // Avoid needlessly waking up |thread_| unless playing. | 442 // Avoid needlessly waking up |thread_| unless playing. |
443 if (state_ == kPlaying) | 443 if (state_ == kPlaying) |
444 frame_available_.Signal(); | 444 frame_available_.Signal(); |
445 } | 445 } |
446 | 446 |
447 void VideoRendererImpl::AttemptRead() { | 447 void VideoRendererImpl::AttemptRead() { |
448 base::AutoLock auto_lock(lock_); | 448 base::AutoLock auto_lock(lock_); |
449 AttemptRead_Locked(); | 449 AttemptRead_Locked(); |
450 } | 450 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 state_ = kFlushed; | 492 state_ = kFlushed; |
493 last_timestamp_ = kNoTimestamp(); | 493 last_timestamp_ = kNoTimestamp(); |
494 base::ResetAndReturn(&flush_cb_).Run(); | 494 base::ResetAndReturn(&flush_cb_).Run(); |
495 } | 495 } |
496 | 496 |
497 base::TimeDelta VideoRendererImpl::CalculateSleepDuration( | 497 base::TimeDelta VideoRendererImpl::CalculateSleepDuration( |
498 const scoped_refptr<VideoFrame>& next_frame, | 498 const scoped_refptr<VideoFrame>& next_frame, |
499 float playback_rate) { | 499 float playback_rate) { |
500 // Determine the current and next presentation timestamps. | 500 // Determine the current and next presentation timestamps. |
501 base::TimeDelta now = get_time_cb_.Run(); | 501 base::TimeDelta now = get_time_cb_.Run(); |
502 base::TimeDelta next_pts = next_frame->GetTimestamp(); | 502 base::TimeDelta next_pts = next_frame->timestamp(); |
503 | 503 |
504 // Scale our sleep based on the playback rate. | 504 // Scale our sleep based on the playback rate. |
505 base::TimeDelta sleep = next_pts - now; | 505 base::TimeDelta sleep = next_pts - now; |
506 return base::TimeDelta::FromMicroseconds( | 506 return base::TimeDelta::FromMicroseconds( |
507 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); | 507 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); |
508 } | 508 } |
509 | 509 |
510 void VideoRendererImpl::DoStopOrError_Locked() { | 510 void VideoRendererImpl::DoStopOrError_Locked() { |
511 lock_.AssertAcquired(); | 511 lock_.AssertAcquired(); |
512 last_timestamp_ = kNoTimestamp(); | 512 last_timestamp_ = kNoTimestamp(); |
(...skipping 28 matching lines...) Expand all Loading... |
541 statistics_cb_.Run(statistics); | 541 statistics_cb_.Run(statistics); |
542 | 542 |
543 frames_decoded_ = 0; | 543 frames_decoded_ = 0; |
544 frames_dropped_ = 0; | 544 frames_dropped_ = 0; |
545 } | 545 } |
546 | 546 |
547 frame_available_.TimedWait(wait_duration); | 547 frame_available_.TimedWait(wait_duration); |
548 } | 548 } |
549 | 549 |
550 } // namespace media | 550 } // namespace media |
OLD | NEW |