FPMT: Handle reference refresh for parallel encode frames

Initialized ref_frame_map for frames in a parallel encode set.
Moved the calls to refresh_reference_frames() to
av1_post_encode_updates() and added ref_frame_map_copy in
AV1_PRIMARY to facilitate sequential update of ref_frame_map
by frames encoded ahead of time in a parallel encode set.

Change-Id: I8d7b65fc14df262fb1ac2d53ba97160ef244af07
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index a01d6f3..38636bc 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3432,8 +3432,6 @@
     av1_denoiser_update_ref_frame(cpi);
 #endif
 
-    refresh_reference_frames(cpi);
-
     // Since we allocate a spot for the OVERLAY frame in the gf group, we need
     // to do post-encoding update accordingly.
     av1_set_target_rate(cpi, cm->width, cm->height);
@@ -3655,8 +3653,6 @@
   //       for the purpose to verify no mismatch between encoder and decoder.
   if (cm->show_frame) cpi->last_show_frame_buf = cm->cur_frame;
 
-  refresh_reference_frames(cpi);
-
   if (features->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
     *cm->fc = cpi->tile_data[largest_tile_id].tctx;
     av1_reset_cdf_symbol_counters(cm->fc);
@@ -4207,6 +4203,31 @@
   AV1_COMMON *const cm = &cpi->common;
 
   if (!is_stat_generation_stage(cpi) && !cpi->is_dropped_frame) {
+#if CONFIG_FRAME_PARALLEL_ENCODE
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+    // Before calling refresh_reference_frames(), copy ppi->ref_frame_map_copy
+    // to cm->ref_frame_map for frame_parallel_level 2 frame in a parallel
+    // encode set of lower layer frames.
+    if (ppi->gf_group.frame_parallel_level[cpi->gf_frame_index - 1] == 1 &&
+        ppi->gf_group.update_type[cpi->gf_frame_index - 1] ==
+            INTNL_ARF_UPDATE) {
+      memcpy(cm->ref_frame_map, ppi->ref_frame_map_copy,
+             sizeof(cm->ref_frame_map));
+    }
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE
+    refresh_reference_frames(cpi);
+#if CONFIG_FRAME_PARALLEL_ENCODE
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+    // For frame_parallel_level 1 frame in a parallel encode set of lower layer
+    // frames, store the updated cm->ref_frame_map in ppi->ref_frame_map_copy.
+    if (ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 1 &&
+        ppi->gf_group.update_type[cpi->gf_frame_index] == INTNL_ARF_UPDATE) {
+      memcpy(ppi->ref_frame_map_copy, cm->ref_frame_map,
+             sizeof(cm->ref_frame_map));
+    }
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE
     av1_rc_postencode_update(cpi, size);
   }
 
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 336d638..f38dbc3 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -2232,6 +2232,15 @@
    * avg_frame_qindex.
    */
   int temp_avg_frame_qindex[FRAME_TYPES];
+
+#if CONFIG_FRAME_PARALLEL_ENCODE_2
+  /*!
+   * Copy of cm->ref_frame_map maintained to facilitate sequential update of
+   * ref_frame_map by lower layer depth frames encoded ahead of time in a
+   * parallel encode set.
+   */
+  RefCntBuffer *ref_frame_map_copy[REF_FRAMES];
+#endif  // CONFIG_FRAME_PARALLEL_ENCODE_2
 #endif  // CONFIG_FRAME_PARALLEL_ENCODE
   /*!
    * Encode stage top level structure
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 203810a..3b366bf 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -2418,6 +2418,8 @@
       cur_cpi->gf_frame_index = i;
       cur_cpi->common.current_frame.frame_number = cur_frame_num;
       cur_cpi->do_frame_data_update = false;
+      memcpy(cur_cpi->common.ref_frame_map, first_cpi->common.ref_frame_map,
+             sizeof(first_cpi->common.ref_frame_map));
       parallel_frame_count++;
     }