Refactor obmc prediction Unify the obmc prediction for above and left neighbors. Change-Id: I25da638d6367671133475e285f1ca801fd020f8f
diff --git a/av1/common/obmc.h b/av1/common/obmc.h index 1c90cd9..2cf73be 100644 --- a/av1/common/obmc.h +++ b/av1/common/obmc.h
@@ -12,10 +12,10 @@ #ifndef AOM_AV1_COMMON_OBMC_H_ #define AOM_AV1_COMMON_OBMC_H_ -typedef void (*overlappable_nb_visitor_t)(MACROBLOCKD *xd, int rel_mi_pos, - uint8_t nb_mi_size, - MB_MODE_INFO *nb_mi, void *fun_ctxt, - const int num_planes); +typedef void (*overlappable_nb_visitor_t)(MACROBLOCKD *xd, int rel_mi_row, + int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *nb_mi, + void *fun_ctxt, const int num_planes); static INLINE void foreach_overlappable_nb_above(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_col, @@ -49,7 +49,7 @@ } if (is_neighbor_overlappable(*above_mi)) { ++nb_count; - fun(xd, above_mi_col - mi_col, AOMMIN(xd->n4_w, mi_step), *above_mi, + fun(xd, 0, above_mi_col - mi_col, AOMMIN(xd->n4_w, mi_step), 0, *above_mi, fun_ctxt, num_planes); } } @@ -82,7 +82,7 @@ } if (is_neighbor_overlappable(*left_mi)) { ++nb_count; - fun(xd, left_mi_row - mi_row, AOMMIN(xd->n4_h, mi_step), *left_mi, + fun(xd, left_mi_row - mi_row, 0, AOMMIN(xd->n4_h, mi_step), 1, *left_mi, fun_ctxt, num_planes); } }
diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c index 86501c4..16ebcbe 100644 --- a/av1/common/reconinter.c +++ b/av1/common/reconinter.c
@@ -731,12 +731,15 @@ } } -static INLINE void increment_int_ptr(MACROBLOCKD *xd, int rel_mi_rc, - uint8_t mi_hw, MB_MODE_INFO *mi, - void *fun_ctxt, const int num_planes) { +static INLINE void increment_int_ptr(MACROBLOCKD *xd, int rel_mi_row, + int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *mi, void *fun_ctxt, + const int num_planes) { (void)xd; - (void)rel_mi_rc; - (void)mi_hw; + (void)rel_mi_row; + (void)rel_mi_col; + (void)op_mi_size; + (void)dir; (void)mi; ++*(int *)fun_ctxt; (void)num_planes; @@ -794,12 +797,12 @@ int *adjacent_stride; }; -static INLINE void build_obmc_inter_pred_above(MACROBLOCKD *xd, int rel_mi_col, - uint8_t above_mi_width, - MB_MODE_INFO *above_mi, - void *fun_ctxt, - const int num_planes) { +static INLINE void build_obmc_inter_pred_above( + MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *above_mi, void *fun_ctxt, const int num_planes) { (void)above_mi; + (void)rel_mi_row; + (void)dir; struct obmc_inter_pred_ctxt *ctxt = (struct obmc_inter_pred_ctxt *)fun_ctxt; const BLOCK_SIZE bsize = xd->mi[0]->sb_type; const int overlap = @@ -807,7 +810,7 @@ for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *pd = &xd->plane[plane]; - const int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x; + const int bw = (op_mi_size * MI_SIZE) >> pd->subsampling_x; const int bh = overlap >> pd->subsampling_y; const int plane_col = (rel_mi_col * MI_SIZE) >> pd->subsampling_x; @@ -833,12 +836,12 @@ } } -static INLINE void build_obmc_inter_pred_left(MACROBLOCKD *xd, int rel_mi_row, - uint8_t left_mi_height, - MB_MODE_INFO *left_mi, - void *fun_ctxt, - const int num_planes) { +static INLINE void build_obmc_inter_pred_left( + MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *left_mi, void *fun_ctxt, const int num_planes) { (void)left_mi; + (void)rel_mi_col; + (void)dir; struct obmc_inter_pred_ctxt *ctxt = (struct obmc_inter_pred_ctxt *)fun_ctxt; const BLOCK_SIZE bsize = xd->mi[0]->sb_type; const int overlap = @@ -847,7 +850,7 @@ for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *pd = &xd->plane[plane]; const int bw = overlap >> pd->subsampling_x; - const int bh = (left_mi_height * MI_SIZE) >> pd->subsampling_y; + const int bh = (op_mi_size * MI_SIZE) >> pd->subsampling_y; const int plane_row = (rel_mi_row * MI_SIZE) >> pd->subsampling_y; if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue; @@ -898,6 +901,37 @@ build_obmc_inter_pred_left, &ctxt_left); } +void av1_setup_address_for_obmc(MACROBLOCKD *xd, int mi_row_offset, + int mi_col_offset, MB_MODE_INFO *ref_mbmi, + struct build_prediction_ctxt *ctxt, + const int num_planes) { + const BLOCK_SIZE ref_bsize = AOMMAX(BLOCK_8X8, ref_mbmi->sb_type); + const int ref_mi_row = ctxt->mi_row + mi_row_offset; + const int ref_mi_col = ctxt->mi_col + mi_col_offset; + + for (int plane = 0; plane < num_planes; ++plane) { + struct macroblockd_plane *const pd = &xd->plane[plane]; + setup_pred_plane(&pd->dst, ref_bsize, ctxt->tmp_buf[plane], + ctxt->tmp_width[plane], ctxt->tmp_height[plane], + ctxt->tmp_stride[plane], mi_row_offset, mi_col_offset, + NULL, pd->subsampling_x, pd->subsampling_y); + } + + const MV_REFERENCE_FRAME frame = ref_mbmi->ref_frame[0]; + + const RefCntBuffer *const ref_buf = get_ref_frame_buf(ctxt->cm, frame); + const struct scale_factors *const sf = + get_ref_scale_factors_const(ctxt->cm, frame); + + xd->block_ref_scale_factors[0] = sf; + if ((!av1_is_valid_scale(sf))) + aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, + "Reference frame has invalid dimensions"); + + av1_setup_pre_planes(xd, 0, &ref_buf->buf, ref_mi_row, ref_mi_col, sf, + num_planes); +} + void av1_setup_build_prediction_by_above_pred( MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, MB_MODE_INFO *above_mbmi, struct build_prediction_ctxt *ctxt,
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h index 054b031..6b38f77 100644 --- a/av1/common/reconinter.h +++ b/av1/common/reconinter.h
@@ -323,6 +323,11 @@ return 1; } +void av1_setup_address_for_obmc(MACROBLOCKD *xd, int mi_row_offset, + int mi_col_offset, MB_MODE_INFO *ref_mbmi, + struct build_prediction_ctxt *ctxt, + const int num_planes); + void av1_setup_build_prediction_by_above_pred( MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, MB_MODE_INFO *above_mbmi, struct build_prediction_ctxt *ctxt,
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 78c4b2c..0633104 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -917,14 +917,17 @@ } static INLINE void dec_build_prediction_by_above_pred( - MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, - MB_MODE_INFO *above_mbmi, void *fun_ctxt, const int num_planes) { + MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *above_mbmi, void *fun_ctxt, const int num_planes) { struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; const int above_mi_col = ctxt->mi_col + rel_mi_col; int mi_x, mi_y; MB_MODE_INFO backup_mbmi = *above_mbmi; - av1_setup_build_prediction_by_above_pred(xd, rel_mi_col, above_mi_width, + (void)rel_mi_row; + (void)dir; + + av1_setup_build_prediction_by_above_pred(xd, rel_mi_col, op_mi_size, &backup_mbmi, ctxt, num_planes); mi_x = above_mi_col << MI_SIZE_LOG2; mi_y = ctxt->mi_row << MI_SIZE_LOG2; @@ -933,7 +936,7 @@ 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; + int bw = (op_mi_size * MI_SIZE) >> pd->subsampling_x; int bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4, block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1)); @@ -971,14 +974,17 @@ } static INLINE void dec_build_prediction_by_left_pred( - MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height, - MB_MODE_INFO *left_mbmi, void *fun_ctxt, const int num_planes) { + MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *left_mbmi, void *fun_ctxt, const int num_planes) { struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; const int left_mi_row = ctxt->mi_row + rel_mi_row; int mi_x, mi_y; MB_MODE_INFO backup_mbmi = *left_mbmi; - av1_setup_build_prediction_by_left_pred(xd, rel_mi_row, left_mi_height, + (void)rel_mi_col; + (void)dir; + + av1_setup_build_prediction_by_left_pred(xd, rel_mi_row, op_mi_size, &backup_mbmi, ctxt, num_planes); mi_x = ctxt->mi_col << MI_SIZE_LOG2; mi_y = left_mi_row << MI_SIZE_LOG2; @@ -988,7 +994,7 @@ const struct macroblockd_plane *pd = &xd->plane[j]; int bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4, block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1)); - int bh = (left_mi_height << MI_SIZE_LOG2) >> pd->subsampling_y; + int bh = (op_mi_size << MI_SIZE_LOG2) >> pd->subsampling_y; if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue; dec_build_inter_predictors(ctxt->cm, xd, j, &backup_mbmi, 1, bw, bh, mi_x,
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index cd66f11..4a024bc 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -9635,13 +9635,16 @@ int mv_field_check_result; }; -static INLINE void obmc_check_identical_mv(MACROBLOCKD *xd, int rel_mi_col, - uint8_t nb_mi_width, - MB_MODE_INFO *nb_mi, void *fun_ctxt, +static INLINE void obmc_check_identical_mv(MACROBLOCKD *xd, int rel_mi_row, + int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *nb_mi, + void *fun_ctxt, const int num_planes) { (void)xd; + (void)rel_mi_row; (void)rel_mi_col; - (void)nb_mi_width; + (void)op_mi_size; + (void)dir; (void)num_planes; struct obmc_check_mv_field_ctxt *ctxt = (struct obmc_check_mv_field_ctxt *)fun_ctxt; @@ -13556,10 +13559,12 @@ }; static INLINE void calc_target_weighted_pred_above( - MACROBLOCKD *xd, int rel_mi_col, uint8_t nb_mi_width, MB_MODE_INFO *nb_mi, - void *fun_ctxt, const int num_planes) { + MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *nb_mi, void *fun_ctxt, const int num_planes) { (void)nb_mi; (void)num_planes; + (void)rel_mi_row; + (void)dir; struct calc_target_weighted_pred_ctxt *ctxt = (struct calc_target_weighted_pred_ctxt *)fun_ctxt; @@ -13576,7 +13581,7 @@ for (int row = 0; row < ctxt->overlap; ++row) { const uint8_t m0 = mask1d[row]; const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0; - for (int col = 0; col < nb_mi_width * MI_SIZE; ++col) { + for (int col = 0; col < op_mi_size * MI_SIZE; ++col) { wsrc[col] = m1 * tmp[col]; mask[col] = m0; } @@ -13590,7 +13595,7 @@ for (int row = 0; row < ctxt->overlap; ++row) { const uint8_t m0 = mask1d[row]; const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0; - for (int col = 0; col < nb_mi_width * MI_SIZE; ++col) { + for (int col = 0; col < op_mi_size * MI_SIZE; ++col) { wsrc[col] = m1 * tmp16[col]; mask[col] = m0; } @@ -13602,10 +13607,12 @@ } static INLINE void calc_target_weighted_pred_left( - MACROBLOCKD *xd, int rel_mi_row, uint8_t nb_mi_height, MB_MODE_INFO *nb_mi, - void *fun_ctxt, const int num_planes) { + MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *nb_mi, void *fun_ctxt, const int num_planes) { (void)nb_mi; (void)num_planes; + (void)rel_mi_col; + (void)dir; struct calc_target_weighted_pred_ctxt *ctxt = (struct calc_target_weighted_pred_ctxt *)fun_ctxt; @@ -13619,7 +13626,7 @@ const int is_hbd = is_cur_buf_hbd(xd); if (!is_hbd) { - for (int row = 0; row < nb_mi_height * MI_SIZE; ++row) { + for (int row = 0; row < op_mi_size * MI_SIZE; ++row) { for (int col = 0; col < ctxt->overlap; ++col) { const uint8_t m0 = mask1d[col]; const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0; @@ -13634,7 +13641,7 @@ } else { const uint16_t *tmp16 = CONVERT_TO_SHORTPTR(tmp); - for (int row = 0; row < nb_mi_height * MI_SIZE; ++row) { + for (int row = 0; row < op_mi_size * MI_SIZE; ++row) { for (int col = 0; col < ctxt->overlap; ++col) { const uint8_t m0 = mask1d[col]; const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
diff --git a/av1/encoder/reconinter_enc.c b/av1/encoder/reconinter_enc.c index e1d5eb8..06154f6 100644 --- a/av1/encoder/reconinter_enc.c +++ b/av1/encoder/reconinter_enc.c
@@ -333,18 +333,16 @@ &subpel_params); } -static INLINE void build_prediction_by_above_pred( - MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, - MB_MODE_INFO *above_mbmi, void *fun_ctxt, const int num_planes) { +static INLINE void build_obmc_prediction(MACROBLOCKD *xd, int rel_mi_row, + int rel_mi_col, uint8_t op_mi_size, + int dir, MB_MODE_INFO *above_mbmi, + void *fun_ctxt, const int num_planes) { struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; - const int above_mi_col = ctxt->mi_col + rel_mi_col; - int mi_x, mi_y; - MB_MODE_INFO backup_mbmi = *above_mbmi; + av1_setup_address_for_obmc(xd, rel_mi_row, rel_mi_col, above_mbmi, ctxt, + num_planes); - av1_setup_build_prediction_by_above_pred(xd, rel_mi_col, above_mi_width, - &backup_mbmi, ctxt, num_planes); - mi_x = above_mi_col << MI_SIZE_LOG2; - mi_y = ctxt->mi_row << MI_SIZE_LOG2; + int mi_x = (ctxt->mi_col + rel_mi_col) << MI_SIZE_LOG2; + int mi_y = (ctxt->mi_row + rel_mi_row) << MI_SIZE_LOG2; const BLOCK_SIZE bsize = xd->mi[0]->sb_type; @@ -352,19 +350,29 @@ 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; - int bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4, - block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1)); + int bw = 0, bh = 0; - if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue; + if (dir) { + // prepare left reference block size + bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4, + block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1)); + bh = (op_mi_size << MI_SIZE_LOG2) >> pd->subsampling_y; + } else { + // prepare above reference block size + bw = (op_mi_size * MI_SIZE) >> pd->subsampling_x; + bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4, + block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1)); + } + + if (av1_skip_u4x4_pred_in_obmc(bsize, pd, dir)) continue; const struct buf_2d *const pre_buf = &pd->pre[0]; - const MV mv = backup_mbmi.mv[0].as_mv; + const MV mv = above_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); + pre_buf, above_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, @@ -395,52 +403,13 @@ BLOCK_SIZE bsize = xd->mi[0]->sb_type; foreach_overlappable_nb_above(cm, xd, mi_col, max_neighbor_obmc[mi_size_wide_log2[bsize]], - build_prediction_by_above_pred, &ctxt); + build_obmc_prediction, &ctxt); xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); xd->mb_to_right_edge = ctxt.mb_to_far_edge; xd->mb_to_bottom_edge -= (this_height - pred_height) * 8; } -static INLINE void build_prediction_by_left_pred( - MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height, - MB_MODE_INFO *left_mbmi, void *fun_ctxt, const int num_planes) { - struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; - const int left_mi_row = ctxt->mi_row + rel_mi_row; - int mi_x, mi_y; - MB_MODE_INFO backup_mbmi = *left_mbmi; - - av1_setup_build_prediction_by_left_pred(xd, rel_mi_row, left_mi_height, - &backup_mbmi, ctxt, num_planes); - mi_x = ctxt->mi_col << MI_SIZE_LOG2; - mi_y = left_mi_row << MI_SIZE_LOG2; - 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 = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4, - block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1)); - int bh = (left_mi_height << MI_SIZE_LOG2) >> pd->subsampling_y; - - if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue; - - 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); - } -} - void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col, uint8_t *tmp_buf[MAX_MB_PLANE], @@ -463,7 +432,7 @@ BLOCK_SIZE bsize = xd->mi[0]->sb_type; foreach_overlappable_nb_left(cm, xd, mi_row, max_neighbor_obmc[mi_size_high_log2[bsize]], - build_prediction_by_left_pred, &ctxt); + build_obmc_prediction, &ctxt); xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); xd->mb_to_right_edge -= (this_width - pred_width) * 8;