Add encoder support to ALTREF2
This CL adds the use of ALTREF2_FRAME to both single / comp reference
prediction at the encoder side. In particular, the encoder keeps the
distant altref as ALTREF, and uses the internal extra altrefs to
refresh ALTREF2.
Compared with the baseline (ext_tx and global_motion disabled simply
for speed concern):
(a) lowres: avg_psnr -0.395% ovr_psnr -0.393% ssim -0.329%
(b) midres: avg_psnr -0.419% ovr_psnr -0.431% ssim -0.444%
(c) AWCY High Latency:
PSNR | PSNR Cb | PSNR Cr | PSNR HVS | SSIM | MS SSIM | CIEDE 2000
-0.6661 | -0.5988 | -0.6669 | -0.6993 | -0.6988 | -0.7303 | -0.6051
(d) AWCY Low Latency:
PSNR | PSNR Cb | PSNR Cr | PSNR HVS | SSIM | MS SSIM | CIEDE 2000
0.0720 | -0.0505 | 0.1501 | 0.0670 | 0.0842 | 0.0517 | 0.0158
TODO list:
(1) To have altref2 incorporated with ext-comp-refs;
(2) To have altref2 fully work with new-multisymbol;
(3) To re-collect the initial default probs/cdfs;
(4) To tune the encoder gf group structure design for altref2.
Change-Id: I6ad63fd65afa903d3bba20acdb68e3b67acf7fdf
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 9d76628..568199c 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -1153,6 +1153,29 @@
#endif // CONFIG_VAR_REFS
}
+#if CONFIG_ALTREF2
+
+#if CONFIG_VAR_REFS
+ // Test need to explicitly code (BWD,ALT2) vs (ALT) branch node in tree
+ if (BWD_OR_ALT2(cm) && ALTREF_IS_VALID(cm)) {
+#endif // CONFIG_VAR_REFS
+ const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME;
+ WRITE_REF_BIT(bit_bwd, comp_bwdref_p);
+
+ if (!bit_bwd) {
+#if CONFIG_VAR_REFS
+ // Test need to explicitly code (BWD,ALT2) vs (ALT) branch node in
+ // tree
+ if (BWD_AND_ALT2(cm))
+#endif // CONFIG_VAR_REFS
+ WRITE_REF_BIT(mbmi->ref_frame[1] == ALTREF2_FRAME, comp_bwdref_p1);
+ }
+#if CONFIG_VAR_REFS
+ }
+#endif // CONFIG_VAR_REFS
+
+#else // !CONFIG_ALTREF2
+
#if CONFIG_VAR_REFS
// Test need to explicitly code (BWD) vs (ALT) branch node in tree
if (BWD_AND_ALT(cm)) {
@@ -1163,22 +1186,50 @@
}
#endif // CONFIG_VAR_REFS
+#endif // CONFIG_ALTREF2
+
#else // !CONFIG_EXT_REFS
const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME;
WRITE_REF_BIT(bit, comp_ref_p);
#endif // CONFIG_EXT_REFS
} else {
#if CONFIG_EXT_REFS
- const int bit0 = (mbmi->ref_frame[0] == ALTREF_FRAME ||
- mbmi->ref_frame[0] == BWDREF_FRAME);
+ const int bit0 = (mbmi->ref_frame[0] <= ALTREF_FRAME &&
+ mbmi->ref_frame[0] >= BWDREF_FRAME);
#if CONFIG_VAR_REFS
+#if CONFIG_ALTREF2
+ // Test need to explicitly code (L,L2,L3,G) vs (BWD,ALT2,ALT) branch node
+ // in tree
+ if ((L_OR_L2(cm) || L3_OR_G(cm)) &&
+ (BWD_OR_ALT2(cm) || ALTREF_IS_VALID(cm)))
+#else // !CONFIG_ALTREF2
// Test need to explicitly code (L,L2,L3,G) vs (BWD,ALT) branch node in
// tree
if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm))
+#endif // CONFIG_ALTREF2
#endif // CONFIG_VAR_REFS
WRITE_REF_BIT(bit0, single_ref_p1);
if (bit0) {
+#if CONFIG_ALTREF2
+#if CONFIG_VAR_REFS
+ // Test need to explicitly code (BWD,ALT2) vs (ALT) branch node in tree
+ if (BWD_OR_ALT2(cm) && ALTREF_IS_VALID(cm)) {
+#endif // CONFIG_VAR_REFS
+ const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME;
+ WRITE_REF_BIT(bit1, single_ref_p2);
+
+ if (!bit1) {
+#if CONFIG_VAR_REFS
+ // Test need to explicitly code (BWD) vs (ALT2) branch node in tree
+ if (BWD_AND_ALT2(cm))
+#endif // CONFIG_VAR_REFS
+ WRITE_REF_BIT(mbmi->ref_frame[0] == ALTREF2_FRAME, single_ref_p6);
+ }
+#if CONFIG_VAR_REFS
+ }
+#endif // CONFIG_VAR_REFS
+#else // !CONFIG_ALTREF2
#if CONFIG_VAR_REFS
// Test need to explicitly code (BWD) vs (ALT) branch node in tree
if (BWD_AND_ALT(cm)) {
@@ -1188,6 +1239,7 @@
#if CONFIG_VAR_REFS
}
#endif // CONFIG_VAR_REFS
+#endif // CONFIG_ALTREF2
} else {
const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
mbmi->ref_frame[0] == GOLDEN_FRAME);
@@ -3638,13 +3690,19 @@
// LAST3_FRAME.
refresh_mask |=
(cpi->refresh_last_frame << cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]);
+
+#if CONFIG_ALTREF2
+ refresh_mask |= (cpi->refresh_bwd_ref_frame << cpi->bwd_fb_idx);
+ refresh_mask |= (cpi->refresh_alt2_ref_frame << cpi->alt2_fb_idx);
+#else // !CONFIG_ALTREF2
if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
// We have swapped the virtual indices
refresh_mask |= (cpi->refresh_bwd_ref_frame << cpi->arf_map[0]);
} else {
refresh_mask |= (cpi->refresh_bwd_ref_frame << cpi->bwd_fb_idx);
}
-#else
+#endif // CONFIG_ALTREF2
+#else // !CONFIG_EXT_REFS
refresh_mask |= (cpi->refresh_last_frame << cpi->lst_fb_idx);
#endif // CONFIG_EXT_REFS
@@ -3662,9 +3720,13 @@
return refresh_mask | (cpi->refresh_golden_frame << cpi->alt_fb_idx);
} else {
#if CONFIG_EXT_REFS
+#if CONFIG_ALTREF2
+ const int arf_idx = cpi->alt_fb_idx;
+#else // !CONFIG_ALTREF2
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
- int arf_idx = cpi->arf_map[gf_group->arf_update_idx[gf_group->index]];
-#else
+ const int arf_idx = cpi->arf_map[gf_group->arf_update_idx[gf_group->index]];
+#endif // CONFIG_ALTREF2
+#else // !CONFIG_EXT_REFS
int arf_idx = cpi->alt_fb_idx;
if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;