/*
 * 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 "av1/common/tip.h"

#include "config/aom_scale_rtcd.h"

// CHROMA_MI_SIZE is the block size in luma unit for Chroma TIP interpolation
#define CHROMA_MI_SIZE (TMVP_MI_SIZE)

// Maximum block size  allowed to combine the blocks with same MV.
// Encoder and decoder must use 8x8 units to prevent scaled pred mismatches
#define MAX_BLOCK_SIZE_WITH_SAME_MV 8
// If superres/resize are not used MAX_BLOCK_SIZE_WITH_SAME_MV could be set 128

// Percentage threshold of number of blocks with available motion
// projection in a frame to allow TIP mode
#define TIP_ENABLE_COUNT_THRESHOLD 60

static void tip_find_closest_bi_dir_ref_frames(AV1_COMMON *cm,
                                               int ref_order_hints[2],
                                               MV_REFERENCE_FRAME rf[2]) {
  const OrderHintInfo *const order_hint_info = &cm->seq_params.order_hint_info;

  if (!order_hint_info->enable_order_hint || frame_is_intra_only(cm)) return;

  const int cur_order_hint = cm->current_frame.order_hint;

  // Identify the nearest forward and backward references.
#if CONFIG_NEW_REF_SIGNALING
  for (int i = 0; i < INTER_REFS_PER_FRAME; i++) {
#else
  for (int i = LAST_FRAME; i < REF_FRAMES; ++i) {
#endif  // CONFIG_NEW_REF_SIGNALING
    const RefCntBuffer *const buf = get_ref_frame_buf(cm, i);
    if (buf == NULL) continue;

    const int ref_order_hint = buf->order_hint;
    const int ref_to_cur_dist =
        get_relative_dist(order_hint_info, ref_order_hint, cur_order_hint);
    if (ref_to_cur_dist < 0) {
      // Forward reference
      if (ref_order_hints[0] == -1 ||
          get_relative_dist(order_hint_info, ref_order_hint,
                            ref_order_hints[0]) > 0) {
        ref_order_hints[0] = ref_order_hint;
        rf[0] = i;
      }
    } else if (ref_to_cur_dist > 0) {
      // Backward reference
      if (ref_order_hints[1] == INT_MAX ||
          get_relative_dist(order_hint_info, ref_order_hint,
                            ref_order_hints[1]) < 0) {
        ref_order_hints[1] = ref_order_hint;
        rf[1] = i;
      }
    }
  }
}

static AOM_INLINE int tip_find_reference_frame(AV1_COMMON *cm, int start_frame,
                                               int target_frame_order) {
  const RefCntBuffer *const start_frame_buf =
      get_ref_frame_buf(cm, start_frame);

#if CONFIG_NEW_REF_SIGNALING
  const int *const ref_order_hints = &start_frame_buf->ref_order_hints[0];
  for (MV_REFERENCE_FRAME rf = 0; rf < INTER_REFS_PER_FRAME; ++rf) {
    if (ref_order_hints[rf] == target_frame_order) {
      return 1;
    }
  }
#else
  const unsigned int *const ref_order_hints =
      &start_frame_buf->ref_order_hints[0];
  for (MV_REFERENCE_FRAME rf = LAST_FRAME; rf <= INTER_REFS_PER_FRAME; ++rf) {
    const int ref_order = ref_order_hints[rf - LAST_FRAME];
    if (ref_order == target_frame_order) {
      return 1;
    }
  }
#endif  // CONFIG_NEW_REF_SIGNALING

  return 0;
}

static int tip_motion_field_projection(AV1_COMMON *cm,
                                       MV_REFERENCE_FRAME nearest_ref[2],
                                       int nearest_ref_order_hint[2]) {
  int ref_frame_offset = 0;
  int target_order_hint = 0;
  OrderHintInfo *order_hint_info = &cm->seq_params.order_hint_info;

  MV_REFERENCE_FRAME start_frame = NONE_FRAME;
  int find_ref =
      tip_find_reference_frame(cm, nearest_ref[0], nearest_ref_order_hint[1]);
  if (find_ref) {
    ref_frame_offset = get_relative_dist(
        order_hint_info, nearest_ref_order_hint[0], nearest_ref_order_hint[1]);
    start_frame = nearest_ref[0];
    target_order_hint = nearest_ref_order_hint[1];
  } else {
    find_ref =
        tip_find_reference_frame(cm, nearest_ref[1], nearest_ref_order_hint[0]);
    if (!find_ref) return 0;
    ref_frame_offset = get_relative_dist(
        order_hint_info, nearest_ref_order_hint[1], nearest_ref_order_hint[0]);
    start_frame = nearest_ref[1];
    target_order_hint = nearest_ref_order_hint[0];
  }

  const RefCntBuffer *const start_frame_buf =
      get_ref_frame_buf(cm, start_frame);
  if (!is_ref_motion_field_eligible(cm, start_frame_buf)) return 0;

#if CONFIG_ACROSS_SCALE_TPL_MVS
  const int is_scaled = (start_frame_buf->width != cm->width ||
                         start_frame_buf->height != cm->height);
  struct scale_factors sf_;
  // Inverse scale factor
  av1_setup_scale_factors_for_frame(&sf_, cm->width, cm->height,
                                    start_frame_buf->width,
                                    start_frame_buf->height);
  const struct scale_factors *sf = &sf_;
#else
  assert(start_frame_buf->width == cm->width &&
         start_frame_buf->height == cm->height);
#endif  // CONFIG_ACROSS_SCALE_TPL_MVS

  const int start_frame_order_hint = start_frame_buf->order_hint;
#if CONFIG_NEW_REF_SIGNALING
  const int *const ref_order_hints = start_frame_buf->ref_order_hints;
#else
  const unsigned int *const ref_order_hints = start_frame_buf->ref_order_hints;
#endif  // CONFIG_NEW_REF_SIGNALING
  const int cur_order_hint = cm->cur_frame->order_hint;
  int start_to_current_frame_offset = get_relative_dist(
      order_hint_info, start_frame_order_hint, cur_order_hint);

  const int is_backward = ref_frame_offset < 0;
  if (is_backward) {
    ref_frame_offset = -ref_frame_offset;
    start_to_current_frame_offset = -start_to_current_frame_offset;
  }

  const int temporal_scale_factor =
      tip_derive_scale_factor(start_to_current_frame_offset, ref_frame_offset);

  TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
  const MV_REF *mv_ref_base = start_frame_buf->mvs;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;
  const int start_mvs_rows =
      ROUND_POWER_OF_TWO(start_frame_buf->mi_rows, TMVP_SHIFT_BITS);
  const int start_mvs_cols =
      ROUND_POWER_OF_TWO(start_frame_buf->mi_cols, TMVP_SHIFT_BITS);
  (void)mvs_rows;
#if CONFIG_ACROSS_SCALE_TPL_MVS
  uint32_t scaled_blk_col_hr_0 = 0;
  uint32_t scaled_blk_col_hr_step = 0;
  uint32_t scaled_blk_col_hr = 0;
  uint32_t scaled_blk_row_hr_0 = 0;
  uint32_t scaled_blk_row_hr_step = 0;
  uint32_t scaled_blk_row_hr = 0;
  if (is_scaled) {
    scaled_blk_col_hr_0 =
        (uint32_t)sf->x_scale_fp * 4;  // center of first block
    scaled_blk_col_hr_step = (uint32_t)sf->x_scale_fp * 8;  // step
    scaled_blk_row_hr_0 =
        (uint32_t)sf->y_scale_fp * 4;  // center of first block
    scaled_blk_row_hr_step = (uint32_t)sf->y_scale_fp * 8;  // step
    scaled_blk_row_hr = scaled_blk_row_hr_0;
  }
#endif  // CONFIG_ACROSS_SCALE_TPL_MVS
  for (int blk_row = 0; blk_row < start_mvs_rows; ++blk_row) {
    int scaled_blk_row = blk_row;
#if CONFIG_ACROSS_SCALE_TPL_MVS
    if (is_scaled) {
      scaled_blk_col_hr = scaled_blk_col_hr_0;
      scaled_blk_row =
          ROUND_POWER_OF_TWO(scaled_blk_row_hr, REF_SCALE_SHIFT + 3);
      scaled_blk_row = AOMMIN(scaled_blk_row, mvs_rows - 1);
    }
#endif  // CONFIG_ACROSS_SCALE_TPL_MVS
    for (int blk_col = 0; blk_col < start_mvs_cols; ++blk_col) {
      const MV_REF *mv_ref = &mv_ref_base[blk_row * start_mvs_cols + blk_col];
      MV_REFERENCE_FRAME ref_frame[2] = { mv_ref->ref_frame[0],
                                          mv_ref->ref_frame[1] };
      for (int idx = 0; idx < 2; ++idx) {
        if (is_inter_ref_frame(ref_frame[idx])) {
#if CONFIG_NEW_REF_SIGNALING
          const int ref_frame_order_hint = ref_order_hints[ref_frame[idx]];
#else
          const int ref_frame_order_hint =
              ref_order_hints[ref_frame[idx] - LAST_FRAME];
#endif  // #if CONFIG_NEW_REF_SIGNALING
          if (ref_frame_order_hint == target_order_hint) {
            MV ref_mv = mv_ref->mv[idx].as_mv;
            int scaled_blk_col = blk_col;
#if CONFIG_ACROSS_SCALE_TPL_MVS
            if (is_scaled) {
              scaled_blk_col =
                  ROUND_POWER_OF_TWO(scaled_blk_col_hr, REF_SCALE_SHIFT + 3);
              scaled_blk_col = AOMMIN(scaled_blk_col, mvs_cols - 1);
              ref_mv.row = sf->scale_value_y_gen(ref_mv.row, sf);
              ref_mv.col = sf->scale_value_x_gen(ref_mv.col, sf);
            }
#endif  // CONFIG_ACROSS_SCALE_TPL_MVS
            int_mv this_mv;
            int mi_r = 0;
            int mi_c = 0;
            tip_get_mv_projection(&this_mv.as_mv, ref_mv,
                                  temporal_scale_factor);
            const int pos_valid =
                get_block_position(cm, &mi_r, &mi_c, scaled_blk_row,
                                   scaled_blk_col, this_mv.as_mv, 0);
            if (pos_valid) {
              assert(mi_r < mvs_rows);
              assert(mi_c < mvs_cols);
              if (is_backward) {
                ref_mv.row = -ref_mv.row;
                ref_mv.col = -ref_mv.col;
              }

              const int mi_offset = mi_r * mvs_stride + mi_c;
              if (tpl_mvs_base[mi_offset].mfmv0.as_int == INVALID_MV) {
                tpl_mvs_base[mi_offset].mfmv0.as_mv.row = ref_mv.row;
                tpl_mvs_base[mi_offset].mfmv0.as_mv.col = ref_mv.col;
                tpl_mvs_base[mi_offset].ref_frame_offset = ref_frame_offset;
              }
            }
          }
        }
      }
#if CONFIG_ACROSS_SCALE_TPL_MVS
      if (is_scaled) scaled_blk_col_hr += scaled_blk_col_hr_step;
#endif  // CONFIG_ACROSS_SCALE_TPL_MVS
    }
#if CONFIG_ACROSS_SCALE_TPL_MVS
    if (is_scaled) scaled_blk_row_hr += scaled_blk_row_hr_step;
#endif  // CONFIG_ACROSS_SCALE_TPL_MVS
  }

  return 1;
}

void av1_derive_tip_nearest_ref_frames_motion_projection(AV1_COMMON *cm) {
  int nearest_ref_order_hints[2] = { -1, INT_MAX };
  MV_REFERENCE_FRAME nearest_rf[2] = { NONE_FRAME, NONE_FRAME };
  tip_find_closest_bi_dir_ref_frames(cm, nearest_ref_order_hints, nearest_rf);
  if (nearest_rf[0] != NONE_FRAME && nearest_rf[1] != NONE_FRAME) {
    cm->tip_ref.ref_frame[0] = nearest_rf[0];
    cm->tip_ref.ref_frame[1] = nearest_rf[1];
    tip_motion_field_projection(cm, nearest_rf, nearest_ref_order_hints);
  } else {
    cm->tip_ref.ref_frame[0] = NONE_FRAME;
    cm->tip_ref.ref_frame[1] = NONE_FRAME;
  }
}

static void tip_temporal_scale_motion_field(AV1_COMMON *cm,
                                            const int ref_frames_offset) {
  TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;
  for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
    for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
      const int tpl_offset = blk_row * mvs_stride + blk_col;
      TPL_MV_REF *tpl_mvs = tpl_mvs_base + tpl_offset;
      if (tpl_mvs->mfmv0.as_int != INVALID_MV) {
        int_mv this_refmv;
        get_mv_projection(&this_refmv.as_mv, tpl_mvs->mfmv0.as_mv,
                          ref_frames_offset, tpl_mvs->ref_frame_offset);
        tpl_mvs->mfmv0.as_int = this_refmv.as_int;
        tpl_mvs->ref_frame_offset = ref_frames_offset;
      }
    }
  }
}

static void tip_fill_motion_field_holes(AV1_COMMON *cm) {
  TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;
  const int total_units = mvs_rows * mvs_cols;

  MV_REF *tmvp_mvs = cm->cur_frame->mvs;
  int write_pos = 0;
  for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
    for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
      const int tpl_offset = blk_row * mvs_stride + blk_col;
      TPL_MV_REF *tpl_mvs = tpl_mvs_base + tpl_offset;
      if (tpl_mvs->mfmv0.as_int != INVALID_MV) {
        tmvp_mvs[write_pos].mv[0].as_mv.row = blk_row;
        tmvp_mvs[write_pos].mv[0].as_mv.col = blk_col;
        write_pos++;
      }
    }
  }

#define ITER_DIR 4
  const int dirs[ITER_DIR][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };

  int read_pos = 0;
  while (read_pos < write_pos && write_pos < total_units) {
    const int start = read_pos;
    const int end = write_pos;
    for (int i = start; i < end; ++i) {
      const int cur_row = tmvp_mvs[i].mv[0].as_mv.row;
      const int cur_col = tmvp_mvs[i].mv[0].as_mv.col;
      const int cur_tpl_offset = cur_row * mvs_stride + cur_col;
      for (int dir = 0; dir < ITER_DIR; ++dir) {
        const int next_row = cur_row + dirs[dir][0];
        const int next_col = cur_col + dirs[dir][1];
        const int next_tpl_offset = next_row * mvs_stride + next_col;
        if (next_row < 0 || next_row >= mvs_rows || next_col < 0 ||
            next_col >= mvs_cols ||
            tpl_mvs_base[next_tpl_offset].mfmv0.as_int != INVALID_MV) {
          continue;
        }
        tpl_mvs_base[next_tpl_offset].mfmv0.as_int =
            tpl_mvs_base[cur_tpl_offset].mfmv0.as_int;
        tmvp_mvs[write_pos].mv[0].as_mv.row = next_row;
        tmvp_mvs[write_pos].mv[0].as_mv.col = next_col;
        write_pos++;
      }
    }
    read_pos = end;
  }
}

static void tip_blk_average_filter_mv(AV1_COMMON *cm) {
  TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;

  MV_REF *avg_mvs = cm->cur_frame->mvs;
  for (int i = 0; i < mvs_rows; i++) {
    const int i0 = i - 1;
    const int i1 = i + 1;
    for (int j = 0; j < mvs_cols; j++) {
      const int j0 = j - 1;
      const int j1 = j + 1;
      int count = 1;
      MV this_mv;
      const int cur_pos = i * mvs_stride + j;
      this_mv.row = tpl_mvs_base[cur_pos].mfmv0.as_mv.row;
      this_mv.col = tpl_mvs_base[cur_pos].mfmv0.as_mv.col;
      if (i0 >= 0) {
        count++;
        const int top_pos = i0 * mvs_stride + j;
        this_mv.row += tpl_mvs_base[top_pos].mfmv0.as_mv.row;
        this_mv.col += tpl_mvs_base[top_pos].mfmv0.as_mv.col;
      }

      if (i1 < mvs_rows) {
        count++;
        const int bottom_pos = i1 * mvs_stride + j;
        this_mv.row += tpl_mvs_base[bottom_pos].mfmv0.as_mv.row;
        this_mv.col += tpl_mvs_base[bottom_pos].mfmv0.as_mv.col;
      }

      if (j0 >= 0) {
        count++;
        const int left_pos = i * mvs_stride + j0;
        this_mv.row += tpl_mvs_base[left_pos].mfmv0.as_mv.row;
        this_mv.col += tpl_mvs_base[left_pos].mfmv0.as_mv.col;
      }

      if (j1 < mvs_cols) {
        count++;
        const int right_pos = i * mvs_stride + j1;
        this_mv.row += tpl_mvs_base[right_pos].mfmv0.as_mv.row;
        this_mv.col += tpl_mvs_base[right_pos].mfmv0.as_mv.col;
      }

      avg_mvs[cur_pos].mv[0].as_mv.row = this_mv.row / count;
      avg_mvs[cur_pos].mv[0].as_mv.col = this_mv.col / count;
    }
  }

  for (int i = 0; i < mvs_rows; i++) {
    for (int j = 0; j < mvs_cols; j++) {
      const int tpl_offset = i * mvs_stride + j;
      tpl_mvs_base[tpl_offset].mfmv0.as_int = avg_mvs[tpl_offset].mv[0].as_int;
    }
  }
}

static INLINE MV tip_clamp_tip_mv_to_umv_border_sb(
    const MV *src_mv, int bw, int bh, int ss_x, int ss_y, int dist_to_left_edge,
    int dist_to_right_edge, int dist_to_top_edge, int dist_to_bottom_edge) {
  // If the MV points so far into the UMV border that no visible pixels
  // are used for reconstruction, the subpel part of the MV can be
  // discarded and the MV limited to 16 pixels with equivalent results.
  const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
  const int spel_right = spel_left - SUBPEL_SHIFTS;
  const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
  const int spel_bottom = spel_top - SUBPEL_SHIFTS;
  MV clamped_mv = { (int16_t)(src_mv->row * (1 << (1 - ss_y))),
                    (int16_t)(src_mv->col * (1 << (1 - ss_x))) };
  assert(ss_x <= 1);
  assert(ss_y <= 1);
  const SubpelMvLimits mv_limits = {
    dist_to_left_edge * (1 << (1 - ss_x)) - spel_left,
    dist_to_right_edge * (1 << (1 - ss_x)) + spel_right,
    dist_to_top_edge * (1 << (1 - ss_y)) - spel_top,
    dist_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom
  };

  clamp_mv(&clamped_mv, &mv_limits);

  return clamped_mv;
}

static INLINE int tip_check_motion_field(AV1_COMMON *cm, const MV *mv, int mi_x,
                                         int mi_y, int bw, int bh, int frame_w,
                                         int frame_h) {
  TIP *tip_ref = &cm->tip_ref;
  MV this_mv[2];
  tip_get_mv_projection(&this_mv[0], *mv, tip_ref->ref_frames_offset_sf[0]);
  tip_get_mv_projection(&this_mv[1], *mv, tip_ref->ref_frames_offset_sf[1]);

  const int dist_to_top_edge = -GET_MV_SUBPEL(mi_y);
  const int dist_to_bottom_edge = GET_MV_SUBPEL(frame_h - bh - mi_y);
  const int dist_to_left_edge = -GET_MV_SUBPEL(mi_x);
  const int dist_to_right_edge = GET_MV_SUBPEL(frame_w - bw - mi_x);

  MV temp_mv;
  temp_mv = tip_clamp_tip_mv_to_umv_border_sb(
      &this_mv[0], bw, bh, 0, 0, dist_to_left_edge, dist_to_right_edge,
      dist_to_top_edge, dist_to_bottom_edge);
  if (temp_mv.row != this_mv[0].row || temp_mv.col != this_mv[0].col) {
    return 1;
  }

  temp_mv = tip_clamp_tip_mv_to_umv_border_sb(
      &this_mv[1], bw, bh, 0, 0, dist_to_left_edge, dist_to_right_edge,
      dist_to_top_edge, dist_to_bottom_edge);
  if (temp_mv.row != this_mv[1].row || temp_mv.col != this_mv[1].col) {
    return 1;
  }

  return 0;
}

static void tip_motion_field_within_frame(AV1_COMMON *cm) {
  TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;
  av1_zero_array(cm->tip_ref.mf_need_clamp, mvs_rows * mvs_stride);

  const int width = (mvs_cols << TMVP_MI_SZ_LOG2);
  const int height = (mvs_rows << TMVP_MI_SZ_LOG2);

  int *mf_need_clamp = cm->tip_ref.mf_need_clamp;
  for (int i = 0; i < mvs_rows; i++) {
    for (int j = 0; j < mvs_cols; j++) {
      const int cur_pos = i * mvs_stride + j;
      if (tpl_mvs_base[cur_pos].mfmv0.as_int != INVALID_MV &&
          tpl_mvs_base[cur_pos].mfmv0.as_int != 0) {
        MV this_mv;
        this_mv.row = tpl_mvs_base[cur_pos].mfmv0.as_mv.row;
        this_mv.col = tpl_mvs_base[cur_pos].mfmv0.as_mv.col;

        const int tpl_row = i << TMVP_MI_SZ_LOG2;
        const int tpl_col = j << TMVP_MI_SZ_LOG2;

        mf_need_clamp[cur_pos] =
            tip_check_motion_field(cm, &this_mv, tpl_col, tpl_row, TMVP_MI_SIZE,
                                   TMVP_MI_SIZE, width, height);
      } else {
        tpl_mvs_base[cur_pos].mfmv0.as_int = 0;
      }
    }
  }
}

static void tip_check_enable_tip_mode(AV1_COMMON *cm) {
  const TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;

  int count = 0;
  for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
    for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
      const int tpl_offset = blk_row * mvs_stride + blk_col;
      const TPL_MV_REF *tpl_mvs = tpl_mvs_base + tpl_offset;
      if (tpl_mvs->mfmv0.as_int != INVALID_MV) {
        ++count;
      }
    }
  }

  // Percentage of number of blocks with available motion field
  const int percent = (count * 100) / (mvs_rows * mvs_cols);
  if (percent < TIP_ENABLE_COUNT_THRESHOLD) {
    cm->features.tip_frame_mode = TIP_FRAME_DISABLED;
  } else {
    cm->features.tip_frame_mode = TIP_FRAME_AS_REF;
  }
}

static void tip_config_tip_parameter(AV1_COMMON *cm, int check_tip_threshold) {
  TIP *tip_ref = &cm->tip_ref;
  if (cm->current_frame.frame_type == KEY_FRAME ||
      cm->current_frame.frame_type == INTRA_ONLY_FRAME ||
      cm->current_frame.frame_type == S_FRAME) {
    cm->features.tip_frame_mode = TIP_FRAME_DISABLED;
    tip_ref->ref_frame[0] = NONE_FRAME;
    tip_ref->ref_frame[1] = NONE_FRAME;
    return;
  }

  const OrderHintInfo *const order_hint_info = &cm->seq_params.order_hint_info;
  const int cur_order_hint = cm->cur_frame->order_hint;

  MV_REFERENCE_FRAME nearest_rf[2] = { tip_ref->ref_frame[0],
                                       tip_ref->ref_frame[1] };

  if (nearest_rf[0] != NONE_FRAME && nearest_rf[1] != NONE_FRAME &&
      (is_ref_motion_field_eligible(cm, get_ref_frame_buf(cm, nearest_rf[0])) ||
       is_ref_motion_field_eligible(cm,
                                    get_ref_frame_buf(cm, nearest_rf[1])))) {
    if (check_tip_threshold) {
      tip_check_enable_tip_mode(cm);
    }

    if (cm->features.tip_frame_mode) {
      cm->features.allow_tip_hole_fill = cm->seq_params.enable_tip_hole_fill;
      RefCntBuffer *ref0_frame_buf = get_ref_frame_buf(cm, nearest_rf[0]);
      const int ref0_frame_order_hint = ref0_frame_buf->order_hint;
      const int cur_to_ref0_offset = get_relative_dist(
          order_hint_info, cur_order_hint, ref0_frame_order_hint);

      RefCntBuffer *ref1_frame_buf = get_ref_frame_buf(cm, nearest_rf[1]);
      const int ref1_frame_order_hint = ref1_frame_buf->order_hint;
      const int cur_to_ref1_offset = get_relative_dist(
          order_hint_info, cur_order_hint, ref1_frame_order_hint);

      const int ref_frames_offset = get_relative_dist(
          order_hint_info, ref1_frame_order_hint, ref0_frame_order_hint);
      tip_ref->ref_frame_buffer[0] = ref0_frame_buf;
      tip_ref->ref_frame_buffer[1] = ref1_frame_buf;
      tip_ref->ref_scale_factor[0] =
          get_ref_scale_factors_const(cm, nearest_rf[0]);
      tip_ref->ref_scale_factor[1] =
          get_ref_scale_factors_const(cm, nearest_rf[1]);
      tip_ref->ref_frames_offset_sf[0] =
          tip_derive_scale_factor(cur_to_ref0_offset, ref_frames_offset);
      tip_ref->ref_frames_offset_sf[1] =
          tip_derive_scale_factor(cur_to_ref1_offset, ref_frames_offset);
      tip_ref->ref_frames_offset = ref_frames_offset;
      tip_ref->ref_offset[0] = cur_to_ref0_offset;
      tip_ref->ref_offset[1] = cur_to_ref1_offset;
      tip_ref->ref_order_hint[0] = ref0_frame_order_hint;
      tip_ref->ref_order_hint[1] = ref1_frame_order_hint;
    }
  } else {
    cm->features.tip_frame_mode = TIP_FRAME_DISABLED;
    cm->features.allow_tip_hole_fill = false;
    tip_ref->ref_frame[0] = NONE_FRAME;
    tip_ref->ref_frame[1] = NONE_FRAME;
  }
}

void av1_setup_tip_motion_field(AV1_COMMON *cm, int check_tip_threshold) {
  tip_config_tip_parameter(cm, check_tip_threshold);
  if (cm->features.tip_frame_mode) {
    tip_temporal_scale_motion_field(cm, cm->tip_ref.ref_frames_offset);
    if (cm->features.allow_tip_hole_fill) {
      tip_fill_motion_field_holes(cm);
      tip_blk_average_filter_mv(cm);
    }
    tip_motion_field_within_frame(cm);
  }
}

static AOM_INLINE void tip_highbd_convolve_2d_facade_compound(
    const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride,
    const int w, const int h, const InterpFilterParams *interp_filters[2],
    SubpelParams *subpel_params, ConvolveParams *conv_params, int bd) {
  const int subpel_x_qn = subpel_params->subpel_x;
  const int subpel_y_qn = subpel_params->subpel_y;
  if (subpel_x_qn && subpel_y_qn) {
    assert(subpel_x_qn && subpel_y_qn);
    av1_highbd_dist_wtd_convolve_2d(src, src_stride, dst, dst_stride, w, h,
                                    interp_filters[0], interp_filters[1],
                                    subpel_x_qn, subpel_y_qn, conv_params, bd);
  } else if (subpel_x_qn && !subpel_y_qn) {
    av1_highbd_dist_wtd_convolve_x(src, src_stride, dst, dst_stride, w, h,
                                   interp_filters[0], subpel_x_qn, conv_params,
                                   bd);
  } else if (!subpel_x_qn && subpel_y_qn) {
    av1_highbd_dist_wtd_convolve_y(src, src_stride, dst, dst_stride, w, h,
                                   interp_filters[1], subpel_y_qn, conv_params,
                                   bd);
  } else {
    av1_highbd_dist_wtd_convolve_2d_copy(src, src_stride, dst, dst_stride, w, h,
                                         conv_params, bd);
  }
}

static AOM_INLINE void tip_highbd_inter_predictor(
    const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
    SubpelParams *subpel_params, int w, int h, ConvolveParams *conv_params,
    const InterpFilterParams *interp_filters[2], int bd) {
  assert(conv_params->do_average == 0 || conv_params->do_average == 1);
  const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
  const uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
  uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
  assert(conv_params->dst != NULL);
  if (is_scaled) {
    av1_highbd_convolve_2d_scale(
        src16, src_stride, dst16, dst_stride, w, h, interp_filters[0],
        interp_filters[1], subpel_params->subpel_x, subpel_params->xs,
        subpel_params->subpel_y, subpel_params->ys, conv_params, bd);
  } else {
    revert_scale_extra_bits(subpel_params);
    tip_highbd_convolve_2d_facade_compound(src16, src_stride, dst16, dst_stride,
                                           w, h, interp_filters, subpel_params,
                                           conv_params, bd);
  }
}

static AOM_INLINE void tip_build_one_inter_predictor(
    uint8_t *dst, int dst_stride, const MV *const src_mv,
    InterPredParams *inter_pred_params, MACROBLOCKD *xd, int mi_x, int mi_y,
    int ref, uint8_t **mc_buf, CalcSubpelParamsFunc calc_subpel_params_func) {
  SubpelParams subpel_params;
  uint8_t *src;
  int src_stride;
  calc_subpel_params_func(src_mv, inter_pred_params, xd, mi_x, mi_y, ref,
#if CONFIG_OPTFLOW_REFINEMENT
                          0,
#endif  // CONFIG_OPTFLOW_REFINEMENT
                          mc_buf, &src, &subpel_params, &src_stride);

  tip_highbd_inter_predictor(
      src, src_stride, dst, dst_stride, &subpel_params,
      inter_pred_params->block_width, inter_pred_params->block_height,
      &inter_pred_params->conv_params, inter_pred_params->interp_filter_params,
      inter_pred_params->bit_depth);
}

static AOM_INLINE void tip_build_inter_predictors_8x8_and_bigger(
    const AV1_COMMON *cm, MACROBLOCKD *xd, int plane, TIP_PLANE *tip_plane,
    const MV mv[2], int bw, int bh, int mi_x, int mi_y, uint8_t **mc_buf,
    CONV_BUF_TYPE *tmp_conv_dst, CalcSubpelParamsFunc calc_subpel_params_func) {
  TIP_PLANE *const tip = &tip_plane[plane];
  struct buf_2d *const dst_buf = &tip->dst;
  uint8_t *const dst = dst_buf->buf;

  const int bd = cm->seq_params.bit_depth;

  const int ss_x = plane ? cm->seq_params.subsampling_x : 0;
  const int ss_y = plane ? cm->seq_params.subsampling_y : 0;
  const int comp_pixel_x = (mi_x >> ss_x);
  const int comp_pixel_y = (mi_y >> ss_y);
  const int comp_bw = bw >> ss_x;
  const int comp_bh = bh >> ss_y;
  for (int ref = 0; ref < 2; ++ref) {
    const struct scale_factors *const sf = cm->tip_ref.ref_scale_factor[ref];
    struct buf_2d *const pred_buf = &tip->pred[ref];

    InterPredParams inter_pred_params;
    av1_init_inter_params(&inter_pred_params, comp_bw, comp_bh, comp_pixel_y,
                          comp_pixel_x, ss_x, ss_y, bd, 0, sf, pred_buf,
                          MULTITAP_SHARP);

    inter_pred_params.comp_mode = UNIFORM_COMP;

    const int width = (cm->mi_params.mi_cols << MI_SIZE_LOG2);
    const int height = (cm->mi_params.mi_rows << MI_SIZE_LOG2);
    inter_pred_params.dist_to_top_edge = -GET_MV_SUBPEL(mi_y);
    inter_pred_params.dist_to_bottom_edge = GET_MV_SUBPEL(height - bh - mi_y);
    inter_pred_params.dist_to_left_edge = -GET_MV_SUBPEL(mi_x);
    inter_pred_params.dist_to_right_edge = GET_MV_SUBPEL(width - bw - mi_x);

    inter_pred_params.conv_params =
        get_conv_params_no_round(ref, plane, tmp_conv_dst, MAX_SB_SIZE, 1, bd);

    tip_build_one_inter_predictor(dst, dst_buf->stride, &mv[ref],
                                  &inter_pred_params, xd, mi_x, mi_y, ref,
                                  mc_buf, calc_subpel_params_func);
  }
}

static AOM_INLINE void tip_component_build_inter_predictors(
    const AV1_COMMON *cm, MACROBLOCKD *xd, int plane, TIP_PLANE *tip_plane,
    const MV mv[2], int bw, int bh, int mi_x, int mi_y, uint8_t **mc_buf,
    CONV_BUF_TYPE *tmp_conv_dst, CalcSubpelParamsFunc calc_subpel_params_func) {
  tip_build_inter_predictors_8x8_and_bigger(
      cm, xd, plane, tip_plane, mv, bw, bh, mi_x, mi_y, mc_buf, tmp_conv_dst,
      calc_subpel_params_func);
}

static INLINE void tip_setup_pred_plane(struct buf_2d *dst, uint8_t *src,
                                        int width, int height, int stride,
                                        int tpl_row, int tpl_col,
                                        const struct scale_factors *scale,
                                        int subsampling_x, int subsampling_y) {
  const int x = tpl_col >> subsampling_x;
  const int y = tpl_row >> subsampling_y;
  dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
  dst->buf0 = src;
  dst->width = width;
  dst->height = height;
  dst->stride = stride;
}

static AOM_INLINE void tip_component_setup_pred_planes(AV1_COMMON *const cm,
                                                       const int plane,
                                                       const int tpl_row,
                                                       const int tpl_col) {
  TIP *tip_ref = &cm->tip_ref;
  for (int ref = 0; ref < 2; ++ref) {
    const YV12_BUFFER_CONFIG *ref_buf = &tip_ref->ref_frame_buffer[ref]->buf;
    TIP_PLANE *const pd = &tip_ref->tip_plane[plane];
    int is_uv = 0;
    int subsampling_x = 0;
    int subsampling_y = 0;
    if (plane > 0) {
      is_uv = 1;
      subsampling_x = cm->seq_params.subsampling_x;
      subsampling_y = cm->seq_params.subsampling_y;
    }
    tip_setup_pred_plane(
        &pd->pred[ref], ref_buf->buffers[plane], ref_buf->crop_widths[is_uv],
        ref_buf->crop_heights[is_uv], ref_buf->strides[is_uv], tpl_row, tpl_col,
        tip_ref->ref_scale_factor[ref], subsampling_x, subsampling_y);
  }
}

static AOM_INLINE void tip_component_setup_dst_planes(AV1_COMMON *const cm,
                                                      const int plane,
                                                      const int tpl_row,
                                                      const int tpl_col) {
  const YV12_BUFFER_CONFIG *src = &cm->tip_ref.tip_frame->buf;
  TIP_PLANE *const pd = &cm->tip_ref.tip_plane[plane];
  int is_uv = 0;
  int subsampling_x = 0;
  int subsampling_y = 0;
  if (plane > 0) {
    is_uv = 1;
    subsampling_x = cm->seq_params.subsampling_x;
    subsampling_y = cm->seq_params.subsampling_y;
  }
  tip_setup_pred_plane(&pd->dst, src->buffers[plane], src->crop_widths[is_uv],
                       src->crop_heights[is_uv], src->strides[is_uv], tpl_row,
                       tpl_col, NULL, subsampling_x, subsampling_y);
}

static void tip_setup_tip_frame_plane(
    AV1_COMMON *cm, MACROBLOCKD *xd, int plane, int blk_row_start,
    int blk_col_start, int blk_row_end, int blk_col_end, int mvs_stride,
    int unit_blk_size, int max_allow_blk_size, uint8_t **mc_buf,
    CONV_BUF_TYPE *tmp_conv_dst, CalcSubpelParamsFunc calc_subpel_params_func) {
  TIP *tip_ref = &cm->tip_ref;
  const TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;

  MV zero_mv[2];
  memset(zero_mv, 0, sizeof(zero_mv));

  const int step = (unit_blk_size >> TMVP_MI_SZ_LOG2);
  for (int blk_row = blk_row_start; blk_row < blk_row_end; blk_row += step) {
    for (int blk_col = blk_col_start; blk_col < blk_col_end; blk_col += step) {
      const int tpl_offset = blk_row * mvs_stride + blk_col;
      const TPL_MV_REF *tpl_mvs = tpl_mvs_base + tpl_offset;
      const int tpl_row = blk_row << TMVP_MI_SZ_LOG2;
      const int tpl_col = blk_col << TMVP_MI_SZ_LOG2;

      int blk_width = unit_blk_size;
      int blk_height = unit_blk_size;
      int offset = step;
      // Make sure blocks do not cross 128 aligned boundaries
      while (blk_col + offset < blk_col_end && blk_width < max_allow_blk_size &&
             tip_ref->mf_need_clamp[tpl_offset] ==
                 tip_ref->mf_need_clamp[tpl_offset + offset] &&
             tpl_mvs->mfmv0.as_int ==
                 tpl_mvs_base[tpl_offset + offset].mfmv0.as_int) {
        blk_width += unit_blk_size;
        offset += step;
      }
      blk_col += (offset - step);

      MV mv[2];
      if (tpl_mvs->mfmv0.as_int != 0) {
        tip_get_mv_projection(&mv[0], tpl_mvs->mfmv0.as_mv,
                              tip_ref->ref_frames_offset_sf[0]);
        tip_get_mv_projection(&mv[1], tpl_mvs->mfmv0.as_mv,
                              tip_ref->ref_frames_offset_sf[1]);
      } else {
        mv[0] = zero_mv[0];
        mv[1] = zero_mv[1];
      }
      tip_component_setup_pred_planes(cm, plane, tpl_row, tpl_col);
      tip_component_setup_dst_planes(cm, plane, tpl_row, tpl_col);
      tip_component_build_inter_predictors(
          cm, xd, plane, tip_ref->tip_plane, mv, blk_width, blk_height, tpl_col,
          tpl_row, mc_buf, tmp_conv_dst, calc_subpel_params_func);
    }
  }
}

static AOM_INLINE void tip_setup_tip_frame_planes(
    AV1_COMMON *cm, MACROBLOCKD *xd, int blk_row_start, int blk_col_start,
    int blk_row_end, int blk_col_end, int mvs_stride, uint8_t **mc_buf,
    CONV_BUF_TYPE *tmp_conv_dst, CalcSubpelParamsFunc calc_subpel_params_func) {
  const int num_planes = av1_num_planes(cm);
  for (int plane = 0; plane < num_planes; ++plane) {
    if (plane == 0) {
      tip_setup_tip_frame_plane(cm, xd, plane, blk_row_start, blk_col_start,
                                blk_row_end, blk_col_end, mvs_stride,
                                TMVP_MI_SIZE, MAX_BLOCK_SIZE_WITH_SAME_MV,
                                mc_buf, tmp_conv_dst, calc_subpel_params_func);
    } else {
      // CHROMA_MI_SIZE is the block size in luma unit for Chroma
      // TIP interpolation, will convert to the step size in TMVP 8x8 unit
      tip_setup_tip_frame_plane(cm, xd, plane, blk_row_start, blk_col_start,
                                blk_row_end, blk_col_end, mvs_stride,
                                CHROMA_MI_SIZE, MAX_BLOCK_SIZE_WITH_SAME_MV,
                                mc_buf, tmp_conv_dst, calc_subpel_params_func);
    }
  }

  aom_extend_frame_borders(&cm->tip_ref.tip_frame->buf, av1_num_planes(cm));
}

void av1_setup_tip_frame(AV1_COMMON *cm, MACROBLOCKD *xd, uint8_t **mc_buf,
                         CONV_BUF_TYPE *tmp_conv_dst,
                         CalcSubpelParamsFunc calc_subpel_params_func) {
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  tip_setup_tip_frame_planes(cm, xd, 0, 0, mvs_rows, mvs_cols, mvs_cols, mc_buf,
                             tmp_conv_dst, calc_subpel_params_func);
#if CONFIG_ALLOW_TIP_DIRECT_WITH_SUPERRES
  if (av1_superres_scaled(cm)) {
    // Upscale tip_frame and store in upsampled_tip_frame_buf
#if CONFIG_EXT_SUPERRES
    av1_upscale_2d_normative_and_extend_frame(
        cm, &cm->tip_ref.tip_frame->buf, &cm->tip_ref.upscaled_tip_frame_buf);
#else
    av1_upscale_normative_and_extend_frame(cm, &cm->tip_ref.tip_frame->buf,
                                           &cm->tip_ref.upscaled_tip_frame_buf);
#endif  // CONFIG_EXT_SUPERRES
  }
#endif  // CONFIG_ALLOW_TIP_DIRECT_WITH_SUPERRES
}

static void tip_extend_plane_block_based_highbd(
    uint8_t *const src8, int src_stride, int width, int height, int extend_top,
    int extend_left, int extend_bottom, int extend_right, int start_w,
    int start_h, int blk_w, int blk_h) {
  assert(src8 != NULL);
  uint16_t *src = CONVERT_TO_SHORTPTR(src8);
  int i = 0;

  if (extend_left) {
    // copy the left most columns out
    uint16_t *src_ptr = src + start_h * src_stride;
    uint16_t *dst_ptr = src_ptr - extend_left;
    for (i = 0; i < blk_h; ++i) {
      aom_memset16(dst_ptr, src_ptr[0], extend_left);
      src_ptr += src_stride;
      dst_ptr += src_stride;
    }
  }

  if (extend_right) {
    // copy the right most columns out
    uint16_t *src_ptr = src + start_h * src_stride + width - 1;
    uint16_t *dst_ptr = src_ptr + 1;
    for (i = 0; i < blk_h; ++i) {
      aom_memset16(dst_ptr, src_ptr[0], extend_right);
      src_ptr += src_stride;
      dst_ptr += src_stride;
    }
  }

  if (extend_top) {
    // copy the top lines into each line of the respective borders
    uint16_t *src_ptr = src + start_w - extend_left;
    uint16_t *dst_ptr = src_ptr - src_stride * extend_top;
    const int extend_size = extend_left + extend_right + blk_w;
    for (i = 0; i < extend_top; ++i) {
      memcpy(dst_ptr, src_ptr, extend_size * sizeof(uint16_t));
      dst_ptr += src_stride;
    }
  }

  if (extend_bottom) {
    // copy the bottom lines into each line of the respective borders
    uint16_t *src_ptr = src + src_stride * (height - 1) + start_w - extend_left;
    uint16_t *dst_ptr = src_ptr + src_stride;
    const int extend_size = extend_left + extend_right + blk_w;
    for (i = 0; i < extend_bottom; ++i) {
      memcpy(dst_ptr, src_ptr, extend_size * sizeof(uint16_t));
      dst_ptr += src_stride;
    }
  }
}

static void tip_extend_plane_border(AV1_COMMON *cm, int blk_row_start,
                                    int blk_col_start, int blk_height,
                                    int blk_width) {
  YV12_BUFFER_CONFIG *tip_buf = &cm->tip_ref.tip_frame->buf;
  const int width = tip_buf->y_width;
  const int height = tip_buf->y_height;

  int top_border = 0;
  int bottom_border = 0;
  int left_border = 0;
  int right_border = 0;
  if (blk_row_start == 0) {
    top_border = 1;
  }

  if (blk_row_start + blk_height >= height) {
    bottom_border = 1;
    blk_height = height - blk_row_start;
  }

  if (blk_col_start == 0) {
    left_border = 1;
  }

  if (blk_col_start + blk_width >= width) {
    right_border = 1;
    blk_width = width - blk_col_start;
  }

  if (top_border || bottom_border || left_border || right_border) {
    const int subsampling_x = cm->seq_params.subsampling_x;
    const int subsampling_y = cm->seq_params.subsampling_y;
    const int y_stride = tip_buf->y_stride;
    const int uv_stride = tip_buf->uv_stride;
    const int extend_border = tip_buf->border;
    const int y_width = tip_buf->y_crop_width;
    const int y_height = tip_buf->y_crop_height;
    const int uv_width = tip_buf->uv_crop_width;
    const int uv_height = tip_buf->uv_crop_height;
    uint8_t *y_dst = tip_buf->y_buffer;
    uint8_t *u_dst = tip_buf->u_buffer;
    uint8_t *v_dst = tip_buf->v_buffer;

    const int extend_top = top_border ? extend_border : 0;
    const int extend_bottom = bottom_border ? extend_border : 0;
    const int extend_left = left_border ? extend_border : 0;
    const int extend_right = right_border ? extend_border : 0;

    const int uv_extend_top = extend_top >> subsampling_y;
    const int uv_extend_bottom = extend_bottom >> subsampling_y;
    const int uv_extend_left = extend_left >> subsampling_x;
    const int uv_extend_right = extend_right >> subsampling_x;

    tip_extend_plane_block_based_highbd(y_dst, y_stride, y_width, y_height,
                                        extend_top, extend_left, extend_bottom,
                                        extend_right, blk_col_start,
                                        blk_row_start, blk_width, blk_height);

    blk_col_start >>= subsampling_x;
    blk_row_start >>= subsampling_y;
    blk_width >>= subsampling_x;
    blk_height >>= subsampling_y;
    tip_extend_plane_block_based_highbd(
        u_dst, uv_stride, uv_width, uv_height, uv_extend_top, uv_extend_left,
        uv_extend_bottom, uv_extend_right, blk_col_start, blk_row_start,
        blk_width, blk_height);
    tip_extend_plane_block_based_highbd(
        v_dst, uv_stride, uv_width, uv_height, uv_extend_top, uv_extend_left,
        uv_extend_bottom, uv_extend_right, blk_col_start, blk_row_start,
        blk_width, blk_height);
  }
}

static void tip_setup_tip_plane_blocks(
    AV1_COMMON *cm, MACROBLOCKD *xd, int plane, int blk_row_start,
    int blk_col_start, int blk_row_end, int blk_col_end, int mvs_stride,
    int unit_blk_size, int max_allow_blk_size, uint8_t **mc_buf,
    CONV_BUF_TYPE *tmp_conv_dst, CalcSubpelParamsFunc calc_subpel_params_func) {
  TIP *tip_ref = &cm->tip_ref;
  const TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;

  MV zero_mv[2];
  memset(zero_mv, 0, sizeof(zero_mv));

  const int step = (unit_blk_size >> TMVP_MI_SZ_LOG2);
  for (int blk_row = blk_row_start; blk_row < blk_row_end; blk_row += step) {
    for (int blk_col = blk_col_start; blk_col < blk_col_end; blk_col += step) {
      const int tpl_offset = blk_row * mvs_stride + blk_col;
      if (tip_ref->available_flag[tpl_offset]) continue;
      const TPL_MV_REF *tpl_mvs = tpl_mvs_base + tpl_offset;
      const int tpl_row = blk_row << TMVP_MI_SZ_LOG2;
      const int tpl_col = blk_col << TMVP_MI_SZ_LOG2;

      int blk_width = unit_blk_size;
      int blk_height = unit_blk_size;
      int offset = step;
      // Make sure blocks do not cross 128 aligned boundaries
      while (blk_col + offset < blk_col_end && blk_width < max_allow_blk_size &&
             !tip_ref->available_flag[tpl_offset + offset] &&
             tip_ref->mf_need_clamp[tpl_offset] ==
                 tip_ref->mf_need_clamp[tpl_offset + offset] &&
             tpl_mvs->mfmv0.as_int ==
                 tpl_mvs_base[tpl_offset + offset].mfmv0.as_int) {
        blk_width += unit_blk_size;
        offset += step;
      }
      blk_col += (offset - step);

      MV mv[2];
      if (tpl_mvs->mfmv0.as_int != 0) {
        tip_get_mv_projection(&mv[0], tpl_mvs->mfmv0.as_mv,
                              tip_ref->ref_frames_offset_sf[0]);
        tip_get_mv_projection(&mv[1], tpl_mvs->mfmv0.as_mv,
                              tip_ref->ref_frames_offset_sf[1]);
      } else {
        mv[0] = zero_mv[0];
        mv[1] = zero_mv[1];
      }

      tip_component_setup_pred_planes(cm, plane, tpl_row, tpl_col);
      tip_component_setup_dst_planes(cm, plane, tpl_row, tpl_col);
      tip_component_build_inter_predictors(
          cm, xd, plane, tip_ref->tip_plane, mv, blk_width, blk_height, tpl_col,
          tpl_row, mc_buf, tmp_conv_dst, calc_subpel_params_func);
    }
  }
}

static AOM_INLINE void tip_setup_tip_planes_blocks(
    AV1_COMMON *cm, MACROBLOCKD *xd, int blk_row_start, int blk_col_start,
    int blk_row_end, int blk_col_end, int mvs_stride, uint8_t **mc_buf,
    CONV_BUF_TYPE *tmp_conv_dst, CalcSubpelParamsFunc calc_subpel_params_func) {
  const int num_planes = av1_num_planes(cm);
  for (int plane = 0; plane < num_planes; ++plane) {
    if (plane == 0) {
      tip_setup_tip_plane_blocks(cm, xd, plane, blk_row_start, blk_col_start,
                                 blk_row_end, blk_col_end, mvs_stride,
                                 TMVP_MI_SIZE, MAX_BLOCK_SIZE_WITH_SAME_MV,
                                 mc_buf, tmp_conv_dst, calc_subpel_params_func);
    } else {
      // CHROMA_MI_SIZE is the block size in luma unit for Chroma
      // TIP interpolation, will convert to the step size in TMVP 8x8 unit
      tip_setup_tip_plane_blocks(cm, xd, plane, blk_row_start, blk_col_start,
                                 blk_row_end, blk_col_end, mvs_stride,
                                 CHROMA_MI_SIZE, MAX_BLOCK_SIZE_WITH_SAME_MV,
                                 mc_buf, tmp_conv_dst, calc_subpel_params_func);
    }
  }

  const int step = (TMVP_MI_SIZE >> TMVP_MI_SZ_LOG2);
  for (int blk_row = blk_row_start; blk_row < blk_row_end; blk_row += step) {
    for (int blk_col = blk_col_start; blk_col < blk_col_end; blk_col += step) {
      const int tpl_offset = blk_row * mvs_stride + blk_col;
      cm->tip_ref.available_flag[tpl_offset] = 1;
    }
  }
}

void av1_setup_tip_on_the_fly(AV1_COMMON *cm, MACROBLOCKD *xd,
                              int blk_row_start, int blk_col_start,
                              int blk_row_end, int blk_col_end, int mvs_stride,
                              uint8_t **mc_buf, CONV_BUF_TYPE *tmp_conv_dst,
                              CalcSubpelParamsFunc calc_subpel_params_func) {
  tip_setup_tip_planes_blocks(cm, xd, blk_row_start, blk_col_start, blk_row_end,
                              blk_col_end, mvs_stride, mc_buf, tmp_conv_dst,
                              calc_subpel_params_func);
  tip_extend_plane_border(cm, blk_row_start << TMVP_MI_SZ_LOG2,
                          blk_col_start << TMVP_MI_SZ_LOG2,
                          (blk_row_end - blk_row_start) << TMVP_MI_SZ_LOG2,
                          (blk_col_end - blk_col_start) << TMVP_MI_SZ_LOG2);
}

void av1_copy_tip_frame_tmvp_mvs(const AV1_COMMON *const cm) {
  MV_REF *frame_mvs = cm->cur_frame->mvs;
  const TPL_MV_REF *tpl_mvs = cm->tpl_mvs;
  const TIP *tip_ref = &cm->tip_ref;
  const int mvs_rows =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
  const int mvs_cols =
      ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
  const int mvs_stride = mvs_cols;

  for (int h = 0; h < mvs_rows; h++) {
    MV_REF *mv = frame_mvs;
    const TPL_MV_REF *tpl_mv = tpl_mvs;
    for (int w = 0; w < mvs_cols; w++) {
      mv->ref_frame[0] = NONE_FRAME;
      mv->ref_frame[1] = NONE_FRAME;
      mv->mv[0].as_int = 0;
      mv->mv[1].as_int = 0;
      if (tpl_mv->mfmv0.as_int != INVALID_MV) {
        int_mv this_mv[2] = { 0 };
        tip_get_mv_projection(&this_mv[0].as_mv, tpl_mv->mfmv0.as_mv,
                              tip_ref->ref_frames_offset_sf[0]);
        tip_get_mv_projection(&this_mv[1].as_mv, tpl_mv->mfmv0.as_mv,
                              tip_ref->ref_frames_offset_sf[1]);

        if ((abs(this_mv[0].as_mv.row) <= REFMVS_LIMIT) &&
            (abs(this_mv[0].as_mv.col) <= REFMVS_LIMIT)) {
          mv->ref_frame[0] = tip_ref->ref_frame[0];
          mv->mv[0].as_int = this_mv[0].as_int;
        }

        if ((abs(this_mv[1].as_mv.row) <= REFMVS_LIMIT) &&
            (abs(this_mv[1].as_mv.col) <= REFMVS_LIMIT)) {
          mv->ref_frame[1] = tip_ref->ref_frame[1];
          mv->mv[1].as_int = this_mv[1].as_int;
        }
      }
      mv++;
      tpl_mv++;
    }
    frame_mvs += mvs_stride;
    tpl_mvs += mvs_stride;
  }
}
