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