From 4e8acca92533d969892d7236d812899e45b9f904 Mon Sep 17 00:00:00 2001 From: Wei-ting Lin <weitinglin@google.com> Date: Mon, 22 Aug 2016 11:19:30 -0700 Subject: [PATCH] Allow LF_UPDATE type of frames to use BWDREF Originally, only bi-pred type of frames can use BWDREF. When extra alt-refs are inserted in a gf group, the closest alt-ref serves as ALTREF for the frames within the corresponding subgroup. Therefore, the original alt-ref can be used as BWDREF for the LF_UPDATE type of frames. This patch further swaps the virtual indices of BWDREF and ALTREF for those frames whose BWDREF is farther than ALTREF. As a result, the BWDREF is always the closet backward reference frame, and the ALTREF is the farther one. It improves the average RD performance by 0.132% in lowres, and 0.030% in midres. The overall gains for the ext-refs compared to the baseline are 5.486% in lowres, and 4.666% in midres. Change-Id: I22e4e5f378f19c4c89196a0a5e9214adb46c3428 --- vp10/encoder/encoder.c | 12 ++++++++++-- vp10/encoder/firstpass.c | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index 266c02dccd..dfafb2a753 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -3260,7 +3260,8 @@ void vp10_update_reference_frames(VP10_COMP *cpi) { // NOTE: The ALT_REFs' are indexed reversely, and ALT0 refers to the // farthest ALT_REF from the first frame in the gf group. int tmp = cpi->arf_map[0]; - cpi->arf_map[0] = cpi->bwd_fb_idx; + cpi->arf_map[0] = cpi->alt_fb_idx; + cpi->alt_fb_idx = cpi->bwd_fb_idx; cpi->bwd_fb_idx = tmp; } ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx], @@ -3309,7 +3310,14 @@ void vp10_update_reference_frames(VP10_COMP *cpi) { // v v v // lst_fb_idxes[2], lst_fb_idxes[0], lst_fb_idxes[1] int ref_frame; - + if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) { + // We have swapped the virtual indices to use ALT0 as BWD_REF + // and we need to swap them back. + int tmp = cpi->arf_map[0]; + cpi->arf_map[0] = cpi->alt_fb_idx; + cpi->alt_fb_idx = cpi->bwd_fb_idx; + cpi->bwd_fb_idx = tmp; + } if (cm->frame_type == KEY_FRAME) { for (ref_frame = 0; ref_frame < LAST_REF_FRAMES; ++ref_frame) { ref_cnt_fb(pool->frame_bufs, diff --git a/vp10/encoder/firstpass.c b/vp10/encoder/firstpass.c index 1d1bf52016..2b3c85f783 100644 --- a/vp10/encoder/firstpass.c +++ b/vp10/encoder/firstpass.c @@ -2578,7 +2578,18 @@ static void configure_buffer_updates(VP10_COMP *cpi) { cpi->refresh_last_frame = 1; cpi->refresh_golden_frame = 0; #if CONFIG_EXT_REFS - cpi->refresh_bwd_ref_frame = 0; + // If we have extra ALT_REFs, we can use the farthest ALT (ALT0) as + // the BWD_REF. + if (cpi->num_extra_arfs) { + int tmp = cpi->bwd_fb_idx; + + cpi->rc.is_bwd_ref_frame = 1; + cpi->bwd_fb_idx = cpi->alt_fb_idx; + cpi->alt_fb_idx = cpi->arf_map[0];; + cpi->arf_map[0] = tmp; + } else { + cpi->rc.is_bwd_ref_frame = 0; + } #endif // CONFIG_EXT_REFS cpi->refresh_alt_ref_frame = 0; break; @@ -2619,12 +2630,13 @@ static void configure_buffer_updates(VP10_COMP *cpi) { cpi->refresh_alt_ref_frame = 0; cpi->rc.is_bwd_ref_frame = 1; if (cpi->num_extra_arfs) { - // Allow BRF uses the farthest ALT_REF (ALT0) as BWD_REF by swapping + // Allow BRF use the farthest ALT_REF (ALT0) as BWD_REF by swapping // the virtual indices. // NOTE: The indices will be swapped back after this frame is encoded // (in vp10_update_reference_frames()). int tmp = cpi->bwd_fb_idx; - cpi->bwd_fb_idx = cpi->arf_map[0]; + cpi->bwd_fb_idx = cpi->alt_fb_idx; + cpi->alt_fb_idx = cpi->arf_map[0]; cpi->arf_map[0] = tmp; } break; -- GitLab