/*
 * Copyright (c) 2020, 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 "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/y4m_video_source.h"
#include "test/i420_video_source.h"
#include "test/util.h"
#include "aom/aom_codec.h"

#include "av1/encoder/encoder.h"
#include "av1/encoder/subgop.h"

// Silence compiler warning for unused static functions
static void yuvconfig2image(aom_image_t *img, const YV12_BUFFER_CONFIG *yv12,
                            void *user_priv) AOM_UNUSED;
static aom_codec_err_t image2yuvconfig(const aom_image_t *img,
                                       YV12_BUFFER_CONFIG *yv12) AOM_UNUSED;
#include "av1/av1_iface_common.h"

#define MAX_SUBGOP_CODES 3

static const char *subgop_config_str_nondef[] = {
  // enh, subgop size = 4
  "4:0:4U1/2U2/1V3/2S/3V3/4S,"
  "4:1:3U1/2U2/1V3/2S/3S/4V3,"
  // enh, subgop size = 5
  "5:0:5U1/3U2/1V3/2V3/3S/4V3/5S,"
  "5:1:4U1/2U2/1V3/2S/3V3/4S/5V3,"
  // enh, subgop size = 7
  "7:0:7U1/3U2/1V4/2V4/3S/5U3/4V4/5S/6V4/7S,"
  "7:1:6U1/3U2/2U3/1V4/2S/3S/5U3/4V4/5S/6S/7V4,"
  // enh, subgop size = 9
  "9:0:9F1/4U2/2U3/1V4/2S/3V4/4S/7U3/5V4/6V5/7S/8V5/9R1,"
  "9:1:7F1/3U2/1V4/2V4/3S/5U3/4V4/5S/6V4/7R1/9U3/8V4/9S,",
};

namespace {
// Default config
extern "C" const char subgop_config_str_def[];
// An enhanced config where the last subgop uses a shorter dist to arf
extern "C" const char subgop_config_str_enh[];
// A config that honors temporally scalable prediction structure, i.e.
// no frame is coded with references at higher pyramid depths.
extern "C" const char subgop_config_str_ts[];
// An asymmetrical config where the hierarchical frames are not exactly
// dyadic, but slightly skewed.
extern "C" const char subgop_config_str_asym[];
// low delay config without references
extern "C" const char subgop_config_str_ld[];

typedef enum {
  DEFAULT,
  ENHANCE,
  ASYMMETRIC,
  TEMPORAL_SCALABLE,
  LOW_DELAY,
} subgop_config_tag;

typedef struct {
  const char *preset_tag;
  const char *preset_str;
} subgop_config_str_preset_map_type;

const subgop_config_str_preset_map_type subgop_config_str_preset_map[] = {
  { "def", subgop_config_str_def },   { "enh", subgop_config_str_enh },
  { "asym", subgop_config_str_asym }, { "ts", subgop_config_str_ts },
  { "ld", subgop_config_str_ld },
};

typedef struct {
  const char *subgop_str;
  const char *input_file;
  int min_gf_interval;
  int max_gf_interval;
  int frame_w;
  int frame_h;
  int cpu_used;
  int lag_in_frames;
} SubgopTestParams;

int is_extension_y4m(const char *filename) {
  const char *dot = strrchr(filename, '.');
  if (!dot || dot == filename)
    return 0;
  else
    return !strcmp(dot, ".y4m");
}

static const SubgopTestParams SubGopTestVectors[] = {
  // Default subgop config
  { subgop_config_str_preset_map[DEFAULT].preset_tag,
    "hantro_collage_w352h288.yuv", 0, 16, 352, 288, 3, 35 },
  { subgop_config_str_preset_map[DEFAULT].preset_tag, "desktop1.320_180.yuv", 0,
    16, 320, 180, 5, 35 },
  { subgop_config_str_preset_map[DEFAULT].preset_tag,
    "pixel_capture_w320h240.yuv", 0, 16, 320, 240, 3, 35 },

  // Enhanced subgop config
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "niklas_640_480_30.yuv",
    0, 15, 640, 480, 5, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "paris_352_288_30.y4m", 0,
    6, 352, 288, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "hantro_collage_w352h288.yuv", 0, 16, 352, 288, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "pixel_capture_w320h240.yuv", 0, 12, 320, 240, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "niklas_1280_720_30.y4m",
    0, 11, 1280, 720, 5, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "screendata.y4m", 0, 16,
    640, 480, 5, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "pixel_capture_w320h240.yuv", 0, 14, 320, 240, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "desktop1.320_180.yuv", 0,
    10, 320, 180, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "paris_352_288_30.y4m", 0,
    13, 352, 288, 5, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "pixel_capture_w320h240.yuv", 0, 8, 320, 240, 5, 35 },

  // Asymmetric subgop config
  { subgop_config_str_preset_map[ASYMMETRIC].preset_tag,
    "pixel_capture_w320h240.yuv", 0, 16, 320, 240, 5, 35 },
  { subgop_config_str_preset_map[ASYMMETRIC].preset_tag, "desktop1.320_180.yuv",
    0, 16, 320, 180, 3, 35 },

  // Temporal scalable subgop config
  { subgop_config_str_preset_map[TEMPORAL_SCALABLE].preset_tag,
    "pixel_capture_w320h240.yuv", 0, 16, 320, 240, 3, 35 },
  { subgop_config_str_preset_map[TEMPORAL_SCALABLE].preset_tag,
    "hantro_collage_w352h288.yuv", 0, 16, 352, 288, 5, 35 },

  // Low delay subgop config
  { subgop_config_str_preset_map[LOW_DELAY].preset_tag, "paris_352_288_30.y4m",
    0, 16, 352, 288, 5, 0 },
  { subgop_config_str_preset_map[LOW_DELAY].preset_tag, "desktop1.320_180.yuv",
    0, 16, 320, 180, 3, 0 },

  // Non-default subgop config
  { subgop_config_str_nondef[0], "pixel_capture_w320h240.yuv", 0, 4, 320, 240,
    3, 35 },
  { subgop_config_str_nondef[0], "desktop1.320_180.yuv", 0, 5, 320, 180, 5,
    35 },
  { subgop_config_str_nondef[0], "pixel_capture_w320h240.yuv", 0, 7, 320, 240,
    5, 35 },
  { subgop_config_str_nondef[0], "hantro_collage_w352h288.yuv", 0, 9, 352, 288,
    3, 35 },
};

std::ostream &operator<<(std::ostream &os, const SubgopTestParams &test_arg) {
  return os << "SubgopTestParams { sub_gop_config:" << test_arg.subgop_str
            << " source_file:" << test_arg.input_file
            << " min_gf_interval:" << test_arg.min_gf_interval
            << " max_gf_interval:" << test_arg.max_gf_interval
            << " frame_width:" << test_arg.frame_w
            << " frame_height:" << test_arg.frame_h
            << " cpu_used:" << test_arg.cpu_used
            << " lag_in_frames:" << test_arg.lag_in_frames << " }";
}
// This class is used to validate the subgop config in a gop.
class SubGopTestLarge
    : public ::libaom_test::CodecTestWith2Params<SubgopTestParams, aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  SubGopTestLarge()
      : EncoderTest(GET_PARAM(0)), subgop_test_params_(GET_PARAM(1)),
        rc_end_usage_(GET_PARAM(2)) {
    InitSubgop();
  }
  virtual ~SubGopTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(::libaom_test::kOnePassGood);
    const aom_rational timebase = { 1, 30 };
    cfg_.g_timebase = timebase;
    cfg_.g_threads = 1;
    cfg_.rc_end_usage = rc_end_usage_;
    // Note: kf_min_dist, kf_max_dist, g_lag_in_frames are configurable
    // parameters
    cfg_.kf_min_dist = 65;
    cfg_.kf_max_dist = 65;
    cfg_.g_lag_in_frames = subgop_test_params_.lag_in_frames;
  }

  // check if subgop_config_str is a preset tag
  void GetSubGOPConfigStr() {
    int num_preset_configs = sizeof(subgop_config_str_preset_map) /
                             sizeof(*subgop_config_str_preset_map);
    for (int p = 0; p < num_preset_configs; ++p) {
      if (!strcmp(subgop_test_params_.subgop_str,
                  subgop_config_str_preset_map[p].preset_tag)) {
        subgop_test_params_.subgop_str =
            subgop_config_str_preset_map[p].preset_str;
        break;
      }
    }
  }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, subgop_test_params_.cpu_used);
      encoder->Control(AV1E_ENABLE_SUBGOP_STATS, enable_subgop_stats_);
      GetSubGOPConfigStr();
      encoder->Control(AV1E_SET_SUBGOP_CONFIG_STR,
                       subgop_test_params_.subgop_str);
      av1_process_subgop_config_set(subgop_test_params_.subgop_str,
                                    &user_cfg_set_);
      encoder->Control(AV1E_SET_MIN_GF_INTERVAL,
                       subgop_test_params_.min_gf_interval);
      encoder->Control(AV1E_SET_MAX_GF_INTERVAL,
                       subgop_test_params_.max_gf_interval);
    }
  }

  virtual bool DoDecode() const { return 1; }

  virtual void PreDecodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Decoder *decoder) {
    aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
    if (video->frame() == 0)
      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AV1D_ENABLE_SUBGOP_STATS,
                                    enable_subgop_stats_);
  }

  void InitSubgop() {
    memset(&user_cfg_set_, 0, sizeof(user_cfg_set_));
    subgop_data_.num_steps = MAX_SUBGOP_STATS_SIZE;
    ResetSubgop();
    is_first_frame_in_subgop_key_ = 0;
    frames_from_key_ = 0;
    frame_num_ = 0;
    // TODO(any): Extend this unit test for 'CONFIG_REALTIME_ONLY'
    enable_subgop_stats_ = 1;
    memset(&subgop_last_step_, 0, sizeof(subgop_last_step_));
  }

  void ResetSubgop() {
    subgop_info_.is_user_specified = 0;
    subgop_info_.frames_to_key = 0;
    subgop_info_.gf_interval = 0;
    subgop_info_.size = 0;
    subgop_info_.pos_code = SUBGOP_IN_GOP_GENERIC;

    for (int idx = 0; idx < MAX_SUBGOP_STATS_SIZE; idx++) {
      subgop_data_.step[idx].disp_frame_idx = -1;
      subgop_data_.step[idx].show_existing_frame = -1;
      subgop_data_.step[idx].show_frame = -1;
      subgop_data_.step[idx].is_filtered = -1;
      subgop_data_.step[idx].pyramid_level = 0;
      subgop_data_.step[idx].qindex = 0;
      subgop_data_.step[idx].refresh_frame_flags = 0;
      subgop_data_.step[idx].num_references = -1;
      memset(subgop_data_.step[idx].ref_frame_pyr_level, 0,
             sizeof(subgop_data_.step[idx].ref_frame_pyr_level));
      memset(subgop_data_.step[idx].is_valid_ref_frame, 0,
             sizeof(subgop_data_.step[idx].is_valid_ref_frame));
      memset(subgop_data_.step[idx].ref_frame_map, 0,
             sizeof(subgop_data_.step[idx].ref_frame_map));
      for (int ref = 0; ref < INTER_REFS_PER_FRAME; ref++) {
        subgop_data_.step[idx].ref_frame_disp_order[ref] = -1;
        display_order_test_[idx][ref] = -1;
      }
    }
    subgop_data_.num_steps = 0;
    subgop_data_.step_idx_enc = 0;
    subgop_data_.step_idx_dec = 0;

    subgop_code_test_ = SUBGOP_IN_GOP_GENERIC;
    subgop_size_ = 0;
    frame_num_in_subgop_ = 0;
  }

  void DetermineSubgopCode(libaom_test::Encoder *encoder) {
    encoder->Control(AV1E_GET_FRAME_TYPE, &frame_type_test_);
    if (frame_type_test_ == KEY_FRAME) {
      is_first_frame_in_subgop_key_ = 1;
      return;
    }
    const int is_last_subgop =
        subgop_info_.frames_to_key <= (subgop_info_.gf_interval + 1);
    const int is_first_subgop = is_first_frame_in_subgop_key_;
    if (is_last_subgop)
      subgop_code_test_ = SUBGOP_IN_GOP_LAST;
    else if (is_first_subgop)
      subgop_code_test_ = SUBGOP_IN_GOP_FIRST;
    else
      subgop_code_test_ = SUBGOP_IN_GOP_GENERIC;
    subgop_size_ = subgop_info_.gf_interval;
  }

  virtual bool HandleEncodeResult(::libaom_test::VideoSource *video,
                                  libaom_test::Encoder *encoder) {
    (void)video;
    // Capturing the subgop info at the start of subgop.
    if (!frame_num_in_subgop_) {
      encoder->Control(AV1E_GET_SUB_GOP_CONFIG, &subgop_info_);
      DetermineSubgopCode(encoder);
      // Validation of user specified subgop structure adoption in encoder path.
      ValidateSubgopConfig();
      subgop_data_.num_steps = subgop_info_.num_steps;
    }
    if (subgop_info_.is_user_specified)
      encoder->Control(AV1E_GET_FRAME_INFO, &subgop_data_);
    return 1;
  }

  void FillTestSubgopConfig() {
    int filtered_frames[REF_FRAMES] = { 0 }, buf_idx = 0;
    if (frame_type_test_ == KEY_FRAME) return;

    subgop_cfg_test_.num_frames = (int8_t)subgop_info_.size;
    subgop_cfg_test_.num_steps = (int8_t)subgop_data_.num_steps;
    subgop_cfg_test_.subgop_in_gop_code = subgop_info_.pos_code;
    // Populating the filter-type of out-of-order frames appropriately for all
    // steps in sub-gop.
    for (int idx = 0; idx < subgop_data_.num_steps; idx++) {
      subgop_cfg_test_.step[idx].disp_frame_idx =
          (int8_t)(subgop_data_.step[idx].disp_frame_idx - frames_from_key_);
      subgop_cfg_test_.step[idx].pyr_level =
          (int8_t)subgop_data_.step[idx].pyramid_level;
      subgop_cfg_test_.step[idx].num_references =
          (int8_t)subgop_data_.step[idx].num_references;
      for (int ref = 0; ref < INTER_REFS_PER_FRAME; ref++) {
        subgop_cfg_test_.step[idx].references[ref] =
            (int8_t)subgop_data_.step[idx].ref_frame_pyr_level[ref];
        display_order_test_[idx][ref] =
            subgop_data_.step[idx].ref_frame_disp_order[ref];
      }
      if (subgop_data_.step[idx].is_filtered) {
        filtered_frames[buf_idx++] =
            subgop_data_.step[idx].disp_frame_idx - frames_from_key_;
      } else {
        for (int ref_frame = 0; ref_frame < buf_idx; ref_frame++) {
          if (subgop_cfg_test_.step[idx].disp_frame_idx ==
              (int8_t)filtered_frames[ref_frame])
            subgop_data_.step[idx].is_filtered = 1;
        }
      }
    }
    // Calculating frame type code for all the steps in subgop.
    for (int idx = 0; idx < subgop_data_.num_steps; idx++) {
      FRAME_TYPE_CODE frame_type_code = FRAME_TYPE_INO_VISIBLE;
      int show_existing_frame = subgop_data_.step[idx].show_existing_frame;
      int show_frame = subgop_data_.step[idx].show_frame;
      int is_filtered = subgop_data_.step[idx].is_filtered;

      assert(show_existing_frame >= 0);
      assert(show_frame >= 0);
      assert(frame_type_code != 0);
      if (show_existing_frame == 0) {
        if (show_frame == 0)
          frame_type_code = (is_filtered == 1) ? FRAME_TYPE_OOO_FILTERED
                                               : FRAME_TYPE_OOO_UNFILTERED;
        else if (show_frame == 1)
          frame_type_code = (is_filtered == 1) ? FRAME_TYPE_INO_REPEAT
                                               : FRAME_TYPE_INO_VISIBLE;
      } else if (show_existing_frame == 1) {
        frame_type_code = (is_filtered == 1) ? FRAME_TYPE_INO_REPEAT
                                             : FRAME_TYPE_INO_SHOWEXISTING;
      }
      subgop_cfg_test_.step[idx].type_code = frame_type_code;
    }
  }

  SubGOPCfg *DetermineSubgopConfig() {
    SubGOPCfg *subgop_cfg = user_cfg_set_.config;
    SubGOPCfg *viable_subgop_cfg[MAX_SUBGOP_CODES] = { NULL };
    unsigned int cfg_count = 0;

    for (int idx = 0; idx < user_cfg_set_.num_configs; idx++) {
      if (subgop_cfg[idx].num_frames == (int8_t)subgop_size_) {
        if (subgop_cfg[idx].subgop_in_gop_code == subgop_code_test_)
          return &subgop_cfg[idx];
        else
          viable_subgop_cfg[cfg_count++] = &subgop_cfg[idx];
        assert(cfg_count < MAX_SUBGOP_CODES);
      }
    }
    subgop_code_test_ = SUBGOP_IN_GOP_GENERIC;
    for (unsigned int cfg = 0; cfg < cfg_count; cfg++) {
      if (viable_subgop_cfg[cfg]->subgop_in_gop_code == subgop_code_test_)
        return viable_subgop_cfg[cfg];
    }
    return NULL;
  }

  // Validates frametype(along with temporal filtering), frame coding order
  bool ValidateSubgopFrametype() {
    for (int idx = 0; idx < subgop_cfg_ref_->num_steps; idx++) {
      EXPECT_EQ(subgop_cfg_ref_->step[idx].disp_frame_idx,
                subgop_cfg_test_.step[idx].disp_frame_idx)
          << "Error:display_index doesn't match";
      EXPECT_EQ(subgop_cfg_ref_->step[idx].type_code,
                subgop_cfg_test_.step[idx].type_code)
          << "Error:frame type doesn't match";
    }
    return 1;
  }

  // Validates Pyramid level with user config
  void ValidatePyramidLevel() {
    int8_t max_pyramid_level = 0;
    for (int idx = 0; idx < subgop_cfg_ref_->num_steps; idx++) {
      if (max_pyramid_level < subgop_cfg_ref_->step[idx].pyr_level)
        max_pyramid_level = subgop_cfg_ref_->step[idx].pyr_level;
    }
    for (int idx = 0; idx < subgop_cfg_ref_->num_steps; idx++) {
      int8_t ref_pyramid_level =
          (subgop_cfg_ref_->step[idx].pyr_level == max_pyramid_level)
              ? 6
              : subgop_cfg_ref_->step[idx].pyr_level;
      EXPECT_EQ(subgop_cfg_test_.step[idx].pyr_level, ref_pyramid_level)
          << "Error:pyramid level doesn't match";
    }
  }

  // Validates Pyramid level along with qindex assignment
  void ValidatePyramidLevelQIndex() {
    int level_qindex[REF_FRAMES] = { 0 };
    int8_t pyramid_level;
    for (int idx = 0; idx < subgop_cfg_ref_->num_steps; idx++) {
      pyramid_level = subgop_cfg_test_.step[idx].pyr_level;
      if (!level_qindex[pyramid_level]) {
        level_qindex[pyramid_level] = subgop_data_.step[idx].qindex;
      } else if (!subgop_data_.step[idx].show_existing_frame &&
                 !subgop_data_.step[idx].is_filtered) {
        EXPECT_EQ(level_qindex[pyramid_level], subgop_data_.step[idx].qindex)
            << "Error:qindex in a pyramid level doesn't match";
      }
    }
    pyramid_level = 1;
    for (int idx = 1; idx < REF_FRAMES; idx++) {
      if (level_qindex[pyramid_level]) {
        EXPECT_LT(level_qindex[pyramid_level - 1], level_qindex[pyramid_level])
            << "Error:qindex should be higher in hierarchical pyramid level";
        pyramid_level++;
      }
    }
  }

  // Validates reference buffer refresh
  void ValidateRefBufRefresh() {
    int start_idx = 0;
    SubGOPStepData *prev_step_data = &subgop_last_step_;
    if (is_first_frame_in_subgop_key_) {
      start_idx = 1;
      prev_step_data = &subgop_data_.step[0];
    }

    for (int idx = start_idx; idx < subgop_cfg_ref_->num_steps; idx++) {
      SubGOPStepData *curr_step_data = &subgop_data_.step[idx];
      int ref_count = 0;
      int refresh_frame_flags = curr_step_data->refresh_frame_flags;
      // Validates user-defined refresh_flag with decoder
      if (subgop_cfg_ref_->step[idx].refresh != -1 &&
          !curr_step_data->show_existing_frame) {
        EXPECT_EQ(subgop_cfg_ref_->step[idx].refresh,
                  (int8_t)refresh_frame_flags)
            << "Error: refresh flag mismatch";
      }
      // Validates reference picture management w.r.t refresh_flags
      if (refresh_frame_flags && !curr_step_data->show_existing_frame) {
        for (int mask = refresh_frame_flags; mask; mask >>= 1) {
          if (mask & 1)
            EXPECT_EQ(curr_step_data->disp_frame_idx,
                      (int)curr_step_data->ref_frame_map[ref_count])
                << "Error: reference buffer refresh failed";
          else
            EXPECT_EQ(prev_step_data->ref_frame_map[ref_count],
                      curr_step_data->ref_frame_map[ref_count])
                << "Error: reference buffer refresh failed";
          assert(ref_count < REF_FRAMES);
          ref_count++;
        }
      }

      for (int ref_idx = ref_count; ref_idx < REF_FRAMES; ref_idx++)
        EXPECT_EQ(prev_step_data->ref_frame_map[ref_idx],
                  curr_step_data->ref_frame_map[ref_idx])
            << "Error: reference buffer refresh failed";
      prev_step_data = curr_step_data;
    }
  }

  void ValidateRefFrames() {
    int start_idx = is_first_frame_in_subgop_key_;
    for (int idx = start_idx; idx < subgop_cfg_ref_->num_steps; idx++) {
      unsigned int *ref_frame_map =
          (idx > 0) ? subgop_data_.step[idx - 1].ref_frame_map
                    : subgop_last_step_.ref_frame_map;
      if (!subgop_data_.step[idx].show_existing_frame) {
        EXPECT_EQ(subgop_cfg_ref_->step[idx].num_references,
                  subgop_cfg_test_.step[idx].num_references)
            << "Error:Reference frames count doesn't match";
      }
      // To validate the count of ref_frames and their management with user
      // config.
      for (int ref = 0; ref < subgop_cfg_test_.step[idx].num_references;
           ref++) {
        if (subgop_data_.step[idx].is_valid_ref_frame[ref]) {
          EXPECT_EQ(subgop_cfg_ref_->step[idx].references[ref],
                    subgop_cfg_test_.step[idx].references[ref])
              << "Error:Reference frame level doesn't match";
          for (int buf = 0; buf < REF_FRAMES; buf++) {
            if (display_order_test_[idx][ref] == (int)ref_frame_map[buf]) break;
            EXPECT_NE(buf, REF_FRAMES - 1)
                << "Error:Ref frame isn't part of ref_picture_buf";
          }
        }
      }
    }
  }

  bool IsInputSubgopCfgUsed() {
    int num_ooo_frames_ref = 0;
    int num_ooo_frames_test = 0;
    // Encoder may choose to opt out input sub-gop config when use_altref is 0
    // for the given sub-gop
    for (int idx = 0; idx < subgop_cfg_ref_->num_steps; idx++) {
      // Count number out-of-order frames in reference config
      num_ooo_frames_ref +=
          subgop_cfg_ref_->step[idx].type_code == FRAME_TYPE_OOO_FILTERED;
      num_ooo_frames_ref +=
          subgop_cfg_ref_->step[idx].type_code == FRAME_TYPE_OOO_UNFILTERED;
      // Count number out-of-order frames in test config
      num_ooo_frames_test +=
          subgop_cfg_test_.step[idx].type_code == FRAME_TYPE_OOO_FILTERED;
      num_ooo_frames_test +=
          subgop_cfg_test_.step[idx].type_code == FRAME_TYPE_OOO_UNFILTERED;
    }
    return num_ooo_frames_ref == num_ooo_frames_test;
  }

  void ValidateSubgopConfig() {
    if (frame_type_test_ == KEY_FRAME) return;
    subgop_cfg_ref_ = DetermineSubgopConfig();
    if (subgop_cfg_ref_) {
      EXPECT_EQ((int8_t)subgop_size_, subgop_cfg_ref_->num_frames)
          << "Error:subgop config selection wrong";
      subgop_info_.is_user_specified = 1;
    }
  }

  virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
                                  libaom_test::Decoder *decoder) {
    EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
    if (AOM_CODEC_OK != res_dec) return 0;
    aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
    frame_num_in_subgop_++;
    int is_last_frame_in_subgop = (frame_num_in_subgop_ == subgop_info_.size);

    if (subgop_info_.is_user_specified ||
        is_last_frame_in_subgop)  // To collect last step info of subgop in
                                  // encoder defined config
      AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_FRAME_INFO,
                                    &subgop_data_);
    if (is_last_frame_in_subgop) {
      // Validation of sub-gop structure propagation to decoder.
      if (subgop_info_.is_user_specified) {
        FillTestSubgopConfig();
        if ((subgop_info_.is_user_specified = IsInputSubgopCfgUsed())) {
          EXPECT_EQ(subgop_code_test_, subgop_info_.pos_code)
              << "Error:subgop code doesn't match";
          ValidateSubgopFrametype();
          ValidatePyramidLevel();
          if (rc_end_usage_ == AOM_Q) ValidatePyramidLevelQIndex();
          ValidateRefBufRefresh();
          ValidateRefFrames();
        }
      }
      frames_from_key_ += subgop_info_.size;
      if (frame_type_test_ == KEY_FRAME) {
        frames_from_key_ = 0;
      } else {
        is_first_frame_in_subgop_key_ = 0;
        // To collect last step info of subgop.
        assert(subgop_data_.step_idx_dec >= 0);
        memcpy(&subgop_last_step_,
               &subgop_data_.step[subgop_data_.step_idx_dec - 1],
               sizeof(subgop_last_step_));
      }
      ResetSubgop();
    }
    frame_num_++;
    return AOM_CODEC_OK == res_dec;
  }

  SubgopTestParams subgop_test_params_;
  SubGOPSetCfg user_cfg_set_;
  SubGOPCfg subgop_cfg_test_;
  SubGOPCfg *subgop_cfg_ref_;
  SubGOPInfo subgop_info_;
  SubGOPData subgop_data_;
  SubGOPStepData subgop_last_step_;
  SUBGOP_IN_GOP_CODE subgop_code_test_;
  FRAME_TYPE frame_type_test_;
  aom_rc_mode rc_end_usage_;
  int display_order_test_[MAX_SUBGOP_SIZE][REF_FRAMES];
  int subgop_size_;
  bool is_first_frame_in_subgop_key_;
  int frames_from_key_;
  int frame_num_in_subgop_;
  unsigned int frame_num_;
  unsigned int enable_subgop_stats_;
};

TEST_P(SubGopTestLarge, SubGopTest) {
  if (!is_extension_y4m(subgop_test_params_.input_file)) {
    libaom_test::I420VideoSource video(
        subgop_test_params_.input_file, subgop_test_params_.frame_w,
        subgop_test_params_.frame_h, cfg_.g_timebase.den, cfg_.g_timebase.num,
        0, 200);
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  } else {
    ::libaom_test::Y4mVideoSource video(subgop_test_params_.input_file, 0, 200);
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }
}

AV1_INSTANTIATE_TEST_SUITE(SubGopTestLarge,
                           ::testing::ValuesIn(SubGopTestVectors),
                           ::testing::Values(AOM_Q, AOM_VBR, AOM_CQ, AOM_CBR));

typedef struct {
  const char *subgop_str;
  const char *input_file;
  int frame_w;
  int frame_h;
  int cpu_used;
  int lag_in_frames;
} SubgopPsnrTestParams;

static const SubgopPsnrTestParams SubGopPsnrTestVectors[] = {
  { subgop_config_str_preset_map[DEFAULT].preset_tag,
    "hantro_collage_w352h288.yuv", 352, 288, 3, 35 },
  { subgop_config_str_preset_map[DEFAULT].preset_tag, "desktop1.320_180.yuv",
    320, 180, 5, 35 },

  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "hantro_collage_w352h288.yuv", 352, 288, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "pixel_capture_w320h240.yuv", 320, 240, 5, 35 },
  // TODO(any): Enable after fix
  /* { subgop_config_str_preset_map[ENHANCE].preset_tag, "paris_352_288_30.y4m",
     352, 288, 3, 35 },
     { subgop_config_str_preset_map[ENHANCE].preset_tag, "screendata.y4m", 640,
     480, 5, 35 },
     { subgop_config_str_preset_map[ENHANCE].preset_tag, "paris_352_288_30.y4m",
     352, 288, 5, 35 }, */

  { subgop_config_str_preset_map[ASYMMETRIC].preset_tag,
    "pixel_capture_w320h240.yuv", 320, 240, 5, 35 },
  // TODO(any): Enable after fix
  /* { subgop_config_str_preset_map[ASYMMETRIC].preset_tag,
    "desktop1.320_180.yuv", 320, 180, 3, 35 }, */

  { subgop_config_str_preset_map[TEMPORAL_SCALABLE].preset_tag,
    "hantro_collage_w352h288.yuv", 352, 288, 5, 35 },

  // TODO(any): Enable after fix
  /* { subgop_config_str_preset_map[LOW_DELAY].preset_tag,
     "paris_352_288_30.y4m", 352, 288, 5, 0 },
     { subgop_config_str_preset_map[LOW_DELAY].preset_tag,
     "desktop1.320_180.yuv", 320, 180, 3, 0 }, */
};

std::ostream &operator<<(std::ostream &os,
                         const SubgopPsnrTestParams &test_arg) {
  return os << "SubgopPsnrTestParams { sub_gop_config:" << test_arg.subgop_str
            << " source_file:" << test_arg.input_file
            << " frame_width:" << test_arg.frame_w
            << " frame_height:" << test_arg.frame_h
            << " cpu_used:" << test_arg.cpu_used
            << " lag_in_frames:" << test_arg.lag_in_frames << " }";
}

class SubGopPSNRCheckTest
    : public ::libaom_test::CodecTestWith2Params<SubgopPsnrTestParams,
                                                 aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  SubGopPSNRCheckTest()
      : EncoderTest(GET_PARAM(0)), test_params_(GET_PARAM(1)),
        rc_end_usage_(GET_PARAM(2)) {
    Reset();
  }
  virtual ~SubGopPSNRCheckTest() {}

  void Reset() {
    frame_num_ = 0;
    total_psnr_ = 0.0;
    enable_subgop_ = 0;
  }

  virtual void SetUp() {
    InitializeConfig();
    SetMode(::libaom_test::kOnePassGood);
    cfg_.g_threads = 1;
    cfg_.g_lag_in_frames = test_params_.lag_in_frames;
    cfg_.rc_end_usage = rc_end_usage_;
    init_flags_ = AOM_CODEC_USE_PSNR;
  }

  virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
    // Accumulate total psnr
    total_psnr_ += pkt->data.psnr.psnr[0];
    frame_num_++;
  }

  double GetAveragePsnr() const {
    if (frame_num_) return total_psnr_ / frame_num_;
    return 0.0;
  }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, test_params_.cpu_used);
      if (enable_subgop_)
        encoder->Control(AV1E_SET_SUBGOP_CONFIG_STR, test_params_.subgop_str);
    }
  }
  unsigned int enable_subgop_;
  SubgopPsnrTestParams test_params_;

 private:
  aom_rc_mode rc_end_usage_;
  double total_psnr_;
  unsigned int frame_num_;
};

TEST_P(SubGopPSNRCheckTest, SubGopPSNRCheck) {
  std::unique_ptr<libaom_test::VideoSource> video;
  const unsigned int kFrames = 100;
  const double psnr_diff_thresh = 0.2;
  if (is_extension_y4m(test_params_.input_file)) {
    video.reset(
        new libaom_test::Y4mVideoSource(test_params_.input_file, 0, kFrames));
  } else {
    video.reset(new libaom_test::YUVVideoSource(
        test_params_.input_file, AOM_IMG_FMT_I420, test_params_.frame_w,
        test_params_.frame_h, 30, 1, 0, kFrames));
  }

  // Encode with no sub-gop configuration
  ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
  const double psnr_no_subgop_ = GetAveragePsnr();
  Reset();

  // Encode with default sub-gop configuration
  enable_subgop_ = 1;
  ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
  const double psnr_subgop_ = GetAveragePsnr();

  const double psnr_diff = psnr_subgop_ - psnr_no_subgop_;
  EXPECT_LE(fabs(psnr_diff), psnr_diff_thresh);
}

// TODO(any) : Enable AOM_CBR after fix
AV1_INSTANTIATE_TEST_SUITE(SubGopPSNRCheckTest,
                           ::testing::ValuesIn(SubGopPsnrTestVectors),
                           ::testing::Values(AOM_Q, AOM_VBR,
                                             AOM_CQ /*, AOM_CBR*/));

typedef struct {
  const char *subgop_str;
  const char *input_file;
  int frame_w;
  int frame_h;
  int cpu_used;
  int lag_in_frames;
} SubGopSwitchTestParams;

static const SubGopSwitchTestParams SubgopSwitchTestVectors[] = {
  { subgop_config_str_preset_map[DEFAULT].preset_tag, "niklas_640_480_30.yuv",
    640, 480, 5, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag, "desktop1.320_180.yuv",
    320, 180, 3, 35 },
  { subgop_config_str_preset_map[ENHANCE].preset_tag,
    "hantro_collage_w352h288.yuv", 352, 288, 5, 35 },
  { subgop_config_str_preset_map[ASYMMETRIC].preset_tag,
    "pixel_capture_w320h240.yuv", 320, 240, 3, 35 },
  { subgop_config_str_preset_map[TEMPORAL_SCALABLE].preset_tag,
    "paris_352_288_30.y4m", 352, 288, 3, 35 },
  { subgop_config_str_preset_map[LOW_DELAY].preset_tag, "screendata.y4m", 640,
    480, 5, 0 },
};

using libaom_test::ACMRandom;
class SubGopSwitchingTest
    : public ::libaom_test::CodecTestWith2Params<SubGopSwitchTestParams,
                                                 aom_rc_mode>,
      public ::libaom_test::EncoderTest {
 protected:
  SubGopSwitchingTest()
      : EncoderTest(GET_PARAM(0)), test_params_(GET_PARAM(1)),
        rc_end_usage_(GET_PARAM(2)) {
    last_subgop_str_ = NULL;
    num_subgop_cfg_used_ = 0;
    rnd_.Reset(ACMRandom::DeterministicSeed());
    ResetSubgop();
  }
  virtual ~SubGopSwitchingTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(::libaom_test::kOnePassGood);
    cfg_.g_threads = 1;
    cfg_.rc_end_usage = rc_end_usage_;
    cfg_.g_lag_in_frames = test_params_.lag_in_frames;
  }

  void ResetSubgop() {
    frame_num_in_subgop_ = 0;
    subgop_size_ = 0;
    memset(&subgop_info_, 0, sizeof(subgop_info_));
  }

  bool GetRandSwitch() { return !(rnd_.Rand8() & 1); }

  int GetRandGFIntervalEnh() {
    const int subgop_size_enh[] = { 6, 8, 10, 11, 12, 13, 14, 15, 16 };
    const int length = sizeof(subgop_size_enh) / sizeof(subgop_size_enh[0]);
    const int idx = rnd_.Rand8() % length;

    return subgop_size_enh[idx];
  }

  void set_subgop_config(::libaom_test::Encoder *encoder) {
    const bool switch_subgop_cfg = GetRandSwitch();
    if (!switch_subgop_cfg) return;

    // Switch between input sub-gop and no sub-gop config and configure the
    // encoder
    const char *subgop_str = last_subgop_str_ ? NULL : test_params_.subgop_str;
    int max_gf_interval = 16;
    // Get max gf interval for enh config
    if (subgop_str && !strcmp(subgop_str, "enh"))
      max_gf_interval = GetRandGFIntervalEnh();

    // Set subgop config string
    encoder->Control(AV1E_SET_SUBGOP_CONFIG_STR, subgop_str);

    // Set max gf interval
    if (subgop_str) encoder->Control(AV1E_SET_MAX_GF_INTERVAL, max_gf_interval);

    last_subgop_str_ = subgop_str;
  }

  virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
                                  ::libaom_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(AOME_SET_CPUUSED, test_params_.cpu_used);
      // Set min gf interval
      encoder->Control(AV1E_SET_MIN_GF_INTERVAL, 6);
      set_subgop_config(encoder);
    }

    // Configure sub-gop string before sub-gop decision
    if (frame_num_in_subgop_ == subgop_size_) {
      ResetSubgop();
      set_subgop_config(encoder);
    }
  }

  virtual bool HandleEncodeResult(::libaom_test::VideoSource *video,
                                  libaom_test::Encoder *encoder) {
    (void)video;
    // Get sub-gop info at beginning of the sub-gop
    if (!frame_num_in_subgop_) {
      FRAME_TYPE frame_type = FRAME_TYPES;

      // Get current frame type
      encoder->Control(AV1E_GET_FRAME_TYPE, &frame_type);
      assert(frame_type != FRAME_TYPES);
      // Get subgop config
      encoder->Control(AV1E_GET_SUB_GOP_CONFIG, &subgop_info_);

      // Compute sub-gop size
      subgop_size_ = subgop_info_.gf_interval;
      // Include KF in sub-gop size
      if (frame_type == KEY_FRAME) subgop_size_++;

      // Update count of subgop cfg usage by the encoder
      num_subgop_cfg_used_ += subgop_info_.is_user_specified;
    }
    return 1;
  }

  virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
                                  libaom_test::Decoder *decoder) {
    EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
    if (AOM_CODEC_OK != res_dec) return 0;

    frame_num_in_subgop_++;

    return AOM_CODEC_OK == res_dec;
  }
  SubGopSwitchTestParams test_params_;
  unsigned int num_subgop_cfg_used_;

 private:
  ACMRandom rnd_;
  aom_rc_mode rc_end_usage_;
  SubGOPInfo subgop_info_;
  unsigned int frame_num_in_subgop_;
  unsigned int subgop_size_;
  const char *last_subgop_str_;
};

TEST_P(SubGopSwitchingTest, SubGopSwitching) {
  std::unique_ptr<libaom_test::VideoSource> video;
  const unsigned int kFrames = 200;

  if (is_extension_y4m(test_params_.input_file)) {
    video.reset(
        new libaom_test::Y4mVideoSource(test_params_.input_file, 0, kFrames));
  } else {
    video.reset(new libaom_test::YUVVideoSource(
        test_params_.input_file, AOM_IMG_FMT_I420, test_params_.frame_w,
        test_params_.frame_h, 30, 1, 0, kFrames));
  }

  ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));

  // Check input config is used by the encoder
  EXPECT_TRUE(num_subgop_cfg_used_);
}

AV1_INSTANTIATE_TEST_SUITE(SubGopSwitchingTest,
                           ::testing::ValuesIn(SubgopSwitchTestVectors),
                           ::testing::Values(AOM_Q, AOM_VBR, AOM_CQ, AOM_CBR));
}  // namespace
