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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 void VideoRendererImpl::SetPlaybackRate(float playback_rate) { | 121 void VideoRendererImpl::SetPlaybackRate(float playback_rate) { |
122 DCHECK(message_loop_->BelongsToCurrentThread()); | 122 DCHECK(message_loop_->BelongsToCurrentThread()); |
123 base::AutoLock auto_lock(lock_); | 123 base::AutoLock auto_lock(lock_); |
124 playback_rate_ = playback_rate; | 124 playback_rate_ = playback_rate; |
125 } | 125 } |
126 | 126 |
127 void VideoRendererImpl::Preroll(base::TimeDelta time, | 127 void VideoRendererImpl::Preroll(base::TimeDelta time, |
128 const PipelineStatusCB& cb) { | 128 const PipelineStatusCB& cb) { |
129 DCHECK(message_loop_->BelongsToCurrentThread()); | 129 DCHECK(message_loop_->BelongsToCurrentThread()); |
130 base::AutoLock auto_lock(lock_); | 130 base::AutoLock auto_lock(lock_); |
131 DCHECK_EQ(state_, kFlushed) << "Must flush prior to prerolling."; | |
132 DCHECK(!cb.is_null()); | 131 DCHECK(!cb.is_null()); |
133 DCHECK(preroll_cb_.is_null()); | 132 DCHECK(preroll_cb_.is_null()); |
| 133 DCHECK(state_ == kFlushed || state_== kPaused) << "state_ " << state_; |
| 134 |
| 135 if (state_ == kFlushed) { |
| 136 DCHECK(time != kNoTimestamp()); |
| 137 DCHECK(!pending_read_); |
| 138 DCHECK(ready_frames_.empty()); |
| 139 } else { |
| 140 DCHECK(time == kNoTimestamp()); |
| 141 } |
134 | 142 |
135 state_ = kPrerolling; | 143 state_ = kPrerolling; |
136 preroll_cb_ = cb; | 144 preroll_cb_ = cb; |
137 preroll_timestamp_ = time; | 145 preroll_timestamp_ = time; |
| 146 |
| 147 if (ShouldTransitionToPrerolled_Locked()) { |
| 148 TransitionToPrerolled_Locked(); |
| 149 return; |
| 150 } |
| 151 |
138 AttemptRead_Locked(); | 152 AttemptRead_Locked(); |
139 } | 153 } |
140 | 154 |
141 void VideoRendererImpl::Initialize(DemuxerStream* stream, | 155 void VideoRendererImpl::Initialize(DemuxerStream* stream, |
142 const PipelineStatusCB& init_cb, | 156 const PipelineStatusCB& init_cb, |
143 const StatisticsCB& statistics_cb, | 157 const StatisticsCB& statistics_cb, |
144 const TimeCB& max_time_cb, | 158 const TimeCB& max_time_cb, |
145 const NaturalSizeChangedCB& size_changed_cb, | 159 const NaturalSizeChangedCB& size_changed_cb, |
146 const base::Closure& ended_cb, | 160 const base::Closure& ended_cb, |
147 const PipelineStatusCB& error_cb, | 161 const PipelineStatusCB& error_cb, |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 max_time_cb_.Run(get_duration_cb_.Run()); | 395 max_time_cb_.Run(get_duration_cb_.Run()); |
382 | 396 |
383 if (state_ == kPrerolling) | 397 if (state_ == kPrerolling) |
384 TransitionToPrerolled_Locked(); | 398 TransitionToPrerolled_Locked(); |
385 | 399 |
386 return; | 400 return; |
387 } | 401 } |
388 | 402 |
389 // Maintain the latest frame decoded so the correct frame is displayed after | 403 // Maintain the latest frame decoded so the correct frame is displayed after |
390 // prerolling has completed. | 404 // prerolling has completed. |
391 if (state_ == kPrerolling && frame->GetTimestamp() <= preroll_timestamp_) { | 405 if (state_ == kPrerolling && preroll_timestamp_ != kNoTimestamp() && |
| 406 frame->GetTimestamp() <= preroll_timestamp_) { |
392 ready_frames_.clear(); | 407 ready_frames_.clear(); |
393 } | 408 } |
394 | 409 |
395 AddReadyFrame_Locked(frame); | 410 AddReadyFrame_Locked(frame); |
396 | 411 |
397 if (state_ == kPrerolling) { | 412 if (ShouldTransitionToPrerolled_Locked()) |
398 if (!video_frame_stream_.CanReadWithoutStalling() || | 413 TransitionToPrerolled_Locked(); |
399 ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames)) { | |
400 TransitionToPrerolled_Locked(); | |
401 } | |
402 } | |
403 | 414 |
404 // Always request more decoded video if we have capacity. This serves two | 415 // Always request more decoded video if we have capacity. This serves two |
405 // purposes: | 416 // purposes: |
406 // 1) Prerolling while paused | 417 // 1) Prerolling while paused |
407 // 2) Keeps decoding going if video rendering thread starts falling behind | 418 // 2) Keeps decoding going if video rendering thread starts falling behind |
408 AttemptRead_Locked(); | 419 AttemptRead_Locked(); |
409 } | 420 } |
410 | 421 |
| 422 bool VideoRendererImpl::ShouldTransitionToPrerolled_Locked() { |
| 423 return state_ == kPrerolling && |
| 424 (!video_frame_stream_.CanReadWithoutStalling() || |
| 425 ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames)); |
| 426 } |
| 427 |
411 void VideoRendererImpl::AddReadyFrame_Locked( | 428 void VideoRendererImpl::AddReadyFrame_Locked( |
412 const scoped_refptr<VideoFrame>& frame) { | 429 const scoped_refptr<VideoFrame>& frame) { |
413 lock_.AssertAcquired(); | 430 lock_.AssertAcquired(); |
414 DCHECK(!frame->end_of_stream()); | 431 DCHECK(!frame->end_of_stream()); |
415 | 432 |
416 // Adjust the incoming frame if its rendering stop time is past the duration | 433 // Adjust the incoming frame if its rendering stop time is past the duration |
417 // of the video itself. This is typically the last frame of the video and | 434 // of the video itself. This is typically the last frame of the video and |
418 // occurs if the container specifies a duration that isn't a multiple of the | 435 // occurs if the container specifies a duration that isn't a multiple of the |
419 // frame rate. Another way for this to happen is for the container to state | 436 // frame rate. Another way for this to happen is for the container to state |
420 // a smaller duration than the largest packet timestamp. | 437 // a smaller duration than the largest packet timestamp. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 statistics_cb_.Run(statistics); | 548 statistics_cb_.Run(statistics); |
532 | 549 |
533 frames_decoded_ = 0; | 550 frames_decoded_ = 0; |
534 frames_dropped_ = 0; | 551 frames_dropped_ = 0; |
535 } | 552 } |
536 | 553 |
537 frame_available_.TimedWait(wait_duration); | 554 frame_available_.TimedWait(wait_duration); |
538 } | 555 } |
539 | 556 |
540 } // namespace media | 557 } // namespace media |
OLD | NEW |