Refactor build_prediction_by_above_pred()

Streamline the inter prediction control flow.

Change-Id: Ifa4c5bd3f7b56f8a7c4290cc5e634ac505f7fe3f
diff --git a/av1/encoder/reconinter_enc.c b/av1/encoder/reconinter_enc.c
index fcd91a5..545d30b 100644
--- a/av1/encoder/reconinter_enc.c
+++ b/av1/encoder/reconinter_enc.c
@@ -290,14 +290,45 @@
   mv.col += SCALE_EXTRA_OFF;
   mv.row += SCALE_EXTRA_OFF;
 
-  const SubpelParams subpel_params = {
-    inter_pred_params->scale_factors->x_step_q4,
-    inter_pred_params->scale_factors->y_step_q4, mv.col & SCALE_SUBPEL_MASK,
-    mv.row & SCALE_SUBPEL_MASK
-  };
+  SubpelParams subpel_params = { inter_pred_params->scale_factors->x_step_q4,
+                                 inter_pred_params->scale_factors->y_step_q4,
+                                 mv.col & SCALE_SUBPEL_MASK,
+                                 mv.row & SCALE_SUBPEL_MASK };
   src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride +
          (mv.col >> SCALE_SUBPEL_BITS);
 
+  const struct scale_factors *sf = inter_pred_params->scale_factors;
+  const int is_scaled = av1_is_scaled(sf);
+  // Re-compute the address when the reference frame is scaled.
+  if (is_scaled) {
+    struct buf_2d *pre_buf = &inter_pred_params->ref_frame_buf;
+    int ssx = inter_pred_params->subsampling_x;
+    int ssy = inter_pred_params->subsampling_y;
+    int orig_pos_y = (inter_pred_params->pix_row >> ssy) << SUBPEL_BITS;
+    orig_pos_y += src_mv->row * (1 << (1 - ssy));
+    int orig_pos_x = (inter_pred_params->pix_col >> ssx) << SUBPEL_BITS;
+    orig_pos_x += src_mv->col * (1 << (1 - ssx));
+    int pos_y = sf->scale_value_y(orig_pos_y, sf);
+    int pos_x = sf->scale_value_x(orig_pos_x, sf);
+    pos_x += SCALE_EXTRA_OFF;
+    pos_y += SCALE_EXTRA_OFF;
+
+    const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy);
+    const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx);
+    const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
+                       << SCALE_SUBPEL_BITS;
+    const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
+    pos_y = clamp(pos_y, top, bottom);
+    pos_x = clamp(pos_x, left, right);
+
+    src = pre_buf->buf0 + (pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
+          (pos_x >> SCALE_SUBPEL_BITS);
+    subpel_params.subpel_x = pos_x & SCALE_SUBPEL_MASK;
+    subpel_params.subpel_y = pos_y & SCALE_SUBPEL_MASK;
+    subpel_params.xs = sf->x_step_q4;
+    subpel_params.ys = sf->y_step_q4;
+  }
+
   av1_make_inter_predictor(src, src_stride, dst, dst_stride, inter_pred_params,
                            &subpel_params);
 }
@@ -317,6 +348,8 @@
 
   const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
 
+  InterPredParams inter_pred_params;
+
   for (int j = 0; j < num_planes; ++j) {
     const struct macroblockd_plane *pd = &xd->plane[j];
     int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x;
@@ -324,8 +357,19 @@
                    block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1));
 
     if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue;
-    build_inter_predictors(ctxt->cm, xd, j, &backup_mbmi, 1, bw, bh, mi_x,
-                           mi_y);
+
+    const struct buf_2d *const pre_buf = &pd->pre[0];
+    const MV mv = backup_mbmi.mv[0].as_mv;
+
+    av1_init_inter_params(&inter_pred_params, bw, bh, mi_y, mi_x,
+                          pd->subsampling_x, pd->subsampling_y, xd->bd,
+                          is_cur_buf_hbd(xd), 0, xd->block_ref_scale_factors[0],
+                          pre_buf, backup_mbmi.interp_filters);
+    inter_pred_params.conv_params = get_conv_params(0, 0, xd->bd);
+
+    av1_build_inter_predictor(pre_buf->buf, pre_buf->stride, pd->dst.buf,
+                              pd->dst.stride, &mv, mi_x, mi_y,
+                              &inter_pred_params);
   }
 }