/* Copyright 2017 The Chromium OS 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 "hal/usb/frame_buffer.h"

#include <sys/mman.h>

#include <utility>

#include <hardware/gralloc.h>

#include "cros-camera/common.h"
#include "hal/usb/image_processor.h"

namespace cros {

FrameBuffer::FrameBuffer()
    : data_size_(0),
      buffer_size_(0),
      width_(0),
      height_(0),
      fourcc_(0),
      num_planes_(0) {}

FrameBuffer::~FrameBuffer() {}

uint8_t* FrameBuffer::GetData(size_t plane) const {
  if (plane >= num_planes_ || plane >= data_.size()) {
    LOGF(ERROR) << "Invalid plane " << plane;
    return nullptr;
  }
  return data_[plane];
}

size_t FrameBuffer::GetStride(size_t plane) const {
  if (plane >= num_planes_) {
    LOGF(ERROR) << "Invalid plane " << plane;
    return 0;
  }
  return stride_[plane];
}

void FrameBuffer::SetFourcc(uint32_t fourcc) {
  fourcc_ = fourcc;
}

int FrameBuffer::SetDataSize(size_t data_size) {
  if (data_size > buffer_size_) {
    LOGF(ERROR) << "Buffer overflow: Buffer only has " << buffer_size_
                << ", but data needs " << data_size;
    return -EINVAL;
  }
  data_size_ = data_size;
  return 0;
}

// static
bool SharedFrameBuffer::Reallocate(uint32_t width,
                                   uint32_t height,
                                   uint32_t fourcc,
                                   std::unique_ptr<SharedFrameBuffer>* frame) {
  if (!(*frame)) {
    *frame = std::make_unique<SharedFrameBuffer>(0);
  }
  (*frame)->SetFourcc(fourcc);
  (*frame)->SetWidth(width);
  (*frame)->SetHeight(height);
  size_t data_size = ImageProcessor::GetConvertedSize(**frame);
  if (data_size == 0 || (*frame)->SetDataSize(data_size) != 0) {
    LOG(ERROR) << "Set data size failed: " << width << "x" << height << " "
               << FormatToString(fourcc) << ", " << data_size;
    return false;
  }
  return true;
}

SharedFrameBuffer::SharedFrameBuffer(int buffer_size) {
  shm_region_ = base::UnsafeSharedMemoryRegion::Create(buffer_size);
  shm_mapping_ = shm_region_.Map();
  buffer_size_ = buffer_size;
  num_planes_ = 1;
  data_.resize(num_planes_, nullptr);
  data_[0] = shm_mapping_.GetMemoryAs<uint8_t>();
  stride_.resize(num_planes_, 0);
}

SharedFrameBuffer::~SharedFrameBuffer() {}

void SharedFrameBuffer::SetWidth(uint32_t width) {
  width_ = width;
  if (fourcc_ && height_) {
    SetStride();
  }
}

void SharedFrameBuffer::SetHeight(uint32_t height) {
  height_ = height;
  if (fourcc_ && width_) {
    SetStride();
  }
}

void SharedFrameBuffer::SetFourcc(uint32_t fourcc) {
  fourcc_ = fourcc;
  if (width_ && height_) {
    SetStride();
  }
}

int SharedFrameBuffer::SetDataSize(size_t data_size) {
  if (data_size > buffer_size_) {
    shm_region_ = base::UnsafeSharedMemoryRegion::Create(data_size);
    shm_mapping_ = shm_region_.Map();
    if (!shm_mapping_.IsValid()) {
      LOGF(ERROR) << "Created Shared Memory Fail";
      return -ENOMEM;
    }
    buffer_size_ = data_size;
  }
  data_size_ = data_size;
  SetData();
  return 0;
}

void SharedFrameBuffer::SetData() {
  switch (fourcc_) {
    case V4L2_PIX_FMT_YUV420:   // YU12
    case V4L2_PIX_FMT_YUV420M:  // YM12, multiple planes YU12
      if (num_planes_ != 3) {
        LOGF(ERROR) << "Stride is not set correctly";
        return;
      }
      data_.resize(num_planes_, 0);
      data_[YPLANE] = shm_mapping_.GetMemoryAs<uint8_t>();
      data_[UPLANE] = data_[YPLANE] + stride_[YPLANE] * height_;
      data_[VPLANE] = data_[UPLANE] + stride_[UPLANE] * height_ / 2;
      break;
    default:
      data_.resize(num_planes_, 0);
      data_[0] = shm_mapping_.GetMemoryAs<uint8_t>();
      break;
  }
}

void SharedFrameBuffer::SetStride() {
  if (!width_ || !height_ || !fourcc_) {
    LOGF(ERROR) << "Invalid width (" << width_ << ") or height (" << height_
                << ") or fourcc (" << FormatToString(fourcc_) << ")";
    return;
  }
  switch (fourcc_) {
    case V4L2_PIX_FMT_YUV420:   // YU12
    case V4L2_PIX_FMT_YUV420M:  // YM12, multiple planes YU12
      num_planes_ = 3;
      stride_.resize(num_planes_, 0);
      stride_[YPLANE] = width_;
      stride_[UPLANE] = stride_[VPLANE] = width_ / 2;
      break;
    default:
      LOGF(ERROR) << "Pixel format " << FormatToString(fourcc_)
                  << " is unsupported.";
      break;
  }
}

V4L2FrameBuffer::V4L2FrameBuffer(base::ScopedFD fd,
                                 int buffer_size,
                                 uint32_t width,
                                 uint32_t height,
                                 uint32_t fourcc)
    : fd_(std::move(fd)), is_mapped_(false) {
  buffer_size_ = buffer_size;
  width_ = width;
  height_ = height;
  fourcc_ = fourcc;

  switch (fourcc_) {
    case V4L2_PIX_FMT_YUV420:
      num_planes_ = 3;
      break;
    default:
      num_planes_ = 1;
      break;
  }
  data_.resize(num_planes_, nullptr);
  stride_.resize(num_planes_, 0);
}

V4L2FrameBuffer::~V4L2FrameBuffer() {
  if (Unmap()) {
    LOGF(ERROR) << "Unmap failed";
  }
}

int V4L2FrameBuffer::Map() {
  base::AutoLock l(lock_);
  if (is_mapped_)
    return 0;

  // TODO(b/141517606): We should tweak the mapping implementation to:
  //   1. Mapped with PROT_READ | PROT_WRITE (Due to: crbug.com/178582)
  //   2. Support non-zero offset
  void* addr = mmap(NULL, buffer_size_, PROT_READ, MAP_SHARED, fd_.get(), 0);
  if (addr == MAP_FAILED) {
    PLOGF(ERROR) << "mmap() failed";
    return -EINVAL;
  }
  data_[0] = static_cast<uint8_t*>(addr);
  is_mapped_ = true;
  switch (fourcc_) {
    case V4L2_PIX_FMT_Y16:
    case V4L2_PIX_FMT_Z16:
      stride_[0] = width_;
      break;
    case V4L2_PIX_FMT_RGB24:
      stride_[0] = width_ * 3;
      break;
    case V4L2_PIX_FMT_MJPEG:
      stride_[0] = data_size_;
      break;
    case V4L2_PIX_FMT_YUYV:
      stride_[0] = width_ * 2;
      break;
    case V4L2_PIX_FMT_YUV420:
      stride_[0] = width_;
      stride_[1] = (width_ + 1) / 2;
      stride_[2] = (width_ + 1) / 2;
      data_[1] = data_[0] + stride_[0] * height_;
      data_[2] = data_[1] + stride_[1] * (height_ + 1) / 2;
      break;
    default:
      LOGF(WARNING) << "The strides for pixel format "
                    << FormatToString(fourcc_) << " are not given.";
      break;
  }
  return 0;
}

int V4L2FrameBuffer::Unmap() {
  base::AutoLock l(lock_);
  if (!is_mapped_)
    return 0;

  if (munmap(data_[0], buffer_size_)) {
    PLOGF(ERROR) << "mummap() failed";
    return -EINVAL;
  }
  is_mapped_ = false;
  return 0;
}

// static
bool GrallocFrameBuffer::Reallocate(
    uint32_t width,
    uint32_t height,
    uint32_t fourcc,
    std::unique_ptr<GrallocFrameBuffer>* frame) {
  if (!(*frame) || (*frame)->GetWidth() != width ||
      (*frame)->GetHeight() != height || (*frame)->GetFourcc() != fourcc) {
    *frame = std::make_unique<GrallocFrameBuffer>(width, height, fourcc);
  }
  return true;
}

GrallocFrameBuffer::GrallocFrameBuffer(buffer_handle_t buffer,
                                       uint32_t width,
                                       uint32_t height)
    : buffer_(buffer),
      buffer_manager_(CameraBufferManager::GetInstance()),
      is_buffer_owner_(false),
      is_mapped_(false) {
  int ret = buffer_manager_->Register(buffer_);
  if (ret) {
    LOGF(ERROR) << "Failed to register buffer";
    return;
  }
  width_ = width;
  height_ = height;
  fourcc_ = buffer_manager_->GetV4L2PixelFormat(buffer);
  num_planes_ = buffer_manager_->GetNumPlanes(buffer);
  data_.resize(num_planes_, nullptr);
  stride_.resize(num_planes_, 0);
}

GrallocFrameBuffer::GrallocFrameBuffer(uint32_t width,
                                       uint32_t height,
                                       uint32_t fourcc)
    : buffer_(nullptr),
      buffer_manager_(CameraBufferManager::GetInstance()),
      is_buffer_owner_(true),
      is_mapped_(false) {
  if (fourcc != V4L2_PIX_FMT_NV12 && fourcc != V4L2_PIX_FMT_NV12M &&
      fourcc != V4L2_PIX_FMT_YUV420 && fourcc != V4L2_PIX_FMT_YUV420M) {
    LOGF(ERROR) << "Unsupported format: " << FormatToString(fourcc);
    return;
  }
  uint32_t hal_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
  uint32_t hal_usage =
      GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
  if (fourcc == V4L2_PIX_FMT_YUV420 || fourcc == V4L2_PIX_FMT_YUV420M) {
    hal_usage |= GRALLOC_USAGE_FORCE_I420;
  }

  uint32_t stride;
  int ret = buffer_manager_->Allocate(width, height, hal_format, hal_usage,
                                      GRALLOC, &buffer_, &stride);
  if (ret) {
    LOGF(ERROR) << "Failed to allocate buffer";
    return;
  }
  width_ = buffer_manager_->GetWidth(buffer_);
  height_ = buffer_manager_->GetHeight(buffer_);
  fourcc_ = buffer_manager_->GetV4L2PixelFormat(buffer_);
  num_planes_ = buffer_manager_->GetNumPlanes(buffer_);
  data_.resize(num_planes_, nullptr);
  stride_.resize(num_planes_, 0);
}

GrallocFrameBuffer::~GrallocFrameBuffer() {
  if (Unmap()) {
    LOGF(ERROR) << "Unmap failed";
  }

  if (is_buffer_owner_) {
    int ret = buffer_manager_->Free(buffer_);
    if (ret) {
      LOGF(ERROR) << "Failed to free buffer";
    }
  } else {
    int ret = buffer_manager_->Deregister(buffer_);
    if (ret) {
      LOGF(ERROR) << "Failed to unregister buffer";
    }
  }
}

int GrallocFrameBuffer::Map() {
  base::AutoLock l(lock_);
  if (is_mapped_)
    return 0;

  buffer_size_ = 0;
  for (size_t i = 0; i < num_planes_; i++) {
    buffer_size_ += buffer_manager_->GetPlaneSize(buffer_, i);
  }

  void* addr;
  int ret;
  switch (fourcc_) {
    case V4L2_PIX_FMT_JPEG:
      ret = buffer_manager_->Lock(buffer_, 0, 0, 0, buffer_size_, 1, &addr);
      if (!ret) {
        data_[0] = static_cast<uint8_t*>(addr);
      }
      break;
    case V4L2_PIX_FMT_RGBX32: {
      ret = buffer_manager_->Lock(buffer_, 0, 0, 0, width_, height_, &addr);
      if (!ret) {
        data_[0] = static_cast<uint8_t*>(addr);
        stride_[0] = width_ * 4;
      }
      break;
    }
    case V4L2_PIX_FMT_NV12:
    case V4L2_PIX_FMT_NV12M: {
      struct android_ycbcr ycbcr;
      ret =
          buffer_manager_->LockYCbCr(buffer_, 0, 0, 0, width_, height_, &ycbcr);
      if (!ret) {
        data_[YPLANE] = static_cast<uint8_t*>(ycbcr.y);
        data_[UPLANE] = static_cast<uint8_t*>(ycbcr.cb);
        stride_[YPLANE] = ycbcr.ystride;
        stride_[UPLANE] = ycbcr.cstride;
      }
      break;
    }
    case V4L2_PIX_FMT_YVU420:
    case V4L2_PIX_FMT_YVU420M: {
      struct android_ycbcr ycbcr;
      ret =
          buffer_manager_->LockYCbCr(buffer_, 0, 0, 0, width_, height_, &ycbcr);
      if (!ret) {
        data_[YPLANE] = static_cast<uint8_t*>(ycbcr.y);
        data_[UPLANE] = static_cast<uint8_t*>(ycbcr.cb);
        data_[VPLANE] = static_cast<uint8_t*>(ycbcr.cr);
        stride_[YPLANE] = ycbcr.ystride;
        stride_[UPLANE] = ycbcr.cstride;
        stride_[VPLANE] = ycbcr.cstride;
      }
      break;
    }
    default:
      LOGF(ERROR) << "Format " << FormatToString(fourcc_) << " is unsupported";
      return -EINVAL;
  }

  if (ret) {
    LOGF(ERROR) << "Failed to map buffer";
    return -EINVAL;
  }
  is_mapped_ = true;
  return 0;
}

int GrallocFrameBuffer::Unmap() {
  base::AutoLock l(lock_);
  if (!is_mapped_)
    return 0;

  if (buffer_manager_->Unlock(buffer_)) {
    LOGF(ERROR) << "Failed to unmap buffer";
    return -EINVAL;
  }
  is_mapped_ = false;
  return 0;
}

}  // namespace cros
