Support refinemv in CONFIG_REFINED_MVS_IN_TMVP
This change adds the refined MVs obtained in CONFIG_REFINEMV in the TMVP list, which addresses the issue #339
When DAMR is off: -0.06 (Y), -0.08 (U), -0.24 (V), -0.07 (YUV)
When DAMR is on: -0.01 (Y), +0.11 (U), +0.02 (V), +0.00 (YUV)
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index e00a842..435192c 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -87,34 +87,45 @@
refined_mv.as_mv.col = mv_offset_x;
} else {
#endif // CONFIG_AFFINE_REFINEMENT
- refined_mv.as_mv.row = mi->mv[idx].as_mv.row;
- refined_mv.as_mv.col = mi->mv[idx].as_mv.col;
+#if CONFIG_REFINEMV
+ // Refined MVs are stored per 4x4 in refinemv_subinfo, but h and
+ // w for TMVP are per 8x8, so (h<<1) and (w<<1) are used here.
+ if (mi->refinemv_flag)
+ refined_mv.as_mv =
+ xd->refinemv_subinfo[(h << 1) * MAX_MIB_SIZE + (w << 1)]
+ .refinemv[idx]
+ .as_mv;
+ else
+#endif // CONFIG_REFINEMV
+ refined_mv.as_mv = mi->mv[idx].as_mv;
#if CONFIG_AFFINE_REFINEMENT
}
#endif // CONFIG_AFFINE_REFINEMENT
- if (n == 4) {
- // Since TMVP is stored per 8x8 unit, for refined MV with 4x4
- // subblock, take the average of 4 refined MVs
- refined_mv.as_mv.row +=
- ROUND_POWER_OF_TWO_SIGNED(xd->mv_delta[0].mv[idx].as_mv.row +
- xd->mv_delta[1].mv[idx].as_mv.row +
- xd->mv_delta[2].mv[idx].as_mv.row +
- xd->mv_delta[3].mv[idx].as_mv.row,
- 2 + MV_REFINE_PREC_BITS - 3);
- refined_mv.as_mv.col +=
- ROUND_POWER_OF_TWO_SIGNED(xd->mv_delta[0].mv[idx].as_mv.col +
- xd->mv_delta[1].mv[idx].as_mv.col +
- xd->mv_delta[2].mv[idx].as_mv.col +
- xd->mv_delta[3].mv[idx].as_mv.col,
- 2 + MV_REFINE_PREC_BITS - 3);
- } else {
- int sbmv_stride = bw >> 3;
- refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
- xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.row,
- MV_REFINE_PREC_BITS - 3);
- refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
- xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.col,
- MV_REFINE_PREC_BITS - 3);
+ if (opfl_allowed_for_cur_block(cm, mi)) {
+ if (n == 4) {
+ // Since TMVP is stored per 8x8 unit, for refined MV with 4x4
+ // subblock, take the average of 4 refined MVs
+ refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[0].mv[idx].as_mv.row +
+ xd->mv_delta[1].mv[idx].as_mv.row +
+ xd->mv_delta[2].mv[idx].as_mv.row +
+ xd->mv_delta[3].mv[idx].as_mv.row,
+ 2 + MV_REFINE_PREC_BITS - 3);
+ refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[0].mv[idx].as_mv.col +
+ xd->mv_delta[1].mv[idx].as_mv.col +
+ xd->mv_delta[2].mv[idx].as_mv.col +
+ xd->mv_delta[3].mv[idx].as_mv.col,
+ 2 + MV_REFINE_PREC_BITS - 3);
+ } else {
+ int sbmv_stride = bw >> 3;
+ refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.row,
+ MV_REFINE_PREC_BITS - 3);
+ refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.col,
+ MV_REFINE_PREC_BITS - 3);
+ }
}
#if OPFL_MVS_CLAMPED
refined_mv.as_mv.row =
@@ -282,34 +293,45 @@
refined_mv.as_mv.col = mv_offset_x;
} else {
#endif // CONFIG_AFFINE_REFINEMENT
- refined_mv.as_mv.row = mi->mv[idx].as_mv.row;
- refined_mv.as_mv.col = mi->mv[idx].as_mv.col;
+#if CONFIG_REFINEMV
+ // Refined MVs are stored per 4x4 in refinemv_subinfo, but h and
+ // w for TMVP are per 8x8, so (h<<1) and (w<<1) are used here.
+ if (mi->refinemv_flag)
+ refined_mv.as_mv =
+ xd->refinemv_subinfo[(h << 1) * MAX_MIB_SIZE + (w << 1)]
+ .refinemv[idx]
+ .as_mv;
+ else
+#endif // CONFIG_REFINEMV
+ refined_mv.as_mv = mi->mv[idx].as_mv;
#if CONFIG_AFFINE_REFINEMENT
}
#endif // CONFIG_AFFINE_REFINEMENT
- if (n == 4) {
- // Since TMVP is stored per 8x8 unit, for refined MV with 4x4
- // subblock, take the average of 4 refined MVs
- refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
- xd->mv_delta[0].mv[idx].as_mv.row +
- xd->mv_delta[1].mv[idx].as_mv.row +
- xd->mv_delta[2].mv[idx].as_mv.row +
- xd->mv_delta[3].mv[idx].as_mv.row,
- 2 + MV_REFINE_PREC_BITS - 3);
- refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
- xd->mv_delta[0].mv[idx].as_mv.col +
- xd->mv_delta[1].mv[idx].as_mv.col +
- xd->mv_delta[2].mv[idx].as_mv.col +
- xd->mv_delta[3].mv[idx].as_mv.col,
- 2 + MV_REFINE_PREC_BITS - 3);
- } else {
- int sbmv_stride = bw >> 3;
- refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
- xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.row,
- MV_REFINE_PREC_BITS - 3);
- refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
- xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.col,
- MV_REFINE_PREC_BITS - 3);
+ if (opfl_allowed_for_cur_block(cm, mi)) {
+ if (n == 4) {
+ // Since TMVP is stored per 8x8 unit, for refined MV with 4x4
+ // subblock, take the average of 4 refined MVs
+ refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[0].mv[idx].as_mv.row +
+ xd->mv_delta[1].mv[idx].as_mv.row +
+ xd->mv_delta[2].mv[idx].as_mv.row +
+ xd->mv_delta[3].mv[idx].as_mv.row,
+ 2 + MV_REFINE_PREC_BITS - 3);
+ refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[0].mv[idx].as_mv.col +
+ xd->mv_delta[1].mv[idx].as_mv.col +
+ xd->mv_delta[2].mv[idx].as_mv.col +
+ xd->mv_delta[3].mv[idx].as_mv.col,
+ 2 + MV_REFINE_PREC_BITS - 3);
+ } else {
+ int sbmv_stride = bw >> 3;
+ refined_mv.as_mv.row += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.row,
+ MV_REFINE_PREC_BITS - 3);
+ refined_mv.as_mv.col += ROUND_POWER_OF_TWO_SIGNED(
+ xd->mv_delta[h * sbmv_stride + w].mv[idx].as_mv.col,
+ MV_REFINE_PREC_BITS - 3);
+ }
}
#if OPFL_MVS_CLAMPED
refined_mv.as_mv.row =
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 057e9a6..66f3879 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -2151,7 +2151,11 @@
if (!frame_is_intra_only(cm) &&
cm->seq_params.order_hint_info.enable_ref_frame_mvs) {
MB_MODE_INFO *const mi = xd->mi[0];
- if (opfl_allowed_for_cur_block(cm, mi)) {
+ if (opfl_allowed_for_cur_block(cm, mi)
+#if CONFIG_REFINEMV
+ || (mi->refinemv_flag && mi->interinter_comp.type == COMPOUND_AVERAGE)
+#endif // CONFIG_REFINEMV
+ ) {
const int bw = mi_size_wide[bsize];
const int bh = mi_size_high[bsize];
const int x_inside_boundary = AOMMIN(bw, cm->mi_params.mi_cols - mi_col);
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index 40d6f6b..7dd4298 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -2062,7 +2062,11 @@
#if CONFIG_REFINED_MVS_IN_TMVP
if (!dry_run && cm->seq_params.order_hint_info.enable_ref_frame_mvs) {
const MB_MODE_INFO *const mi = &ctx->mic;
- if (opfl_allowed_for_cur_block(cm, mi)) {
+ if (opfl_allowed_for_cur_block(cm, mi)
+#if CONFIG_REFINEMV
+ || (mi->refinemv_flag && mi->interinter_comp.type == COMPOUND_AVERAGE)
+#endif // CONFIG_REFINEMV
+ ) {
const int bw = mi_size_wide[mi->sb_type[xd->tree_type == CHROMA_PART]];
const int bh = mi_size_high[mi->sb_type[xd->tree_type == CHROMA_PART]];
const int x_inside_boundary = AOMMIN(bw, cm->mi_params.mi_cols - mi_col);