/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  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
 * aomedia.org/license/patent-license/.
 */

#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/util.h"
namespace {
typedef struct {
  const unsigned int min_kf_dist;
  const unsigned int max_kf_dist;
  const unsigned int min_gf_interval;
  const unsigned int max_gf_interval;
  const unsigned int lag_in_frames;
  libaom_test::TestMode encoding_mode;
} AltRefTestParams;

static const AltRefTestParams TestParams[] = {
  { 0, 10, 4, 8, 10, ::libaom_test::kOnePassGood },
  { 0, 30, 8, 12, 16, ::libaom_test::kOnePassGood },
  { 30, 30, 12, 16, 25, ::libaom_test::kOnePassGood },
  { 0, 60, 12, 20, 25, ::libaom_test::kOnePassGood },
  { 60, 60, 16, 28, 30, ::libaom_test::kOnePassGood },
  { 0, 100, 16, 32, 35, ::libaom_test::kOnePassGood },
};

std::ostream &operator<<(std::ostream &os, const AltRefTestParams &test_arg) {
  return os << "AltRefTestParams { min_kf_dist:" << test_arg.min_kf_dist
            << " max_kf_dist:" << test_arg.max_kf_dist
            << " min_gf_interval:" << test_arg.min_gf_interval
            << " max_gf_interval:" << test_arg.max_gf_interval
            << " lag_in_frames:" << test_arg.lag_in_frames
            << " encoding_mode:" << test_arg.encoding_mode << " }";
}

// This class is used to check the presence of altref frame.
class AltRefFramePresenceTestLarge
    : public ::libaom_test::CodecTestWith2Params<AltRefTestParams, aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  AltRefFramePresenceTestLarge()
      : EncoderTest(GET_PARAM(0)), altref_test_params_(GET_PARAM(1)),
        rc_end_usage_(GET_PARAM(2)) {
    is_arf_frame_present_ = 0;
  }
  virtual ~AltRefFramePresenceTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(altref_test_params_.encoding_mode);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.rc_end_usage = rc_end_usage_;
    cfg_.g_threads = 1;
    cfg_.kf_min_dist = altref_test_params_.min_kf_dist;
    cfg_.kf_max_dist = altref_test_params_.max_kf_dist;
    cfg_.g_lag_in_frames = altref_test_params_.lag_in_frames;
    cfg_.rc_target_bitrate = 200;
  }

  virtual bool DoDecode() const { return 1; }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, 5);
      if (rc_end_usage_ == AOM_Q || rc_end_usage_ == AOM_CQ) {
        encoder->Control(AOME_SET_QP, 210);
      }
      encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(AV1E_SET_MIN_GF_INTERVAL,
                       altref_test_params_.min_gf_interval);
      encoder->Control(AV1E_SET_MAX_GF_INTERVAL,
                       altref_test_params_.max_gf_interval);
    }
  }

  virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
                                  libaom_test::Decoder *decoder) {
    EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
    if (is_arf_frame_present_ != 1 && AOM_CODEC_OK == res_dec) {
      aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_ALTREF_PRESENT,
                                    &is_arf_frame_present_);
    }
    return AOM_CODEC_OK == res_dec;
  }

  const AltRefTestParams altref_test_params_;
  int is_arf_frame_present_;
  aom_rc_mode rc_end_usage_;
};

TEST_P(AltRefFramePresenceTestLarge, AltRefFrameEncodePresenceTest) {
  libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                     cfg_.g_timebase.den, cfg_.g_timebase.num,
                                     0, 100);
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  ASSERT_EQ(is_arf_frame_present_, 1);
}

AV1_INSTANTIATE_TEST_SUITE(AltRefFramePresenceTestLarge,
                           ::testing::ValuesIn(TestParams),
                           ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ));

typedef struct {
  const ::libaom_test::TestMode encoding_mode;
  const unsigned int min_gf_interval;
  const unsigned int max_gf_interval;
} gfIntervalParam;

const gfIntervalParam gfTestParams[] = {
  // single pass
  { ::libaom_test::kOnePassGood, 0, 6 },
  { ::libaom_test::kOnePassGood, 0, 8 },
  { ::libaom_test::kOnePassGood, 5, 10 },
  { ::libaom_test::kOnePassGood, 8, 16 },
  { ::libaom_test::kOnePassGood, 16, 16 },
};

// This class is used to test if the gf interval bounds configured by the user
// are respected by the encoder.
class GoldenFrameIntervalTestLarge
    : public ::libaom_test::CodecTestWith2Params<gfIntervalParam, aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  GoldenFrameIntervalTestLarge()
      : EncoderTest(GET_PARAM(0)), gf_interval_param_(GET_PARAM(1)),
        rc_end_usage_(GET_PARAM(2)) {
    baseline_gf_interval_ = -1;
    limit_ = 30;
    frame_num_ = 0;
  }
  virtual ~GoldenFrameIntervalTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(gf_interval_param_.encoding_mode);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.rc_end_usage = rc_end_usage_;
    cfg_.g_threads = 1;
    // kf_min_dist is equal to kf_max_dist to make sure that there are no scene
    // cuts due to which the min_gf_interval may not be respected.
    cfg_.kf_min_dist = limit_;
    cfg_.kf_max_dist = limit_;
    cfg_.g_limit = limit_;
    cfg_.g_lag_in_frames = 19;
    cfg_.rc_target_bitrate = 200;
  }

  virtual bool DoDecode() const { return 1; }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, 5);
      if (rc_end_usage_ == AOM_Q || rc_end_usage_ == AOM_CQ) {
        encoder->Control(AOME_SET_QP, 210);
      }
      encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(AV1E_SET_MIN_GF_INTERVAL,
                       gf_interval_param_.min_gf_interval);
      encoder->Control(AV1E_SET_MAX_GF_INTERVAL,
                       gf_interval_param_.max_gf_interval);
    }
    if (frame_num_ > 0) {
      encoder->Control(AV1E_GET_BASELINE_GF_INTERVAL, &baseline_gf_interval_);
      ASSERT_LE(baseline_gf_interval_, (int)gf_interval_param_.max_gf_interval);
      if ((frame_num_ + (int)gf_interval_param_.min_gf_interval) <= limit_) {
        ASSERT_GE(baseline_gf_interval_,
                  (int)gf_interval_param_.min_gf_interval);
      }
    }
  }

  virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt,
                            ::libaom_test::DxDataIterator *dec_iter) {
    (void)dec_iter;
    (void)pkt;
    ++frame_num_;
  }

  const gfIntervalParam gf_interval_param_;
  int baseline_gf_interval_;
  int limit_;
  int frame_num_;
  aom_rc_mode rc_end_usage_;
};

TEST_P(GoldenFrameIntervalTestLarge, GoldenFrameIntervalTest) {
  libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                     cfg_.g_timebase.den, cfg_.g_timebase.num,
                                     0, limit_);
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}

AV1_INSTANTIATE_TEST_SUITE(GoldenFrameIntervalTestLarge,
                           ::testing::ValuesIn(gfTestParams),
                           ::testing::Values(AOM_Q, AOM_VBR, AOM_CQ, AOM_CBR));

}  // namespace
