Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: media/renderers/video_renderer_impl.cc

Issue 2007463005: Paint first frame faster, don't crash with no frames during EOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698