Add frame_refs_short_signaling support for rtc

This commit is to enable frame_refs_short_signaling feature for rtc low
resolution (resolution < 360p) and high speed (speed >= 9) case. In this
case, we only use LAST and GOLD ref frames, so we could
potentially save some header bits for parsing unused ref frame index,
which is frame_refs_short_signaling will do.

Note that "--enable-order-hint" is disabled in default rtc configutaions,
but enabling frame_refs_short_signaling requires "--enable-order-hint"
to be turned on. The Borg resutls below are comparing "origin/main +
--enable-order-hint=0 " vs. "this commit + --enable-order-hint=1". The
bdrate gain shows that enabling frame_refs_short_signaling not only
compensated the overhead by enabling order hint, but also provided some
extra gain.

Test set: rtc_derf
speed   avg_psnr/ovr_psnr/ssim  encoding_speedup
9       -0.209/-0.204/-0.233       +0.042
10      -0.024/-0.034/0.017        +0.005

Change-Id: I51c5bc7095f7f3fda135176b3e934d8a876fc9c5
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index a7d3254..0b74f2f 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2764,7 +2764,31 @@
   }
 }
 
-static int check_frame_refs_short_signaling(AV1_COMMON *const cm) {
+static int check_frame_refs_short_signaling(AV1_COMMON *const cm,
+                                            int enable_ref_short_signaling) {
+  // In rtc case when res < 360p and speed >= 9, we turn on
+  // frame_refs_short_signaling if it won't break the decoder.
+  if (enable_ref_short_signaling) {
+    const int gld_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
+    const int base =
+        1 << (cm->seq_params->order_hint_info.order_hint_bits_minus_1 + 1);
+
+    const int order_hint_group_cur =
+        cm->current_frame.display_order_hint / base;
+    const int order_hint_group_gld =
+        cm->ref_frame_map[gld_map_idx]->display_order_hint / base;
+    const int relative_dist = cm->current_frame.order_hint -
+                              cm->ref_frame_map[gld_map_idx]->order_hint;
+
+    // If current frame and GOLDEN frame are in the same order_hint group, and
+    // they are not far apart (i.e., > 64 frames), then return 1.
+    if (order_hint_group_cur == order_hint_group_gld && relative_dist >= 0 &&
+        relative_dist <= 64) {
+      return 1;
+    }
+    return 0;
+  }
+
   // Check whether all references are distinct frames.
   const RefCntBuffer *seen_bufs[FRAME_BUFFERS] = { NULL };
   int num_refs = 0;
@@ -2842,7 +2866,13 @@
   CurrentFrame *const current_frame = &cm->current_frame;
   FeatureFlags *const features = &cm->features;
 
-  current_frame->frame_refs_short_signaling = 0;
+  if (!cpi->sf.rt_sf.enable_ref_short_signaling ||
+      !seq_params->order_hint_info.enable_order_hint ||
+      seq_params->order_hint_info.enable_ref_frame_mvs) {
+    current_frame->frame_refs_short_signaling = 0;
+  } else {
+    current_frame->frame_refs_short_signaling = 1;
+  }
 
   if (seq_params->still_picture) {
     assert(cm->show_existing_frame == 0);
@@ -3008,12 +3038,20 @@
 #endif  // FRAME_REFS_SHORT_SIGNALING
 
       if (current_frame->frame_refs_short_signaling) {
-        // NOTE(zoeliu@google.com):
-        //   An example solution for encoder-side implementation on frame refs
-        //   short signaling, which is only turned on when the encoder side
-        //   decision on ref frames is identical to that at the decoder side.
+        //    In rtc case when cpi->sf.rt_sf.enable_ref_short_signaling is 1, we
+        //    turn on frame_refs_short_signaling when the current frame
+        //    and golden frame are in the same order_hint group,
+        //    and their relative distance is <= 64 (in order to be decodable).
+
+        //    For other cases, an example solution for encoder-side
+        //    implementation on frame_refs_short_signaling is also provided in
+        //    this function, where frame_refs_short_signaling is only turned on
+        //    when the encoder side decision on ref frames is identical to that
+        //    at the decoder side.
+
         current_frame->frame_refs_short_signaling =
-            check_frame_refs_short_signaling(cm);
+            check_frame_refs_short_signaling(
+                cm, cpi->sf.rt_sf.enable_ref_short_signaling);
       }
 
       if (seq_params->order_hint_info.enable_order_hint)
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 998785f..601895e 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1280,7 +1280,15 @@
       sf->rt_sf.nonrd_agressive_skip = 1;
       sf->rt_sf.skip_intra_pred = 1;
       sf->rt_sf.use_rtc_tf = 2;
-
+      // Only turn on enable_ref_short_signaling for low resolution when only
+      // LAST and GOLDEN ref frames are used.
+      sf->rt_sf.enable_ref_short_signaling =
+          (sf->rt_sf.use_nonrd_altref_frame ||
+           (sf->rt_sf.use_comp_ref_nonrd &&
+            (sf->rt_sf.ref_frame_comp_nonrd[1] ||
+             sf->rt_sf.ref_frame_comp_nonrd[2])))
+              ? 0
+              : 1;
 // TODO(kyslov) Re-enable when AV1 models are trained
 #if 0
 #if CONFIG_RT_ML_PARTITIONING
@@ -2075,6 +2083,7 @@
   rt_sf->set_zeromv_skip_based_on_source_sad = 1;
   rt_sf->use_adaptive_subpel_search = false;
   rt_sf->screen_content_cdef_filter_qindex_thresh = 0;
+  rt_sf->enable_ref_short_signaling = 0;
 }
 
 // Populate appropriate sub-pel search method based on speed feature and user
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 6af3afc..26735c49 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1657,6 +1657,12 @@
   // Downgrades the subpel search to av1_find_best_sub_pixel_tree_pruned_more
   // when either the fullpel search performed well, or when zeromv has low sad.
   bool use_adaptive_subpel_search;
+
+  // A flag used in RTC case to control frame_refs_short_signaling. Note that
+  // the final decision is made in check_frame_refs_short_signaling(). The flag
+  // can only be turned on when res < 360p and speed >= 9, in which case only
+  // LAST and GOLDEN ref frames are used now.
+  int enable_ref_short_signaling;
 } REAL_TIME_SPEED_FEATURES;
 
 /*!\endcond */