/*
 * 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 "aom_dsp/flow_estimation/corner_detect.h"
#include "aom_dsp/flow_estimation/flow_estimation.h"
#include "aom_dsp/pyramid.h"

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

// Range of model types to search
#define FIRST_GLOBAL_TRANS_TYPE ROTZOOM
#define LAST_GLOBAL_TRANS_TYPE ROTZOOM

// 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);
}

// 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, struct aom_internal_error_info *error_info,
    YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME], int frame,
    MotionModel *motion_models, 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, struct aom_internal_error_info *error_info,
    YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME], int frame,
    MotionModel *motion_models, uint8_t *segment_map, const int segment_map_w,
    const int segment_map_h, const WarpedMotionParams *ref_params) {
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION
  AV1_COMMON *const cm = &cpi->common;
#if CONFIG_IMPROVED_GLOBAL_MOTION
  GlobalMotionInfo *const gm_info = &cpi->gm_info;
#endif  // CONFIG_IMPROVED_GLOBAL_MOTION

  int src_width = cpi->source->y_crop_width;
  int src_height = cpi->source->y_crop_height;
  int src_stride = cpi->source->y_stride;

  assert(ref_buf[frame] != NULL);

  aom_clear_system_state();

  int bit_depth = cpi->common.seq_params.bit_depth;
  GlobalMotionMethod global_motion_method = default_global_motion_method;
  int downsample_level = cpi->sf.gm_sf.downsample_level;
  int num_refinements = cpi->sf.gm_sf.num_refinement_steps;
  bool mem_alloc_failed = false;

  // Select the best model based on fractional error reduction.
  // By initializing this to erroradv_tr, the same logic which is used to
  // select the best model will automatically filter out any model which
  // doesn't meet the required quality threshold
  double best_erroradv = erroradv_tr;
  for (TransformationType model = FIRST_GLOBAL_TRANS_TYPE;
       model <= LAST_GLOBAL_TRANS_TYPE; ++model) {
    if (!aom_compute_global_motion(model, cpi->source, ref_buf[frame],
                                   bit_depth, global_motion_method,
                                   downsample_level, motion_models,
                                   RANSAC_NUM_MOTIONS, &mem_alloc_failed)) {
      if (mem_alloc_failed) {
        aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
                           "Failed to allocate global motion buffers");
      }
      continue;
    }
#if CONFIG_ACROSS_SCALE_WARP
    cm->global_motion[frame].invalid = 0;
#endif  // CONFIG_ACROSS_SCALE_WARP
    for (int i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
      if (motion_models[i].num_inliers == 0) continue;

      WarpedMotionParams tmp_wm_params;
      memcpy(tmp_wm_params.wmmat, motion_models[i].params,
             MAX_PARAMDIM * sizeof(*tmp_wm_params.wmmat));
      tmp_wm_params.wmtype = get_wmtype(&tmp_wm_params);
      tmp_wm_params.invalid = 0;

      // Check that the generated model is warp-able
      if (!av1_get_shear_params(&tmp_wm_params
#if CONFIG_ACROSS_SCALE_WARP
                                ,
                                get_ref_scale_factors_const(cm, frame)
#endif  // CONFIG_ACROSS_SCALE_WARP
                                    ))
        continue;

      // Skip models that we won't use (IDENTITY or TRANSLATION)
      //
      // 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.
      //
      // For TRANSLATION type global motion models, gm_get_motion_vector() gives
      // the wrong motion vector (see comments in that function for details).
      // As translation-type models do not give much gain, we can avoid this bug
      // by never choosing a TRANSLATION type model
      if (tmp_wm_params.wmtype <= TRANSLATION) continue;

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

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

      if (ref_frame_error == 0) continue;

      const int64_t warp_error = av1_refine_integerized_param(
          &tmp_wm_params, tmp_wm_params.wmtype, bit_depth,
          ref_buf[frame]->y_buffer, ref_buf[frame]->y_crop_width,
          ref_buf[frame]->y_crop_height, ref_buf[frame]->y_stride,
          cpi->source->y_buffer, src_width, src_height, src_stride,
          num_refinements, ref_frame_error, segment_map, segment_map_w
#if CONFIG_ACROSS_SCALE_WARP
          ,
          get_ref_scale_factors_const(cm, frame)
#endif  // CONFIG_ACROSS_SCALE_WARP
      );

      // av1_refine_integerized_param() can return a simpler model type than
      // its input, so re-check model type here
      if (tmp_wm_params.wmtype <= TRANSLATION) continue;

      double erroradvantage = (double)warp_error / ref_frame_error;

#if !CONFIG_IMPROVED_GLOBAL_MOTION
      // Check that the model signaling cost is not too high
      if (!av1_is_enough_erroradvantage(
              erroradvantage,
              gm_get_params_cost(&tmp_wm_params, ref_params,
                                 cm->features.allow_high_precision_mv))) {
        continue;
      }
#endif  // !CONFIG_IMPROVED_GLOBAL_MOTION

      if (erroradvantage < best_erroradv) {
        best_erroradv = erroradvantage;
        // 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 CONFIG_IMPROVED_GLOBAL_MOTION
  gm_info->erroradvantage[frame] = best_erroradv;
#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, struct aom_internal_error_info *error_info,
    YV12_BUFFER_CONFIG *ref_buf[INTER_REFS_PER_FRAME], int frame,
    MotionModel *motion_models, uint8_t *segment_map, int segment_map_w,
    int segment_map_h) {
#if CONFIG_IMPROVED_GLOBAL_MOTION
  compute_global_motion_for_ref_frame(cpi, error_info, ref_buf, frame,
                                      motion_models, 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, error_info, ref_buf, frame,
                                      motion_models, 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,
    MotionModel *motion_models, uint8_t *segment_map, const int segment_map_w,
    const int segment_map_h) {
  AV1_COMMON *const cm = &cpi->common;
  struct aom_internal_error_info *const error_info =
      cpi->td.mb.e_mbd.error_info;
  // 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, error_info, ref_buf, ref_frame,
                                        motion_models, 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_filters'.
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_SAME_REF_COMPOUND
    assert(frame <= INTER_REFS_PER_FRAME);
#endif  // CONFIG_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 {
#if CONFIG_ACROSS_SCALE_WARP
      // Get the scaled buffer
      if (av1_is_scaled(get_ref_scale_factors(cm, frame)))
        ref_buf[frame] = &cpi->scaled_ref_buf[frame]->buf;
      else
        ref_buf[frame] = &buf->buf;
#else
      ref_buf[frame] = &buf->buf;
#endif  // CONFIG_ACROSS_SCALE_WARP
    }

    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 *motion_models,
                                                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(motion_models[m]);
    motion_models[m].inliers =
        aom_malloc(sizeof(*(motion_models[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 *motion_models,
                                                  uint8_t *segment_map) {
  aom_free(segment_map);

  for (int m = 0; m < RANSAC_NUM_MOTIONS; m++) {
    aom_free(motion_models[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;

  gm_info->segment_map_w =
      (source->y_crop_width + WARP_ERROR_BLOCK - 1) >> WARP_ERROR_BLOCK_LOG;
  gm_info->segment_map_h =
      (source->y_crop_height + WARP_ERROR_BLOCK - 1) >> 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);
}

// 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 motion_models[RANSAC_NUM_MOTIONS];
  uint8_t *segment_map = NULL;

  alloc_global_motion_data(motion_models, &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], motion_models, segment_map,
          gm_info->segment_map_w, gm_info->segment_map_h);
  }

  dealloc_global_motion_data(motion_models, segment_map);
}

// 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 i, is_gm_present = 0;

  // Check if the current frame has any valid global motion model across its
  // reference frames
  for (i = 0; i < INTER_REFS_PER_FRAME; i++) {
    if (cpi->common.global_motion[i].wmtype != IDENTITY) {
      is_gm_present = 1;
      break;
    }
  }

  int update_actual_stats = 1;
  if (update_actual_stats) {
    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) {
    if (gf_group->index == 0) {
      for (int i = 0; i < FRAME_UPDATE_TYPES; i++) {
        cpi->valid_gm_model_found[i] = INT32_MAX;
      }
    }
  }

  if (cpi->common.current_frame.frame_type == INTER_FRAME && cpi->source &&
      cpi->oxcf.tool_cfg.enable_global_motion &&
      cpi->sf.gm_sf.max_ref_frames > 0 && !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

    update_gm_stats(cpi);

    gm_info->search_done = 1;
  }

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