// Copyright 2018 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/gpu/chromeos/generic_dmabuf_video_frame_mapper.h"

#include <sys/mman.h>

#include <algorithm>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "media/gpu/macros.h"

namespace media {

namespace {

uint8_t* Mmap(const size_t length, const int fd) {
  void* addr =
      mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0u);
  if (addr == MAP_FAILED) {
    VLOGF(1) << "Failed to mmap.";
    return nullptr;
  }
  return static_cast<uint8_t*>(addr);
}

void MunmapBuffers(const std::vector<std::pair<uint8_t*, size_t>>& chunks,
                   scoped_refptr<const VideoFrame> video_frame) {
  for (const auto& chunk : chunks) {
    DLOG_IF(ERROR, !chunk.first) << "Pointer to be released is nullptr.";
    munmap(chunk.first, chunk.second);
  }
}

// Create VideoFrame whose dtor unmaps memory in mapped planes referred
// by |plane_addrs|. |plane_addrs| are addresses to (Y, U, V) in this order.
// |chunks| is the vector of pair of (address, size) to be called in munmap().
// |src_video_frame| is the video frame that owns dmabufs to the mapped planes.
scoped_refptr<VideoFrame> CreateMappedVideoFrame(
    scoped_refptr<const VideoFrame> src_video_frame,
    uint8_t* plane_addrs[VideoFrame::kMaxPlanes],
    const std::vector<std::pair<uint8_t*, size_t>>& chunks) {
  scoped_refptr<VideoFrame> video_frame;

  const auto& layout = src_video_frame->layout();
  const auto& visible_rect = src_video_frame->visible_rect();
  if (IsYuvPlanar(layout.format())) {
    video_frame = VideoFrame::WrapExternalYuvDataWithLayout(
        layout, visible_rect, visible_rect.size(), plane_addrs[0],
        plane_addrs[1], plane_addrs[2], src_video_frame->timestamp());
  } else if (VideoFrame::NumPlanes(layout.format()) == 1) {
    video_frame = VideoFrame::WrapExternalDataWithLayout(
        layout, visible_rect, visible_rect.size(), plane_addrs[0],
        layout.planes()[0].size, src_video_frame->timestamp());
  }
  if (!video_frame) {
    MunmapBuffers(chunks, /*video_frame=*/nullptr);
    return nullptr;
  }

  // Pass org_video_frame so that it outlives video_frame.
  video_frame->AddDestructionObserver(
      base::BindOnce(MunmapBuffers, chunks, std::move(src_video_frame)));
  return video_frame;
}

bool IsFormatSupported(VideoPixelFormat format) {
  constexpr VideoPixelFormat supported_formats[] = {
      // RGB pixel formats.
      PIXEL_FORMAT_ABGR,
      PIXEL_FORMAT_ARGB,
      PIXEL_FORMAT_XBGR,

      // YUV pixel formats.
      PIXEL_FORMAT_I420,
      PIXEL_FORMAT_NV12,
      PIXEL_FORMAT_YV12,

      // Compressed format.
      PIXEL_FORMAT_MJPEG,
  };
  return std::find(std::cbegin(supported_formats), std::cend(supported_formats),
                   format) != std::cend(supported_formats);
}

}  // namespace

// static
std::unique_ptr<GenericDmaBufVideoFrameMapper>
GenericDmaBufVideoFrameMapper::Create(VideoPixelFormat format) {
  if (!IsFormatSupported(format)) {
    VLOGF(1) << "Unsupported format: " << format;
    return nullptr;
  }
  return base::WrapUnique(new GenericDmaBufVideoFrameMapper(format));
}

GenericDmaBufVideoFrameMapper::GenericDmaBufVideoFrameMapper(
    VideoPixelFormat format)
    : VideoFrameMapper(format) {}

scoped_refptr<VideoFrame> GenericDmaBufVideoFrameMapper::Map(
    scoped_refptr<const VideoFrame> video_frame) const {
  if (!video_frame) {
    LOG(ERROR) << "Video frame is nullptr";
    return nullptr;
  }

  if (video_frame->storage_type() != VideoFrame::StorageType::STORAGE_DMABUFS) {
    VLOGF(1) << "VideoFrame's storage type is not DMABUF: "
             << video_frame->storage_type();
    return nullptr;
  }

  if (video_frame->format() != format_) {
    VLOGF(1) << "Unexpected format: " << video_frame->format()
             << ", expected: " << format_;
    return nullptr;
  }

  // Map all buffers from their start address.
  const auto& planes = video_frame->layout().planes();
  if (planes[0].offset != 0) {
    VLOGF(1) << "The offset of the first plane is not zero";
    return nullptr;
  }

  // Always prepare VideoFrame::kMaxPlanes addresses for planes initialized by
  // nullptr. This enables to specify nullptr to redundant plane, for pixel
  // format whose number of planes are less than VideoFrame::kMaxPlanes.
  uint8_t* plane_addrs[VideoFrame::kMaxPlanes] = {};
  const size_t num_planes = planes.size();
  const auto& dmabuf_fds = video_frame->DmabufFds();
  std::vector<std::pair<uint8_t*, size_t>> chunks;
  DCHECK_EQ(dmabuf_fds.size(), num_planes);
  for (size_t i = 0; i < num_planes;) {
    size_t next_buf = i + 1;
    // Search the index of the plane from which the next buffer starts.
    while (next_buf < num_planes && planes[next_buf].offset != 0)
      next_buf++;

    // Map the current buffer.
    const auto& last_plane = planes[next_buf - 1];

    size_t mapped_size = 0;
    if (!base::CheckAdd<size_t>(last_plane.offset, last_plane.size)
             .AssignIfValid(&mapped_size)) {
      VLOGF(1) << "Overflow happens with offset=" << last_plane.offset
               << " + size=" << last_plane.size;
      MunmapBuffers(chunks, /*video_frame=*/nullptr);
      return nullptr;
    }

    uint8_t* mapped_addr = Mmap(mapped_size, dmabuf_fds[i].get());
    chunks.emplace_back(mapped_addr, mapped_size);
    for (size_t j = i; j < next_buf; ++j)
      plane_addrs[j] = mapped_addr + planes[j].offset;

    i = next_buf;
  }

  return CreateMappedVideoFrame(std::move(video_frame), plane_addrs, chunks);
}

}  // namespace media
