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

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

Issue 2437623004: Fix perf and paint issues with VRI::PaintSingleFrame. (Closed)
Patch Set: Address comments. Created 4 years, 2 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/renderers/video_renderer_impl.h ('k') | no next file » | 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 drop_frames_(drop_frames), 52 drop_frames_(drop_frames),
53 buffering_state_(BUFFERING_HAVE_NOTHING), 53 buffering_state_(BUFFERING_HAVE_NOTHING),
54 frames_decoded_(0), 54 frames_decoded_(0),
55 frames_dropped_(0), 55 frames_dropped_(0),
56 tick_clock_(new base::DefaultTickClock()), 56 tick_clock_(new base::DefaultTickClock()),
57 was_background_rendering_(false), 57 was_background_rendering_(false),
58 time_progressing_(false), 58 time_progressing_(false),
59 last_video_memory_usage_(0), 59 last_video_memory_usage_(0),
60 have_renderered_frames_(false), 60 have_renderered_frames_(false),
61 last_frame_opaque_(false), 61 last_frame_opaque_(false),
62 painted_first_frame_(false),
62 weak_factory_(this), 63 weak_factory_(this),
63 frame_callback_weak_factory_(this) { 64 frame_callback_weak_factory_(this) {
64 if (gpu_factories && 65 if (gpu_factories &&
65 gpu_factories->ShouldUseGpuMemoryBuffersForVideoFrames()) { 66 gpu_factories->ShouldUseGpuMemoryBuffersForVideoFrames()) {
66 gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool( 67 gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool(
67 media_task_runner, worker_task_runner, gpu_factories)); 68 media_task_runner, worker_task_runner, gpu_factories));
68 } 69 }
69 } 70 }
70 71
71 VideoRendererImpl::~VideoRendererImpl() { 72 VideoRendererImpl::~VideoRendererImpl() {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 frame_callback_weak_factory_.InvalidateWeakPtrs(); 108 frame_callback_weak_factory_.InvalidateWeakPtrs();
108 video_frame_stream_->Reset( 109 video_frame_stream_->Reset(
109 base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone, 110 base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone,
110 weak_factory_.GetWeakPtr())); 111 weak_factory_.GetWeakPtr()));
111 112
112 // To avoid unnecessary work by VDAs, only delete queued frames after 113 // To avoid unnecessary work by VDAs, only delete queued frames after
113 // resetting |video_frame_stream_|. If this is done in the opposite order VDAs 114 // resetting |video_frame_stream_|. If this is done in the opposite order VDAs
114 // will get a bunch of ReusePictureBuffer() calls before the Reset(), which 115 // will get a bunch of ReusePictureBuffer() calls before the Reset(), which
115 // they may use to output more frames that won't be used. 116 // they may use to output more frames that won't be used.
116 algorithm_->Reset(); 117 algorithm_->Reset();
118 painted_first_frame_ = false;
117 } 119 }
118 120
119 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { 121 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
120 DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")"; 122 DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")";
121 DCHECK(task_runner_->BelongsToCurrentThread()); 123 DCHECK(task_runner_->BelongsToCurrentThread());
122 base::AutoLock auto_lock(lock_); 124 base::AutoLock auto_lock(lock_);
123 DCHECK_EQ(state_, kFlushed); 125 DCHECK_EQ(state_, kFlushed);
124 DCHECK(!pending_read_); 126 DCHECK(!pending_read_);
125 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 127 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
126 128
127 state_ = kPlaying; 129 state_ = kPlaying;
128 start_timestamp_ = timestamp; 130 start_timestamp_ = timestamp;
131 painted_first_frame_ = false;
129 AttemptRead_Locked(); 132 AttemptRead_Locked();
130 } 133 }
131 134
132 void VideoRendererImpl::Initialize( 135 void VideoRendererImpl::Initialize(
133 DemuxerStream* stream, 136 DemuxerStream* stream,
134 CdmContext* cdm_context, 137 CdmContext* cdm_context,
135 RendererClient* client, 138 RendererClient* client,
136 const TimeSource::WallClockTimeCB& wall_clock_time_cb, 139 const TimeSource::WallClockTimeCB& wall_clock_time_cb,
137 const PipelineStatusCB& init_cb) { 140 const PipelineStatusCB& init_cb) {
138 DCHECK(task_runner_->BelongsToCurrentThread()); 141 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 // Attempt to purge bad frames in case of underflow or backgrounding. 396 // Attempt to purge bad frames in case of underflow or backgrounding.
394 RemoveFramesForUnderflowOrBackgroundRendering(); 397 RemoveFramesForUnderflowOrBackgroundRendering();
395 398
396 // We may have removed all frames above and have reached end of stream. 399 // We may have removed all frames above and have reached end of stream.
397 MaybeFireEndedCallback_Locked(time_progressing_); 400 MaybeFireEndedCallback_Locked(time_progressing_);
398 401
399 // Update statistics here instead of during Render() when the sink is stopped. 402 // Update statistics here instead of during Render() when the sink is stopped.
400 if (!sink_started_) 403 if (!sink_started_)
401 UpdateStats_Locked(); 404 UpdateStats_Locked();
402 405
403 // Paint the first frame if possible and necessary. PaintSingleFrame() will 406 // Paint the first frame if possible and necessary. Paint ahead of
404 // ignore repeated calls for the same frame. Paint ahead of HAVE_ENOUGH_DATA 407 // HAVE_ENOUGH_DATA to ensure the user sees the frame as early as possible.
405 // to ensure the user sees the frame as early as possible. 408 if (!sink_started_ && algorithm_->frames_queued() && !painted_first_frame_) {
406 if (!sink_started_ && algorithm_->frames_queued()) {
407 // We want to paint the first frame under two conditions: Either (1) we have 409 // We want to paint the first frame under two conditions: Either (1) we have
408 // enough frames to know it's definitely the first frame or (2) there may be 410 // enough frames to know it's definitely the first frame or (2) there may be
409 // no more frames coming (sometimes unless we paint one of them). 411 // no more frames coming (sometimes unless we paint one of them).
410 // 412 //
411 // For the first condition, we need at least two frames or the first frame 413 // For the first condition, we need at least two frames or the first frame
412 // must have a timestamp >= |start_timestamp_|, since otherwise we may be 414 // must have a timestamp >= |start_timestamp_|, since otherwise we may be
413 // prerolling frames before the actual start time that will be dropped. 415 // prerolling frames before the actual start time that will be dropped.
414 if (algorithm_->frames_queued() > 1 || received_end_of_stream_ || 416 if (algorithm_->frames_queued() > 1 || received_end_of_stream_ ||
415 algorithm_->first_frame()->timestamp() >= start_timestamp_ || 417 frame->timestamp() >= start_timestamp_ || low_delay_ ||
416 low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) { 418 !video_frame_stream_->CanReadWithoutStalling()) {
417 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); 419 scoped_refptr<VideoFrame> first_frame =
418 CheckForMetadataChanges(frame->format(), frame->natural_size()); 420 algorithm_->Render(base::TimeTicks(), base::TimeTicks(), nullptr);
419 sink_->PaintSingleFrame(frame); 421 CheckForMetadataChanges(first_frame->format(),
422 first_frame->natural_size());
423 sink_->PaintSingleFrame(first_frame);
424 painted_first_frame_ = true;
420 } 425 }
421 } 426 }
422 427
423 // Signal buffering state if we've met our conditions. 428 // Signal buffering state if we've met our conditions.
424 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) 429 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked())
425 TransitionToHaveEnough_Locked(); 430 TransitionToHaveEnough_Locked();
426 431
427 // Always request more decoded video if we have capacity. 432 // Always request more decoded video if we have capacity.
428 AttemptRead_Locked(); 433 AttemptRead_Locked();
429 } 434 }
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 frames_dropped_ += algorithm_->RemoveExpiredFrames( 671 frames_dropped_ += algorithm_->RemoveExpiredFrames(
667 current_time + algorithm_->average_frame_duration()); 672 current_time + algorithm_->average_frame_duration());
668 673
669 // If we've paused for underflow, and still have no effective frames, clear 674 // If we've paused for underflow, and still have no effective frames, clear
670 // the entire queue. Note: this may cause slight inaccuracies in the number 675 // the entire queue. Note: this may cause slight inaccuracies in the number
671 // of dropped frames since the frame may have been rendered before. 676 // of dropped frames since the frame may have been rendered before.
672 if (!sink_started_ && !algorithm_->effective_frames_queued()) { 677 if (!sink_started_ && !algorithm_->effective_frames_queued()) {
673 frames_dropped_ += algorithm_->frames_queued(); 678 frames_dropped_ += algorithm_->frames_queued();
674 algorithm_->Reset( 679 algorithm_->Reset(
675 VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates); 680 VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates);
681 painted_first_frame_ = false;
676 682
677 // It's possible in the background rendering case for us to expire enough 683 // It's possible in the background rendering case for us to expire enough
678 // frames that we need to transition from HAVE_ENOUGH => HAVE_NOTHING. Just 684 // frames that we need to transition from HAVE_ENOUGH => HAVE_NOTHING. Just
679 // calling this function will check if we need to transition or not. 685 // calling this function will check if we need to transition or not.
680 if (buffering_state_ == BUFFERING_HAVE_ENOUGH) 686 if (buffering_state_ == BUFFERING_HAVE_ENOUGH)
681 TransitionToHaveNothing_Locked(); 687 TransitionToHaveNothing_Locked();
682 } 688 }
683 } 689 }
684 690
685 void VideoRendererImpl::CheckForMetadataChanges(VideoPixelFormat pixel_format, 691 void VideoRendererImpl::CheckForMetadataChanges(VideoPixelFormat pixel_format,
(...skipping 18 matching lines...) Expand all
704 710
705 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( 711 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges(
706 VideoPixelFormat pixel_format, 712 VideoPixelFormat pixel_format,
707 const gfx::Size& natural_size) { 713 const gfx::Size& natural_size) {
708 base::AutoLock auto_lock(lock_); 714 base::AutoLock auto_lock(lock_);
709 CheckForMetadataChanges(pixel_format, natural_size); 715 CheckForMetadataChanges(pixel_format, natural_size);
710 AttemptRead_Locked(); 716 AttemptRead_Locked();
711 } 717 }
712 718
713 } // namespace media 719 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/video_renderer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698