Not signal reference_mode if one ref avaialble

Use the frame ID that indicates the frame display order to identify
whether two different reference frames exist for inter-coded frames.
If there is only one unique reference valid in the reference buffer,
there is no need to signal reference_mode. Instead, the decoder may
identify such scenario and set reference_mode to SINGLE_REFERENCE.

Change-Id: If7d374f5355f153c50b408be5a9956a833c976c3
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index 26b7c50..df42044 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -367,6 +367,38 @@
   return 0;
 }
 
+static INLINE int av1_is_compound_reference_allowed(const AV1_COMMON *cm) {
+  if (frame_is_intra_only(cm)) return 0;
+#if CONFIG_FRAME_MARKER
+  // Check whether two different reference frames exist.
+  int ref, ref_offset0;
+  int is_comp_allowed = 0;
+
+  for (ref = 0; ref < INTER_REFS_PER_FRAME; ++ref) {
+    const int buf_idx = cm->frame_refs[ref].idx;
+    if (buf_idx == INVALID_IDX) continue;
+    ref_offset0 = cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset;
+    ref++;
+    break;
+  }
+
+  for (; ref < INTER_REFS_PER_FRAME; ++ref) {
+    const int buf_idx = cm->frame_refs[ref].idx;
+    if (buf_idx == INVALID_IDX) continue;
+    const int ref_offset =
+        cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset;
+    if (ref_offset != ref_offset0) {
+      is_comp_allowed = 1;
+      break;
+    }
+  }
+
+  return is_comp_allowed;
+#else
+  return 1;
+#endif  // CONFIG_FRAME_MARKER
+}
+
 #if CONFIG_FRAME_MARKER
 static INLINE int av1_refs_are_one_sided(const AV1_COMMON *cm) {
   assert(!frame_is_intra_only(cm));
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 64d3210..23073e8 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -89,10 +89,6 @@
 static size_t read_uncompressed_header(AV1Decoder *pbi,
                                        struct aom_read_bit_buffer *rb);
 
-static int is_compound_reference_allowed(const AV1_COMMON *cm) {
-  return !frame_is_intra_only(cm);
-}
-
 static void setup_compound_reference_mode(AV1_COMMON *cm) {
   cm->comp_fwd_ref[0] = LAST_FRAME;
   cm->comp_fwd_ref[1] = LAST2_FRAME;
@@ -129,7 +125,7 @@
 
 static REFERENCE_MODE read_frame_reference_mode(
     const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
-  if (is_compound_reference_allowed(cm)) {
+  if (av1_is_compound_reference_allowed(cm)) {
 #if CONFIG_REF_ADAPT
     return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
 #else
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index a918abc..6aff5f4 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -3940,14 +3940,8 @@
   mismatch_reset_frame();
 #endif
 
-  // In the longer term the encoder should be generalized to match the
-  // decoder such that we allow compound where one of the 3 buffers has a
-  // different sign bias and that buffer is then the fixed ref. However, this
-  // requires further work in the rd loop. For now the only supported encoder
-  // side behavior is where the ALT ref buffer has opposite sign bias to
-  // the other two.
-  if (!frame_is_intra_only(cm)) {
-    cpi->allow_comp_inter_inter = 1;
+  cpi->allow_comp_inter_inter = av1_is_compound_reference_allowed(cm);
+  if (cpi->allow_comp_inter_inter) {
     cm->comp_fwd_ref[0] = LAST_FRAME;
     cm->comp_fwd_ref[1] = LAST2_FRAME;
     cm->comp_fwd_ref[2] = LAST3_FRAME;
@@ -3955,8 +3949,6 @@
     cm->comp_bwd_ref[0] = BWDREF_FRAME;
     cm->comp_bwd_ref[1] = ALTREF2_FRAME;
     cm->comp_bwd_ref[2] = ALTREF_FRAME;
-  } else {
-    cpi->allow_comp_inter_inter = 0;
   }
 
   if (cpi->sf.frame_parameter_update) {