/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <climits>
#include <vector>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/video_source.h"
#include "test/util.h"

namespace {

const unsigned int kCqLevel = 18;
const double kMaxPsnr = 100.0;

// kPsnrThreshold represents the psnr threshold used to validate the quality of
// the first frame. The indices, 0 and 1 correspond to non-allintra and allintra
// encoding modes.
const double kPsnrThreshold[2] = { 29.0, 41.5 };

// kPsnrFluctuation represents the maximum allowed psnr fluctuation w.r.t first
// frame. The indices, 0 and 1 correspond to non-allintra and allintra encoding
// modes.
const double kPsnrFluctuation[2] = { 2.5, 0.3 };

class MonochromeTest
    : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, int,
                                                 int>,
      public ::libaom_test::EncoderTest {
 protected:
  MonochromeTest()
      : EncoderTest(GET_PARAM(0)), lossless_(GET_PARAM(2)),
        frame0_psnr_y_(0.0) {}

  virtual ~MonochromeTest() {}

  virtual void SetUp() { InitializeConfig(GET_PARAM(1)); }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, GET_PARAM(3));
      if (mode_ == ::libaom_test::kAllIntra) {
        encoder->Control(AOME_SET_CQ_LEVEL, kCqLevel);
      }
      if (lossless_) {
        encoder->Control(AV1E_SET_LOSSLESS, 1);
      }
    }
  }

  virtual void DecompressedFrameHook(const aom_image_t &img,
                                     aom_codec_pts_t pts) {
    (void)pts;

    // Get value of top-left corner pixel of U plane
    int chroma_value = img.planes[AOM_PLANE_U][0];

    bool is_chroma_constant =
        ComparePlaneToValue(img, AOM_PLANE_U, chroma_value) &&
        ComparePlaneToValue(img, AOM_PLANE_V, chroma_value);

    // Chroma planes should be constant
    EXPECT_TRUE(is_chroma_constant);

    // Monochrome flag on image should be set
    EXPECT_EQ(img.monochrome, 1);

    chroma_value_list_.push_back(chroma_value);
  }

  // Returns true if all pixels on the plane are equal to value, and returns
  // false otherwise.
  bool ComparePlaneToValue(const aom_image_t &img, const int plane,
                           const int value) {
    const int w = aom_img_plane_width(&img, plane);
    const int h = aom_img_plane_height(&img, plane);
    const uint8_t *const buf = img.planes[plane];
    const int stride = img.stride[plane];

    for (int r = 0; r < h; ++r) {
      for (int c = 0; c < w; ++c) {
        if (buf[r * stride + c] != value) return false;
      }
    }
    return true;
  }

  virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
    // Check average PSNR value is >= 100 db in case of lossless encoding.
    if (lossless_) {
      EXPECT_GE(pkt->data.psnr.psnr[0], kMaxPsnr);
      return;
    }
    const bool is_allintra = (mode_ == ::libaom_test::kAllIntra);
    // Check that the initial Y PSNR value is 'high enough', and check that
    // subsequent Y PSNR values are 'close' to this initial value.
    if (frame0_psnr_y_ == 0.0) {
      frame0_psnr_y_ = pkt->data.psnr.psnr[1];
      EXPECT_GT(frame0_psnr_y_, kPsnrThreshold[is_allintra]);
    }
    EXPECT_NEAR(pkt->data.psnr.psnr[1], frame0_psnr_y_,
                kPsnrFluctuation[is_allintra]);
  }

  int lossless_;
  std::vector<int> chroma_value_list_;
  double frame0_psnr_y_;
};

TEST_P(MonochromeTest, TestMonochromeEncoding) {
  ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                       30, 1, 0, 5);

  init_flags_ = AOM_CODEC_USE_PSNR;

  cfg_.rc_buf_initial_sz = 500;
  cfg_.rc_buf_optimal_sz = 600;
  cfg_.rc_buf_sz = 1000;
  cfg_.rc_min_quantizer = 2;
  cfg_.rc_max_quantizer = 56;
  cfg_.rc_undershoot_pct = 50;
  cfg_.rc_overshoot_pct = 50;
  cfg_.rc_end_usage = AOM_CBR;
  cfg_.g_lag_in_frames = 1;
  cfg_.kf_min_dist = cfg_.kf_max_dist = 3000;
  // Enable dropped frames.
  cfg_.rc_dropframe_thresh = 1;
  // Run at low bitrate.
  cfg_.rc_target_bitrate = 40;
  // Set monochrome encoding flag
  cfg_.monochrome = 1;

  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  // Check that the chroma planes are equal across all frames
  std::vector<int>::const_iterator iter = chroma_value_list_.begin();
  int initial_chroma_value = *iter;
  for (; iter != chroma_value_list_.end(); ++iter) {
    // Check that all decoded frames have the same constant chroma planes.
    EXPECT_EQ(*iter, initial_chroma_value);
  }
}

class MonochromeAllIntraTest : public MonochromeTest {};

TEST_P(MonochromeAllIntraTest, TestMonochromeEncoding) {
  ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                       30, 1, 0, 5);
  init_flags_ = AOM_CODEC_USE_PSNR;
  // Set monochrome encoding flag
  cfg_.monochrome = 1;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  // Check that the chroma planes are equal across all frames
  std::vector<int>::const_iterator iter = chroma_value_list_.begin();
  int initial_chroma_value = *iter;
  for (; iter != chroma_value_list_.end(); ++iter) {
    // Check that all decoded frames have the same constant chroma planes.
    EXPECT_EQ(*iter, initial_chroma_value);
  }
}

AV1_INSTANTIATE_TEST_SUITE(MonochromeTest,
                           ::testing::Values(::libaom_test::kOnePassGood,
                                             ::libaom_test::kTwoPassGood),
                           ::testing::Values(0),   // lossless
                           ::testing::Values(0));  // cpu_used

AV1_INSTANTIATE_TEST_SUITE(MonochromeAllIntraTest,
                           ::testing::Values(::libaom_test::kAllIntra),
                           ::testing::Values(0, 1),   // lossless
                           ::testing::Values(6, 9));  // cpu_used
}  // namespace
