// Copyright (c) 2012 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.
//
// Implementation notes: This needs to work on a variety of hardware
// configurations where the speed of the CPU and GPU greatly affect overall
// performance. Spanning several threads, the process of capturing has been
// split up into four conceptual stages:
//
//   1. Reserve Buffer: Before a frame can be captured, a slot in the client's
//      shared-memory IPC buffer is reserved. There are only a few of these;
//      when they run out, it indicates that the downstream client -- likely a
//      video encoder -- is the performance bottleneck, and that the rate of
//      frame capture should be throttled back.
//
//   2. Capture: A bitmap is snapshotted/copied from the RenderView's backing
//      store. This is initiated on the UI BrowserThread, and often occurs
//      asynchronously. Where supported, the GPU scales and color converts
//      frames to our desired size, and the readback happens directly into the
//      shared-memory buffer. But this is not always possible, particularly when
//      accelerated compositing is disabled.
//
//   3. Render (if needed): If the web contents cannot be captured directly into
//      our target size and color format, scaling and colorspace conversion must
//      be done on the CPU. A dedicated thread is used for this operation, to
//      avoid blocking the UI thread. The Render stage always reads from a
//      bitmap returned by Capture, and writes into the reserved slot in the
//      shared-memory buffer.
//
//   4. Deliver: The rendered video frame is returned to the client (which
//      implements the VideoCaptureDevice::Client interface). Because all
//      paths have written the frame into the IPC buffer, this step should
//      never need to do an additional copy of the pixel data.
//
// In the best-performing case, the Render step is bypassed: Capture produces
// ready-to-Deliver frames. But when accelerated readback is not possible, the
// system is designed so that Capture and Render may run concurrently. A timing
// diagram helps illustrate this point (@30 FPS):
//
//    Time: 0ms                 33ms                 66ms                 99ms
// thread1: |-Capture-f1------v |-Capture-f2------v  |-Capture-f3----v    |-Capt
// thread2:                   |-Render-f1-----v   |-Render-f2-----v  |-Render-f3
//
// In the above example, both capturing and rendering *each* take almost the
// full 33 ms available between frames, yet we see that the required throughput
// is obtained.
//
// Turning on verbose logging will cause the effective frame rate to be logged
// at 5-second intervals.

#include "content/browser/renderer_host/media/web_contents_video_capture_device.h"

#include <algorithm>
#include <list>
#include <string>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/callback_helpers.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/metrics/histogram.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/media/video_capture_oracle.h"
#include "content/browser/renderer_host/media/web_contents_capture_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "media/base/bind_to_loop.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/base/yuv_convert.h"
#include "media/video/capture/video_capture_types.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/skia_util.h"

namespace content {

namespace {

const int kMinFrameWidth = 2;
const int kMinFrameHeight = 2;

// TODO(nick): Remove this once frame subscription is supported on Aura and
// Linux.
#if (defined(OS_WIN) || defined(OS_MACOSX)) || defined(USE_AURA)
const bool kAcceleratedSubscriberIsSupported = true;
#else
const bool kAcceleratedSubscriberIsSupported = false;
#endif

// Returns the nearest even integer closer to zero.
template<typename IntType>
IntType MakeEven(IntType x) {
  return x & static_cast<IntType>(-2);
}

// Compute a letterbox region, aligned to even coordinates.
gfx::Rect ComputeYV12LetterboxRegion(const gfx::Size& frame_size,
                                     const gfx::Size& content_size) {

  gfx::Rect result = media::ComputeLetterboxRegion(gfx::Rect(frame_size),
                                                   content_size);

  result.set_x(MakeEven(result.x()));
  result.set_y(MakeEven(result.y()));
  result.set_width(std::max(kMinFrameWidth, MakeEven(result.width())));
  result.set_height(std::max(kMinFrameHeight, MakeEven(result.height())));

  return result;
}

// Thread-safe, refcounted proxy to the VideoCaptureOracle.  This proxy wraps
// the VideoCaptureOracle, which decides which frames to capture, and a
// VideoCaptureDevice::Client, which allocates and receives the captured
// frames, in a lock to synchronize state between the two.
class ThreadSafeCaptureOracle
    : public base::RefCountedThreadSafe<ThreadSafeCaptureOracle> {
 public:
  ThreadSafeCaptureOracle(scoped_ptr<media::VideoCaptureDevice::Client> client,
                          scoped_ptr<VideoCaptureOracle> oracle,
                          const gfx::Size& capture_size);

  bool ObserveEventAndDecideCapture(
      VideoCaptureOracle::Event event,
      base::Time event_time,
      scoped_refptr<media::VideoFrame>* storage,
      RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback);

  base::TimeDelta capture_period() const {
    return oracle_->capture_period();
  }

  // Stop new captures from happening (but doesn't forget the client).
  void Stop();

  // Signal an error to the client.
  void ReportError();

 private:
  friend class base::RefCountedThreadSafe<ThreadSafeCaptureOracle>;
  virtual ~ThreadSafeCaptureOracle() {}

  // Callback invoked on completion of all captures.
  void DidCaptureFrame(const scoped_refptr<media::VideoFrame>& frame,
                       int frame_number,
                       base::Time timestamp,
                       bool success);
  // Protects everything below it.
  base::Lock lock_;

  // Recipient of our capture activity.
  scoped_ptr<media::VideoCaptureDevice::Client> client_;

  // Makes the decision to capture a frame.
  const scoped_ptr<VideoCaptureOracle> oracle_;

  // The resolution at which we're capturing.
  const gfx::Size capture_size_;
};

// FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible
// with RenderWidgetHostViewFrameSubscriber. We create one per event type.
class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
 public:
  FrameSubscriber(VideoCaptureOracle::Event event_type,
                  const scoped_refptr<ThreadSafeCaptureOracle>& oracle)
      : event_type_(event_type),
        oracle_proxy_(oracle) {}

  virtual bool ShouldCaptureFrame(
      base::Time present_time,
      scoped_refptr<media::VideoFrame>* storage,
      RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback*
          deliver_frame_cb) OVERRIDE;

 private:
  const VideoCaptureOracle::Event event_type_;
  scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
};

// ContentCaptureSubscription is the relationship between a RenderWidgetHost
// whose content is updating, a subscriber that is deciding which of these
// updates to capture (and where to deliver them to), and a callback that
// knows how to do the capture and prepare the result for delivery.
//
// In practice, this means (a) installing a RenderWidgetHostFrameSubscriber in
// the RenderWidgetHostView, to process updates that occur via accelerated
// compositing, (b) installing itself as an observer of updates to the
// RenderWidgetHost's backing store, to hook updates that occur via software
// rendering, and (c) running a timer to possibly initiate non-event-driven
// captures that the subscriber might request.
//
// All of this happens on the UI thread, although the
// RenderWidgetHostViewFrameSubscriber we install may be dispatching updates
// autonomously on some other thread.
class ContentCaptureSubscription : public content::NotificationObserver {
 public:
  typedef base::Callback<void(
      const base::Time&,
      const scoped_refptr<media::VideoFrame>&,
      const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)>
          CaptureCallback;

  // Create a subscription. Whenever a manual capture is required, the
  // subscription will invoke |capture_callback| on the UI thread to do the
  // work.
  ContentCaptureSubscription(
      const RenderWidgetHost& source,
      const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
      const CaptureCallback& capture_callback);
  virtual ~ContentCaptureSubscription();

  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

 private:
  void OnTimer();

  const int render_process_id_;
  const int render_view_id_;

  FrameSubscriber paint_subscriber_;
  FrameSubscriber timer_subscriber_;
  content::NotificationRegistrar registrar_;
  CaptureCallback capture_callback_;
  base::Timer timer_;

  DISALLOW_COPY_AND_ASSIGN(ContentCaptureSubscription);
};

// Render the SkBitmap |input| into the given VideoFrame buffer |output|, then
// invoke |done_cb| to indicate success or failure. |input| is expected to be
// ARGB. |output| must be YV12 or I420. Colorspace conversion is always done.
// Scaling and letterboxing will be done as needed.
//
// This software implementation should be used only when GPU acceleration of
// these activities is not possible. This operation may be expensive (tens to
// hundreds of milliseconds), so the caller should ensure that it runs on a
// thread where such a pause would cause UI jank.
void RenderVideoFrame(const SkBitmap& input,
                      const scoped_refptr<media::VideoFrame>& output,
                      const base::Callback<void(bool)>& done_cb);

// Keeps track of the RenderView to be sourced, and executes copying of the
// backing store on the UI BrowserThread.
//
// TODO(nick): It would be nice to merge this with WebContentsTracker, but its
// implementation is currently asynchronous -- in our case, the "rvh changed"
// notification would get posted back to the UI thread and processed later, and
// this seems disadvantageous.
class CaptureMachine : public WebContentsObserver,
                       public base::SupportsWeakPtr<CaptureMachine> {
 public:
  virtual ~CaptureMachine();

  // Creates a CaptureMachine. Must be run on the UI BrowserThread. Returns
  // NULL if the indicated render view cannot be found.
  static scoped_ptr<CaptureMachine> Create(
      int render_process_id,
      int render_view_id,
      const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
      const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy);

  // Starts a copy from the backing store or the composited surface. Must be run
  // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation
  // completes. The copy will occur to |target|.
  //
  // This may be used as a ContentCaptureSubscription::CaptureCallback.
  void Capture(
      const base::Time& start_time,
      const scoped_refptr<media::VideoFrame>& target,
      const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
          deliver_frame_cb);

  // content::WebContentsObserver implementation.
  virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE {
    fullscreen_widget_id_ = routing_id;
    RenewFrameSubscription();
  }

  virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE {
    DCHECK_EQ(fullscreen_widget_id_, routing_id);
    fullscreen_widget_id_ = MSG_ROUTING_NONE;
    RenewFrameSubscription();
  }

  virtual void RenderViewReady() OVERRIDE {
    RenewFrameSubscription();
  }

  virtual void AboutToNavigateRenderView(RenderViewHost* rvh) OVERRIDE {
    RenewFrameSubscription();
  }

  virtual void DidNavigateMainFrame(
      const LoadCommittedDetails& details,
      const FrameNavigateParams& params) OVERRIDE {
    RenewFrameSubscription();
  }

  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;

 private:
  CaptureMachine(
     const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
     const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy);

  // Starts observing the web contents, returning false if lookup fails.
  bool StartObservingWebContents(int initial_render_process_id,
                                 int initial_render_view_id);

  // Helper function to determine the view that we are currently tracking.
  RenderWidgetHost* GetTarget();

  // Response callback for RenderWidgetHost::CopyFromBackingStore().
  void DidCopyFromBackingStore(
      const base::Time& start_time,
      const scoped_refptr<media::VideoFrame>& target,
      const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
          deliver_frame_cb,
      bool success,
      const SkBitmap& bitmap);

  // Response callback for RWHVP::CopyFromCompositingSurfaceToVideoFrame().
  void DidCopyFromCompositingSurfaceToVideoFrame(
      const base::Time& start_time,
      const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
          deliver_frame_cb,
      bool success);

  // Remove the old subscription, and start a new one. This should be called
  // after any change to the WebContents that affects the RenderWidgetHost or
  // attached views.
  void RenewFrameSubscription();

  // The task runner of the thread on which SkBitmap->VideoFrame conversion will
  // occur. Only used when this activity cannot be done on the GPU.
  const scoped_refptr<base::SequencedTaskRunner> render_task_runner_;

  // Makes all the decisions about which frames to copy, and how.
  const scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;

  // Routing ID of any active fullscreen render widget or MSG_ROUTING_NONE
  // otherwise.
  int fullscreen_widget_id_;

  // Last known RenderView size.
  gfx::Size last_view_size_;

  // Responsible for forwarding events from the active RenderWidgetHost to the
  // oracle, and initiating captures accordingly.
  scoped_ptr<ContentCaptureSubscription> subscription_;

  DISALLOW_COPY_AND_ASSIGN(CaptureMachine);
};

// Responsible for logging the effective frame rate.
// TODO(nick): Make this compatible with the push model and hook it back up.
class VideoFrameDeliveryLog {
 public:
  VideoFrameDeliveryLog();

  // Treat |frame_number| as having been delivered, and update the
  // frame rate statistics accordingly.
  void ChronicleFrameDelivery(int frame_number);

 private:
  // The following keep track of and log the effective frame rate whenever
  // verbose logging is turned on.
  base::Time last_frame_rate_log_time_;
  int count_frames_rendered_;
  int last_frame_number_;

  DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog);
};

ThreadSafeCaptureOracle::ThreadSafeCaptureOracle(
    scoped_ptr<media::VideoCaptureDevice::Client> client,
    scoped_ptr<VideoCaptureOracle> oracle,
    const gfx::Size& capture_size)
    : client_(client.Pass()),
      oracle_(oracle.Pass()),
      capture_size_(capture_size) {
}

bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
    VideoCaptureOracle::Event event,
    base::Time event_time,
    scoped_refptr<media::VideoFrame>* storage,
    RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback) {
  base::AutoLock guard(lock_);

  if (!client_)
    return false;  // Capture is stopped.

  scoped_refptr<media::VideoFrame> output_buffer =
      client_->ReserveOutputBuffer(capture_size_);
  const bool should_capture =
      oracle_->ObserveEventAndDecideCapture(event, event_time);
  const bool content_is_dirty =
      (event == VideoCaptureOracle::kCompositorUpdate ||
       event == VideoCaptureOracle::kSoftwarePaint);
  const char* event_name =
      (event == VideoCaptureOracle::kTimerPoll ? "poll" :
       (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" :
       "paint"));

  // Consider the various reasons not to initiate a capture.
  if (should_capture && !output_buffer.get()) {
    TRACE_EVENT_INSTANT1("mirroring",
                         "EncodeLimited",
                         TRACE_EVENT_SCOPE_THREAD,
                         "trigger",
                         event_name);
    return false;
  } else if (!should_capture && output_buffer.get()) {
    if (content_is_dirty) {
      // This is a normal and acceptable way to drop a frame. We've hit our
      // capture rate limit: for example, the content is animating at 60fps but
      // we're capturing at 30fps.
      TRACE_EVENT_INSTANT1("mirroring", "FpsRateLimited",
                           TRACE_EVENT_SCOPE_THREAD,
                           "trigger", event_name);
    }
    return false;
  } else if (!should_capture && !output_buffer.get()) {
    // We decided not to capture, but we wouldn't have been able to if we wanted
    // to because no output buffer was available.
    TRACE_EVENT_INSTANT1("mirroring", "NearlyEncodeLimited",
                         TRACE_EVENT_SCOPE_THREAD,
                         "trigger", event_name);
    return false;
  }
  int frame_number = oracle_->RecordCapture();
  TRACE_EVENT_ASYNC_BEGIN2("mirroring", "Capture", output_buffer.get(),
                           "frame_number", frame_number,
                           "trigger", event_name);
  *storage = output_buffer;
  *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame,
                         this, output_buffer, frame_number);
  return true;
}

void ThreadSafeCaptureOracle::Stop() {
  base::AutoLock guard(lock_);
  client_.reset();
}

void ThreadSafeCaptureOracle::ReportError() {
  base::AutoLock guard(lock_);
  if (client_)
    client_->OnError();
}

void ThreadSafeCaptureOracle::DidCaptureFrame(
    const scoped_refptr<media::VideoFrame>& frame,
    int frame_number,
    base::Time timestamp,
    bool success) {
  base::AutoLock guard(lock_);
  TRACE_EVENT_ASYNC_END2("mirroring", "Capture", frame.get(),
                         "success", success,
                         "timestamp", timestamp.ToInternalValue());

  if (!client_)
    return;  // Capture is stopped.

  if (success) {
    if (oracle_->CompleteCapture(frame_number, timestamp))
      client_->OnIncomingCapturedVideoFrame(frame, timestamp);
  }
}

bool FrameSubscriber::ShouldCaptureFrame(
    base::Time present_time,
    scoped_refptr<media::VideoFrame>* storage,
    DeliverFrameCallback* deliver_frame_cb) {
  TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame",
               "instance", this);

  return oracle_proxy_->ObserveEventAndDecideCapture(event_type_, present_time,
                                                     storage, deliver_frame_cb);
}

ContentCaptureSubscription::ContentCaptureSubscription(
    const RenderWidgetHost& source,
    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
    const CaptureCallback& capture_callback)
    : render_process_id_(source.GetProcess()->GetID()),
      render_view_id_(source.GetRoutingID()),
      paint_subscriber_(VideoCaptureOracle::kSoftwarePaint, oracle_proxy),
      timer_subscriber_(VideoCaptureOracle::kTimerPoll, oracle_proxy),
      capture_callback_(capture_callback),
      timer_(true, true) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  RenderWidgetHostViewPort* view =
      RenderWidgetHostViewPort::FromRWHV(source.GetView());

  // Subscribe to accelerated presents. These will be serviced directly by the
  // oracle.
  if (view && kAcceleratedSubscriberIsSupported) {
    scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
        new FrameSubscriber(VideoCaptureOracle::kCompositorUpdate,
            oracle_proxy));
    view->BeginFrameSubscription(subscriber.Pass());
  }

  // Subscribe to software paint events. This instance will service these by
  // reflecting them back to the CaptureMachine via |capture_callback|.
  registrar_.Add(
      this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
      Source<RenderWidgetHost>(&source));

  // Subscribe to timer events. This instance will service these as well.
  timer_.Start(FROM_HERE, oracle_proxy->capture_period(),
               base::Bind(&ContentCaptureSubscription::OnTimer,
                          base::Unretained(this)));
}

ContentCaptureSubscription::~ContentCaptureSubscription() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (kAcceleratedSubscriberIsSupported) {
    RenderViewHost* source = RenderViewHost::FromID(render_process_id_,
                                                    render_view_id_);
    if (source) {
      RenderWidgetHostViewPort* view =
          RenderWidgetHostViewPort::FromRWHV(source->GetView());
      if (view)
        view->EndFrameSubscription();
    }
  }
}

void ContentCaptureSubscription::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_EQ(NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, type);

  RenderWidgetHostImpl* rwh =
      RenderWidgetHostImpl::From(Source<RenderWidgetHost>(source).ptr());

  // This message occurs on window resizes and visibility changes even when
  // accelerated compositing is active, so we need to filter out these cases.
  if (!rwh || !rwh->GetView() || (rwh->is_accelerated_compositing_active() &&
                                  rwh->GetView()->IsSurfaceAvailableForCopy()))
    return;

  TRACE_EVENT1("mirroring", "ContentCaptureSubscription::Observe",
               "instance", this);

  base::Closure copy_done_callback;
  scoped_refptr<media::VideoFrame> frame;
  RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb;
  const base::Time start_time = base::Time::Now();
  if (paint_subscriber_.ShouldCaptureFrame(start_time,
                                           &frame,
                                           &deliver_frame_cb)) {
    // This message happens just before paint. If we post a task to do the copy,
    // it should run soon after the paint.
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(capture_callback_, start_time, frame, deliver_frame_cb));
  }
}

void ContentCaptureSubscription::OnTimer() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TRACE_EVENT0("mirroring", "ContentCaptureSubscription::OnTimer");

  scoped_refptr<media::VideoFrame> frame;
  RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb;

  const base::Time start_time = base::Time::Now();
  if (timer_subscriber_.ShouldCaptureFrame(start_time,
                                           &frame,
                                           &deliver_frame_cb)) {
    capture_callback_.Run(start_time, frame, deliver_frame_cb);
  }
}

void RenderVideoFrame(const SkBitmap& input,
                      const scoped_refptr<media::VideoFrame>& output,
                      const base::Callback<void(bool)>& done_cb) {
  base::ScopedClosureRunner failure_handler(base::Bind(done_cb, false));

  SkAutoLockPixels locker(input);

  // Sanity-check the captured bitmap.
  if (input.empty() ||
      !input.readyToDraw() ||
      input.config() != SkBitmap::kARGB_8888_Config ||
      input.width() < 2 || input.height() < 2) {
    DVLOG(1) << "input unacceptable (size="
             << input.getSize()
             << ", ready=" << input.readyToDraw()
             << ", config=" << input.config() << ')';
    return;
  }

  // Sanity-check the output buffer.
  if (output->format() != media::VideoFrame::I420) {
    NOTREACHED();
    return;
  }

  // Calculate the width and height of the content region in the |output|, based
  // on the aspect ratio of |input|.
  gfx::Rect region_in_frame = ComputeYV12LetterboxRegion(
      output->coded_size(), gfx::Size(input.width(), input.height()));

  // Scale the bitmap to the required size, if necessary.
  SkBitmap scaled_bitmap;
  if (input.width() != region_in_frame.width() ||
      input.height() != region_in_frame.height()) {

    skia::ImageOperations::ResizeMethod method;
    if (input.width() < region_in_frame.width() ||
        input.height() < region_in_frame.height()) {
      // Avoid box filtering when magnifying, because it's actually
      // nearest-neighbor.
      method = skia::ImageOperations::RESIZE_HAMMING1;
    } else {
      method = skia::ImageOperations::RESIZE_BOX;
    }

    TRACE_EVENT_ASYNC_STEP_INTO0("mirroring", "Capture", output.get(), "Scale");
    scaled_bitmap = skia::ImageOperations::Resize(input, method,
                                                  region_in_frame.width(),
                                                  region_in_frame.height());
  } else {
    scaled_bitmap = input;
  }

  TRACE_EVENT_ASYNC_STEP_INTO0("mirroring", "Capture", output.get(), "YUV");
  {
    SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);

    media::CopyRGBToVideoFrame(
        reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
        scaled_bitmap.rowBytes(),
        region_in_frame,
        output.get());
  }

  // The result is now ready.
  ignore_result(failure_handler.Release());
  done_cb.Run(true);
}

VideoFrameDeliveryLog::VideoFrameDeliveryLog()
    : last_frame_rate_log_time_(),
      count_frames_rendered_(0),
      last_frame_number_(0) {
}

void VideoFrameDeliveryLog::ChronicleFrameDelivery(int frame_number) {
  // Log frame rate, if verbose logging is turned on.
  static const base::TimeDelta kFrameRateLogInterval =
      base::TimeDelta::FromSeconds(10);
  const base::Time now = base::Time::Now();
  if (last_frame_rate_log_time_.is_null()) {
    last_frame_rate_log_time_ = now;
    count_frames_rendered_ = 0;
    last_frame_number_ = frame_number;
  } else {
    ++count_frames_rendered_;
    const base::TimeDelta elapsed = now - last_frame_rate_log_time_;
    if (elapsed >= kFrameRateLogInterval) {
      const double measured_fps =
          count_frames_rendered_ / elapsed.InSecondsF();
      const int frames_elapsed = frame_number - last_frame_number_;
      const int count_frames_dropped = frames_elapsed - count_frames_rendered_;
      DCHECK_LE(0, count_frames_dropped);
      UMA_HISTOGRAM_PERCENTAGE(
          "TabCapture.FrameDropPercentage",
          (count_frames_dropped * 100 + frames_elapsed / 2) / frames_elapsed);
      UMA_HISTOGRAM_COUNTS(
          "TabCapture.FrameRate",
          static_cast<int>(measured_fps));
      VLOG(1) << "Current measured frame rate for "
              << "WebContentsVideoCaptureDevice is " << measured_fps << " FPS.";
      last_frame_rate_log_time_ = now;
      count_frames_rendered_ = 0;
      last_frame_number_ = frame_number;
    }
  }
}

// static
scoped_ptr<CaptureMachine> CaptureMachine::Create(
    int render_process_id,
    int render_view_id,
    const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(render_task_runner.get());
  DCHECK(oracle_proxy.get());
  scoped_ptr<CaptureMachine> machine(
      new CaptureMachine(render_task_runner, oracle_proxy));

  if (!machine->StartObservingWebContents(render_process_id, render_view_id))
    machine.reset();

  return machine.Pass();
}

CaptureMachine::CaptureMachine(
    const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy)
    : render_task_runner_(render_task_runner),
      oracle_proxy_(oracle_proxy),
      fullscreen_widget_id_(MSG_ROUTING_NONE) {}

CaptureMachine::~CaptureMachine() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
         !BrowserThread::IsMessageLoopValid(BrowserThread::UI));

  // Stop observing the web contents.
  subscription_.reset();
  if (web_contents()) {
    web_contents()->DecrementCapturerCount();
    Observe(NULL);
  }
}

void CaptureMachine::Capture(
    const base::Time& start_time,
    const scoped_refptr<media::VideoFrame>& target,
    const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
        deliver_frame_cb) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  RenderWidgetHost* rwh = GetTarget();
  RenderWidgetHostViewPort* view =
      rwh ? RenderWidgetHostViewPort::FromRWHV(rwh->GetView()) : NULL;
  if (!view || !rwh) {
    deliver_frame_cb.Run(base::Time(), false);
    return;
  }

  gfx::Size video_size = target->coded_size();
  gfx::Size view_size = view->GetViewBounds().size();
  gfx::Size fitted_size;
  if (!view_size.IsEmpty()) {
    fitted_size = ComputeYV12LetterboxRegion(video_size, view_size).size();
  }
  if (view_size != last_view_size_) {
    last_view_size_ = view_size;

    // Measure the number of kilopixels.
    UMA_HISTOGRAM_COUNTS_10000(
        "TabCapture.ViewChangeKiloPixels",
        view_size.width() * view_size.height() / 1024);
  }

  if (!view->IsSurfaceAvailableForCopy()) {
    // Fallback to the more expensive renderer-side copy if the surface and
    // backing store are not accessible.
    rwh->GetSnapshotFromRenderer(
        gfx::Rect(),
        base::Bind(&CaptureMachine::DidCopyFromBackingStore, this->AsWeakPtr(),
                   start_time, target, deliver_frame_cb));
  } else if (view->CanCopyToVideoFrame()) {
    view->CopyFromCompositingSurfaceToVideoFrame(
        gfx::Rect(view_size),
        target,
        base::Bind(&CaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame,
                   this->AsWeakPtr(), start_time, deliver_frame_cb));
  } else {
    rwh->CopyFromBackingStore(
        gfx::Rect(),
        fitted_size,  // Size here is a request not always honored.
        base::Bind(&CaptureMachine::DidCopyFromBackingStore, this->AsWeakPtr(),
                   start_time, target, deliver_frame_cb));
  }
}

bool CaptureMachine::StartObservingWebContents(int initial_render_process_id,
                                               int initial_render_view_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // Look-up the RenderViewHost and, from that, the WebContents that wraps it.
  // If successful, begin observing the WebContents instance.
  //
  // Why this can be unsuccessful: The request for mirroring originates in a
  // render process, and this request is based on the current RenderView
  // associated with a tab.  However, by the time we get up-and-running here,
  // there have been multiple back-and-forth IPCs between processes, as well as
  // a bit of indirection across threads.  It's easily possible that, in the
  // meantime, the original RenderView may have gone away.
  RenderViewHost* const rvh =
      RenderViewHost::FromID(initial_render_process_id,
                             initial_render_view_id);
  DVLOG_IF(1, !rvh) << "RenderViewHost::FromID("
                    << initial_render_process_id << ", "
                    << initial_render_view_id << ") returned NULL.";
  Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL);

  WebContentsImpl* contents = static_cast<WebContentsImpl*>(web_contents());
  if (contents) {
    contents->IncrementCapturerCount();
    fullscreen_widget_id_ = contents->GetFullscreenWidgetRoutingID();
    RenewFrameSubscription();
    return true;
  }

  DVLOG(1) << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL.";
  return false;
}

void CaptureMachine::WebContentsDestroyed(WebContents* web_contents) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  subscription_.reset();
  web_contents->DecrementCapturerCount();
  oracle_proxy_->ReportError();
}

RenderWidgetHost* CaptureMachine::GetTarget() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!web_contents())
    return NULL;

  RenderWidgetHost* rwh = NULL;
  if (fullscreen_widget_id_ != MSG_ROUTING_NONE) {
    RenderProcessHost* process = web_contents()->GetRenderProcessHost();
    if (process)
      rwh = RenderWidgetHost::FromID(process->GetID(), fullscreen_widget_id_);
  } else {
    rwh = web_contents()->GetRenderViewHost();
  }

  return rwh;
}

void CaptureMachine::DidCopyFromBackingStore(
    const base::Time& start_time,
    const scoped_refptr<media::VideoFrame>& target,
    const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
        deliver_frame_cb,
    bool success,
    const SkBitmap& bitmap) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  base::Time now = base::Time::Now();
  if (success) {
    UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeBitmap", now - start_time);
    TRACE_EVENT_ASYNC_STEP_INTO0("mirroring", "Capture", target.get(),
                                 "Render");
    render_task_runner_->PostTask(FROM_HERE, base::Bind(
        &RenderVideoFrame, bitmap, target,
        base::Bind(deliver_frame_cb, start_time)));
  } else {
    // Capture can fail due to transient issues, so just skip this frame.
    DVLOG(1) << "CopyFromBackingStore failed; skipping frame.";
    deliver_frame_cb.Run(start_time, false);
  }
}

void CaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame(
    const base::Time& start_time,
    const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
        deliver_frame_cb,
    bool success) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  base::Time now = base::Time::Now();

  if (success) {
    UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeVideoFrame", now - start_time);
  } else {
    // Capture can fail due to transient issues, so just skip this frame.
    DVLOG(1) << "CopyFromCompositingSurface failed; skipping frame.";
  }
  deliver_frame_cb.Run(start_time, success);
}

void CaptureMachine::RenewFrameSubscription() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // Always destroy the old subscription before creating a new one.
  subscription_.reset();

  RenderWidgetHost* rwh = GetTarget();
  if (!rwh || !rwh->GetView())
    return;

  subscription_.reset(new ContentCaptureSubscription(*rwh, oracle_proxy_,
      base::Bind(&CaptureMachine::Capture, this->AsWeakPtr())));
}

void DeleteCaptureMachineOnUIThread(
    scoped_ptr<CaptureMachine> capture_machine) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  capture_machine.reset();
}

}  // namespace

// The "meat" of the video capture implementation, which is a ref-counted class.
// Separating this from the "shell class" WebContentsVideoCaptureDevice allows
// safe destruction without needing to block any threads (e.g., the IO
// BrowserThread).
//
// WebContentsVideoCaptureDevice::Impl manages a simple state machine and the
// pipeline (see notes at top of this file).  It times the start of successive
// captures and facilitates the processing of each through the stages of the
// pipeline.
class WebContentsVideoCaptureDevice::Impl : public base::SupportsWeakPtr<Impl> {
 public:

  Impl(int render_process_id, int render_view_id);
  virtual ~Impl();

  // Asynchronous requests to change WebContentsVideoCaptureDevice::Impl state.
  void AllocateAndStart(int width,
                        int height,
                        int frame_rate,
                        scoped_ptr<media::VideoCaptureDevice::Client> client);
  void StopAndDeAllocate();

 private:

  // Flag indicating current state.
  enum State {
    kIdle,
    kCapturing,
    kError
  };

  void TransitionStateTo(State next_state);

  // Stops capturing and notifies client_ of an error state.
  void Error();

  // Called in response to CaptureMachine::Create that runs on the UI thread.
  // It will assign the capture machine to the Impl class if it still exists
  // otherwise it will post a task to delete CaptureMachine on the UI thread.
  static void AssignCaptureMachine(
      base::WeakPtr<WebContentsVideoCaptureDevice::Impl> impl,
      scoped_ptr<CaptureMachine> capture_machine);

  // Tracks that all activity occurs on the media stream manager's thread.
  base::ThreadChecker thread_checker_;

  // These values identify the starting view that will be captured. After
  // capture starts, the target view IDs will change as navigation occurs, and
  // so these values are not relevant after the initial bootstrapping.
  const int initial_render_process_id_;
  const int initial_render_view_id_;

  // Current lifecycle state.
  State state_;

  // A dedicated worker thread for doing image operations. Started/joined here,
  // but used by the CaptureMachine.
  base::Thread render_thread_;

  // Tracks the CaptureMachine that's doing work on our behalf on the UI thread.
  // This value should never be dereferenced by this class, other than to
  // create and destroy it on the UI thread.
  scoped_ptr<CaptureMachine> capture_machine_;

  // Our thread-safe capture oracle which serves as the gateway to the video
  // capture pipeline. Besides the WCVCD itself, it is the only component of the
  // system with direct access to |client_|.
  scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;

  DISALLOW_COPY_AND_ASSIGN(Impl);
};

WebContentsVideoCaptureDevice::Impl::Impl(int render_process_id,
                                          int render_view_id)
    : initial_render_process_id_(render_process_id),
      initial_render_view_id_(render_view_id),
      state_(kIdle),
      render_thread_("WebContentsVideo_RenderThread") {}

void WebContentsVideoCaptureDevice::Impl::AllocateAndStart(
    int width,
    int height,
    int frame_rate,
    scoped_ptr<VideoCaptureDevice::Client> client) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (state_ != kIdle) {
    DVLOG(1) << "Allocate() invoked when not in state Idle.";
    return;
  }

  if (frame_rate <= 0) {
    DVLOG(1) << "invalid frame_rate: " << frame_rate;
    client->OnError();
    return;
  }

  if (!render_thread_.Start()) {
    DVLOG(1) << "Failed to spawn render thread.";
    client->OnError();
    return;
  }

  // Frame dimensions must each be a positive, even integer, since the client
  // wants (or will convert to) YUV420.
  width = MakeEven(width);
  height = MakeEven(height);
  if (width < kMinFrameWidth || height < kMinFrameHeight) {
    DVLOG(1) << "invalid width (" << width << ") and/or height ("
             << height << ")";
    client->OnError();
    return;
  }

  // Need to call OnFrameInfo just to set the frame rate.
  // TODO(nick): http://crbug.com/309907 The other parameters of this struct are
  // ignored. Come up with a better way to communicate the frame rate.
  media::VideoCaptureCapability settings;
  settings.frame_rate = frame_rate;
  client->OnFrameInfo(settings);

  base::TimeDelta capture_period = base::TimeDelta::FromMicroseconds(
      1000000.0 / frame_rate + 0.5);

  scoped_ptr<VideoCaptureOracle> oracle(
      new VideoCaptureOracle(capture_period,
                             kAcceleratedSubscriberIsSupported));
  oracle_proxy_ = new ThreadSafeCaptureOracle(
      client.Pass(), oracle.Pass(), gfx::Size(width, height));

  // Allocates the CaptureMachine. The CaptureMachine will be tracking render
  // view swapping over its lifetime, and we don't want to lose our reference to
  // the current render view by starting over with the stale
  // |initial_render_view_id_|.
  DCHECK(!capture_machine_.get());
  BrowserThread::PostTaskAndReplyWithResult(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&CaptureMachine::Create,
                 initial_render_process_id_,
                 initial_render_view_id_,
                 render_thread_.message_loop_proxy(), oracle_proxy_),
      base::Bind(&Impl::AssignCaptureMachine, AsWeakPtr()));

  TransitionStateTo(kCapturing);
}

// static
void WebContentsVideoCaptureDevice::Impl::AssignCaptureMachine(
    base::WeakPtr<WebContentsVideoCaptureDevice::Impl> impl,
    scoped_ptr<CaptureMachine> capture_machine) {
  DCHECK(!impl.get() || impl->thread_checker_.CalledOnValidThread());

  if (!impl.get()) {
    // If WCVD::Impl was destroyed before we got back on it's thread and
    // capture_machine is not NULL, then we need to return to the UI thread to
    // safely cleanup the CaptureMachine.
    if (capture_machine) {
      BrowserThread::PostTask(
          BrowserThread::UI, FROM_HERE, base::Bind(
              &DeleteCaptureMachineOnUIThread, base::Passed(&capture_machine)));
      return;
    }
  } else if (!capture_machine) {
    impl->Error();
  } else {
    impl->capture_machine_ = capture_machine.Pass();
  }
}

void WebContentsVideoCaptureDevice::Impl::StopAndDeAllocate() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (state_ != kCapturing) {
    return;
  }
  oracle_proxy_->Stop();
  oracle_proxy_ = NULL;
  render_thread_.Stop();

  TransitionStateTo(kIdle);

  // There is still a capture pipeline running that is checking in with the
  // oracle, and processing captures that are already started in flight. That
  // pipeline must be shut down asynchronously, on the UI thread.
  if (capture_machine_) {
    // The task that is posted to the UI thread might not run if we are shutting
    // down, so we transfer ownership of CaptureMachine to the closure so that
    // it is still cleaned up when the closure is deleted.
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE, base::Bind(
            &DeleteCaptureMachineOnUIThread, base::Passed(&capture_machine_)));
  }
}

WebContentsVideoCaptureDevice::Impl::~Impl() {
  DCHECK(!capture_machine_) << "Cleanup on UI thread did not happen.";
  DVLOG(1) << "WebContentsVideoCaptureDevice::Impl@" << this << " destroying.";
}

void WebContentsVideoCaptureDevice::Impl::TransitionStateTo(State next_state) {
  DCHECK(thread_checker_.CalledOnValidThread());

#ifndef NDEBUG
  static const char* kStateNames[] = {
    "Idle", "Allocated", "Capturing", "Error"
  };
  DVLOG(1) << "State change: " << kStateNames[state_]
           << " --> " << kStateNames[next_state];
#endif

  state_ = next_state;
}

void WebContentsVideoCaptureDevice::Impl::Error() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (state_ == kIdle)
    return;

  if (oracle_proxy_)
    oracle_proxy_->ReportError();

  StopAndDeAllocate();
  TransitionStateTo(kError);
}

WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice(
    int render_process_id,
    int render_view_id)
    : impl_(new WebContentsVideoCaptureDevice::Impl(render_process_id,
                                                    render_view_id)) {}

WebContentsVideoCaptureDevice::~WebContentsVideoCaptureDevice() {
  DVLOG(2) << "WebContentsVideoCaptureDevice@" << this << " destroying.";
}

// static
media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create(
    const std::string& device_id) {
  // Parse device_id into render_process_id and render_view_id.
  int render_process_id = -1;
  int render_view_id = -1;
  if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
           device_id, &render_process_id, &render_view_id)) {
    return NULL;
  }

  return new WebContentsVideoCaptureDevice(render_process_id, render_view_id);
}

void WebContentsVideoCaptureDevice::AllocateAndStart(
    const media::VideoCaptureCapability& capture_format,
    scoped_ptr<Client> client) {
  DVLOG(1) << "Allocating " << capture_format.width << "x"
           << capture_format.height;
  impl_->AllocateAndStart(capture_format.width,
                          capture_format.height,
                          capture_format.frame_rate,
                          client.Pass());
}

void WebContentsVideoCaptureDevice::StopAndDeAllocate() {
  impl_->StopAndDeAllocate();
}

}  // namespace content
