FPMT: Handle reference picture assignment

During parallel encode of lower layer frames, a frame
with frame_parallel_level 1 is excluded from the reference
picture assignment of a frame with frame_parallel_level 2.

Change-Id: I89b4c372d2656ba362cea7ba34fef99a6d2ffc87
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index d6d9306..b67271f 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -1129,6 +1129,9 @@
 
 static void get_ref_frames(AV1_COMP *const cpi,
                            RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                           int gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
                            int cur_frame_disp) {
   AV1_COMMON *cm = &cpi->common;
   int *const remapped_ref_idx = cm->remapped_ref_idx;
@@ -1143,6 +1146,11 @@
   memset(buffer_map, 0, REF_FRAMES * sizeof(buffer_map[0]));
   int min_level = MAX_ARF_LAYERS;
   int max_level = 0;
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+  GF_GROUP *gf_group = &cpi->ppi->gf_group;
+  int skip_ref_unmapping = 0;
+  int is_one_pass_rt = is_one_pass_rt_params(cpi);
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 
   // Go through current reference buffers and store display order, pyr level,
   // and map index.
@@ -1202,6 +1210,25 @@
         buffer_map[i].pyr_level != min_level)
       n_past_high_level++;
 
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+    // During parallel encodes of lower layer frames, exclude the first frame
+    // (frame_parallel_level 1) from being used for the reference assignment of
+    // the second frame (frame_parallel_level 2).
+    if (!is_one_pass_rt &&
+        gf_group->skip_frame_as_ref[gf_index] != INVALID_IDX) {
+      assert(gf_group->frame_parallel_level[gf_index] == 2 &&
+             gf_group->update_type[gf_index] == INTNL_ARF_UPDATE);
+      assert(gf_group->frame_parallel_level[gf_index - 1] == 1 &&
+             gf_group->update_type[gf_index - 1] == INTNL_ARF_UPDATE);
+      if (buffer_map[i].disp_order == gf_group->skip_frame_as_ref[gf_index]) {
+        buffer_map[i].used = 1;
+        // In case a ref frame is excluded from being used during assignment,
+        // skip the call to set_unmapped_ref(). Applicable in steady state.
+        skip_ref_unmapping = 1;
+      }
+    }
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+
     // Keep track of where the frames change from being past frames to future
     // frames.
     if (buffer_map[i].disp_order < cur_frame_disp && closest_past_ref < 0)
@@ -1220,8 +1247,11 @@
   }
 
   // Find the buffer to be excluded from the mapping.
-  set_unmapped_ref(buffer_map, n_bufs, n_min_level_refs, min_level,
-                   cur_frame_disp);
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+  if (!skip_ref_unmapping)
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+    set_unmapped_ref(buffer_map, n_bufs, n_min_level_refs, min_level,
+                     cur_frame_disp);
 
   // Place past frames in LAST_FRAME, LAST2_FRAME, and LAST3_FRAME.
   for (int frame = LAST_FRAME; frame < GOLDEN_FRAME; frame++) {
@@ -1306,12 +1336,19 @@
                         AV1_COMP *cpi,
                         RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
                         int cur_frame_disp,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                        int gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                         int remapped_ref_idx[REF_FRAMES]) {
 #if CONFIG_FRAME_PARALLEL_ENCODE
   (void)ref_buffer_stack;
   (void)remapped_ref_idx;
-  get_ref_frames(cpi, ref_frame_map_pairs, cur_frame_disp);
+  get_ref_frames(cpi, ref_frame_map_pairs,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                 gf_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+                 cur_frame_disp);
   return;
 #else
   const int *const arf_stack = ref_buffer_stack->arf_stack;
@@ -1630,6 +1667,9 @@
       av1_get_ref_frames(&cpi->ref_buffer_stack,
 #if CONFIG_FRAME_PARALLEL_ENCODE
                          cpi, ref_frame_map_pairs, cur_frame_disp,
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+                         cpi->gf_frame_index,
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
                          cm->remapped_ref_idx);
     } else if (cpi->svc.set_ref_frame_config) {