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