// Copyright 2014 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 "media/capture/content/android/thread_safe_capture_oracle.h"

#include <stdint.h>

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bits.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_metadata.h"
#include "media/base/video_util.h"
#include "media/capture/video_capture_types.h"
#include "ui/gfx/geometry/rect.h"

namespace media {

namespace {

// The target maximum amount of the buffer pool to utilize.  Actual buffer pool
// utilization is attenuated by this amount before being reported to the
// VideoCaptureOracle.  This value takes into account the maximum number of
// buffer pool buffers and a desired safety margin.
const int kTargetMaxPoolUtilizationPercent = 60;

}  // namespace

struct ThreadSafeCaptureOracle::InFlightFrameCapture {
  int frame_number;
  VideoCaptureDevice::Client::Buffer buffer;
  std::unique_ptr<VideoCaptureBufferHandle> buffer_access;
  base::TimeTicks begin_time;
  base::TimeDelta frame_duration;
};

ThreadSafeCaptureOracle::ThreadSafeCaptureOracle(
    std::unique_ptr<VideoCaptureDevice::Client> client,
    const VideoCaptureParams& params)
    : client_(std::move(client)), oracle_(false), params_(params) {
  DCHECK_GE(params.requested_format.frame_rate, 1e-6f);
  oracle_.SetMinCapturePeriod(base::Microseconds(
      static_cast<int64_t>(1000000.0 / params.requested_format.frame_rate +
                           0.5 /* to round to nearest int */)));
  const auto constraints = params.SuggestConstraints();
  oracle_.SetCaptureSizeConstraints(constraints.min_frame_size,
                                    constraints.max_frame_size,
                                    constraints.fixed_aspect_ratio);
}

ThreadSafeCaptureOracle::~ThreadSafeCaptureOracle() = default;

bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
    VideoCaptureOracle::Event event,
    const gfx::Rect& damage_rect,
    base::TimeTicks event_time,
    scoped_refptr<VideoFrame>* storage,
    CaptureFrameCallback* callback) {
  // Grab the current time before waiting to acquire the |lock_|.
  const base::TimeTicks capture_begin_time = base::TimeTicks::Now();

  gfx::Size visible_size;
  gfx::Size coded_size;
  media::VideoCaptureDevice::Client::Buffer output_buffer;
  double attenuated_utilization;
  int frame_number;
  base::TimeDelta estimated_frame_duration;
  {
    base::AutoLock guard(lock_);

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

    if (!oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) {
      // 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("gpu.capture", "FpsRateLimited",
                           TRACE_EVENT_SCOPE_THREAD, "trigger",
                           VideoCaptureOracle::EventAsString(event));
      return false;
    }

    frame_number = oracle_.next_frame_number();
    visible_size = oracle_.capture_size();
    // TODO(miu): Clients should request exact padding, instead of this
    // memory-wasting hack to make frames that are compatible with all HW
    // encoders.  http://crbug.com/555911
    coded_size.SetSize(base::bits::AlignUp(visible_size.width(), 16),
                       base::bits::AlignUp(visible_size.height(), 16));

    const auto result_code = client_->ReserveOutputBuffer(
        coded_size, params_.requested_format.pixel_format, frame_number,
        &output_buffer);

    // Get the current buffer pool utilization and attenuate it: The utilization
    // reported to the oracle is in terms of a maximum sustainable amount (not
    // the absolute maximum).
    attenuated_utilization = client_->GetBufferPoolUtilization() *
                             (100.0 / kTargetMaxPoolUtilizationPercent);

    if (result_code != VideoCaptureDevice::Client::ReserveResult::kSucceeded) {
      TRACE_EVENT_INSTANT2(
          "gpu.capture", "PipelineLimited", TRACE_EVENT_SCOPE_THREAD, "trigger",
          VideoCaptureOracle::EventAsString(event), "atten_util_percent",
          base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5));
      oracle_.RecordWillNotCapture(attenuated_utilization);
      return false;
    }

    oracle_.RecordCapture(attenuated_utilization);
    estimated_frame_duration = oracle_.estimated_frame_duration();
  }  // End of critical section.

  if (attenuated_utilization >= 1.0) {
    TRACE_EVENT_INSTANT2(
        "gpu.capture", "NearlyPipelineLimited", TRACE_EVENT_SCOPE_THREAD,
        "trigger", VideoCaptureOracle::EventAsString(event),
        "atten_util_percent",
        base::saturated_cast<int>(attenuated_utilization * 100.0 + 0.5));
  }

  TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
      "gpu.capture", "Capture",
      TRACE_ID_WITH_SCOPE("Capture", output_buffer.id), "frame_number",
      frame_number, "trigger", VideoCaptureOracle::EventAsString(event));

  std::unique_ptr<VideoCaptureBufferHandle> output_buffer_access =
      output_buffer.handle_provider->GetHandleForInProcessAccess();
  *storage = VideoFrame::WrapExternalData(
      params_.requested_format.pixel_format, coded_size,
      gfx::Rect(visible_size), visible_size, output_buffer_access->data(),
      output_buffer_access->mapped_size(), base::TimeDelta());

  // Note: Passing the |output_buffer_access| in the callback is a bit of a
  // hack. Really, the access should be owned by the VideoFrame so that access
  // is released (unpinning the shared memory) when the VideoFrame goes
  // out-of-scope. However, there is an an issue where, at browser shutdown, the
  // callback below may never be run, and instead it self-deletes: If this
  // happens, the VideoFrame will release access *after* the Buffer goes
  // out-of-scope, which is an invalid sequence of steps. This could be fixed in
  // upstream implementation, but it's not worth spending time tracking it down
  // because all of this code (and upstream code) is about to be replaced.
  // http://crbug.com/754872
  //
  // To be clear, this solution allows |output_buffer_access| to be deleted
  // before |output_buffer| if the callback self-deletes rather than ever being
  // run. The InFlightFrameCapture destructor ensures this.
  std::unique_ptr<InFlightFrameCapture> capture(new InFlightFrameCapture{
      frame_number, std::move(output_buffer), std::move(output_buffer_access),
      capture_begin_time, estimated_frame_duration});

  // If creating the VideoFrame wrapper failed, call DidCaptureFrame() with
  // !success to execute the required post-capture steps (tracing, notification
  // of failure to VideoCaptureOracle, etc.).
  if (!(*storage)) {
    DidCaptureFrame(std::move(capture), *storage, event_time, false);
    return false;
  }

  *callback = base::BindOnce(&ThreadSafeCaptureOracle::DidCaptureFrame, this,
                             std::move(capture));

  return true;
}

gfx::Size ThreadSafeCaptureOracle::GetCaptureSize() const {
  base::AutoLock guard(lock_);
  return oracle_.capture_size();
}

void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) {
  base::AutoLock guard(lock_);
  VLOG(1) << "Source size changed to " << source_size.ToString();
  oracle_.SetSourceSize(source_size);
}

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

void ThreadSafeCaptureOracle::ReportError(media::VideoCaptureError error,
                                          const base::Location& from_here,
                                          const std::string& reason) {
  base::AutoLock guard(lock_);
  if (client_)
    client_->OnError(error, from_here, reason);
}

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

void ThreadSafeCaptureOracle::DidCaptureFrame(
    std::unique_ptr<InFlightFrameCapture> capture,
    scoped_refptr<VideoFrame> frame,
    base::TimeTicks reference_time,
    bool success) {
  // Release |buffer_access| now that nothing is accessing the memory via the
  // VideoFrame data pointers anymore.
  capture->buffer_access.reset();

  base::AutoLock guard(lock_);

  const bool should_deliver_frame =
      oracle_.CompleteCapture(capture->frame_number, success, &reference_time);

  TRACE_EVENT_NESTABLE_ASYNC_END2(
      "gpu.capture", "Capture",
      TRACE_ID_WITH_SCOPE("Capture", capture->buffer.id), "success",
      should_deliver_frame, "timestamp",
      (reference_time - base::TimeTicks()).InMicroseconds());

  if (!should_deliver_frame || !client_)
    return;

  frame->metadata().frame_rate = params_.requested_format.frame_rate;
  frame->metadata().capture_begin_time = capture->begin_time;
  frame->metadata().capture_end_time = base::TimeTicks::Now();
  frame->metadata().frame_duration = capture->frame_duration;
  frame->metadata().reference_time = reference_time;

  media::VideoCaptureFormat format(frame->coded_size(),
                                   params_.requested_format.frame_rate,
                                   frame->format());
  client_->OnIncomingCapturedBufferExt(
      std::move(capture->buffer), format, frame->ColorSpace(), reference_time,
      frame->timestamp(), frame->visible_rect(), frame->metadata());
}

void ThreadSafeCaptureOracle::OnConsumerReportingUtilization(
    int frame_number,
    const media::VideoCaptureFeedback& feedback) {
  base::AutoLock guard(lock_);
  oracle_.RecordConsumerFeedback(frame_number, feedback);
}

}  // namespace media
