12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/video_frame_provider_client_impl.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/debug/trace_event.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/video_layer_impl.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/video_frame.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<VideoFrameProviderClientImpl>
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VideoFrameProviderClientImpl::Create(
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        VideoFrameProvider* provider) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_refptr(
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new VideoFrameProviderClientImpl(provider));
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VideoFrameProviderClientImpl::~VideoFrameProviderClientImpl() {}
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VideoFrameProviderClientImpl::VideoFrameProviderClientImpl(
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VideoFrameProvider* provider)
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : active_video_layer_(NULL), provider_(provider) {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This only happens during a commit on the compositor thread while the main
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // thread is blocked. That makes this a thread-safe call to set the video
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame provider client that does not require a lock. The same is true of
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the call to Stop().
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_->SetVideoFrameProviderClient(this);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This matrix is the default transformation for stream textures, and flips
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on the Y axis.
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_texture_matrix_ = gfx::Transform(
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      1.0, 0.0, 0.0, 0.0,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0.0, -1.0, 0.0, 1.0,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0.0, 0.0, 1.0, 0.0,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0.0, 0.0, 0.0, 1.0);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoFrameProviderClientImpl::Stop() {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!provider_)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_->SetVideoFrameProviderClient(NULL);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_ = NULL;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<media::VideoFrame>
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VideoFrameProviderClientImpl::AcquireLockAndCurrentFrame() {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_lock_.Acquire();  // Balanced by call to ReleaseLock().
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!provider_)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return provider_->GetCurrentFrame();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoFrameProviderClientImpl::PutCurrentFrame(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<media::VideoFrame>& frame) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_lock_.AssertAcquired();
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_->PutCurrentFrame(frame);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoFrameProviderClientImpl::ReleaseLock() {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_lock_.AssertAcquired();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_lock_.Release();
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoFrameProviderClientImpl::StopUsingProvider() {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Block the provider from shutting down until this client is done
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // using the frame.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock locker(provider_lock_);
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_ = NULL;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoFrameProviderClientImpl::DidReceiveFrame() {
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TRACE_EVENT1("cc",
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch               "VideoFrameProviderClientImpl::DidReceiveFrame",
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch               "active_video_layer",
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch               !!active_video_layer_);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (active_video_layer_)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    active_video_layer_->SetNeedsRedraw();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoFrameProviderClientImpl::DidUpdateMatrix(const float* matrix) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_texture_matrix_ = gfx::Transform(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      matrix[0], matrix[4], matrix[8], matrix[12],
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      matrix[1], matrix[5], matrix[9], matrix[13],
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      matrix[2], matrix[6], matrix[10], matrix[14],
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      matrix[3], matrix[7], matrix[11], matrix[15]);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (active_video_layer_)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    active_video_layer_->SetNeedsRedraw();
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
96