Pre-process first pass stats in RC lib.

This patch calculates the correlation coefficients, noise variance,
etc. base on the first pass stats provided. It is needed to correctly
partition gop size.

This also allows future changes to use such processed results.

Change-Id: I847e4b73ab3a8012eb82675ca5158ce2f995cf17
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 650595e..1dd9721 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -3489,8 +3489,8 @@
   rc->base_frame_target = target_rate;
 }
 
-static void mark_flashes(FIRSTPASS_STATS *first_stats,
-                         FIRSTPASS_STATS *last_stats) {
+void av1_mark_flashes(FIRSTPASS_STATS *first_stats,
+                      FIRSTPASS_STATS *last_stats) {
   FIRSTPASS_STATS *this_stats = first_stats, *next_stats;
   while (this_stats < last_stats - 1) {
     next_stats = this_stats + 1;
@@ -3509,8 +3509,8 @@
 }
 
 // Estimate the noise variance of each frame from the first pass stats
-static void estimate_noise(FIRSTPASS_STATS *first_stats,
-                           FIRSTPASS_STATS *last_stats) {
+void av1_estimate_noise(FIRSTPASS_STATS *first_stats,
+                        FIRSTPASS_STATS *last_stats) {
   FIRSTPASS_STATS *this_stats, *next_stats;
   double C1, C2, C3, noise;
   for (this_stats = first_stats + 2; this_stats < last_stats; this_stats++) {
@@ -3598,8 +3598,8 @@
 }
 
 // Estimate correlation coefficient of each frame with its previous frame.
-static void estimate_coeff(FIRSTPASS_STATS *first_stats,
-                           FIRSTPASS_STATS *last_stats) {
+void av1_estimate_coeff(FIRSTPASS_STATS *first_stats,
+                        FIRSTPASS_STATS *last_stats) {
   FIRSTPASS_STATS *this_stats;
   for (this_stats = first_stats + 1; this_stats < last_stats; this_stats++) {
     const double C =
@@ -3752,12 +3752,12 @@
       p_rc->frames_till_regions_update = rest_frames;
 
       if (cpi->ppi->lap_enabled) {
-        mark_flashes(twopass->stats_buf_ctx->stats_in_start,
-                     twopass->stats_buf_ctx->stats_in_end);
-        estimate_noise(twopass->stats_buf_ctx->stats_in_start,
-                       twopass->stats_buf_ctx->stats_in_end);
-        estimate_coeff(twopass->stats_buf_ctx->stats_in_start,
-                       twopass->stats_buf_ctx->stats_in_end);
+        av1_mark_flashes(twopass->stats_buf_ctx->stats_in_start,
+                         twopass->stats_buf_ctx->stats_in_end);
+        av1_estimate_noise(twopass->stats_buf_ctx->stats_in_start,
+                           twopass->stats_buf_ctx->stats_in_end);
+        av1_estimate_coeff(twopass->stats_buf_ctx->stats_in_start,
+                           twopass->stats_buf_ctx->stats_in_end);
         av1_identify_regions(cpi->twopass_frame.stats_in, rest_frames,
                              (rc->frames_since_key == 0), p_rc->regions,
                              &p_rc->num_regions);
@@ -3922,12 +3922,12 @@
 
   if (!twopass->stats_buf_ctx->stats_in_end) return;
 
-  mark_flashes(twopass->stats_buf_ctx->stats_in_start,
-               twopass->stats_buf_ctx->stats_in_end);
-  estimate_noise(twopass->stats_buf_ctx->stats_in_start,
-                 twopass->stats_buf_ctx->stats_in_end);
-  estimate_coeff(twopass->stats_buf_ctx->stats_in_start,
-                 twopass->stats_buf_ctx->stats_in_end);
+  av1_mark_flashes(twopass->stats_buf_ctx->stats_in_start,
+                   twopass->stats_buf_ctx->stats_in_end);
+  av1_estimate_noise(twopass->stats_buf_ctx->stats_in_start,
+                     twopass->stats_buf_ctx->stats_in_end);
+  av1_estimate_coeff(twopass->stats_buf_ctx->stats_in_start,
+                     twopass->stats_buf_ctx->stats_in_end);
 
   stats = twopass->stats_buf_ctx->total_stats;
 
diff --git a/av1/encoder/pass2_strategy.h b/av1/encoder/pass2_strategy.h
index 87e08bb..a75be1a 100644
--- a/av1/encoder/pass2_strategy.h
+++ b/av1/encoder/pass2_strategy.h
@@ -148,6 +148,13 @@
                           int total_frames, int offset, REGIONS *regions,
                           int *total_regions);
 
+void av1_mark_flashes(FIRSTPASS_STATS *first_stats,
+                      FIRSTPASS_STATS *last_stats);
+void av1_estimate_noise(FIRSTPASS_STATS *first_stats,
+                        FIRSTPASS_STATS *last_stats);
+void av1_estimate_coeff(FIRSTPASS_STATS *first_stats,
+                        FIRSTPASS_STATS *last_stats);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/av1/qmode_rc/ratectrl_qmode.cc b/av1/qmode_rc/ratectrl_qmode.cc
index b714006..cff7514 100644
--- a/av1/qmode_rc/ratectrl_qmode.cc
+++ b/av1/qmode_rc/ratectrl_qmode.cc
@@ -854,9 +854,18 @@
   RefFrameManager ref_frame_manager(rc_param_.ref_frame_table_size,
                                     rc_param_.max_ref_frames);
 
+  // Make a copy of the first pass stats, and analyze them
+  FirstpassInfo fp_info_copy = firstpass_info;
+  av1_mark_flashes(fp_info_copy.stats_list.data(),
+                   fp_info_copy.stats_list.data() + stats_size);
+  av1_estimate_noise(fp_info_copy.stats_list.data(),
+                     fp_info_copy.stats_list.data() + stats_size);
+  av1_estimate_coeff(fp_info_copy.stats_list.data(),
+                     fp_info_copy.stats_list.data() + stats_size);
+
   int global_coding_idx_offset = 0;
   int global_order_idx_offset = 0;
-  std::vector<int> key_frame_list = GetKeyFrameList(firstpass_info);
+  std::vector<int> key_frame_list = GetKeyFrameList(fp_info_copy);
   key_frame_list.push_back(stats_size);  // a sentinel value
   for (size_t ki = 0; ki + 1 < key_frame_list.size(); ++ki) {
     int frames_to_key = key_frame_list[ki + 1] - key_frame_list[ki];
@@ -864,11 +873,11 @@
 
     std::vector<REGIONS> regions_list(MAX_FIRSTPASS_ANALYSIS_FRAMES);
     int total_regions = 0;
-    av1_identify_regions(firstpass_info.stats_list.data() + key_order_index,
+    av1_identify_regions(fp_info_copy.stats_list.data() + key_order_index,
                          frames_to_key, 0, regions_list.data(), &total_regions);
     regions_list.resize(total_regions);
     std::vector<int> gf_intervals = PartitionGopIntervals(
-        rc_param_, firstpass_info.stats_list, regions_list, key_order_index,
+        rc_param_, fp_info_copy.stats_list, regions_list, key_order_index,
         /*frames_since_key=*/0, frames_to_key);
     for (size_t gi = 0; gi < gf_intervals.size(); ++gi) {
       const bool has_key_frame = gi == 0;