/*
 * 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 high_bd = cm->seq_params.use_highbitdepth;

  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, high_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_block_based(uint8_t *const src, 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(src != NULL);
  int i = 0;

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

  if (extend_right) {
    // copy the right most columns out
    uint8_t *src_ptr = src + start_h * src_stride + width - 1;
    uint8_t *dst_ptr = src_ptr + 1;
    for (i = 0; i < blk_h; ++i) {
      memset(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
    uint8_t *src_ptr = src + start_w - extend_left;
    uint8_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);
      dst_ptr += src_stride;
    }
  }

  if (extend_bottom) {
    // copy the bottom lines into each line of the respective borders
    uint8_t *src_ptr = src + src_stride * (height - 1) + start_w - extend_left;
    uint8_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);
      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 is_high_bitdepth = tip_buf->flags & YV12_FLAG_HIGHBITDEPTH;
    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;

    if (is_high_bitdepth) {
      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);
    } else {
      tip_extend_plane_block_based(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(
          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(
          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;
  }
}
