Add encoder/decoder support for var-refs

Check the availability of the reference frames at the frame level at
both encoder and decoder, and if a reference frame is not available
for a specific video frame, remove the signaling of such reference
frame info at the block level.

This patch adds the consideration of the bit saving inside the RD
optimization loop.

Change-Id: I4c22f1b843b21c7d2b47e118c99c3ad615a3d4e4
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 3f0f812..e134548 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -567,6 +567,11 @@
   int idx;
   YV12_BUFFER_CONFIG *buf;
   struct scale_factors sf;
+#if CONFIG_VAR_REFS
+  // TODO(zoeliu): To evaluate whether "is_valid" is needed or the use of it can
+  // be simply replaced by checking the "idx".
+  int is_valid;
+#endif  // CONFIG_VAR_REFS
 } RefBuffer;
 
 #if CONFIG_ADAPT_SCAN
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index fb4b503..f1e3a2e 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -505,6 +505,24 @@
   bufs[new_idx].ref_count++;
 }
 
+#if CONFIG_VAR_REFS
+#define LAST_IS_VALID(cm) ((cm)->frame_refs[LAST_FRAME - 1].is_valid)
+#define LAST2_IS_VALID(cm) ((cm)->frame_refs[LAST2_FRAME - 1].is_valid)
+#define LAST3_IS_VALID(cm) ((cm)->frame_refs[LAST3_FRAME - 1].is_valid)
+#define GOLDEN_IS_VALID(cm) ((cm)->frame_refs[GOLDEN_FRAME - 1].is_valid)
+#define BWDREF_IS_VALID(cm) ((cm)->frame_refs[BWDREF_FRAME - 1].is_valid)
+#define ALTREF_IS_VALID(cm) ((cm)->frame_refs[ALTREF_FRAME - 1].is_valid)
+
+#define L_OR_L2(cm) (LAST_IS_VALID(cm) || LAST2_IS_VALID(cm))
+#define L_AND_L2(cm) (LAST_IS_VALID(cm) && LAST2_IS_VALID(cm))
+
+#define L3_OR_G(cm) (LAST3_IS_VALID(cm) || GOLDEN_IS_VALID(cm))
+#define L3_AND_G(cm) (LAST3_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
+
+#define BWD_OR_ALT(cm) (BWDREF_IS_VALID(cm) || ALTREF_IS_VALID(cm))
+#define BWD_AND_ALT(cm) (BWDREF_IS_VALID(cm) && ALTREF_IS_VALID(cm))
+#endif  // CONFIG_VAR_REFS
+
 static INLINE int mi_cols_aligned_to_sb(const AV1_COMMON *cm) {
   return ALIGN_POWER_OF_TWO(cm->mi_cols, cm->mib_size_log2);
 }