/*
 * 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 "aom_dsp/binary_codes_writer.h"
#include "aom_ports/system_state.h"

#include "av1/common/mv.h"
#include "av1/encoder/corner_detect.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/ethread.h"
#include "av1/encoder/rdopt.h"

// Highest motion model to search.
#define GLOBAL_TRANS_TYPES_ENC 3

// Computes the cost for the warp parameters.
static int gm_get_params_cost(const WarpedMotionParams *gm,
                              const WarpedMotionParams *ref_gm,
                              MvSubpelPrecision precision) {
  const int precision_loss = get_gm_precision_loss(precision);
#if CONFIG_IMPROVED_GLOBAL_MOTION
  (void)precision_loss;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION
  int params_cost = 0;
#if CONFIG_IMPROVED_GLOBAL_MOTION
  const int trans_bits = GM_ABS_TRANS_BITS;
  const int trans_prec_diff = GM_TRANS_PREC_DIFF;
  const int trans_max = (1 << trans_bits) - 1;
#else
  const int trans_bits = (gm->wmtype == TRANSLATION)
                             ? GM_ABS_TRANS_ONLY_BITS - precision_loss
                             : GM_ABS_TRANS_BITS;
  const int trans_prec_diff = (gm->wmtype == TRANSLATION)
                                  ? GM_TRANS_ONLY_PREC_DIFF + precision_loss
                                  : GM_TRANS_PREC_DIFF;
  const int trans_max = (1 << trans_bits);
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

  switch (gm->wmtype) {
    case AFFINE:
    case ROTZOOM:
      params_cost += aom_count_signed_primitive_refsubexpfin(
          GM_ALPHA_MAX + 1, SUBEXPFIN_K,
          (ref_gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
          (gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
      params_cost += aom_count_signed_primitive_refsubexpfin(
          GM_ALPHA_MAX + 1, SUBEXPFIN_K,
          (ref_gm->wmmat[3] >> GM_ALPHA_PREC_DIFF),
          (gm->wmmat[3] >> GM_ALPHA_PREC_DIFF));
      if (gm->wmtype >= AFFINE) {
        params_cost += aom_count_signed_primitive_refsubexpfin(
            GM_ALPHA_MAX + 1, SUBEXPFIN_K,
            (ref_gm->wmmat[4] >> GM_ALPHA_PREC_DIFF),
            (gm->wmmat[4] >> GM_ALPHA_PREC_DIFF));
        params_cost += aom_count_signed_primitive_refsubexpfin(
            GM_ALPHA_MAX + 1, SUBEXPFIN_K,
            (ref_gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
                (1 << GM_ALPHA_PREC_BITS),
            (gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
      }
      params_cost += aom_count_signed_primitive_refsubexpfin(
          trans_max + 1, SUBEXPFIN_K, (ref_gm->wmmat[0] >> trans_prec_diff),
          (gm->wmmat[0] >> trans_prec_diff));
      params_cost += aom_count_signed_primitive_refsubexpfin(
          trans_max + 1, SUBEXPFIN_K, (ref_gm->wmmat[1] >> trans_prec_diff),
          (gm->wmmat[1] >> trans_prec_diff));
      AOM_FALLTHROUGH_INTENDED;
    case IDENTITY: break;
    default: assert(0);
  }
  return (params_cost << AV1_PROB_COST_SHIFT);
}

// Calculates the threshold to be used for warp error computation.
static AOM_INLINE int64_t calc_erroradv_threshold(int64_t ref_frame_error) {
  return (int64_t)(ref_frame_error * erroradv_tr + 0.5);
}

// For the given reference frame, computes the global motion parameters for
// different motion models and finds the best.
#if CONFIG_IMPROVED_GLOBAL_MOTION
static AOM_INLINE void compute_global_motion_for_ref_frame(
    AV1_COMP *cpi, YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME], int frame,
    int num_src_corners, int *src_corners, unsigned char *src_buffer,
    MotionModel *params_by_motion, uint8_t *segment_map,
    const int segment_map_w, const int segment_map_h) {
#else
static AOM_INLINE void compute_global_motion_for_ref_frame(
    AV1_COMP *cpi, YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME], int frame,
    int num_src_corners, int *src_corners, unsigned char *src_buffer,
    MotionModel *params_by_motion, uint8_t *segment_map,
    const int segment_map_w, const int segment_map_h,
    const WarpedMotionParams *ref_params) {
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION
  ThreadData *const td = &cpi->td;
  MACROBLOCK *const x = &td->mb;
  AV1_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;
#if CONFIG_IMPROVED_GLOBAL_MOTION
  GlobalMotionInfo *const gm_info = &cpi->gm_info;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

  int i;
  int src_width = cpi->source->y_width;
  int src_height = cpi->source->y_height;
  int src_stride = cpi->source->y_stride;
  // clang-format off
  static const double kIdentityParams[MAX_PARAMDIM - 1] = {
     0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
  };
  // clang-format on
  WarpedMotionParams tmp_wm_params;
  const double *params_this_motion;
  int inliers_by_motion[RANSAC_NUM_MOTIONS];
  assert(ref_buf[frame] != NULL);
  TransformationType model;

  aom_clear_system_state();

  // TODO(sarahparker, debargha): Explore do_adaptive_gm_estimation = 1
  const int do_adaptive_gm_estimation = 0;

#if CONFIG_EXPLICIT_TEMPORAL_DIST_CALC
  const int ref_frame_dist = get_relative_dist(
      &cm->seq_params.order_hint_info, cm->current_frame.display_order_hint,
      cm->cur_frame->ref_display_order_hint[frame]);
#else
  const int ref_frame_dist = get_relative_dist(
      &cm->seq_params.order_hint_info, cm->current_frame.order_hint,
      cm->cur_frame->ref_order_hints[frame]);
#endif  // CONFIG_EXPLICIT_TEMPORAL_DIST_CALC
  const GlobalMotionEstimationType gm_estimation_type =
      cm->seq_params.order_hint_info.enable_order_hint &&
              abs(ref_frame_dist) <= 2 && do_adaptive_gm_estimation
          ? GLOBAL_MOTION_DISFLOW_BASED
          : GLOBAL_MOTION_FEATURE_BASED;
  for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES_ENC; ++model) {
    // Initially set all params to identity.
    for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
      memcpy(params_by_motion[i].params, kIdentityParams,
             (MAX_PARAMDIM - 1) * sizeof(*(params_by_motion[i].params)));
      params_by_motion[i].num_inliers = 0;
    }

    av1_compute_global_motion(model, src_buffer, src_width, src_height,
                              src_stride, src_corners, num_src_corners,
                              ref_buf[frame], cpi->common.seq_params.bit_depth,
                              gm_estimation_type, inliers_by_motion,
                              params_by_motion, RANSAC_NUM_MOTIONS);

    int64_t best_ref_frame_error = 0;
    int64_t best_warp_error = INT64_MAX;
    for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
      if (inliers_by_motion[i] == 0) continue;

      params_this_motion = params_by_motion[i].params;
      av1_convert_model_to_params(params_this_motion, &tmp_wm_params);

#if CONFIG_IMPROVED_GLOBAL_MOTION
      // If the found model can be represented as a simple translation,
      // then reject it. This is because translational motion is cheaper
      // to signal through the standard MV coding tools, rather than through
      // global motion
      if (tmp_wm_params.wmtype <= TRANSLATION) continue;
#else
      // For IDENTITY type models, we don't need to evaluate anything because
      // all the following logic is effectively comparing the estimated model
      // to an identity model.
      if (tmp_wm_params.wmtype == IDENTITY) continue;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

      av1_compute_feature_segmentation_map(
          segment_map, segment_map_w, segment_map_h,
          params_by_motion[i].inliers, params_by_motion[i].num_inliers);

      const int64_t ref_frame_error = av1_segmented_frame_error(
          xd->bd, ref_buf[frame]->y_buffer, ref_buf[frame]->y_stride,
          cpi->source->y_buffer, src_width, src_height, src_stride, segment_map,
          segment_map_w);

      if (ref_frame_error == 0) continue;

      const int64_t erroradv_threshold =
          calc_erroradv_threshold(ref_frame_error);

      const int64_t warp_error = av1_refine_integerized_param(
          &tmp_wm_params, tmp_wm_params.wmtype, xd->bd,
          ref_buf[frame]->y_buffer, ref_buf[frame]->y_width,
          ref_buf[frame]->y_height, ref_buf[frame]->y_stride,
          cpi->source->y_buffer, src_width, src_height, src_stride,
          GM_REFINEMENT_COUNT, best_warp_error, segment_map, segment_map_w,
          erroradv_threshold);

#if CONFIG_IMPROVED_GLOBAL_MOTION
      // av1_refine_integerized_param() can change the wmtype to a simpler
      // model type than its input. So we need to check again to see if
      // we have a translational model
      if (tmp_wm_params.wmtype <= TRANSLATION) continue;
#else
      // av1_refine_integerized_param() can return a simpler model type than
      // its input, so re-check model type here
      if (tmp_wm_params.wmtype == IDENTITY) continue;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

#if CONFIG_IMPROVED_GLOBAL_MOTION
      // Apply initial quality filter, which depends only on the error metrics
      // and not the model cost
      if (warp_error >= ref_frame_error * erroradv_tr) continue;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

      if (warp_error < best_warp_error) {
        best_ref_frame_error = ref_frame_error;
        best_warp_error = warp_error;
        // Save the wm_params modified by
        // av1_refine_integerized_param() rather than motion index to
        // avoid rerunning refine() below.
        memcpy(&(cm->global_motion[frame]), &tmp_wm_params,
               sizeof(WarpedMotionParams));
      }
    }
    if (cm->global_motion[frame].wmtype <= AFFINE)
      if (!av1_get_shear_params(&cm->global_motion[frame]))
        cm->global_motion[frame] = default_warp_params;

#if !CONFIG_IMPROVED_GLOBAL_MOTION
    if (cm->global_motion[frame].wmtype == TRANSLATION) {
      cm->global_motion[frame].wmmat[0] =
          convert_to_trans_prec(cm->features.fr_mv_precision,
                                cm->global_motion[frame].wmmat[0]) *
          GM_TRANS_ONLY_DECODE_FACTOR;
      cm->global_motion[frame].wmmat[1] =
          convert_to_trans_prec(cm->features.fr_mv_precision,
                                cm->global_motion[frame].wmmat[1]) *
          GM_TRANS_ONLY_DECODE_FACTOR;
    }
#endif  // !CONFIG_IMPROVED_GLOBAL_MOTION

    if (cm->global_motion[frame].wmtype == IDENTITY) continue;

    // Once we get here, best_ref_frame_error must be > 0. This is because
    // of the logic above, which skips over any models which have
    // ref_frame_error == 0
    assert(best_ref_frame_error > 0);

#if CONFIG_IMPROVED_GLOBAL_MOTION
    gm_info->erroradvantage[frame] =
        (double)best_warp_error / best_ref_frame_error;

    break;
#else
    // If the best error advantage found doesn't meet the threshold for
    // this motion type, revert to IDENTITY.
    if (!av1_is_enough_erroradvantage(
            (double)best_warp_error / best_ref_frame_error,
            gm_get_params_cost(&cm->global_motion[frame], ref_params,
                               cm->features.fr_mv_precision))) {
      cm->global_motion[frame] = default_warp_params;
    }

    if (cm->global_motion[frame].wmtype != IDENTITY) break;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION
  }

  aom_clear_system_state();
}

// Computes global motion for the given reference frame.
void av1_compute_gm_for_valid_ref_frames(
    AV1_COMP *cpi, YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME], int frame,
    int num_src_corners, int *src_corners, unsigned char *src_buffer,
    MotionModel *params_by_motion, uint8_t *segment_map, int segment_map_w,
    int segment_map_h) {
#if CONFIG_IMPROVED_GLOBAL_MOTION
  compute_global_motion_for_ref_frame(
      cpi, ref_buf, frame, num_src_corners, src_corners, src_buffer,
      params_by_motion, segment_map, segment_map_w, segment_map_h);
#else
  AV1_COMMON *const cm = &cpi->common;
  const WarpedMotionParams *ref_params =
      cm->prev_frame ? &cm->prev_frame->global_motion[frame]
                     : &default_warp_params;

  compute_global_motion_for_ref_frame(
      cpi, ref_buf, frame, num_src_corners, src_corners, src_buffer,
      params_by_motion, segment_map, segment_map_w, segment_map_h, ref_params);
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION
}

// Loops over valid reference frames and computes global motion estimation.
static AOM_INLINE void compute_global_motion_for_references(
    AV1_COMP *cpi, YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME],
    FrameDistPair reference_frame[INTER_REFS_PER_FRAME], int num_ref_frames,
    int num_src_corners, int *src_corners, unsigned char *src_buffer,
    MotionModel *params_by_motion, uint8_t *segment_map,
    const int segment_map_w, const int segment_map_h) {
  // Computation of frame corners for the source frame will be done already.
  assert(num_src_corners != -1);
  AV1_COMMON *const cm = &cpi->common;
  // Compute global motion w.r.t. reference frames starting from the nearest ref
  // frame in a given direction.
  for (int frame = 0; frame < num_ref_frames; frame++) {
    int ref_frame = reference_frame[frame].frame;
    av1_compute_gm_for_valid_ref_frames(
        cpi, ref_buf, ref_frame, num_src_corners, src_corners, src_buffer,
        params_by_motion, segment_map, segment_map_w, segment_map_h);
    // If global motion w.r.t. current ref frame is
    // INVALID/TRANSLATION/IDENTITY, skip the evaluation of global motion w.r.t
    // the remaining ref frames in that direction. The below exit is disabled
    // when ref frame distance w.r.t. current frame is zero. E.g.:
    // source_alt_ref_frame w.r.t. ARF frames.
    if (cpi->sf.gm_sf.prune_ref_frame_for_gm_search &&
        reference_frame[frame].distance != 0 &&
        cm->global_motion[ref_frame].wmtype <= TRANSLATION)
      break;
  }
}

// Compares the distance in 'a' and 'b'. Returns 1 if the frame corresponding to
// 'a' is farther, -1 if the frame corresponding to 'b' is farther, 0 otherwise.
static int compare_distance(const void *a, const void *b) {
  const int diff =
      ((FrameDistPair *)a)->distance - ((FrameDistPair *)b)->distance;
  if (diff > 0)
    return 1;
  else if (diff < 0)
    return -1;
  return 0;
}

static int disable_gm_search_based_on_stats(const AV1_COMP *const cpi) {
  const GF_GROUP *gf_group = &cpi->gf_group;
  int is_gm_present = 1;

  // Check number of GM models only in GF groups with ARF frames. GM param
  // estimation is always done in the case of GF groups with no ARF frames (flat
  // gops)
  if (gf_group->arf_index > -1) {
    // valid_gm_model_found is initialized to INT32_MAX in the beginning of
    // every GF group.
    // Therefore, GM param estimation is always done for all frames until
    // at least 1 frame each of ARF_UPDATE, INTNL_ARF_UPDATE and LF_UPDATE are
    // encoded in a GF group For subsequent frames, GM param estimation is
    // disabled, if no valid models have been found in all the three update
    // types.
    is_gm_present = (cpi->valid_gm_model_found[ARF_UPDATE] != 0) ||
                    (cpi->valid_gm_model_found[INTNL_ARF_UPDATE] != 0) ||
                    (cpi->valid_gm_model_found[LF_UPDATE] != 0);
  }
  return !is_gm_present;
}

// Populates valid reference frames in past/future directions in
// 'reference_frames' and their count in 'num_ref_frames'.
static AOM_INLINE void update_valid_ref_frames_for_gm(
    AV1_COMP *cpi, YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME],
    FrameDistPair reference_frames[MAX_DIRECTIONS][INTER_REFS_PER_FRAME],
    int *num_ref_frames) {
  AV1_COMMON *const cm = &cpi->common;
  int *num_past_ref_frames = &num_ref_frames[0];
  int *num_future_ref_frames = &num_ref_frames[1];
  const GF_GROUP *gf_group = &cpi->gf_group;
  int ref_pruning_enabled = is_frame_eligible_for_ref_pruning(
      gf_group, cpi->sf.inter_sf.selective_ref_frame, 1, gf_group->index);
  int cur_frame_gm_disabled = 0;
  int pyr_lvl = cm->cur_frame->pyramid_level;

  if (cpi->sf.gm_sf.disable_gm_search_based_on_stats) {
    cur_frame_gm_disabled = disable_gm_search_based_on_stats(cpi);
  }

  for (int frame = cm->ref_frames_info.num_total_refs - 1; frame >= 0;
       --frame) {
    const MV_REFERENCE_FRAME ref_frame[2] = { frame, NONE_FRAME };
#if CONFIG_ALLOW_SAME_REF_COMPOUND
    assert(frame <= INTER_REFS_PER_FRAME);
#endif  // CONFIG_ALLOW_SAME_REF_COMPOUND
    const int ref_disabled = !(cm->ref_frame_flags & (1 << frame));
    ref_buf[frame] = NULL;
    cm->global_motion[frame] = default_warp_params;
    RefCntBuffer *buf = get_ref_frame_buf(cm, frame);
    // Skip global motion estimation for invalid ref frames
    if (buf == NULL ||
        (ref_disabled && cpi->sf.hl_sf.recode_loop != DISALLOW_RECODE)) {
      continue;
    } else {
      ref_buf[frame] = &buf->buf;
    }

    int prune_ref_frames =
        ref_pruning_enabled &&
        prune_ref_by_selective_ref_frame(cpi, NULL, ref_frame);
    int ref_pyr_lvl = buf->pyramid_level;

    if (ref_buf[frame]->y_crop_width == cpi->source->y_crop_width &&
        ref_buf[frame]->y_crop_height == cpi->source->y_crop_height &&
        frame < cpi->sf.gm_sf.max_ref_frames && !prune_ref_frames &&
        ref_pyr_lvl <= pyr_lvl && !cur_frame_gm_disabled) {
      assert(ref_buf[frame] != NULL);
      const int relative_frame_dist = av1_encoder_get_relative_dist(
          buf->display_order_hint, cm->cur_frame->display_order_hint);
      // Populate past and future ref frames.
      // reference_frames[0][] indicates past direction and
      // reference_frames[1][] indicates future direction.
      if (relative_frame_dist <= 0) {
        reference_frames[0][*num_past_ref_frames].distance =
            abs(relative_frame_dist);
        reference_frames[0][*num_past_ref_frames].frame = frame;
        (*num_past_ref_frames)++;
      } else {
        reference_frames[1][*num_future_ref_frames].distance =
            abs(relative_frame_dist);
        reference_frames[1][*num_future_ref_frames].frame = frame;
        (*num_future_ref_frames)++;
      }
    }
  }
}

// Allocates and initializes memory for segment_map and MotionModel.
static AOM_INLINE void alloc_global_motion_data(MotionModel *params_by_motion,
                                                uint8_t **segment_map,
                                                const int segment_map_w,
                                                const int segment_map_h) {
  for (int m = 0; m < RANSAC_NUM_MOTIONS; m++) {
    av1_zero(params_by_motion[m]);
    params_by_motion[m].inliers =
        aom_malloc(sizeof(*(params_by_motion[m].inliers)) * 2 * MAX_CORNERS);
  }

  *segment_map = (uint8_t *)aom_malloc(sizeof(*segment_map) * segment_map_w *
                                       segment_map_h);
  av1_zero_array(*segment_map, segment_map_w * segment_map_h);
}

// Deallocates segment_map and inliers.
static AOM_INLINE void dealloc_global_motion_data(MotionModel *params_by_motion,
                                                  uint8_t *segment_map) {
  aom_free(segment_map);

  for (int m = 0; m < RANSAC_NUM_MOTIONS; m++) {
    aom_free(params_by_motion[m].inliers);
  }
}

#if CONFIG_IMPROVED_GLOBAL_MOTION
// Select which global motion model to use as a base
static AOM_INLINE void pick_base_gm_params(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  GlobalMotionInfo *const gm_info = &cpi->gm_info;
  int num_total_refs = cm->ref_frames_info.num_total_refs;

  int best_our_ref;
  int best_their_ref;
  const WarpedMotionParams *best_base_model;
  int best_temporal_distance;
  int best_num_models;
  int best_cost;

  // Bitmask of which models we will actually use if we accept the current
  // best base model
  uint8_t best_enable_models;

  // First, evaluate the identity model as a base
  {
    int this_num_models = 0;
    int this_cost =
        aom_count_primitive_quniform(num_total_refs + 1, num_total_refs)
        << AV1_PROB_COST_SHIFT;
    uint8_t this_enable_models = 0;

    for (int frame = 0; frame < num_total_refs; frame++) {
      const WarpedMotionParams *model = &cm->global_motion[frame];
      if (model->wmtype == IDENTITY) continue;
      int model_cost = gm_get_params_cost(model, &default_warp_params,
                                          cm->features.fr_mv_precision);
      bool use_model = av1_is_enough_erroradvantage(
          gm_info->erroradvantage[frame], model_cost);

      if (use_model) {
        this_num_models += 1;
        this_cost += model_cost;
        this_enable_models |= (1 << frame);
      }
    }

    // Set initial values
    best_our_ref = cm->ref_frames_info.num_total_refs;
    best_their_ref = -1;
    best_base_model = &default_warp_params;
    best_temporal_distance = 1;
    best_num_models = this_num_models;
    best_cost = this_cost;
    best_enable_models = this_enable_models;
  }

  // Then try each available reference model in turn
  for (int our_ref = 0; our_ref < num_total_refs; ++our_ref) {
    const int ref_disabled = !(cm->ref_frame_flags & (1 << our_ref));
    RefCntBuffer *buf = get_ref_frame_buf(cm, our_ref);
    // Skip looking at invalid ref frames
    if (buf == NULL ||
        (ref_disabled && cpi->sf.hl_sf.recode_loop != DISALLOW_RECODE)) {
      continue;
    }

    int their_num_refs = buf->num_ref_frames;
    for (int their_ref = 0; their_ref < their_num_refs; ++their_ref) {
      const WarpedMotionParams *base_model = &buf->global_motion[their_ref];
      if (base_model->wmtype == IDENTITY) {
        continue;
      }

#if CONFIG_EXPLICIT_TEMPORAL_DIST_CALC
      const int our_ref_order_hint = buf->display_order_hint;
      const int their_ref_order_hint = buf->ref_display_order_hint[their_ref];
#else
      const int our_ref_order_hint = buf->order_hint;
      const int their_ref_order_hint = buf->ref_order_hints[their_ref];
#endif  // CONFIG_EXPLICIT_TEMPORAL_DIST_CALC
      int base_temporal_distance =
          get_relative_dist(&seq_params->order_hint_info, our_ref_order_hint,
                            their_ref_order_hint);

      int this_num_models = 0;
      int this_cost =
          (aom_count_primitive_quniform(num_total_refs + 1, our_ref) +
           aom_count_primitive_quniform(their_num_refs, their_ref))
          << AV1_PROB_COST_SHIFT;
      uint8_t this_enable_models = 0;

      for (int frame = 0; frame < num_total_refs; frame++) {
        const WarpedMotionParams *model = &cm->global_motion[frame];
        if (model->wmtype == IDENTITY) continue;

        int temporal_distance;
        if (seq_params->order_hint_info.enable_order_hint) {
          const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, frame);
#if CONFIG_EXPLICIT_TEMPORAL_DIST_CALC
          const int ref_order_hint = ref_buf->display_order_hint;
          const int cur_order_hint = cm->cur_frame->display_order_hint;
#else
          const int ref_order_hint = ref_buf->order_hint;
          const int cur_order_hint = cm->cur_frame->order_hint;
#endif  // CONFIG_EXPLICIT_TEMPORAL_DIST_CALC
          temporal_distance = get_relative_dist(&seq_params->order_hint_info,
                                                cur_order_hint, ref_order_hint);
        } else {
          temporal_distance = 1;
        }

        if (temporal_distance == 0) {
          // Don't code global motion for frames at the same temporal instant
          assert(model->wmtype == IDENTITY);
          continue;
        }

        WarpedMotionParams ref_params;
        av1_scale_warp_model(base_model, base_temporal_distance, &ref_params,
                             temporal_distance);

        int model_cost = gm_get_params_cost(model, &ref_params,
                                            cm->features.fr_mv_precision);
        bool use_model = av1_is_enough_erroradvantage(
            gm_info->erroradvantage[frame], model_cost);

        if (use_model) {
          this_num_models += 1;
          this_cost += model_cost;
          this_enable_models |= (1 << frame);
        }
      }

      if (this_num_models > best_num_models ||
          (this_num_models == best_num_models && this_cost < best_cost)) {
        best_our_ref = our_ref;
        best_their_ref = their_ref;
        best_base_model = base_model;
        best_temporal_distance = base_temporal_distance;
        best_num_models = this_num_models;
        best_cost = this_cost;
        best_enable_models = this_enable_models;
      }
    }
  }

  gm_info->base_model_our_ref = best_our_ref;
  gm_info->base_model_their_ref = best_their_ref;
  cm->base_global_motion_model = *best_base_model;
  cm->base_global_motion_distance = best_temporal_distance;

  for (int frame = 0; frame < num_total_refs; frame++) {
    if ((best_enable_models & (1 << frame)) == 0) {
      // Disable this model
      cm->global_motion[frame] = default_warp_params;
    }
  }
}
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

// Initializes parameters used for computing global motion.
static AOM_INLINE void setup_global_motion_info_params(AV1_COMP *cpi) {
  GlobalMotionInfo *const gm_info = &cpi->gm_info;
  YV12_BUFFER_CONFIG *source = cpi->source;

  // The source buffer is 16-bit, so we need to convert to 8 bits for the
  // following code. We cache the result until the source frame is released.
  gm_info->src_buffer =
      av1_downconvert_frame(source, cpi->common.seq_params.bit_depth);

  gm_info->segment_map_w =
      (source->y_width + WARP_ERROR_BLOCK) >> WARP_ERROR_BLOCK_LOG;
  gm_info->segment_map_h =
      (source->y_height + WARP_ERROR_BLOCK) >> WARP_ERROR_BLOCK_LOG;

  memset(gm_info->reference_frames, -1,
         sizeof(gm_info->reference_frames[0][0]) * MAX_DIRECTIONS *
             (INTER_REFS_PER_FRAME));
  av1_zero(gm_info->num_ref_frames);

  // Populate ref_buf for valid ref frames in global motion
  update_valid_ref_frames_for_gm(cpi, gm_info->ref_buf,
                                 gm_info->reference_frames,
                                 gm_info->num_ref_frames);

  // Sort the past and future ref frames in the ascending order of their
  // distance from the current frame. reference_frames[0] => past direction
  // and reference_frames[1] => future direction.
  qsort(gm_info->reference_frames[0], gm_info->num_ref_frames[0],
        sizeof(gm_info->reference_frames[0][0]), compare_distance);
  qsort(gm_info->reference_frames[1], gm_info->num_ref_frames[1],
        sizeof(gm_info->reference_frames[1][0]), compare_distance);

  gm_info->num_src_corners = -1;
  // If atleast one valid reference frame exists in past/future directions,
  // compute interest points of source frame using FAST features.
  if (gm_info->num_ref_frames[0] > 0 || gm_info->num_ref_frames[1] > 0) {
    gm_info->num_src_corners = av1_fast_corner_detect(
        gm_info->src_buffer, source->y_width, source->y_height,
        source->y_stride, gm_info->src_corners, MAX_CORNERS);
  }
}

// Computes global motion w.r.t. valid reference frames.
static AOM_INLINE void global_motion_estimation(AV1_COMP *cpi) {
  GlobalMotionInfo *const gm_info = &cpi->gm_info;
  MotionModel params_by_motion[RANSAC_NUM_MOTIONS];
  uint8_t *segment_map = NULL;

  alloc_global_motion_data(params_by_motion, &segment_map,
                           gm_info->segment_map_w, gm_info->segment_map_h);

  // Compute global motion w.r.t. past reference frames and future reference
  // frames
  for (int dir = 0; dir < MAX_DIRECTIONS; dir++) {
    if (gm_info->num_ref_frames[dir] > 0)
      compute_global_motion_for_references(
          cpi, gm_info->ref_buf, gm_info->reference_frames[dir],
          gm_info->num_ref_frames[dir], gm_info->num_src_corners,
          gm_info->src_corners, gm_info->src_buffer, params_by_motion,
          segment_map, gm_info->segment_map_w, gm_info->segment_map_h);
  }

  dealloc_global_motion_data(params_by_motion, segment_map);
}

static AOM_INLINE void reset_gm_stats(AV1_COMP *cpi) {
  for (int i = 0; i < FRAME_UPDATE_TYPES; i++) {
    cpi->valid_gm_model_found[i] = INT32_MAX;
  }
}

// Updates frame level stats related to global motion
static AOM_INLINE void update_gm_stats(AV1_COMP *cpi) {
  const GF_GROUP *gf_group = &cpi->gf_group;
  FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index];

  int is_gm_present = 0;
  for (int frame = 0; frame < INTER_REFS_PER_FRAME; frame++) {
    if (cpi->common.global_motion[frame].wmtype != IDENTITY) {
      is_gm_present = 1;
      break;
    }
  }

  if (cpi->valid_gm_model_found[update_type] == INT32_MAX) {
    cpi->valid_gm_model_found[update_type] = is_gm_present;
  } else {
    cpi->valid_gm_model_found[update_type] |= is_gm_present;
  }
}

// Global motion estimation for the current frame is computed.This computation
// happens once per frame and the winner motion model parameters are stored in
// cm->cur_frame->global_motion.
void av1_compute_global_motion_facade(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const GF_GROUP *gf_group = &cpi->gf_group;
  GlobalMotionInfo *const gm_info = &cpi->gm_info;

  // Reset `valid_gm_model_found` at the start of each GOP
  if (cpi->oxcf.tool_cfg.enable_global_motion &&
      cpi->sf.gm_sf.disable_gm_search_based_on_stats && gf_group->index == 0) {
    reset_gm_stats(cpi);
  }

  if (cpi->common.current_frame.frame_type == INTER_FRAME && cpi->source &&
      cpi->oxcf.tool_cfg.enable_global_motion && !gm_info->search_done) {
    setup_global_motion_info_params(cpi);
    if (cpi->mt_info.num_workers > 1)
      av1_global_motion_estimation_mt(cpi);
    else
      global_motion_estimation(cpi);

#if CONFIG_IMPROVED_GLOBAL_MOTION
    // Once we have determined the best motion model for each ref frame,
    // choose the base parameters to minimize the total encoding cost
    pick_base_gm_params(cpi);
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

    // Check if the current frame has any valid global motion model across its
    // reference frames
    if (cpi->sf.gm_sf.disable_gm_search_based_on_stats) {
      update_gm_stats(cpi);
    }

    gm_info->search_done = 1;
  }

  memcpy(cm->cur_frame->global_motion, cm->global_motion,
         sizeof(cm->cur_frame->global_motion));
}
