FPMT: Handle refresh logic for encode reorder

During encode reorder, added extra cases to correctly
handle the reference refresh logic.

Change-Id: I40da969f85e22e58c90ce2d272f2f496a03d45b2
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index ffed121..d6d9306 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -643,7 +643,12 @@
 
 #if CONFIG_FRAME_PARALLEL_ENCODE
 static int get_refresh_idx(RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
-                           int update_arf, int cur_frame_disp) {
+                           int update_arf,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                           GF_GROUP *gf_group, int gf_index,
+                           int enable_refresh_skip,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+                           int cur_frame_disp) {
   int arf_count = 0;
   int oldest_arf_order = INT32_MAX;
   int oldest_arf_idx = -1;
@@ -659,6 +664,22 @@
     // Do not refresh a future frame.
     if (frame_order > cur_frame_disp) continue;
 
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+    if (enable_refresh_skip) {
+      int skip_frame = 0;
+      // Prevent refreshing a frame in gf_group->skip_frame_refresh.
+      for (int i = 0; i < REF_FRAMES; i++) {
+        int frame_to_skip = gf_group->skip_frame_refresh[gf_index][i];
+        if (frame_to_skip == INVALID_IDX) break;
+        if (frame_order == frame_to_skip) {
+          skip_frame = 1;
+          break;
+        }
+      }
+      if (skip_frame) continue;
+    }
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+
     // Keep track of the oldest level 1 frame if the current frame is also level
     // 1.
     if (reference_frame_level == 1) {
@@ -681,6 +702,12 @@
   if (update_arf && arf_count > 2) return oldest_arf_idx;
   if (oldest_idx >= 0) return oldest_idx;
   if (oldest_arf_idx >= 0) return oldest_arf_idx;
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+  if (oldest_idx == -1) {
+    assert(arf_count > 2 && enable_refresh_skip);
+    return oldest_arf_idx;
+  }
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
   assert(0 && "No valid refresh index found");
   return -1;
 }
@@ -692,6 +719,9 @@
 #if CONFIG_FRAME_PARALLEL_ENCODE
                                 int cur_disp_order,
                                 RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                                int gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                                 const RefBufferStack *const ref_buffer_stack) {
   const AV1_COMMON *const cm = &cpi->common;
@@ -779,10 +809,16 @@
     refresh_mask = 1 << free_fb_index;
     return refresh_mask;
   }
-
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+  const int enable_refresh_skip = !is_one_pass_rt_params(cpi);
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
   const int update_arf = frame_update_type == ARF_UPDATE;
   const int refresh_idx =
-      get_refresh_idx(ref_frame_map_pairs, update_arf, cur_disp_order);
+      get_refresh_idx(ref_frame_map_pairs, update_arf,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                      &cpi->ppi->gf_group, gf_index, enable_refresh_skip,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+                      cur_disp_order);
   return 1 << refresh_idx;
 #else
   switch (frame_update_type) {
@@ -1630,6 +1666,9 @@
         av1_get_refresh_frame_flags(cpi, &frame_params, frame_update_type,
 #if CONFIG_FRAME_PARALLEL_ENCODE
                                     cur_frame_disp, ref_frame_map_pairs,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                                    cpi->gf_frame_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                                     &cpi->ref_buffer_stack);
 
diff --git a/av1/encoder/encode_strategy.h b/av1/encoder/encode_strategy.h
index ab6cbf6..2335fe5 100644
--- a/av1/encoder/encode_strategy.h
+++ b/av1/encoder/encode_strategy.h
@@ -73,6 +73,9 @@
 #if CONFIG_FRAME_PARALLEL_ENCODE
                                 int cur_disp_order,
                                 RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                                int gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                                 const RefBufferStack *const ref_buffer_stack);
 
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index 1bd2253..d6efc09 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -218,6 +218,9 @@
 #if CONFIG_FRAME_PARALLEL_ENCODE_2
   // Stores the display order hint of each frame in the current GF_GROUP.
   int display_idx[MAX_STATIC_GF_GROUP_LENGTH];
+  // Stores the display order hint of the frames not to be
+  // refreshed by the current frame.
+  int skip_frame_refresh[MAX_STATIC_GF_GROUP_LENGTH][REF_FRAMES];
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
   /*!\endcond */
diff --git a/av1/encoder/gop_structure.c b/av1/encoder/gop_structure.c
index 3110b99..af53555 100644
--- a/av1/encoder/gop_structure.c
+++ b/av1/encoder/gop_structure.c
@@ -136,6 +136,13 @@
         // layer to 2.
         assert(gf_group->frame_parallel_level[(*frame_ind) - 1] == 1);
         gf_group->frame_parallel_level[*frame_ind] = 2;
+        // Store the display order hints of the past 2 INTNL_ARF_UPDATE
+        // frames which would not have been displayed at the time of the encode
+        // of current frame.
+        gf_group->skip_frame_refresh[*frame_ind][0] =
+            gf_group->display_idx[(*frame_ind) - 1];
+        gf_group->skip_frame_refresh[*frame_ind][1] =
+            gf_group->display_idx[(*frame_ind) - 2];
       }
     }
     // If max_parallel_frames is not exceeded, encode the next internal ARF
@@ -530,6 +537,12 @@
          sizeof(gf_group->is_frame_non_ref[0]) * MAX_STATIC_GF_GROUP_LENGTH);
   memset(gf_group->src_offset, 0,
          sizeof(gf_group->src_offset[0]) * MAX_STATIC_GF_GROUP_LENGTH);
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+  // Initialize gf_group->skip_frame_refresh with INVALID_IDX.
+  memset(gf_group->skip_frame_refresh, INVALID_IDX,
+         sizeof(gf_group->skip_frame_refresh[0][0]) *
+             MAX_STATIC_GF_GROUP_LENGTH * REF_FRAMES);
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif
 
   if (first_frame_update_type == KF_UPDATE &&
@@ -661,6 +674,22 @@
           &count_arf_frames, doh_gf_index_map, &parallel_frame_count,
           &first_frame_index, &cur_disp_index, actual_gf_length, use_altref + 1,
           cpi->ppi->num_fp_contexts);
+
+      // Set gf_group->skip_frame_refresh.
+      for (int i = 0; i < actual_gf_length; i++) {
+        int count = 0;
+        if (gf_group->update_type[i] == INTNL_ARF_UPDATE) {
+          for (int j = 0; j < i; j++) {
+            // Store the display order hint of the frames which would not
+            // have been displayed at the encode call of frame 'i'.
+            if ((gf_group->display_idx[j] < gf_group->display_idx[i]) &&
+                gf_group->update_type[j] == INTNL_ARF_UPDATE) {
+              gf_group->skip_frame_refresh[i][count++] =
+                  gf_group->display_idx[j];
+            }
+          }
+        }
+      }
     } else {
       // Set layer depth threshold for reordering as per the gf length.
       int depth_thr =
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 5a84dad..0907e5f 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -1343,6 +1343,9 @@
         av1_get_refresh_frame_flags(cpi, &frame_params, frame_update_type,
 #if CONFIG_FRAME_PARALLEL_ENCODE
                                     true_disp, ref_frame_map_pairs,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                                    gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                                     &ref_buffer_stack);
 
@@ -1434,6 +1437,9 @@
         av1_get_refresh_frame_flags(cpi, &frame_params, frame_update_type,
 #if CONFIG_FRAME_PARALLEL_ENCODE
                                     true_disp, ref_frame_map_pairs,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                                    gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                                     &ref_buffer_stack);
     int refresh_frame_map_index = av1_get_refresh_ref_frame_map(refresh_mask);