Add framework to compute distance in display order

This patch adds framework for av1_encoder_get_relative_dist()
which will compare the absolute display order hint to compute
the relative distance and overcomes the limitation of
get_relative_dist() which returns incorrect distance when
very old frame is used as a reference.

Change-Id: If5a158f7c8ee64dab36007ac54be9f6023d97c84
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index 1490c55..242a9a9 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -843,12 +843,16 @@
 
 void av1_setup_frame_buf_refs(AV1_COMMON *cm) {
   cm->cur_frame->order_hint = cm->current_frame.order_hint;
+  cm->cur_frame->display_order_hint = cm->current_frame.display_order_hint;
 
   MV_REFERENCE_FRAME ref_frame;
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
     const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
-    if (buf != NULL)
+    if (buf != NULL) {
       cm->cur_frame->ref_order_hints[ref_frame - LAST_FRAME] = buf->order_hint;
+      cm->cur_frame->ref_display_order_hint[ref_frame - LAST_FRAME] =
+          buf->display_order_hint;
+    }
   }
 }
 
@@ -1494,7 +1498,8 @@
     fwd_end_idx--;
   }
 
-  // Assign all the remaining frame(s), if any, to the earliest reference frame.
+  // Assign all the remaining frame(s), if any, to the earliest reference
+  // frame.
   for (; ref_idx < (INTER_REFS_PER_FRAME - 2); ref_idx++) {
     const MV_REFERENCE_FRAME ref_frame = ref_frame_list[ref_idx];
     if (ref_flag_list[ref_frame - LAST_FRAME] == 1) continue;
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index ad4eab6..dde3c12 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -129,6 +129,13 @@
   unsigned int order_hint;
   unsigned int ref_order_hints[INTER_REFS_PER_FRAME];
 
+  // These variables are used only in encoder and compare the absolute
+  // display order hint to compute the relative distance and overcome
+  // the limitation of get_relative_dist() which returns incorrect
+  // distance when a very old frame is used as a reference.
+  unsigned int display_order_hint;
+  unsigned int ref_display_order_hint[INTER_REFS_PER_FRAME];
+
   MV_REF *mvs;
   uint8_t *seg_map;
   struct segmentation seg;
@@ -294,6 +301,7 @@
   REFERENCE_MODE reference_mode;
 
   unsigned int order_hint;
+  unsigned int display_order_hint;
   unsigned int frame_number;
   SkipModeInfo skip_mode_info;
   int refresh_frame_flags;  // Which ref frames are overwritten by this frame
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index ea81fff..81a00b0 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -5538,9 +5538,11 @@
 
   if (cm->show_existing_frame) {
     current_frame->order_hint = cm->cur_frame->order_hint;
+    current_frame->display_order_hint = cm->cur_frame->display_order_hint;
   } else {
     current_frame->order_hint =
         current_frame->frame_number + frame_params->order_offset;
+    current_frame->display_order_hint = current_frame->order_hint;
     current_frame->order_hint %=
         (1 << (cm->seq_params.order_hint_info.order_hint_bits_minus_1 + 1));
   }
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index 0241829..8031bfc 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -184,6 +184,14 @@
     const uint8_t *const p0, const uint8_t *const p1,
     const int16_t *const residual1, const int16_t *const diff10);
 
+static INLINE int av1_encoder_get_relative_dist(const OrderHintInfo *oh, int a,
+                                                int b) {
+  if (!oh->enable_order_hint) return 0;
+
+  assert(a >= 0 && b >= 0);
+  return (a - b);
+}
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif