123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "cc/layers/video_frame_provider_client_impl.h"
- #include "base/trace_event/trace_event.h"
- #include "cc/base/math_util.h"
- #include "cc/layers/video_layer_impl.h"
- #include "media/base/video_frame.h"
- namespace cc {
- // static
- scoped_refptr<VideoFrameProviderClientImpl>
- VideoFrameProviderClientImpl::Create(VideoFrameProvider* provider,
- VideoFrameControllerClient* client) {
- return base::WrapRefCounted(
- new VideoFrameProviderClientImpl(provider, client));
- }
- VideoFrameProviderClientImpl::VideoFrameProviderClientImpl(
- VideoFrameProvider* provider,
- VideoFrameControllerClient* client)
- : provider_(provider),
- client_(client),
- active_video_layer_(nullptr),
- stopped_(false),
- rendering_(false),
- needs_put_current_frame_(false) {
- // |provider_| may be null if destructed before the layer.
- if (provider_) {
- // This only happens during a commit on the compositor thread while the main
- // thread is blocked. That makes this a thread-safe call to set the video
- // frame provider client that does not require a lock. The same is true of
- // the call to Stop().
- provider_->SetVideoFrameProviderClient(this);
- }
- }
- VideoFrameProviderClientImpl::~VideoFrameProviderClientImpl() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(stopped_);
- }
- VideoLayerImpl* VideoFrameProviderClientImpl::ActiveVideoLayer() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return active_video_layer_;
- }
- void VideoFrameProviderClientImpl::SetActiveVideoLayer(
- VideoLayerImpl* video_layer) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(video_layer);
- active_video_layer_ = video_layer;
- }
- void VideoFrameProviderClientImpl::Stop() {
- DCHECK(thread_checker_.CalledOnValidThread());
- active_video_layer_ = nullptr;
- // It's called when the main thread is blocked, so lock isn't needed.
- if (provider_) {
- provider_->SetVideoFrameProviderClient(nullptr);
- provider_ = nullptr;
- }
- if (rendering_)
- StopRendering();
- stopped_ = true;
- }
- bool VideoFrameProviderClientImpl::Stopped() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return stopped_;
- }
- scoped_refptr<media::VideoFrame>
- VideoFrameProviderClientImpl::AcquireLockAndCurrentFrame() {
- DCHECK(thread_checker_.CalledOnValidThread());
- provider_lock_.Acquire(); // Balanced by call to ReleaseLock().
- if (!provider_)
- return nullptr;
- return provider_->GetCurrentFrame();
- }
- void VideoFrameProviderClientImpl::PutCurrentFrame() {
- DCHECK(thread_checker_.CalledOnValidThread());
- provider_->PutCurrentFrame();
- needs_put_current_frame_ = false;
- }
- void VideoFrameProviderClientImpl::ReleaseLock() {
- DCHECK(thread_checker_.CalledOnValidThread());
- provider_lock_.Release();
- }
- bool VideoFrameProviderClientImpl::HasCurrentFrame() {
- base::AutoLock locker(provider_lock_);
- return provider_ && provider_->HasCurrentFrame();
- }
- void VideoFrameProviderClientImpl::StopUsingProvider() {
- {
- // Block the provider from shutting down until this client is done
- // using the frame.
- base::AutoLock locker(provider_lock_);
- provider_ = nullptr;
- }
- if (rendering_)
- StopRendering();
- }
- void VideoFrameProviderClientImpl::StartRendering() {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::StartRendering");
- DCHECK(!rendering_);
- DCHECK(!stopped_);
- rendering_ = true;
- client_->AddVideoFrameController(this);
- }
- void VideoFrameProviderClientImpl::StopRendering() {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::StopRendering");
- DCHECK(rendering_);
- DCHECK(!stopped_);
- client_->RemoveVideoFrameController(this);
- rendering_ = false;
- if (active_video_layer_)
- active_video_layer_->SetNeedsRedraw();
- }
- void VideoFrameProviderClientImpl::DidReceiveFrame() {
- TRACE_EVENT1("cc",
- "VideoFrameProviderClientImpl::DidReceiveFrame",
- "active_video_layer",
- !!active_video_layer_);
- DCHECK(thread_checker_.CalledOnValidThread());
- needs_put_current_frame_ = true;
- if (active_video_layer_)
- active_video_layer_->SetNeedsRedraw();
- }
- void VideoFrameProviderClientImpl::OnBeginFrame(
- const viz::BeginFrameArgs& args) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(rendering_);
- DCHECK(!stopped_);
- TRACE_EVENT0("cc", "VideoFrameProviderClientImpl::OnBeginFrame");
- {
- base::AutoLock locker(provider_lock_);
- // We use frame_time + interval here because that is the estimated time at
- // which a frame returned during this phase will end up being displayed.
- if (!provider_ ||
- !provider_->UpdateCurrentFrame(args.frame_time + args.interval,
- args.frame_time + 2 * args.interval)) {
- return;
- }
- }
- // Warning: Do not hold |provider_lock_| while calling this function, it may
- // lead to a reentrant call to HasCurrentFrame() above.
- DidReceiveFrame();
- }
- void VideoFrameProviderClientImpl::DidDrawFrame() {
- DCHECK(thread_checker_.CalledOnValidThread());
- {
- base::AutoLock locker(provider_lock_);
- if (provider_ && needs_put_current_frame_)
- provider_->PutCurrentFrame();
- }
- needs_put_current_frame_ = false;
- }
- bool VideoFrameProviderClientImpl::IsDrivingFrameUpdates() const {
- // We drive frame updates any time we're rendering, even if we're off-screen.
- return rendering_;
- }
- } // namespace cc
|