Add a new backward reference update rule In the new multi-lay structure, all BWDREFs are replaced with INTRNL_ARFs. Therefore, when GF=4, whenever an INTRNL_ARF is coded, we can use refresh_bwd_ref instead of refresh_alt2_ref. In addition, since every backward reference frame will have one overlay frame, there is no need to use the is_last_bipred flag for show_existing_frame. Change-Id: I7c3d05132197d550166d5d7c5e75d42402048291
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 5dccefe..5d97730 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -3081,28 +3081,52 @@ AV1_COMMON *const cm = &cpi->common; const FRAME_UPDATE_TYPE next_frame_update_type = gf_group->update_type[gf_group->index]; +#if USE_SYMM_MULTI_LAYER + const int which_arf = (cpi->new_bwdref_update_rule == 1) + ? gf_group->arf_update_idx[gf_group->index] > 0 + : gf_group->arf_update_idx[gf_group->index]; +#else const int which_arf = gf_group->arf_update_idx[gf_group->index]; +#endif if (cm->show_existing_frame == 1) { cm->show_existing_frame = 0; } else if (cpi->rc.is_last_bipred_frame) { - // NOTE: If the current frame is a last bi-predictive frame, it is - // needed next to show the BWDREF_FRAME, which is pointed by - // the last_fb_idxes[0] after reference frame buffer update - cpi->rc.is_last_bipred_frame = 0; - cm->show_existing_frame = 1; - cpi->existing_fb_idx_to_show = cpi->ref_fb_idx[0]; +#if USE_SYMM_MULTI_LAYER + // NOTE: When new structure is used, every bwdref will have one overlay + // frame. Therefore, there is no need to find out which frame to + // show in advance. + if (cpi->new_bwdref_update_rule == 0) { +#endif + // NOTE: If the current frame is a last bi-predictive frame, it is + // needed next to show the BWDREF_FRAME, which is pointed by + // the last_fb_idxes[0] after reference frame buffer update + cpi->rc.is_last_bipred_frame = 0; + cm->show_existing_frame = 1; + cpi->existing_fb_idx_to_show = cpi->ref_fb_idx[0]; +#if USE_SYMM_MULTI_LAYER + } +#endif } else if (cpi->is_arf_filter_off[which_arf] && (next_frame_update_type == OVERLAY_UPDATE || next_frame_update_type == INTNL_OVERLAY_UPDATE)) { +#if USE_SYMM_MULTI_LAYER + const int bwdref_to_show = + (cpi->new_bwdref_update_rule == 1) ? BWDREF_FRAME : ALTREF2_FRAME; +#else + const int bwdref_to_show = ALTREF2_FRAME; +#endif // Other parameters related to OVERLAY_UPDATE will be taken care of // in av1_rc_get_second_pass_params(cpi) cm->show_existing_frame = 1; cpi->rc.is_src_frame_alt_ref = 1; cpi->existing_fb_idx_to_show = (next_frame_update_type == OVERLAY_UPDATE) ? cpi->ref_fb_idx[ALTREF_FRAME - 1] - : cpi->ref_fb_idx[ALTREF2_FRAME - 1]; - cpi->is_arf_filter_off[which_arf] = 0; + : cpi->ref_fb_idx[bwdref_to_show - 1]; +#if USE_SYMM_MULTI_LAYER + if (cpi->new_bwdref_update_rule == 0) +#endif + cpi->is_arf_filter_off[which_arf] = 0; } cpi->rc.is_src_frame_ext_arf = 0; } @@ -3378,19 +3402,24 @@ const GF_GROUP *const gf_group = &cpi->twopass.gf_group; assert(gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE); #endif +#if USE_SYMM_MULTI_LAYER + const int bwdref_to_show = + (cpi->new_bwdref_update_rule == 1) ? BWDREF_FRAME : ALTREF2_FRAME; +#else + const int bwdref_to_show = ALTREF2_FRAME; +#endif // Deal with the special case for showing existing internal ALTREF_FRAME // Refresh the LAST_FRAME with the ALTREF_FRAME and retire the LAST3_FRAME // by updating the virtual indices. - const int tmp = cpi->ref_fb_idx[LAST_REF_FRAMES - 1]; shift_last_ref_frames(cpi); - cpi->ref_fb_idx[LAST_FRAME - 1] = cpi->ref_fb_idx[ALTREF2_FRAME - 1]; - cpi->ref_fb_idx[ALTREF2_FRAME - 1] = tmp; + cpi->ref_fb_idx[LAST_FRAME - 1] = cpi->ref_fb_idx[bwdref_to_show - 1]; + cpi->ref_fb_idx[bwdref_to_show - 1] = tmp; memcpy(cpi->interp_filter_selected[LAST_FRAME], - cpi->interp_filter_selected[ALTREF2_FRAME], - sizeof(cpi->interp_filter_selected[ALTREF2_FRAME])); + cpi->interp_filter_selected[bwdref_to_show], + sizeof(cpi->interp_filter_selected[bwdref_to_show])); } else { /* For non key/golden frames */ // === ALTREF_FRAME === if (cpi->refresh_alt_ref_frame) { @@ -3483,7 +3512,14 @@ cpi->interp_filter_selected[0], sizeof(cpi->interp_filter_selected[0])); + // If the new structure is used, we will always have overlay frames coupled + // with bwdref frames. Therefore, we won't have to perform this update + // in advance (we do this update when the overlay frame shows up). +#if USE_SYMM_MULTI_LAYER + if (cpi->new_bwdref_update_rule == 0 && cpi->rc.is_last_bipred_frame) { +#else if (cpi->rc.is_last_bipred_frame) { +#endif // Refresh the LAST_FRAME with the BWDREF_FRAME and retire the // LAST3_FRAME by updating the virtual indices. //
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 0ddb4f1..7577a58 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -505,6 +505,9 @@ int refresh_bwd_ref_frame; int refresh_alt2_ref_frame; int refresh_alt_ref_frame; +#if USE_SYMM_MULTI_LAYER + int new_bwdref_update_rule; +#endif int ext_refresh_frame_flags_pending; int ext_refresh_last_frame;
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c index 4e303dc..008906e 100644 --- a/av1/encoder/firstpass.c +++ b/av1/encoder/firstpass.c
@@ -2299,7 +2299,10 @@ cpi->extra_arf_allowed > 0) { // used only if arf is allowed define_gf_group_structure_4(cpi); + cpi->new_bwdref_update_rule = 1; return; + } else { + cpi->new_bwdref_update_rule = 0; } #endif @@ -3581,8 +3584,17 @@ case INTNL_ARF_UPDATE: cpi->refresh_last_frame = 0; cpi->refresh_golden_frame = 0; - cpi->refresh_bwd_ref_frame = 0; - cpi->refresh_alt2_ref_frame = 1; +#if USE_SYMM_MULTI_LAYER + if (cpi->new_bwdref_update_rule == 1) { + cpi->refresh_bwd_ref_frame = 1; + cpi->refresh_alt2_ref_frame = 0; + } else { +#endif + cpi->refresh_bwd_ref_frame = 0; + cpi->refresh_alt2_ref_frame = 1; +#if USE_SYMM_MULTI_LAYER + } +#endif cpi->refresh_alt_ref_frame = 0; break;