// Copyright 2020 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/video/mac/test/pixel_buffer_test_utils_mac.h"

#include "media/capture/video/mac/pixel_buffer_pool_mac.h"
#include "media/capture/video/mac/pixel_buffer_transferer_mac.h"
#include "third_party/libyuv/include/libyuv/convert_argb.h"
#include "third_party/libyuv/include/libyuv/convert_from_argb.h"

namespace media {

namespace {

// media::PIXEL_FORMAT_YUY2 a.k.a. "yuvs"
constexpr OSType kPixelFormatYuvs = kCVPixelFormatType_422YpCbCr8_yuvs;

// ARGB has 4 bytes per pixel and no padding.
size_t GetArgbStride(size_t width) {
  return width * 4;
}

// YUVS is a 4:2:2 pixel format that is packed to be 2 bytes per pixel.
// https://gstreamer.freedesktop.org/documentation/additional/design/mediatype-video-raw.html?gi-language=c
size_t GetYuvsStride(size_t width) {
  return width * 2;
}

}  // namespace

ByteArrayPixelBuffer::ByteArrayPixelBuffer() {}

ByteArrayPixelBuffer::~ByteArrayPixelBuffer() {}

std::vector<uint8_t> CreateArgbBufferFromSingleRgbColor(int width,
                                                        int height,
                                                        uint8_t r,
                                                        uint8_t g,
                                                        uint8_t b) {
  std::vector<uint8_t> argb_buffer;
  argb_buffer.resize(GetArgbStride(width) * height);
  for (size_t i = 0; i < argb_buffer.size(); i += 4) {
    // ARGB little endian = BGRA in memory.
    argb_buffer[i + 0] = b;
    argb_buffer[i + 1] = g;
    argb_buffer[i + 2] = r;
    argb_buffer[i + 3] = 255u;
  }
  return argb_buffer;
}

bool IsArgbPixelWhite(const std::vector<uint8_t>& argb_buffer, size_t i) {
  // ARGB little endian = BGRA in memory.
  uint8_t b = argb_buffer[i + 0];
  uint8_t g = argb_buffer[i + 1];
  uint8_t r = argb_buffer[i + 2];
  return (r + g + b) / 3 >= 255 / 2;
}

bool ArgbBufferIsSingleColor(const std::vector<uint8_t>& argb_buffer,
                             uint8_t r,
                             uint8_t g,
                             uint8_t b) {
  int signed_r = r;
  int signed_g = g;
  int signed_b = b;
  // ~5% error tolerance.
  constexpr int kErrorTolerance = 0.05 * 255;
  for (size_t i = 0; i < argb_buffer.size(); i += 4) {
    // ARGB little endian = BGRA in memory.
    int pixel_b = argb_buffer[i + 0];
    int pixel_g = argb_buffer[i + 1];
    int pixel_r = argb_buffer[i + 2];
    if (std::abs(pixel_r - signed_r) > kErrorTolerance ||
        std::abs(pixel_g - signed_g) > kErrorTolerance ||
        std::abs(pixel_b - signed_b) > kErrorTolerance) {
      return false;
    }
  }
  return true;
}

std::vector<uint8_t> CreateArgbCheckerPatternBuffer(int width,
                                                    int height,
                                                    int num_tiles_across) {
  std::vector<uint8_t> argb_buffer;
  int tile_width = width / num_tiles_across;
  int tile_height = height / num_tiles_across;
  argb_buffer.resize(GetArgbStride(width) * height);
  for (size_t i = 0; i < argb_buffer.size(); i += 4) {
    size_t pixel_number = i / 4;
    size_t x = pixel_number % width;
    size_t y = pixel_number / width;
    bool is_white = ((x / tile_width) % 2 != 0) != ((y / tile_height) % 2 != 0);
    // ARGB little endian = BGRA in memory.
    argb_buffer[i + 0] = argb_buffer[i + 1] = argb_buffer[i + 2] =
        is_white ? 255u : 100u;
    argb_buffer[i + 3] = 255u;
  }
  return argb_buffer;
}

std::tuple<int, int> GetCheckerPatternNumTilesAccross(
    const std::vector<uint8_t>& argb_buffer,
    int width,
    int height) {
  int num_tiles_across_x = 0;
  bool prev_tile_is_white = false;
  for (int x = 0; x < width; ++x) {
    size_t i = (x * 4);
    bool current_tile_is_white = IsArgbPixelWhite(argb_buffer, i);
    if (x == 0 || prev_tile_is_white != current_tile_is_white) {
      prev_tile_is_white = current_tile_is_white;
      ++num_tiles_across_x;
    }
  }
  int num_tiles_across_y = 0;
  prev_tile_is_white = false;
  for (int y = 0; y < height; ++y) {
    size_t i = y * GetArgbStride(width);
    bool current_tile_is_white = IsArgbPixelWhite(argb_buffer, i);
    if (y == 0 || prev_tile_is_white != current_tile_is_white) {
      prev_tile_is_white = current_tile_is_white;
      ++num_tiles_across_y;
    }
  }
  return std::make_pair(num_tiles_across_x, num_tiles_across_y);
}

std::unique_ptr<ByteArrayPixelBuffer> CreateYuvsPixelBufferFromArgbBuffer(
    int width,
    int height,
    const std::vector<uint8_t>& argb_buffer) {
  std::unique_ptr<ByteArrayPixelBuffer> result =
      std::make_unique<ByteArrayPixelBuffer>();
  size_t yuvs_stride = GetYuvsStride(width);

  // ARGB -> YUVS (a.k.a. YUY2).
  result->byte_array.resize(yuvs_stride * height);
  libyuv::ARGBToYUY2(&argb_buffer[0], GetArgbStride(width),
                     &result->byte_array[0], yuvs_stride, width, height);

  CVReturn error = CVPixelBufferCreateWithBytes(
      nil, width, height, kPixelFormatYuvs, (void*)&result->byte_array[0],
      yuvs_stride, nil, nil, nil, result->pixel_buffer.InitializeInto());
  CHECK(error == noErr);
  return result;
}

std::unique_ptr<ByteArrayPixelBuffer> CreateYuvsPixelBufferFromSingleRgbColor(
    int width,
    int height,
    uint8_t r,
    uint8_t g,
    uint8_t b) {
  return CreateYuvsPixelBufferFromArgbBuffer(
      width, height,
      CreateArgbBufferFromSingleRgbColor(width, height, r, g, b));
}

std::vector<uint8_t> CreateArgbBufferFromYuvsIOSurface(
    IOSurfaceRef io_surface) {
  DCHECK(io_surface);
  size_t width = IOSurfaceGetWidth(io_surface);
  size_t height = IOSurfaceGetHeight(io_surface);
  // These utility methods don't work well with widths that aren't multiples of
  // 16. There could be assumptions about memory alignment, or there could
  // simply be a loss of information in the YUVS <-> ARGB conversions since YUVS
  // is packed. Either way, the pixels may change, so we avoid these widths.
  DCHECK(width % 16 == 0);
  size_t argb_stride = GetArgbStride(width);
  size_t yuvs_stride = GetYuvsStride(width);
  uint8_t* pixels = static_cast<uint8_t*>(IOSurfaceGetBaseAddress(io_surface));
  DCHECK(pixels);
  std::vector<uint8_t> argb_buffer;
  argb_buffer.resize(argb_stride * height);
  libyuv::YUY2ToARGB(pixels, yuvs_stride, &argb_buffer[0], argb_stride, width,
                     height);
  return argb_buffer;
}

bool YuvsIOSurfaceIsSingleColor(IOSurfaceRef io_surface,
                                uint8_t r,
                                uint8_t g,
                                uint8_t b) {
  return ArgbBufferIsSingleColor(CreateArgbBufferFromYuvsIOSurface(io_surface),
                                 r, g, b);
}

bool PixelBufferIsSingleColor(CVPixelBufferRef pixel_buffer,
                              uint8_t r,
                              uint8_t g,
                              uint8_t b) {
  OSType pixel_format = CVPixelBufferGetPixelFormatType(pixel_buffer);
  base::ScopedCFTypeRef<CVPixelBufferRef> yuvs_pixel_buffer;
  if (pixel_format == kPixelFormatYuvs) {
    // The pixel buffer is already YUVS, so we know how to check its color.
    yuvs_pixel_buffer.reset(pixel_buffer, base::scoped_policy::RETAIN);
  } else {
    // Convert to YUVS. We only know how to check the color of YUVS.
    yuvs_pixel_buffer =
        PixelBufferPool::Create(kPixelFormatYuvs,
                                CVPixelBufferGetWidth(pixel_buffer),
                                CVPixelBufferGetHeight(pixel_buffer), 1)
            ->CreateBuffer();
    PixelBufferTransferer transferer;
    bool transfer_success =
        transferer.TransferImage(pixel_buffer, yuvs_pixel_buffer);
    DCHECK(transfer_success);
  }
  IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(yuvs_pixel_buffer);
  DCHECK(io_surface);
  return YuvsIOSurfaceIsSingleColor(io_surface, r, g, b);
}

}  // namespace media
