/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "api/video/nv12_buffer.h"

#include <cstdint>
#include <cstring>

#include "api/scoped_refptr.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_frame_buffer.h"
#include "test/frame_utils.h"
#include "test/gtest.h"

namespace webrtc {

namespace {
int GetY(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
  return buf->DataY()[row * buf->StrideY() + col];
}

int GetU(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
  return buf->DataUV()[(row / 2) * buf->StrideUV() + (col / 2) * 2];
}

int GetV(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
  return buf->DataUV()[(row / 2) * buf->StrideUV() + (col / 2) * 2 + 1];
}

void FillNV12Buffer(rtc::scoped_refptr<NV12Buffer> buf) {
  const uint8_t Y = 1;
  const uint8_t U = 2;
  const uint8_t V = 3;
  for (int row = 0; row < buf->height(); ++row) {
    for (int col = 0; col < buf->width(); ++col) {
      buf->MutableDataY()[row * buf->StrideY() + col] = Y;
    }
  }
  // Fill interleaving UV values.
  for (int row = 0; row < buf->ChromaHeight(); row++) {
    for (int col = 0; col < buf->StrideUV(); col += 2) {
      int uv_index = row * buf->StrideUV() + col;
      buf->MutableDataUV()[uv_index] = U;
      buf->MutableDataUV()[uv_index + 1] = V;
    }
  }
}

}  // namespace

TEST(NV12BufferTest, InitialData) {
  constexpr int stride_y = 3;
  constexpr int stride_uv = 4;
  constexpr int width = 3;
  constexpr int height = 3;

  rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
  EXPECT_EQ(width, nv12_buffer->width());
  EXPECT_EQ(height, nv12_buffer->height());
  EXPECT_EQ(stride_y, nv12_buffer->StrideY());
  EXPECT_EQ(stride_uv, nv12_buffer->StrideUV());
  EXPECT_EQ(2, nv12_buffer->ChromaWidth());
  EXPECT_EQ(2, nv12_buffer->ChromaHeight());
}

TEST(NV12BufferTest, ReadPixels) {
  constexpr int width = 3;
  constexpr int height = 3;

  rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
  // Y = 1, U = 2, V = 3.
  FillNV12Buffer(nv12_buffer);
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      EXPECT_EQ(1, GetY(nv12_buffer, col, row));
      EXPECT_EQ(2, GetU(nv12_buffer, col, row));
      EXPECT_EQ(3, GetV(nv12_buffer, col, row));
    }
  }
}

TEST(NV12BufferTest, ToI420) {
  constexpr int width = 3;
  constexpr int height = 3;
  constexpr int size_y = width * height;
  constexpr int size_u = (width + 1) / 2 * (height + 1) / 2;
  constexpr int size_v = (width + 1) / 2 * (height + 1) / 2;
  rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
  memset(reference->MutableDataY(), 8, size_y);
  memset(reference->MutableDataU(), 4, size_u);
  memset(reference->MutableDataV(), 2, size_v);

  rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
  // Convert the reference buffer to NV12.
  memset(nv12_buffer->MutableDataY(), 8, size_y);
  // Interleaving u/v values.
  for (int i = 0; i < size_u + size_v; i += 2) {
    nv12_buffer->MutableDataUV()[i] = 4;
    nv12_buffer->MutableDataUV()[i + 1] = 2;
  }
  // Confirm YUV values are as expected.
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      EXPECT_EQ(8, GetY(nv12_buffer, col, row));
      EXPECT_EQ(4, GetU(nv12_buffer, col, row));
      EXPECT_EQ(2, GetV(nv12_buffer, col, row));
    }
  }

  rtc::scoped_refptr<I420BufferInterface> i420_buffer(nv12_buffer->ToI420());
  EXPECT_EQ(height, i420_buffer->height());
  EXPECT_EQ(width, i420_buffer->width());
  EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
}

}  // namespace webrtc
