/*
 *  Copyright (c) 2014 The WebM 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 <string>
#include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/md5_helper.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "vp9/encoder/vp9_firstpass.h"

namespace {
// FIRSTPASS_STATS struct:
// {
//   25 double members;
//   1 int64_t member;
// }
// Whenever FIRSTPASS_STATS struct is modified, the following constants need to
// be revisited.
const int kDbl = 25;
const int kInt = 1;
const size_t kFirstPassStatsSz = kDbl * sizeof(double) + kInt * sizeof(int64_t);

class VPxFirstPassEncoderThreadTest
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
 protected:
  VPxFirstPassEncoderThreadTest()
      : EncoderTest(GET_PARAM(0)), encoder_initialized_(false), tiles_(0),
        encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
    init_flags_ = VPX_CODEC_USE_PSNR;

    row_mt_mode_ = 1;
    first_pass_only_ = true;
    firstpass_stats_.buf = nullptr;
    firstpass_stats_.sz = 0;
  }
  virtual ~VPxFirstPassEncoderThreadTest() { free(firstpass_stats_.buf); }

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);

    cfg_.rc_end_usage = VPX_VBR;
    cfg_.rc_2pass_vbr_minsection_pct = 5;
    cfg_.rc_2pass_vbr_maxsection_pct = 2000;
    cfg_.rc_max_quantizer = 56;
    cfg_.rc_min_quantizer = 0;
  }

  virtual void BeginPassHook(unsigned int /*pass*/) {
    encoder_initialized_ = false;
    abort_ = false;
  }

  virtual void EndPassHook() {
    // For first pass stats test, only run first pass encoder.
    if (first_pass_only_ && cfg_.g_pass == VPX_RC_FIRST_PASS)
      abort_ |= first_pass_only_;
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
                                  ::libvpx_test::Encoder *encoder) {
    if (!encoder_initialized_) {
      // Encode in 2-pass mode.
      encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_);
      encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
      encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
      encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
      encoder->Control(VP8E_SET_ARNR_TYPE, 3);
      encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0);

      if (encoding_mode_ == ::libvpx_test::kTwoPassGood)
        encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);

      encoder_initialized_ = true;
    }
  }

  virtual void StatsPktHook(const vpx_codec_cx_pkt_t *pkt) {
    const uint8_t *const pkt_buf =
        reinterpret_cast<uint8_t *>(pkt->data.twopass_stats.buf);
    const size_t pkt_size = pkt->data.twopass_stats.sz;

    // First pass stats size equals sizeof(FIRSTPASS_STATS)
    EXPECT_EQ(pkt_size, kFirstPassStatsSz)
        << "Error: First pass stats size doesn't equal kFirstPassStatsSz";

    firstpass_stats_.buf =
        realloc(firstpass_stats_.buf, firstpass_stats_.sz + pkt_size);
    memcpy((uint8_t *)firstpass_stats_.buf + firstpass_stats_.sz, pkt_buf,
           pkt_size);
    firstpass_stats_.sz += pkt_size;
  }

  bool encoder_initialized_;
  int tiles_;
  ::libvpx_test::TestMode encoding_mode_;
  int set_cpu_used_;
  int row_mt_mode_;
  bool first_pass_only_;
  vpx_fixed_buf_t firstpass_stats_;
};

static void compare_fp_stats(vpx_fixed_buf_t *fp_stats, double factor) {
  // fp_stats consists of 2 set of first pass encoding stats. These 2 set of
  // stats are compared to check if the stats match or at least are very close.
  FIRSTPASS_STATS *stats1 = reinterpret_cast<FIRSTPASS_STATS *>(fp_stats->buf);
  int nframes_ = (int)(fp_stats->sz / sizeof(FIRSTPASS_STATS));
  FIRSTPASS_STATS *stats2 = stats1 + nframes_ / 2;
  int i, j;

  // The total stats are also output and included in the first pass stats. Here
  // ignore that in the comparison.
  for (i = 0; i < (nframes_ / 2 - 1); ++i) {
    const double *frame_stats1 = reinterpret_cast<double *>(stats1);
    const double *frame_stats2 = reinterpret_cast<double *>(stats2);

    for (j = 0; j < kDbl; ++j) {
      ASSERT_LE(fabs(*frame_stats1 - *frame_stats2),
                fabs(*frame_stats1) / factor)
          << "First failure @ frame #" << i << " stat #" << j << " ("
          << *frame_stats1 << " vs. " << *frame_stats2 << ")";
      frame_stats1++;
      frame_stats2++;
    }

    stats1++;
    stats2++;
  }

  // Reset firstpass_stats_ to 0.
  memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz);
  fp_stats->sz = 0;
}

static void compare_fp_stats_md5(vpx_fixed_buf_t *fp_stats) {
  // fp_stats consists of 2 set of first pass encoding stats. These 2 set of
  // stats are compared to check if the stats match.
  uint8_t *stats1 = reinterpret_cast<uint8_t *>(fp_stats->buf);
  uint8_t *stats2 = stats1 + fp_stats->sz / 2;
  ::libvpx_test::MD5 md5_row_mt_0, md5_row_mt_1;

  md5_row_mt_0.Add(stats1, fp_stats->sz / 2);
  const char *md5_row_mt_0_str = md5_row_mt_0.Get();

  md5_row_mt_1.Add(stats2, fp_stats->sz / 2);
  const char *md5_row_mt_1_str = md5_row_mt_1.Get();

  // Check md5 match.
  ASSERT_STREQ(md5_row_mt_0_str, md5_row_mt_1_str)
      << "MD5 checksums don't match";

  // Reset firstpass_stats_ to 0.
  memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz);
  fp_stats->sz = 0;
}

TEST_P(VPxFirstPassEncoderThreadTest, FirstPassStatsTest) {
  ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);

  first_pass_only_ = true;
  cfg_.rc_target_bitrate = 1000;

  // Test row_mt_mode: 0 vs 1 at single thread case(threads = 1, tiles_ = 0)
  tiles_ = 0;
  cfg_.g_threads = 1;

  row_mt_mode_ = 0;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  row_mt_mode_ = 1;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  // Compare to check if using or not using row-mt generates close stats.
  ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 1000.0));

  // Test single thread vs multiple threads
  row_mt_mode_ = 1;
  tiles_ = 0;

  cfg_.g_threads = 1;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  cfg_.g_threads = 4;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  // Compare to check if single-thread and multi-thread stats are close enough.
  ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 1000.0));

  // Bit exact test in row_mt mode.
  // When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact
  // result.
  row_mt_mode_ = 1;
  tiles_ = 2;

  cfg_.g_threads = 2;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  cfg_.g_threads = 8;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  // Compare to check if stats match with row-mt=0/1.
  compare_fp_stats_md5(&firstpass_stats_);
}

class VPxEncoderThreadTest
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWith4Params<libvpx_test::TestMode, int,
                                                 int, int> {
 protected:
  VPxEncoderThreadTest()
      : EncoderTest(GET_PARAM(0)), encoder_initialized_(false),
        tiles_(GET_PARAM(3)), threads_(GET_PARAM(4)),
        encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
    init_flags_ = VPX_CODEC_USE_PSNR;
    md5_.clear();
    row_mt_mode_ = 1;
    psnr_ = 0.0;
    nframes_ = 0;
  }
  virtual ~VPxEncoderThreadTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);

    if (encoding_mode_ != ::libvpx_test::kRealTime) {
      cfg_.rc_end_usage = VPX_VBR;
      cfg_.rc_2pass_vbr_minsection_pct = 5;
      cfg_.rc_2pass_vbr_maxsection_pct = 2000;
    } else {
      cfg_.g_lag_in_frames = 0;
      cfg_.rc_end_usage = VPX_CBR;
      cfg_.g_error_resilient = 1;
    }
    cfg_.rc_max_quantizer = 56;
    cfg_.rc_min_quantizer = 0;
  }

  virtual void BeginPassHook(unsigned int /*pass*/) {
    encoder_initialized_ = false;
    psnr_ = 0.0;
    nframes_ = 0;
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
                                  ::libvpx_test::Encoder *encoder) {
    if (!encoder_initialized_) {
      // Encode 4 column tiles.
      encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_);
      encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
      if (encoding_mode_ != ::libvpx_test::kRealTime) {
        encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
        encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
        encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
        encoder->Control(VP8E_SET_ARNR_TYPE, 3);
        encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0);
      } else {
        encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
        encoder->Control(VP9E_SET_AQ_MODE, 3);
      }
      encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);

      encoder_initialized_ = true;
    }
  }

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

  virtual void DecompressedFrameHook(const vpx_image_t &img,
                                     vpx_codec_pts_t /*pts*/) {
    ::libvpx_test::MD5 md5_res;
    md5_res.Add(&img);
    md5_.push_back(md5_res.Get());
  }

  virtual bool HandleDecodeResult(const vpx_codec_err_t res,
                                  const libvpx_test::VideoSource & /*video*/,
                                  libvpx_test::Decoder * /*decoder*/) {
    if (res != VPX_CODEC_OK) {
      EXPECT_EQ(VPX_CODEC_OK, res);
      return false;
    }

    return true;
  }

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

  bool encoder_initialized_;
  int tiles_;
  int threads_;
  ::libvpx_test::TestMode encoding_mode_;
  int set_cpu_used_;
  int row_mt_mode_;
  double psnr_;
  unsigned int nframes_;
  std::vector<std::string> md5_;
};

TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
  ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
  cfg_.rc_target_bitrate = 1000;

  // Part 1: Bit exact test for row_mt_mode_ = 0.
  // This part keeps original unit tests done before row-mt code is checked in.
  row_mt_mode_ = 0;

  // Encode using single thread.
  cfg_.g_threads = 1;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  const std::vector<std::string> single_thr_md5 = md5_;
  md5_.clear();

  // Encode using multiple threads.
  cfg_.g_threads = threads_;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  const std::vector<std::string> multi_thr_md5 = md5_;
  md5_.clear();

  // Compare to check if two vectors are equal.
  ASSERT_EQ(single_thr_md5, multi_thr_md5);

  // Part 2: row_mt_mode_ = 0 vs row_mt_mode_ = 1 single thread bit exact test.
  row_mt_mode_ = 1;

  // Encode using single thread
  cfg_.g_threads = 1;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  std::vector<std::string> row_mt_single_thr_md5 = md5_;
  md5_.clear();

  ASSERT_EQ(single_thr_md5, row_mt_single_thr_md5);

  // Part 3: Bit exact test with row-mt on
  // When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact
  // result.
  row_mt_mode_ = 1;
  row_mt_single_thr_md5.clear();

  // Encode using 2 threads.
  cfg_.g_threads = 2;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  row_mt_single_thr_md5 = md5_;
  md5_.clear();

  // Encode using multiple threads.
  cfg_.g_threads = threads_;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  const std::vector<std::string> row_mt_multi_thr_md5 = md5_;
  md5_.clear();

  // Compare to check if two vectors are equal.
  ASSERT_EQ(row_mt_single_thr_md5, row_mt_multi_thr_md5);

  // Part 4: PSNR test with bit_match_mode_ = 0
  row_mt_mode_ = 1;

  // Encode using single thread.
  cfg_.g_threads = 1;
  init_flags_ = VPX_CODEC_USE_PSNR;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  const double single_thr_psnr = GetAveragePsnr();

  // Encode using multiple threads.
  cfg_.g_threads = threads_;
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  const double multi_thr_psnr = GetAveragePsnr();

  EXPECT_NEAR(single_thr_psnr, multi_thr_psnr, 0.2);
}

INSTANTIATE_TEST_SUITE_P(
    VP9, VPxFirstPassEncoderThreadTest,
    ::testing::Combine(
        ::testing::Values(
            static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
        ::testing::Values(::libvpx_test::kTwoPassGood),
        ::testing::Range(0, 4)));  // cpu_used

// Split this into two instantiations so that we can distinguish
// between very slow runs ( ie cpu_speed 0 ) vs ones that can be
// run nightly by adding Large to the title.
INSTANTIATE_TEST_SUITE_P(
    VP9, VPxEncoderThreadTest,
    ::testing::Combine(
        ::testing::Values(
            static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
        ::testing::Values(::libvpx_test::kTwoPassGood,
                          ::libvpx_test::kOnePassGood,
                          ::libvpx_test::kRealTime),
        ::testing::Range(3, 10),   // cpu_used
        ::testing::Range(0, 3),    // tile_columns
        ::testing::Range(2, 5)));  // threads

INSTANTIATE_TEST_SUITE_P(
    VP9Large, VPxEncoderThreadTest,
    ::testing::Combine(
        ::testing::Values(
            static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
        ::testing::Values(::libvpx_test::kTwoPassGood,
                          ::libvpx_test::kOnePassGood,
                          ::libvpx_test::kRealTime),
        ::testing::Range(0, 3),    // cpu_used
        ::testing::Range(0, 3),    // tile_columns
        ::testing::Range(2, 5)));  // threads

}  // namespace
