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;