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;