// 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/video/fake_video_encode_accelerator.h"

#include "base/bind.h"
#include "base/check.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"

namespace media {

static const unsigned int kMinimumInputCount = 1;

FakeVideoEncodeAccelerator::FrameToEncode::FrameToEncode() = default;
FakeVideoEncodeAccelerator::FrameToEncode::FrameToEncode(
    const FakeVideoEncodeAccelerator::FrameToEncode&) = default;
FakeVideoEncodeAccelerator::FrameToEncode::~FrameToEncode() = default;

FakeVideoEncodeAccelerator::FakeVideoEncodeAccelerator(
    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
    : task_runner_(task_runner),
      will_initialization_succeed_(true),
      client_(nullptr),
      next_frame_is_first_frame_(true) {}

FakeVideoEncodeAccelerator::~FakeVideoEncodeAccelerator() {
  weak_this_factory_.InvalidateWeakPtrs();
}

VideoEncodeAccelerator::SupportedProfiles
FakeVideoEncodeAccelerator::GetSupportedProfiles() {
  SupportedProfiles profiles;
  SupportedProfile profile;
  profile.max_resolution.SetSize(1920, 1088);
  profile.max_framerate_numerator = 30;
  profile.max_framerate_denominator = 1;

  profile.profile = media::H264PROFILE_MAIN;
  profiles.push_back(profile);
  profile.profile = media::VP8PROFILE_ANY;
  profiles.push_back(profile);
  return profiles;
}

bool FakeVideoEncodeAccelerator::Initialize(const Config& config,
                                            Client* client) {
  if (!will_initialization_succeed_) {
    return false;
  }
  if (config.output_profile == VIDEO_CODEC_PROFILE_UNKNOWN ||
      config.output_profile > VIDEO_CODEC_PROFILE_MAX) {
    return false;
  }
  client_ = client;
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers,
                     weak_this_factory_.GetWeakPtr(), kMinimumInputCount,
                     config.input_visible_size, kMinimumOutputBufferSize));
  return true;
}

void FakeVideoEncodeAccelerator::Encode(scoped_refptr<VideoFrame> frame,
                                        bool force_keyframe) {
  DCHECK(client_);
  FrameToEncode encode;
  encode.frame = frame;
  encode.force_keyframe = force_keyframe;
  queued_frames_.push(encode);
  EncodeTask();
}

void FakeVideoEncodeAccelerator::UseOutputBitstreamBuffer(
    BitstreamBuffer buffer) {
  available_buffers_.push_back(std::move(buffer));
  EncodeTask();
}

void FakeVideoEncodeAccelerator::RequestEncodingParametersChange(
    const Bitrate& bitrate,
    uint32_t framerate) {
  // Reject bitrate mode changes.
  if (stored_bitrates_.empty() ||
      stored_bitrates_.back().mode() == bitrate.mode()) {
    stored_bitrates_.push_back(bitrate);
  }
}

void FakeVideoEncodeAccelerator::RequestEncodingParametersChange(
    const VideoBitrateAllocation& bitrate,
    uint32_t framerate) {
  stored_bitrate_allocations_.push_back(bitrate);
}

void FakeVideoEncodeAccelerator::Destroy() {
  delete this;
}

void FakeVideoEncodeAccelerator::SetWillInitializationSucceed(
    bool will_initialization_succeed) {
  will_initialization_succeed_ = will_initialization_succeed;
}

void FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers(
    unsigned int input_count,
    const gfx::Size& input_coded_size,
    size_t output_buffer_size) const {
  client_->RequireBitstreamBuffers(input_count, input_coded_size,
                                   output_buffer_size);
}

void FakeVideoEncodeAccelerator::EncodeTask() {
  while (!queued_frames_.empty() && !available_buffers_.empty()) {
    FrameToEncode frame_to_encode = queued_frames_.front();
    BitstreamBuffer buffer = std::move(available_buffers_.front());
    available_buffers_.pop_front();
    queued_frames_.pop();

    if (next_frame_is_first_frame_) {
      frame_to_encode.force_keyframe = true;
      next_frame_is_first_frame_ = false;
    }

    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
                       weak_this_factory_.GetWeakPtr(), std::move(buffer),
                       frame_to_encode));
  }
}

void FakeVideoEncodeAccelerator::DoBitstreamBufferReady(
    BitstreamBuffer buffer,
    FrameToEncode frame_to_encode) const {
  BitstreamBufferMetadata metadata(kMinimumOutputBufferSize,
                                   frame_to_encode.force_keyframe,
                                   frame_to_encode.frame->timestamp());

  if (!encoding_callback_.is_null())
    metadata = encoding_callback_.Run(buffer, frame_to_encode.force_keyframe,
                                      frame_to_encode.frame);

  client_->BitstreamBufferReady(buffer.id(), metadata);
}

bool FakeVideoEncodeAccelerator::IsGpuFrameResizeSupported() {
  return resize_supported_;
}

}  // namespace media
