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

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: Whoops, fix comment. Created 4 years, 6 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
« no previous file with comments | « media/base/video_frame.cc ('k') | media/renderers/video_renderer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 361
362 // Can happen when demuxers are preparing for a new Seek(). 362 // Can happen when demuxers are preparing for a new Seek().
363 if (!frame) { 363 if (!frame) {
364 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED); 364 DCHECK_EQ(status, VideoFrameStream::DEMUXER_READ_ABORTED);
365 return; 365 return;
366 } 366 }
367 367
368 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) { 368 if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
369 DCHECK(!received_end_of_stream_); 369 DCHECK(!received_end_of_stream_);
370 received_end_of_stream_ = true; 370 received_end_of_stream_ = true;
371
372 // See if we can fire EOS immediately instead of waiting for Render().
373 MaybeFireEndedCallback_Locked(time_progressing_);
374 } else if ((low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) && 371 } else if ((low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) &&
375 IsBeforeStartTime(frame->timestamp())) { 372 IsBeforeStartTime(frame->timestamp())) {
376 // Don't accumulate frames that are earlier than the start time if we 373 // Don't accumulate frames that are earlier than the start time if we
377 // won't have a chance for a better frame, otherwise we could declare 374 // won't have a chance for a better frame, otherwise we could declare
378 // HAVE_ENOUGH_DATA and start playback prematurely. 375 // HAVE_ENOUGH_DATA and start playback prematurely.
379 AttemptRead_Locked(); 376 AttemptRead_Locked();
380 return; 377 return;
381 } else { 378 } else {
382 // If the sink hasn't been started, we still have time to release less 379 // If the sink hasn't been started, we still have time to release less
383 // than ideal frames prior to startup. We don't use IsBeforeStartTime() 380 // than ideal frames prior to startup. We don't use IsBeforeStartTime()
384 // here since it's based on a duration estimate and we can be exact here. 381 // here since it's based on a duration estimate and we can be exact here.
385 if (!sink_started_ && frame->timestamp() <= start_timestamp_) 382 if (!sink_started_ && frame->timestamp() <= start_timestamp_)
386 algorithm_->Reset(); 383 algorithm_->Reset();
387 384
388 AddReadyFrame_Locked(frame); 385 AddReadyFrame_Locked(frame);
389 } 386 }
390 387
391 // Attempt to purge bad frames in case of underflow or backgrounding. 388 // Attempt to purge bad frames in case of underflow or backgrounding.
392 RemoveFramesForUnderflowOrBackgroundRendering(); 389 RemoveFramesForUnderflowOrBackgroundRendering();
393 390
394 // Signal buffering state if we've met our conditions. 391 // We may have removed all frames above and have reached end of stream.
395 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) { 392 MaybeFireEndedCallback_Locked(time_progressing_);
396 TransitionToHaveEnough_Locked();
397 393
398 // Paint the first frame if necessary. 394 // Paint the first frame if possible and necessary. PaintSingleFrame() will
399 if (!rendered_end_of_stream_ && !sink_started_) { 395 // ignore repeated calls for the same frame. Paint ahead of HAVE_ENOUGH_DATA
400 DCHECK(algorithm_->frames_queued()); 396 // to ensure the user sees the frame as early as possible.
397 if (!sink_started_ && algorithm_->frames_queued()) {
398 // We want to paint the first frame under two conditions: Either (1) we have
399 // enough frames to know it's definitely the first frame or (2) there may be
400 // no more frames coming (sometimes unless we paint one of them).
401 if (algorithm_->frames_queued() > 1 || received_end_of_stream_ ||
402 low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) {
401 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); 403 scoped_refptr<VideoFrame> frame = algorithm_->first_frame();
402 CheckForMetadataChanges(frame->format(), frame->natural_size()); 404 CheckForMetadataChanges(frame->format(), frame->natural_size());
403 sink_->PaintSingleFrame(frame); 405 sink_->PaintSingleFrame(frame);
404 } 406 }
405 } 407 }
406 408
409 // Signal buffering state if we've met our conditions.
410 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked())
411 TransitionToHaveEnough_Locked();
412
407 // Always request more decoded video if we have capacity. This serves two 413 // Always request more decoded video if we have capacity. This serves two
408 // purposes: 414 // purposes:
409 // 1) Prerolling while paused 415 // 1) Prerolling while paused
410 // 2) Keeps decoding going if video rendering thread starts falling behind 416 // 2) Keeps decoding going if video rendering thread starts falling behind
411 AttemptRead_Locked(); 417 AttemptRead_Locked();
412 } 418 }
413 419
414 bool VideoRendererImpl::HaveEnoughData_Locked() { 420 bool VideoRendererImpl::HaveEnoughData_Locked() {
415 DCHECK_EQ(state_, kPlaying); 421 DCHECK_EQ(state_, kPlaying);
416 lock_.AssertAcquired(); 422 lock_.AssertAcquired();
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 682
677 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( 683 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges(
678 VideoPixelFormat pixel_format, 684 VideoPixelFormat pixel_format,
679 const gfx::Size& natural_size) { 685 const gfx::Size& natural_size) {
680 base::AutoLock auto_lock(lock_); 686 base::AutoLock auto_lock(lock_);
681 CheckForMetadataChanges(pixel_format, natural_size); 687 CheckForMetadataChanges(pixel_format, natural_size);
682 AttemptRead_Locked(); 688 AttemptRead_Locked();
683 } 689 }
684 690
685 } // namespace media 691 } // namespace media
OLDNEW
« no previous file with comments | « media/base/video_frame.cc ('k') | media/renderers/video_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698