Chromium Code Reviews| 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/renderers/video_renderer_impl.h" | 5 #include "media/renderers/video_renderer_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 | 367 |
| 368 // Can happen when demuxers are preparing for a new Seek(). | 368 // Can happen when demuxers are preparing for a new Seek(). |
| 369 if (!frame) { | 369 if (!frame) { |
| 370 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED); | 370 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED); |
| 371 return; | 371 return; |
| 372 } | 372 } |
| 373 | 373 |
| 374 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) { | 374 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) { |
| 375 DCHECK(!received_end_of_stream_); | 375 DCHECK(!received_end_of_stream_); |
| 376 received_end_of_stream_ = true; | 376 received_end_of_stream_ = true; |
| 377 | |
| 378 // See if we can fire EOS immediately instead of waiting for Render(). | |
| 379 MaybeFireEndedCallback_Locked(time_progressing_); | |
| 380 } else if ((low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) && | 377 } else if ((low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) && |
| 381 IsBeforeStartTime(frame->timestamp())) { | 378 IsBeforeStartTime(frame->timestamp())) { |
| 382 // Don't accumulate frames that are earlier than the start time if we | 379 // Don't accumulate frames that are earlier than the start time if we |
| 383 // won't have a chance for a better frame, otherwise we could declare | 380 // won't have a chance for a better frame, otherwise we could declare |
| 384 // HAVE_ENOUGH_DATA and start playback prematurely. | 381 // HAVE_ENOUGH_DATA and start playback prematurely. |
| 385 AttemptRead_Locked(); | 382 AttemptRead_Locked(); |
| 386 return; | 383 return; |
| 387 } else { | 384 } else { |
| 388 // If the sink hasn't been started, we still have time to release less | 385 // If the sink hasn't been started, we still have time to release less |
| 389 // than ideal frames prior to startup. We don't use IsBeforeStartTime() | 386 // than ideal frames prior to startup. We don't use IsBeforeStartTime() |
| 390 // here since it's based on a duration estimate and we can be exact here. | 387 // here since it's based on a duration estimate and we can be exact here. |
| 391 if (!sink_started_ && frame->timestamp() <= start_timestamp_) | 388 if (!sink_started_ && frame->timestamp() <= start_timestamp_) |
| 392 algorithm_->Reset(); | 389 algorithm_->Reset(); |
| 393 | 390 |
| 394 AddReadyFrame_Locked(frame); | 391 AddReadyFrame_Locked(frame); |
| 395 } | 392 } |
| 396 | 393 |
| 397 // Attempt to purge bad frames in case of underflow or backgrounding. | 394 // Attempt to purge bad frames in case of underflow or backgrounding. |
| 398 RemoveFramesForUnderflowOrBackgroundRendering(); | 395 RemoveFramesForUnderflowOrBackgroundRendering(); |
| 399 | 396 |
| 400 // Signal buffering state if we've met our conditions. | 397 // We may have removed all frames above and have reached end of stream. |
| 401 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) { | 398 MaybeFireEndedCallback_Locked(time_progressing_); |
| 402 TransitionToHaveEnough_Locked(); | |
| 403 | 399 |
| 404 // Paint the first frame if necessary. | 400 // Paint the first frame if possible and necessary. PaintSingleFrame() will |
| 405 if (!rendered_end_of_stream_ && !sink_started_) { | 401 // ignore repeated calls for the same frame. Paint ahead of HAVE_ENOUGH_DATA |
| 406 DCHECK(algorithm_->frames_queued()); | 402 // to ensure the user sees the frame as early as possible. |
| 403 if (!sink_started_ && algorithm_->frames_queued()) { | |
| 404 // We want to paint the first frame under two conditions: Either (1) we have | |
| 405 // enough frames to know it's definitely the first frame or (2) there may be | |
|
xhwang
2016/05/24 21:46:29
Could you please explain more about why when we se
DaleCurtis
2016/05/24 22:58:24
Done. Also fixed this such that it will also consi
| |
| 406 // no more frames coming (sometimes unless we paint one of them). | |
| 407 if (algorithm_->frames_queued() > 1 || received_end_of_stream_ || | |
| 408 low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) { | |
| 407 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); | 409 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); |
| 408 CheckForMetadataChanges(frame->format(), frame->natural_size()); | 410 CheckForMetadataChanges(frame->format(), frame->natural_size()); |
| 409 sink_->PaintSingleFrame(frame); | 411 sink_->PaintSingleFrame(frame); |
| 410 } | 412 } |
| 411 } | 413 } |
| 412 | 414 |
| 415 // Signal buffering state if we've met our conditions. | |
| 416 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) | |
| 417 TransitionToHaveEnough_Locked(); | |
| 418 | |
| 413 // Always request more decoded video if we have capacity. This serves two | 419 // Always request more decoded video if we have capacity. This serves two |
| 414 // purposes: | 420 // purposes: |
| 415 // 1) Prerolling while paused | 421 // 1) Prerolling while paused |
| 416 // 2) Keeps decoding going if video rendering thread starts falling behind | 422 // 2) Keeps decoding going if video rendering thread starts falling behind |
| 417 AttemptRead_Locked(); | 423 AttemptRead_Locked(); |
| 418 } | 424 } |
| 419 | 425 |
| 420 bool VideoRendererImpl::HaveEnoughData_Locked() { | 426 bool VideoRendererImpl::HaveEnoughData_Locked() { |
| 421 DCHECK_EQ(state_, kPlaying); | 427 DCHECK_EQ(state_, kPlaying); |
| 422 lock_.AssertAcquired(); | 428 lock_.AssertAcquired(); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 677 | 683 |
| 678 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( | 684 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( |
| 679 VideoPixelFormat pixel_format, | 685 VideoPixelFormat pixel_format, |
| 680 const gfx::Size& natural_size) { | 686 const gfx::Size& natural_size) { |
| 681 base::AutoLock auto_lock(lock_); | 687 base::AutoLock auto_lock(lock_); |
| 682 CheckForMetadataChanges(pixel_format, natural_size); | 688 CheckForMetadataChanges(pixel_format, natural_size); |
| 683 AttemptRead_Locked(); | 689 AttemptRead_Locked(); |
| 684 } | 690 } |
| 685 | 691 |
| 686 } // namespace media | 692 } // namespace media |
| OLD | NEW |