Unify the motion field projection operation
Support the motion field projection for both interpolation and
extrapolation situations.
Change-Id: I74e2d3c8956e62a2731f342f0d7a60dbc6b91ed1
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index 7c8c5c6..2f911c5 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -1498,9 +1498,8 @@
return 1;
}
-static void motion_field_projection(AV1_COMMON *cm,
- MV_REFERENCE_FRAME ref_frame, int ref_stamp,
- int dir) {
+static int motion_field_projection(AV1_COMMON *cm, MV_REFERENCE_FRAME ref_frame,
+ int ref_stamp, int dir) {
TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
int cur_rf_index[TOTAL_REFS_PER_FRAME] = { 0 };
int ref_rf_idx[TOTAL_REFS_PER_FRAME] = { 0 };
@@ -1510,7 +1509,8 @@
(void)dir;
int ref_frame_idx = cm->frame_refs[FWD_RF_OFFSET(ref_frame)].idx;
- if (ref_frame_idx < 0) return;
+ if (ref_frame_idx < 0) return 0;
+
int ref_frame_index =
cm->buffer_pool->frame_bufs[ref_frame_idx].cur_frame_offset;
int cur_frame_index = cm->cur_frame->cur_frame_offset;
@@ -1539,6 +1539,16 @@
ref_offset[rf] = ref_frame_index - ref_rf_idx[rf];
}
+ if (dir == 1) {
+ ref_to_cur = -ref_to_cur;
+ for (MV_REFERENCE_FRAME rf = LAST_FRAME; rf <= INTER_REFS_PER_FRAME; ++rf) {
+ cur_offset[rf] = -cur_offset[rf];
+ ref_offset[rf] = -ref_offset[rf];
+ }
+ }
+
+ if (dir == 2) ref_to_cur = -ref_to_cur;
+
MV_REF *mv_ref_base = cm->buffer_pool->frame_bufs[ref_frame_idx].mvs;
const int mvs_rows = (cm->mi_rows + 1) >> 1;
const int mvs_cols = (cm->mi_cols + 1) >> 1;
@@ -1546,17 +1556,17 @@
for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
MV_REF *mv_ref = &mv_ref_base[blk_row * mvs_cols + blk_col];
- MV fwd_mv = mv_ref->mv[0].as_mv;
+ MV fwd_mv = mv_ref->mv[dir & 0x01].as_mv;
- const int ref_frame_offset = ref_offset[mv_ref->ref_frame[0]];
+ const int ref_frame_offset = ref_offset[mv_ref->ref_frame[dir & 0x01]];
- if (mv_ref->ref_frame[0] > INTRA_FRAME) {
+ if (mv_ref->ref_frame[dir & 0x01] > INTRA_FRAME) {
int_mv this_mv;
int mi_r, mi_c;
get_mv_projection(&this_mv.as_mv, fwd_mv, ref_to_cur, ref_frame_offset);
int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
- this_mv.as_mv, 0);
+ this_mv.as_mv, dir >> 1);
if (pos_valid) {
int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
@@ -1570,15 +1580,16 @@
}
}
}
+
+ return 1;
}
void av1_setup_motion_field(AV1_COMMON *cm) {
int cur_frame_index = cm->cur_frame->cur_frame_offset;
- int lst_frame_index = 0, alt_frame_index = 0, gld_frame_index = 0;
- int lst2_frame_index = 0, lst3_frame_index = 0;
+ int alt_frame_index = 0, gld_frame_index = 0;
int bwd_frame_index = 0, alt2_frame_index = 0;
- TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
+ TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
for (int ref_frame = 0; ref_frame < INTER_REFS_PER_FRAME; ++ref_frame) {
int size = ((cm->mi_rows + MAX_MIB_SIZE) >> 1) * (cm->mi_stride >> 1);
for (int idx = 0; idx < size; ++idx) {
@@ -1587,31 +1598,18 @@
}
}
+ int gld_buf_idx = cm->frame_refs[GOLDEN_FRAME - LAST_FRAME].idx;
int alt_buf_idx = cm->frame_refs[ALTREF_FRAME - LAST_FRAME].idx;
int lst_buf_idx = cm->frame_refs[LAST_FRAME - LAST_FRAME].idx;
- int gld_buf_idx = cm->frame_refs[GOLDEN_FRAME - LAST_FRAME].idx;
- int lst2_buf_idx = cm->frame_refs[LAST2_FRAME - LAST_FRAME].idx;
- int lst3_buf_idx = cm->frame_refs[LAST3_FRAME - LAST_FRAME].idx;
int bwd_buf_idx = cm->frame_refs[BWDREF_FRAME - LAST_FRAME].idx;
int alt2_buf_idx = cm->frame_refs[ALTREF2_FRAME - LAST_FRAME].idx;
if (alt_buf_idx >= 0)
alt_frame_index = cm->buffer_pool->frame_bufs[alt_buf_idx].cur_frame_offset;
- if (lst_buf_idx >= 0)
- lst_frame_index = cm->buffer_pool->frame_bufs[lst_buf_idx].cur_frame_offset;
-
if (gld_buf_idx >= 0)
gld_frame_index = cm->buffer_pool->frame_bufs[gld_buf_idx].cur_frame_offset;
- if (lst2_buf_idx >= 0)
- lst2_frame_index =
- cm->buffer_pool->frame_bufs[lst2_buf_idx].cur_frame_offset;
-
- if (lst3_buf_idx >= 0)
- lst3_frame_index =
- cm->buffer_pool->frame_bufs[lst3_buf_idx].cur_frame_offset;
-
if (bwd_buf_idx >= 0)
bwd_frame_index = cm->buffer_pool->frame_bufs[bwd_buf_idx].cur_frame_offset;
@@ -1632,153 +1630,28 @@
cm->ref_frame_side[ref_frame] = -1;
}
- if (alt_frame_index < cur_frame_index) return;
-
int ref_stamp = MFMV_STACK_SIZE - 1;
- // ======================
- // Process last frame
- // ======================
if (lst_buf_idx >= 0) {
- MV_REF *mv_ref_base = cm->buffer_pool->frame_bufs[lst_buf_idx].mvs;
- const int lst_frame_idx =
- cm->buffer_pool->frame_bufs[lst_buf_idx].lst_frame_offset;
const int alt_frame_idx =
cm->buffer_pool->frame_bufs[lst_buf_idx].alt_frame_offset;
- const int gld_frame_idx =
- cm->buffer_pool->frame_bufs[lst_buf_idx].gld_frame_offset;
- const int lst2_frame_idx =
- cm->buffer_pool->frame_bufs[lst_buf_idx].lst2_frame_offset;
- const int lst3_frame_idx =
- cm->buffer_pool->frame_bufs[lst_buf_idx].lst3_frame_offset;
- const int bwd_frame_idx =
- cm->buffer_pool->frame_bufs[lst_buf_idx].bwd_frame_offset;
- const int alt2_frame_idx =
- cm->buffer_pool->frame_bufs[lst_buf_idx].alt2_frame_offset;
-
- int alt_offset = AOMMAX(1, alt_frame_idx - lst_frame_index);
- int lst_offset = AOMMAX(1, lst_frame_index - lst_frame_idx);
- int gld_offset = AOMMAX(1, lst_frame_index - gld_frame_idx);
- int cur_to_lst = cur_frame_index - lst_frame_index;
- int cur_to_alt = alt_frame_index - cur_frame_index;
- int cur_to_gld = cur_frame_index - gld_frame_index;
-
- int bwd_offset = AOMMAX(1, bwd_frame_idx - lst_frame_index);
- int alt2_offset = AOMMAX(1, alt2_frame_idx - lst_frame_index);
- int lst2_offset = AOMMAX(1, lst_frame_index - lst2_frame_idx);
- int lst3_offset = AOMMAX(1, lst_frame_index - lst3_frame_idx);
- int cur_to_lst2 = cur_frame_index - lst2_frame_index;
- int cur_to_lst3 = cur_frame_index - lst3_frame_index;
- int cur_to_bwd = bwd_frame_index - cur_frame_index;
- int cur_to_alt2 = alt2_frame_index - cur_frame_index;
const int is_lst_overlay = (alt_frame_idx == gld_frame_index);
- // clang-format off
- const int ref_frame_offset_buffer[TOTAL_REFS_PER_FRAME] = {
- 0, lst_offset, lst2_offset, lst3_offset, gld_offset,
- bwd_offset, alt2_offset, alt_offset
- };
- // clang-format on
-
- const int mvs_rows = (cm->mi_rows + 1) >> 1;
- const int mvs_cols = (cm->mi_cols + 1) >> 1;
-
- for (int blk_row = 0; blk_row < mvs_rows && !is_lst_overlay; ++blk_row) {
- for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
- MV_REF *mv_ref = &mv_ref_base[blk_row * mvs_cols + blk_col];
- MV fwd_mv = mv_ref->mv[0].as_mv;
- MV_REFERENCE_FRAME ref_frame[2] = { mv_ref->ref_frame[0],
- mv_ref->ref_frame[1] };
-
- // Derive motion vectors toward last reference frame.
- if (ref_frame[0] <= GOLDEN_FRAME && ref_frame[0] > INTRA_FRAME) {
- int_mv this_mv;
- int mi_r, mi_c;
-
- const int ref_frame_offset = ref_frame_offset_buffer[ref_frame[0]];
-
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst,
- ref_frame_offset);
- int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
- this_mv.as_mv, 1);
-
- if (pos_valid) {
- int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(LAST_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
-
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst2,
- ref_frame_offset);
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(LAST2_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
-
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst3,
- ref_frame_offset);
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(LAST3_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_gld,
- ref_frame_offset);
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(GOLDEN_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
- }
- }
-
- for (int idx = 0; idx < 2; ++idx) {
- if (ref_frame[idx] <= GOLDEN_FRAME) continue;
-
- int_mv this_mv;
- int mi_r, mi_c;
- fwd_mv = mv_ref->mv[idx].as_mv;
-
- const int ref_frame_offset = ref_frame_offset_buffer[ref_frame[idx]];
-
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst,
- ref_frame_offset);
- int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
- this_mv.as_mv, 0);
-
- if (pos_valid) {
- int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_alt,
- ref_frame_offset);
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(ALTREF_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
-
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_bwd,
- ref_frame_offset);
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(BWDREF_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
- get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_alt2,
- ref_frame_offset);
- tpl_mvs_base[mi_offset]
- .mfmv[FWD_RF_OFFSET(ALTREF2_FRAME)][ref_stamp]
- .as_int = this_mv.as_int;
- }
- }
- }
- }
+ if (!is_lst_overlay) motion_field_projection(cm, LAST_FRAME, ref_stamp, 1);
--ref_stamp;
}
if (bwd_frame_index > cur_frame_index) {
- motion_field_projection(cm, BWDREF_FRAME, ref_stamp, 0);
- --ref_stamp;
+ if (motion_field_projection(cm, BWDREF_FRAME, ref_stamp, 0)) --ref_stamp;
}
if (alt2_frame_index > cur_frame_index) {
- motion_field_projection(cm, ALTREF2_FRAME, ref_stamp, 0);
- --ref_stamp;
+ if (motion_field_projection(cm, ALTREF2_FRAME, ref_stamp, 0)) --ref_stamp;
}
if (alt_frame_index > cur_frame_index && ref_stamp >= 0)
- motion_field_projection(cm, ALTREF_FRAME, ref_stamp, 0);
+ if (motion_field_projection(cm, ALTREF_FRAME, ref_stamp, 0)) --ref_stamp;
}
#endif // CONFIG_MFMV