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 |