// Copyright 2016 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 "chrome/gpu/arc_gpu_video_decode_accelerator.h"

#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/run_loop.h"
#include "media/base/video_frame.h"
#include "media/gpu/gpu_video_decode_accelerator_factory.h"

namespace chromeos {
namespace arc {

namespace {

// An arbitrary chosen limit of the number of buffers. The number of
// buffers used is requested from the untrusted client side.
const size_t kMaxBufferCount = 128;

// Maximum number of concurrent ARC video clients.
// Currently we have no way to know the resources are not enough to create more
// VDA. Arbitrarily chosen a reasonable constant as the limit.
const int kMaxConcurrentClients = 8;

}  // anonymous namespace

int ArcGpuVideoDecodeAccelerator::client_count_ = 0;

ArcGpuVideoDecodeAccelerator::InputRecord::InputRecord(
    int32_t bitstream_buffer_id,
    uint32_t buffer_index,
    int64_t timestamp)
    : bitstream_buffer_id(bitstream_buffer_id),
      buffer_index(buffer_index),
      timestamp(timestamp) {}

ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() = default;

ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo(
    InputBufferInfo&& other) = default;

ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() = default;

ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo() = default;

ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo(
    OutputBufferInfo&& other) = default;

ArcGpuVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() = default;

ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator(
    const gpu::GpuPreferences& gpu_preferences)
    : arc_client_(nullptr),
      next_bitstream_buffer_id_(0),
      output_pixel_format_(media::PIXEL_FORMAT_UNKNOWN),
      output_buffer_size_(0),
      requested_num_of_output_buffers_(0),
      gpu_preferences_(gpu_preferences) {}

ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (vda_) {
    client_count_--;
  }
}

ArcVideoAccelerator::Result ArcGpuVideoDecodeAccelerator::Initialize(
    const Config& config,
    ArcVideoAccelerator::Client* client) {
  DVLOG(5) << "Initialize(device=" << config.device_type
           << ", input_pixel_format=" << config.input_pixel_format
           << ", num_input_buffers=" << config.num_input_buffers << ")";
  DCHECK(thread_checker_.CalledOnValidThread());
  if (config.device_type != Config::DEVICE_DECODER)
    return INVALID_ARGUMENT;
  DCHECK(client);

  if (arc_client_) {
    DLOG(ERROR) << "Re-Initialize() is not allowed";
    return ILLEGAL_STATE;
  }

  if (client_count_ >= kMaxConcurrentClients) {
    LOG(WARNING) << "Reject to Initialize() due to too many clients: "
                 << client_count_;
    return INSUFFICIENT_RESOURCES;
  }

  arc_client_ = client;

  if (config.num_input_buffers > kMaxBufferCount) {
    DLOG(ERROR) << "Request too many buffers: " << config.num_input_buffers;
    return INVALID_ARGUMENT;
  }
  input_buffer_info_.resize(config.num_input_buffers);

  media::VideoDecodeAccelerator::Config vda_config;
  switch (config.input_pixel_format) {
    case HAL_PIXEL_FORMAT_H264:
      vda_config.profile = media::H264PROFILE_MAIN;
      break;
    case HAL_PIXEL_FORMAT_VP8:
      vda_config.profile = media::VP8PROFILE_ANY;
      break;
    case HAL_PIXEL_FORMAT_VP9:
      vda_config.profile = media::VP9PROFILE_PROFILE0;
      break;
    default:
      DLOG(ERROR) << "Unsupported input format: " << config.input_pixel_format;
      return INVALID_ARGUMENT;
  }
  vda_config.output_mode =
      media::VideoDecodeAccelerator::Config::OutputMode::IMPORT;

  auto vda_factory = media::GpuVideoDecodeAcceleratorFactory::CreateWithNoGL();
  vda_ = vda_factory->CreateVDA(
      this, vda_config, gpu::GpuDriverBugWorkarounds(), gpu_preferences_);
  if (!vda_) {
    DLOG(ERROR) << "Failed to create VDA.";
    return PLATFORM_FAILURE;
  }

  client_count_++;
  DVLOG(5) << "Number of concurrent ArcVideoAccelerator clients: "
           << client_count_;

  return SUCCESS;
}

void ArcGpuVideoDecodeAccelerator::SetNumberOfOutputBuffers(size_t number) {
  DVLOG(5) << "SetNumberOfOutputBuffers(" << number << ")";
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!vda_) {
    DLOG(ERROR) << "VDA not initialized";
    return;
  }

  if (number > kMaxBufferCount) {
    DLOG(ERROR) << "Too many buffers: " << number;
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }

  std::vector<media::PictureBuffer> buffers;
  for (size_t id = 0; id < number; ++id) {
    // TODO(owenlin): Make sure the |coded_size| is what we want.
    buffers.push_back(
        media::PictureBuffer(base::checked_cast<int32_t>(id), coded_size_));
  }
  vda_->AssignPictureBuffers(buffers);

  buffers_pending_import_.clear();
  buffers_pending_import_.resize(number);
}

void ArcGpuVideoDecodeAccelerator::BindSharedMemory(PortType port,
                                                    uint32_t index,
                                                    base::ScopedFD ashmem_fd,
                                                    off_t offset,
                                                    size_t length) {
  DVLOG(5) << "ArcGVDA::BindSharedMemory, offset: " << offset
           << ", length: " << length;
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!vda_) {
    DLOG(ERROR) << "VDA not initialized";
    return;
  }

  if (port != PORT_INPUT) {
    DLOG(ERROR) << "SharedBuffer is only supported for input";
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }
  if (!ValidatePortAndIndex(port, index)) {
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }
  InputBufferInfo* input_info = &input_buffer_info_[index];
  input_info->handle = std::move(ashmem_fd);
  input_info->offset = offset;
  input_info->length = length;
}

bool ArcGpuVideoDecodeAccelerator::VerifyDmabuf(
    const base::ScopedFD& dmabuf_fd,
    const std::vector<DmabufPlane>& dmabuf_planes) const {
  size_t num_planes = media::VideoFrame::NumPlanes(output_pixel_format_);
  if (dmabuf_planes.size() != num_planes) {
    DLOG(ERROR) << "Invalid number of dmabuf planes passed: "
                << dmabuf_planes.size() << ", expected: " << num_planes;
    return false;
  }

  off_t size = lseek(dmabuf_fd.get(), 0, SEEK_END);
  lseek(dmabuf_fd.get(), 0, SEEK_SET);
  if (size < 0) {
    DPLOG(ERROR) << "fail to find the size of dmabuf";
    return false;
  }

  size_t i = 0;
  for (const auto& plane : dmabuf_planes) {
    DVLOG(4) << "Plane " << i << ", offset: " << plane.offset
             << ", stride: " << plane.stride;

    size_t rows =
        media::VideoFrame::Rows(i, output_pixel_format_, coded_size_.height());
    base::CheckedNumeric<off_t> current_size(plane.offset);
    current_size += plane.stride * rows;

    if (!current_size.IsValid() || current_size.ValueOrDie() > size) {
      DLOG(ERROR) << "Invalid strides/offsets";
      return false;
    }

    ++i;
  }

  return true;
}

void ArcGpuVideoDecodeAccelerator::BindDmabuf(
    PortType port,
    uint32_t index,
    base::ScopedFD dmabuf_fd,
    const std::vector<DmabufPlane>& dmabuf_planes) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (!vda_) {
    DLOG(ERROR) << "VDA not initialized";
    return;
  }

  if (port != PORT_OUTPUT) {
    DLOG(ERROR) << "Dmabuf is only supported for input";
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }
  if (!ValidatePortAndIndex(port, index)) {
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }
  if (!VerifyDmabuf(dmabuf_fd, dmabuf_planes)) {
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }

  OutputBufferInfo& info = buffers_pending_import_[index];
  info.handle = std::move(dmabuf_fd);
  info.planes = dmabuf_planes;
}

void ArcGpuVideoDecodeAccelerator::UseBuffer(PortType port,
                                             uint32_t index,
                                             const BufferMetadata& metadata) {
  DVLOG(5) << "UseBuffer(port=" << port << ", index=" << index
           << ", metadata=(bytes_used=" << metadata.bytes_used
           << ", timestamp=" << metadata.timestamp << ")";
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!vda_) {
    DLOG(ERROR) << "VDA not initialized";
    return;
  }
  if (!ValidatePortAndIndex(port, index)) {
    arc_client_->OnError(INVALID_ARGUMENT);
    return;
  }
  switch (port) {
    case PORT_INPUT: {
      InputBufferInfo* input_info = &input_buffer_info_[index];
      int32_t bitstream_buffer_id = next_bitstream_buffer_id_;
      // Mask against 30 bits, to avoid (undefined) wraparound on signed
      // integer.
      next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
      int dup_fd = HANDLE_EINTR(dup(input_info->handle.get()));
      if (dup_fd < 0) {
        DLOG(ERROR) << "dup() failed.";
        arc_client_->OnError(PLATFORM_FAILURE);
        return;
      }
      CreateInputRecord(bitstream_buffer_id, index, metadata.timestamp);
      vda_->Decode(media::BitstreamBuffer(
          bitstream_buffer_id, base::SharedMemoryHandle(dup_fd, true),
          metadata.bytes_used, input_info->offset));
      break;
    }
    case PORT_OUTPUT: {
      // is_valid() is true for the first time the buffer is passed to the VDA.
      // In that case, VDA needs to import the buffer first.
      OutputBufferInfo& info = buffers_pending_import_[index];
      if (info.handle.is_valid()) {
        gfx::GpuMemoryBufferHandle handle;
#if defined(USE_OZONE)
        handle.native_pixmap_handle.fds.emplace_back(
            base::FileDescriptor(info.handle.release(), true));
        for (const auto& plane : info.planes) {
          handle.native_pixmap_handle.planes.emplace_back(plane.stride,
                                                          plane.offset, 0, 0);
        }
#endif
        vda_->ImportBufferForPicture(index, handle);
      } else {
        vda_->ReusePictureBuffer(index);
      }
      break;
    }
    default:
      NOTREACHED();
  }
}

void ArcGpuVideoDecodeAccelerator::Reset() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!vda_) {
    DLOG(ERROR) << "VDA not initialized";
    return;
  }
  vda_->Reset();
}

void ArcGpuVideoDecodeAccelerator::Flush() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!vda_) {
    DLOG(ERROR) << "VDA not initialized";
    return;
  }
  vda_->Flush();
}

void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers(
    uint32_t requested_num_of_buffers,
    media::VideoPixelFormat output_pixel_format,
    uint32_t textures_per_buffer,
    const gfx::Size& dimensions,
    uint32_t texture_target) {
  DVLOG(5) << "ProvidePictureBuffers("
           << "requested_num_of_buffers=" << requested_num_of_buffers
           << ", dimensions=" << dimensions.ToString() << ")";
  DCHECK(thread_checker_.CalledOnValidThread());
  coded_size_ = dimensions;

  // By default, use an empty rect to indicate the visible rectangle is not
  // available.
  visible_rect_ = gfx::Rect();
  if ((output_pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) &&
      (output_pixel_format_ != output_pixel_format)) {
    arc_client_->OnError(PLATFORM_FAILURE);
    return;
  }
  output_pixel_format_ = output_pixel_format;
  requested_num_of_output_buffers_ = requested_num_of_buffers;
  output_buffer_size_ =
      media::VideoFrame::AllocationSize(output_pixel_format_, coded_size_);

  NotifyOutputFormatChanged();
}

void ArcGpuVideoDecodeAccelerator::NotifyOutputFormatChanged() {
  VideoFormat video_format;
  switch (output_pixel_format_) {
    case media::PIXEL_FORMAT_I420:
    case media::PIXEL_FORMAT_YV12:
    case media::PIXEL_FORMAT_NV12:
    case media::PIXEL_FORMAT_NV21:
      // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android
      // which handles all 420 formats, with both orderings of chroma (CbCr and
      // CrCb) as well as planar and semi-planar layouts.
      video_format.pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
      break;
    case media::PIXEL_FORMAT_ARGB:
      video_format.pixel_format = HAL_PIXEL_FORMAT_BGRA_8888;
      break;
    default:
      DLOG(ERROR) << "Format not supported: " << output_pixel_format_;
      arc_client_->OnError(PLATFORM_FAILURE);
      return;
  }
  video_format.buffer_size = output_buffer_size_;
  video_format.min_num_buffers = requested_num_of_output_buffers_;
  video_format.coded_width = coded_size_.width();
  video_format.coded_height = coded_size_.height();
  video_format.crop_top = visible_rect_.y();
  video_format.crop_left = visible_rect_.x();
  video_format.crop_width = visible_rect_.width();
  video_format.crop_height = visible_rect_.height();
  arc_client_->OnOutputFormatChanged(video_format);
}

void ArcGpuVideoDecodeAccelerator::DismissPictureBuffer(
    int32_t picture_buffer) {
  // no-op
}

void ArcGpuVideoDecodeAccelerator::PictureReady(const media::Picture& picture) {
  DVLOG(5) << "PictureReady(picture_buffer_id=" << picture.picture_buffer_id()
           << ", bitstream_buffer_id=" << picture.bitstream_buffer_id();
  DCHECK(thread_checker_.CalledOnValidThread());

  // Handle visible size change.
  if (visible_rect_ != picture.visible_rect()) {
    DVLOG(5) << "visible size changed: " << picture.visible_rect().ToString();
    visible_rect_ = picture.visible_rect();
    NotifyOutputFormatChanged();
  }

  InputRecord* input_record = FindInputRecord(picture.bitstream_buffer_id());
  if (input_record == nullptr) {
    DLOG(ERROR) << "Cannot find for bitstream buffer id: "
                << picture.bitstream_buffer_id();
    arc_client_->OnError(PLATFORM_FAILURE);
    return;
  }

  BufferMetadata metadata;
  metadata.timestamp = input_record->timestamp;
  metadata.bytes_used = output_buffer_size_;
  arc_client_->OnBufferDone(PORT_OUTPUT, picture.picture_buffer_id(), metadata);
}

void ArcGpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
    int32_t bitstream_buffer_id) {
  DVLOG(5) << "NotifyEndOfBitstreamBuffer(" << bitstream_buffer_id << ")";
  DCHECK(thread_checker_.CalledOnValidThread());
  InputRecord* input_record = FindInputRecord(bitstream_buffer_id);
  if (input_record == nullptr) {
    arc_client_->OnError(PLATFORM_FAILURE);
    return;
  }
  arc_client_->OnBufferDone(PORT_INPUT, input_record->buffer_index,
                            BufferMetadata());
}

void ArcGpuVideoDecodeAccelerator::NotifyFlushDone() {
  DCHECK(thread_checker_.CalledOnValidThread());
  arc_client_->OnFlushDone();
}

void ArcGpuVideoDecodeAccelerator::NotifyResetDone() {
  DCHECK(thread_checker_.CalledOnValidThread());
  arc_client_->OnResetDone();
}

static ArcVideoAccelerator::Result ConvertErrorCode(
    media::VideoDecodeAccelerator::Error error) {
  switch (error) {
    case media::VideoDecodeAccelerator::ILLEGAL_STATE:
      return ArcVideoAccelerator::ILLEGAL_STATE;
    case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
      return ArcVideoAccelerator::INVALID_ARGUMENT;
    case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
      return ArcVideoAccelerator::UNREADABLE_INPUT;
    case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
      return ArcVideoAccelerator::PLATFORM_FAILURE;
    default:
      DLOG(ERROR) << "Unknown error: " << error;
      return ArcVideoAccelerator::PLATFORM_FAILURE;
  }
}

void ArcGpuVideoDecodeAccelerator::NotifyError(
    media::VideoDecodeAccelerator::Error error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DLOG(ERROR) << "Error notified: " << error;
  arc_client_->OnError(ConvertErrorCode(error));
}

void ArcGpuVideoDecodeAccelerator::CreateInputRecord(
    int32_t bitstream_buffer_id,
    uint32_t buffer_index,
    int64_t timestamp) {
  input_records_.push_front(
      InputRecord(bitstream_buffer_id, buffer_index, timestamp));

  // The same value copied from media::GpuVideoDecoder. The input record is
  // needed when the input buffer or the corresponding output buffer are
  // returned from VDA. However there is no guarantee how much buffers will be
  // kept in the VDA. We kept the last |kMaxNumberOfInputRecords| in
  // |input_records_| and drop the others.
  const size_t kMaxNumberOfInputRecords = 128;
  if (input_records_.size() > kMaxNumberOfInputRecords)
    input_records_.pop_back();
}

ArcGpuVideoDecodeAccelerator::InputRecord*
ArcGpuVideoDecodeAccelerator::FindInputRecord(int32_t bitstream_buffer_id) {
  for (auto& record : input_records_) {
    if (record.bitstream_buffer_id == bitstream_buffer_id)
      return &record;
  }
  return nullptr;
}

bool ArcGpuVideoDecodeAccelerator::ValidatePortAndIndex(PortType port,
                                                        uint32_t index) const {
  switch (port) {
    case PORT_INPUT:
      if (index >= input_buffer_info_.size()) {
        DLOG(ERROR) << "Invalid index: " << index;
        return false;
      }
      return true;
    case PORT_OUTPUT:
      if (index >= buffers_pending_import_.size()) {
        DLOG(ERROR) << "Invalid index: " << index;
        return false;
      }
      return true;
    default:
      DLOG(ERROR) << "Invalid port: " << port;
      return false;
  }
}

}  // namespace arc
}  // namespace chromeos
