/*
 * Copyright (c) 2021, 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 <cstdlib>

#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"

namespace {

const double kPsnrDiffThreshold = 0.1;

// Params: first pass cpu used, second pass cpu used
class CpuUsedFirstpassTest
    : public ::libaom_test::CodecTestWith2Params<int, int>,
      public ::libaom_test::EncoderTest {
 protected:
  CpuUsedFirstpassTest()
      : EncoderTest(GET_PARAM(0)), second_pass_cpu_used_(GET_PARAM(2)) {}
  ~CpuUsedFirstpassTest() override = default;

  void SetUp() override {
    InitializeConfig(::libaom_test::kTwoPassGood);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.rc_end_usage = AOM_VBR;
    cfg_.rc_target_bitrate = 1000;
    cfg_.g_lag_in_frames = 19;
    cfg_.g_threads = 0;
    init_flags_ = AOM_CODEC_USE_PSNR;
  }

  void BeginPassHook(unsigned int pass) override {
    psnr_ = 0.0;
    nframes_ = 0;

    if (pass == 0)
      cpu_used_ = first_pass_cpu_used_;
    else
      cpu_used_ = second_pass_cpu_used_;
  }

  void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override {
    psnr_ += pkt->data.psnr.psnr[0];
    nframes_++;
  }

  void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                          ::libaom_test::Encoder *encoder) override {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, cpu_used_);
      encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
      encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
    }
  }

  double GetAveragePsnr() const {
    if (nframes_) return psnr_ / nframes_;
    return 0.0;
  }

  double GetPsnrDiffThreshold() { return kPsnrDiffThreshold; }

  void DoTest() {
    libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480,
                                       cfg_.g_timebase.den, cfg_.g_timebase.num,
                                       0, 30);
    double ref_psnr;
    double psnr_diff;

    first_pass_cpu_used_ = second_pass_cpu_used_;
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));  // same preset case ref_psnr
    ref_psnr = GetAveragePsnr();

    first_pass_cpu_used_ = GET_PARAM(1);
    if (first_pass_cpu_used_ == second_pass_cpu_used_) return;
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    psnr_diff = std::abs(ref_psnr - GetAveragePsnr());
    EXPECT_LT(psnr_diff, GetPsnrDiffThreshold())
        << "first pass cpu used = " << first_pass_cpu_used_
        << ", second pass cpu used = " << second_pass_cpu_used_;
  }

  int cpu_used_;
  int first_pass_cpu_used_;
  int second_pass_cpu_used_;
  unsigned int nframes_;
  double psnr_;
};

TEST_P(CpuUsedFirstpassTest, FirstPassTest) { DoTest(); }

class CpuUsedFirstpassTestLarge : public CpuUsedFirstpassTest {};

TEST_P(CpuUsedFirstpassTestLarge, FirstPassTest) { DoTest(); }

#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
static const int kSecondPassCpuUsedLarge[] = { 2, 4 };
static const int kSecondPassCpuUsed[] = { 6 };
#else
static const int kSecondPassCpuUsedLarge[] = { 2 };
static const int kSecondPassCpuUsed[] = { 4, 6 };
#endif
#else
static const int kSecondPassCpuUsedLarge[] = { 2 };
static const int kSecondPassCpuUsed[] = { 4, 6 };
#endif

AV1_INSTANTIATE_TEST_SUITE(
    CpuUsedFirstpassTestLarge, ::testing::Values(2, 4, 6),
    ::testing::ValuesIn(kSecondPassCpuUsedLarge));  // cpu_used

AV1_INSTANTIATE_TEST_SUITE(
    CpuUsedFirstpassTest, ::testing::Values(2, 4, 6),
    ::testing::ValuesIn(kSecondPassCpuUsed));  // cpu_used

}  // namespace
