blob: e855bcc1431d28a0b23ed8451d63eb1d9cf52e52 [file] [log] [blame]
[email protected]48871fc2013-01-23 07:36:511// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cc3cfaa2013-03-18 09:05:525#include "cc/layers/video_frame_provider_client_impl.h"
[email protected]48871fc2013-01-23 07:36:516
primianoc06e2382015-01-28 04:21:497#include "base/trace_event/trace_event.h"
[email protected]681ccff2013-03-18 06:13:528#include "cc/base/math_util.h"
[email protected]cc3cfaa2013-03-18 09:05:529#include "cc/layers/video_layer_impl.h"
[email protected]b7cfc632013-04-10 04:44:4910#include "media/base/video_frame.h"
[email protected]48871fc2013-01-23 07:36:5111
12namespace cc {
13
14// static
15scoped_refptr<VideoFrameProviderClientImpl>
sunnyps7d073dc2015-04-16 23:29:1216VideoFrameProviderClientImpl::Create(VideoFrameProvider* provider,
17 VideoFrameControllerClient* client) {
kylechar973a0412017-09-26 18:40:2918 return base::WrapRefCounted(
19 new VideoFrameProviderClientImpl(provider, client));
[email protected]48871fc2013-01-23 07:36:5120}
21
[email protected]48871fc2013-01-23 07:36:5122VideoFrameProviderClientImpl::VideoFrameProviderClientImpl(
sunnyps7d073dc2015-04-16 23:29:1223 VideoFrameProvider* provider,
24 VideoFrameControllerClient* client)
25 : provider_(provider),
26 client_(client),
27 active_video_layer_(nullptr),
dalecurtisf28f0e52015-05-01 07:08:2528 stopped_(false),
dalecurtise8024c42015-05-29 21:22:3529 rendering_(false),
30 needs_put_current_frame_(false) {
dalecurtise1edb312016-06-22 02:33:2131 // |provider_| may be null if destructed before the layer.
32 if (provider_) {
33 // This only happens during a commit on the compositor thread while the main
34 // thread is blocked. That makes this a thread-safe call to set the video
35 // frame provider client that does not require a lock. The same is true of
36 // the call to Stop().
37 provider_->SetVideoFrameProviderClient(this);
38 }
[email protected]48871fc2013-01-23 07:36:5139}
40
sunnypsa5281722015-03-27 02:39:4841VideoFrameProviderClientImpl::~VideoFrameProviderClientImpl() {
42 DCHECK(thread_checker_.CalledOnValidThread());
43 DCHECK(stopped_);
44}
45
46VideoLayerImpl* VideoFrameProviderClientImpl::ActiveVideoLayer() const {
47 DCHECK(thread_checker_.CalledOnValidThread());
48 return active_video_layer_;
49}
50
dongseong.hwangee88f0aa2015-02-10 19:39:5951void VideoFrameProviderClientImpl::SetActiveVideoLayer(
52 VideoLayerImpl* video_layer) {
53 DCHECK(thread_checker_.CalledOnValidThread());
54 DCHECK(video_layer);
55 active_video_layer_ = video_layer;
56}
57
[email protected]48871fc2013-01-23 07:36:5158void VideoFrameProviderClientImpl::Stop() {
dongseong.hwangee88f0aa2015-02-10 19:39:5959 DCHECK(thread_checker_.CalledOnValidThread());
qiangchen867223f2017-02-14 17:47:1260 active_video_layer_ = nullptr;
sunnypsa5281722015-03-27 02:39:4861 // It's called when the main thread is blocked, so lock isn't needed.
62 if (provider_) {
63 provider_->SetVideoFrameProviderClient(nullptr);
64 provider_ = nullptr;
65 }
dalecurtisf28f0e52015-05-01 07:08:2566 if (rendering_)
67 StopRendering();
sunnypsa5281722015-03-27 02:39:4868 stopped_ = true;
[email protected]48871fc2013-01-23 07:36:5169}
70
sunnypsa5281722015-03-27 02:39:4871bool VideoFrameProviderClientImpl::Stopped() const {
dongseong.hwangee88f0aa2015-02-10 19:39:5972 DCHECK(thread_checker_.CalledOnValidThread());
sunnypsa5281722015-03-27 02:39:4873 return stopped_;
dongseong.hwangee88f0aa2015-02-10 19:39:5974}
75
[email protected]af2cd322013-03-22 16:56:1876scoped_refptr<media::VideoFrame>
77VideoFrameProviderClientImpl::AcquireLockAndCurrentFrame() {
dongseong.hwangee88f0aa2015-02-10 19:39:5978 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]48871fc2013-01-23 07:36:5179 provider_lock_.Acquire(); // Balanced by call to ReleaseLock().
80 if (!provider_)
kulkarni.a4015690f12014-10-10 13:50:0681 return nullptr;
[email protected]48871fc2013-01-23 07:36:5182
83 return provider_->GetCurrentFrame();
84}
85
Bartosz Fabianowski85a823812015-04-16 10:27:5186void VideoFrameProviderClientImpl::PutCurrentFrame() {
dongseong.hwangee88f0aa2015-02-10 19:39:5987 DCHECK(thread_checker_.CalledOnValidThread());
Bartosz Fabianowski85a823812015-04-16 10:27:5188 provider_->PutCurrentFrame();
dalecurtise8024c42015-05-29 21:22:3589 needs_put_current_frame_ = false;
[email protected]48871fc2013-01-23 07:36:5190}
91
92void VideoFrameProviderClientImpl::ReleaseLock() {
dongseong.hwangee88f0aa2015-02-10 19:39:5993 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]48871fc2013-01-23 07:36:5194 provider_lock_.Release();
95}
96
hendrikwe19cc6a2015-05-18 23:14:1497bool VideoFrameProviderClientImpl::HasCurrentFrame() {
98 base::AutoLock locker(provider_lock_);
99 return provider_ && provider_->HasCurrentFrame();
100}
101
[email protected]48871fc2013-01-23 07:36:51102void VideoFrameProviderClientImpl::StopUsingProvider() {
dalecurtis6d37d332015-06-16 20:26:37103 {
104 // Block the provider from shutting down until this client is done
105 // using the frame.
106 base::AutoLock locker(provider_lock_);
107 provider_ = nullptr;
108 }
dalecurtisf28f0e52015-05-01 07:08:25109 if (rendering_)
110 StopRendering();
[email protected]48871fc2013-01-23 07:36:51111}
112
Bartosz Fabianowski85a823812015-04-16 10:27:51113void VideoFrameProviderClientImpl::StartRendering() {
dalecurtisf28f0e52015-05-01 07:08:25114 DCHECK(thread_checker_.CalledOnValidThread());
115 TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::StartRendering");
116 DCHECK(!rendering_);
117 DCHECK(!stopped_);
dalecurtisf28f0e52015-05-01 07:08:25118 rendering_ = true;
sunnypsc052ba992015-05-05 00:42:29119 client_->AddVideoFrameController(this);
Bartosz Fabianowski85a823812015-04-16 10:27:51120}
121
122void VideoFrameProviderClientImpl::StopRendering() {
dalecurtisf28f0e52015-05-01 07:08:25123 DCHECK(thread_checker_.CalledOnValidThread());
124 TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::StopRendering");
125 DCHECK(rendering_);
126 DCHECK(!stopped_);
127 client_->RemoveVideoFrameController(this);
128 rendering_ = false;
qiangchen867223f2017-02-14 17:47:12129 if (active_video_layer_)
130 active_video_layer_->SetNeedsRedraw();
Bartosz Fabianowski85a823812015-04-16 10:27:51131}
132
[email protected]48871fc2013-01-23 07:36:51133void VideoFrameProviderClientImpl::DidReceiveFrame() {
[email protected]9469d782014-04-18 01:23:56134 TRACE_EVENT1("cc",
135 "VideoFrameProviderClientImpl::DidReceiveFrame",
136 "active_video_layer",
137 !!active_video_layer_);
dongseong.hwangee88f0aa2015-02-10 19:39:59138 DCHECK(thread_checker_.CalledOnValidThread());
dalecurtise8024c42015-05-29 21:22:35139 needs_put_current_frame_ = true;
[email protected]48871fc2013-01-23 07:36:51140 if (active_video_layer_)
[email protected]4af49d542013-03-15 22:18:47141 active_video_layer_->SetNeedsRedraw();
[email protected]48871fc2013-01-23 07:36:51142}
143
Fady Samuelc296f5fb2017-07-21 04:02:19144void VideoFrameProviderClientImpl::OnBeginFrame(
145 const viz::BeginFrameArgs& args) {
sunnyps7d073dc2015-04-16 23:29:12146 DCHECK(thread_checker_.CalledOnValidThread());
dalecurtisf28f0e52015-05-01 07:08:25147 DCHECK(rendering_);
148 DCHECK(!stopped_);
149
150 TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::OnBeginFrame");
dalecurtis6d37d332015-06-16 20:26:37151 {
152 base::AutoLock locker(provider_lock_);
dalecurtisf28f0e52015-05-01 07:08:25153
dalecurtis6d37d332015-06-16 20:26:37154 // We use frame_time + interval here because that is the estimated time at
155 // which a frame returned during this phase will end up being displayed.
156 if (!provider_ ||
157 !provider_->UpdateCurrentFrame(args.frame_time + args.interval,
158 args.frame_time + 2 * args.interval)) {
159 return;
160 }
dalecurtisf28f0e52015-05-01 07:08:25161 }
162
dalecurtis6d37d332015-06-16 20:26:37163 // Warning: Do not hold |provider_lock_| while calling this function, it may
164 // lead to a reentrant call to HasCurrentFrame() above.
dalecurtisf28f0e52015-05-01 07:08:25165 DidReceiveFrame();
sunnyps7d073dc2015-04-16 23:29:12166}
167
dalecurtise8024c42015-05-29 21:22:35168void VideoFrameProviderClientImpl::DidDrawFrame() {
169 DCHECK(thread_checker_.CalledOnValidThread());
170 {
171 base::AutoLock locker(provider_lock_);
172 if (provider_ && needs_put_current_frame_)
173 provider_->PutCurrentFrame();
174 }
175 needs_put_current_frame_ = false;
176}
177
[email protected]f14f5162018-08-08 17:09:26178bool VideoFrameProviderClientImpl::IsDrivingFrameUpdates() const {
179 // We drive frame updates any time we're rendering, even if we're off-screen.
180 return rendering_;
181}
182
[email protected]48871fc2013-01-23 07:36:51183} // namespace cc