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

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

Issue 2437623004: Fix perf and paint issues with VRI::PaintSingleFrame. (Closed)
Patch Set: 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
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() {
72 DCHECK(task_runner_->BelongsToCurrentThread()); 73 DCHECK(task_runner_->BelongsToCurrentThread());
73 74
74 if (!init_cb_.is_null()) 75 if (!init_cb_.is_null())
75 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); 76 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
76 77
77 if (!flush_cb_.is_null()) 78 if (!flush_cb_.is_null())
78 base::ResetAndReturn(&flush_cb_).Run(); 79 base::ResetAndReturn(&flush_cb_).Run();
79 80
80 if (sink_started_) 81 if (sink_started_)
81 StopSink(); 82 StopSink();
82 } 83 }
83 84
84 void VideoRendererImpl::Flush(const base::Closure& callback) { 85 void VideoRendererImpl::Flush(const base::Closure& callback) {
chcunningham 2016/10/21 20:27:22 should you reset painted_first_frame_ here?
DaleCurtis 2016/10/21 21:51:17 Yup, done.
85 DVLOG(1) << __func__; 86 DVLOG(1) << __func__;
86 DCHECK(task_runner_->BelongsToCurrentThread()); 87 DCHECK(task_runner_->BelongsToCurrentThread());
87 88
88 if (sink_started_) 89 if (sink_started_)
89 StopSink(); 90 StopSink();
90 91
91 base::AutoLock auto_lock(lock_); 92 base::AutoLock auto_lock(lock_);
92 DCHECK_EQ(state_, kPlaying); 93 DCHECK_EQ(state_, kPlaying);
93 flush_cb_ = callback; 94 flush_cb_ = callback;
94 state_ = kFlushing; 95 state_ = kFlushing;
(...skipping 24 matching lines...) Expand all
119 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { 120 void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
120 DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")"; 121 DVLOG(1) << __func__ << "(" << timestamp.InMicroseconds() << ")";
121 DCHECK(task_runner_->BelongsToCurrentThread()); 122 DCHECK(task_runner_->BelongsToCurrentThread());
122 base::AutoLock auto_lock(lock_); 123 base::AutoLock auto_lock(lock_);
123 DCHECK_EQ(state_, kFlushed); 124 DCHECK_EQ(state_, kFlushed);
124 DCHECK(!pending_read_); 125 DCHECK(!pending_read_);
125 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 126 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
126 127
127 state_ = kPlaying; 128 state_ = kPlaying;
128 start_timestamp_ = timestamp; 129 start_timestamp_ = timestamp;
130 painted_first_frame_ = false;
129 AttemptRead_Locked(); 131 AttemptRead_Locked();
130 } 132 }
131 133
132 void VideoRendererImpl::Initialize( 134 void VideoRendererImpl::Initialize(
133 DemuxerStream* stream, 135 DemuxerStream* stream,
134 CdmContext* cdm_context, 136 CdmContext* cdm_context,
135 RendererClient* client, 137 RendererClient* client,
136 const TimeSource::WallClockTimeCB& wall_clock_time_cb, 138 const TimeSource::WallClockTimeCB& wall_clock_time_cb,
137 const PipelineStatusCB& init_cb) { 139 const PipelineStatusCB& init_cb) {
138 DCHECK(task_runner_->BelongsToCurrentThread()); 140 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. 395 // Attempt to purge bad frames in case of underflow or backgrounding.
394 RemoveFramesForUnderflowOrBackgroundRendering(); 396 RemoveFramesForUnderflowOrBackgroundRendering();
395 397
396 // We may have removed all frames above and have reached end of stream. 398 // We may have removed all frames above and have reached end of stream.
397 MaybeFireEndedCallback_Locked(time_progressing_); 399 MaybeFireEndedCallback_Locked(time_progressing_);
398 400
399 // Update statistics here instead of during Render() when the sink is stopped. 401 // Update statistics here instead of during Render() when the sink is stopped.
400 if (!sink_started_) 402 if (!sink_started_)
401 UpdateStats_Locked(); 403 UpdateStats_Locked();
402 404
403 // Paint the first frame if possible and necessary. PaintSingleFrame() will 405 // 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 406 // 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. 407 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 408 // 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 409 // 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). 410 // no more frames coming (sometimes unless we paint one of them).
410 // 411 //
411 // For the first condition, we need at least two frames or the first frame 412 // 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 413 // must have a timestamp >= |start_timestamp_|, since otherwise we may be
413 // prerolling frames before the actual start time that will be dropped. 414 // prerolling frames before the actual start time that will be dropped.
414 if (algorithm_->frames_queued() > 1 || received_end_of_stream_ || 415 if (algorithm_->frames_queued() > 1 || received_end_of_stream_ ||
415 algorithm_->first_frame()->timestamp() >= start_timestamp_ || 416 frame->timestamp() >= start_timestamp_ || low_delay_ ||
416 low_delay_ || !video_frame_stream_->CanReadWithoutStalling()) { 417 !video_frame_stream_->CanReadWithoutStalling()) {
417 scoped_refptr<VideoFrame> frame = algorithm_->first_frame(); 418 scoped_refptr<VideoFrame> first_frame =
418 CheckForMetadataChanges(frame->format(), frame->natural_size()); 419 algorithm_->Render(base::TimeTicks(), base::TimeTicks(), nullptr);
419 sink_->PaintSingleFrame(frame); 420 CheckForMetadataChanges(first_frame->format(),
421 first_frame->natural_size());
422 sink_->PaintSingleFrame(first_frame);
423 painted_first_frame_ = true;
420 } 424 }
421 } 425 }
422 426
423 // Signal buffering state if we've met our conditions. 427 // Signal buffering state if we've met our conditions.
424 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked()) 428 if (buffering_state_ == BUFFERING_HAVE_NOTHING && HaveEnoughData_Locked())
425 TransitionToHaveEnough_Locked(); 429 TransitionToHaveEnough_Locked();
426 430
427 // Always request more decoded video if we have capacity. 431 // Always request more decoded video if we have capacity.
428 AttemptRead_Locked(); 432 AttemptRead_Locked();
429 } 433 }
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 frames_dropped_ += algorithm_->RemoveExpiredFrames( 670 frames_dropped_ += algorithm_->RemoveExpiredFrames(
667 current_time + algorithm_->average_frame_duration()); 671 current_time + algorithm_->average_frame_duration());
668 672
669 // If we've paused for underflow, and still have no effective frames, clear 673 // 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 674 // the entire queue. Note: this may cause slight inaccuracies in the number
671 // of dropped frames since the frame may have been rendered before. 675 // of dropped frames since the frame may have been rendered before.
672 if (!sink_started_ && !algorithm_->effective_frames_queued()) { 676 if (!sink_started_ && !algorithm_->effective_frames_queued()) {
673 frames_dropped_ += algorithm_->frames_queued(); 677 frames_dropped_ += algorithm_->frames_queued();
674 algorithm_->Reset( 678 algorithm_->Reset(
675 VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates); 679 VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates);
680 painted_first_frame_ = false;
chcunningham 2016/10/21 20:27:22 to be sure I follow, the idea of resetting here is
DaleCurtis 2016/10/21 21:51:17 Correct.
676 681
677 // It's possible in the background rendering case for us to expire enough 682 // 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 683 // 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. 684 // calling this function will check if we need to transition or not.
680 if (buffering_state_ == BUFFERING_HAVE_ENOUGH) 685 if (buffering_state_ == BUFFERING_HAVE_ENOUGH)
681 TransitionToHaveNothing_Locked(); 686 TransitionToHaveNothing_Locked();
682 } 687 }
683 } 688 }
684 689
685 void VideoRendererImpl::CheckForMetadataChanges(VideoPixelFormat pixel_format, 690 void VideoRendererImpl::CheckForMetadataChanges(VideoPixelFormat pixel_format,
(...skipping 18 matching lines...) Expand all
704 709
705 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges( 710 void VideoRendererImpl::AttemptReadAndCheckForMetadataChanges(
706 VideoPixelFormat pixel_format, 711 VideoPixelFormat pixel_format,
707 const gfx::Size& natural_size) { 712 const gfx::Size& natural_size) {
708 base::AutoLock auto_lock(lock_); 713 base::AutoLock auto_lock(lock_);
709 CheckForMetadataChanges(pixel_format, natural_size); 714 CheckForMetadataChanges(pixel_format, natural_size);
710 AttemptRead_Locked(); 715 AttemptRead_Locked();
711 } 716 }
712 717
713 } // namespace media 718 } // namespace media
OLDNEW
« media/filters/video_renderer_algorithm.cc ('K') | « media/renderers/video_renderer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698