/*
 * 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 << 1)
// Maximum block size is allowed to combine the blocks with same MV
#define MAX_BLOCK_SIZE_WITH_SAME_MV 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 (start_frame_buf == NULL) return 0;

  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;
  for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
    for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
      const MV_REF *mv_ref = &mv_ref_base[blk_row * mvs_stride + 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_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, blk_row,
                                                     blk_col, this_mv.as_mv, 0);
            if (pos_valid) {
              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;
              }
            }
          }
        }
      }
    }
  }

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

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 = y_width >> subsampling_x;
    const int uv_heigh = y_height >> subsampling_y;
    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_heigh, 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_heigh, 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;
      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;
  }
}
