/*
 * Copyright (c) 2022, 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.
 */

// Tests for https://crbug.com/aomedia/3327.
//
// In good-quality mode, set cfg.g_lag_in_frames to 1 or 0 and encode two
// frames in one-pass mode. Pass AOM_EFLAG_FORCE_KF to the second
// aom_codec_encode() call. Both frames should be encoded as key frames.

#include <memory>

#include "aom/aomcx.h"
#include "aom/aom_encoder.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

namespace {

void TestOnePassMode(unsigned int lag_in_frames) {
  // A buffer of gray samples of size 128x128, YUV 4:2:0.
  constexpr size_t kImageDataSize = 128 * 128 + 2 * 64 * 64;
  std::unique_ptr<unsigned char[]> img_data(new unsigned char[kImageDataSize]);
  ASSERT_NE(img_data, nullptr);
  memset(img_data.get(), 128, kImageDataSize);

  aom_codec_iface_t *iface = aom_codec_av1_cx();
  aom_codec_enc_cfg_t cfg;
  ASSERT_EQ(AOM_CODEC_OK,
            aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY));
  cfg.g_w = 128;
  cfg.g_h = 128;
  cfg.g_pass = AOM_RC_ONE_PASS;
  cfg.g_lag_in_frames = lag_in_frames;
  aom_codec_ctx_t enc;
  EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));

  aom_image_t img;
  EXPECT_EQ(&img,
            aom_img_wrap(&img, AOM_IMG_FMT_I420, 128, 128, 1, img_data.get()));

  aom_codec_iter_t iter;
  const aom_codec_cx_pkt_t *pkt;
  int frame_count = 0;

  EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));

  iter = nullptr;
  while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
    ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
    EXPECT_NE(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u)
        << "frame " << frame_count;
    frame_count++;
  }

  EXPECT_EQ(AOM_CODEC_OK,
            aom_codec_encode(&enc, &img, 1, 1, AOM_EFLAG_FORCE_KF));

  iter = nullptr;
  while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
    ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
    EXPECT_NE(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u)
        << "frame " << frame_count;
    frame_count++;
  }

  EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 0, 0));

  iter = nullptr;
  while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
    ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
    EXPECT_NE(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u)
        << "frame " << frame_count;
    frame_count++;
  }

  EXPECT_EQ(frame_count, 2);
  EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
}

TEST(ForceKeyFrameTest, OnePassModeLag0) { TestOnePassMode(0); }

TEST(ForceKeyFrameTest, OnePassModeLag1) { TestOnePassMode(1); }

TEST(ForceKeyFrameTest, OnePassModeLag2) { TestOnePassMode(2); }

}  // namespace
