Remove usage of total_stats when lap enabled

total_left_stats and total_stats (in TWO_PASS structure)are
not available in the case of single pass(LAP). Hence they
have been made dynamic allocations in the case of two pass
and they are set to null in the case of single pass when
lap is enabled.

Change-Id: If269b838bf982a363dfc98be5acb4c19e31f256e
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index e412218..9032ad2 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2719,9 +2719,10 @@
   oxcf->target_bandwidth = AOMMIN(oxcf->target_bandwidth, max_bitrate);
   // Also need to update cpi->twopass.bits_left.
   TWO_PASS *const twopass = &cpi->twopass;
-  FIRSTPASS_STATS *stats = &twopass->total_stats;
-  cpi->twopass.bits_left =
-      (int64_t)(stats->duration * cpi->oxcf.target_bandwidth / 10000000.0);
+  FIRSTPASS_STATS *stats = twopass->total_stats;
+  if (stats != NULL)
+    cpi->twopass.bits_left =
+        (int64_t)(stats->duration * cpi->oxcf.target_bandwidth / 10000000.0);
 
   // Adjust max over-shoot percentage.
   oxcf->over_shoot_pct = 0;
@@ -3075,9 +3076,11 @@
       cpi->twopass.stats_in = cpi->twopass.stats_buf_ctx->stats_in_start;
       cpi->twopass.stats_buf_ctx->stats_in_end =
           &cpi->twopass.stats_buf_ctx->stats_in_start[packets - 1];
-    }
 
-    av1_init_second_pass(cpi);
+      av1_init_second_pass(cpi);
+    } else {
+      av1_init_single_pass_lap(cpi);
+    }
   }
 #endif
 
@@ -3598,6 +3601,10 @@
   if (cpi->sf.use_hash_based_trellis) hbt_destroy();
 #endif  // CONFIG_HTB_TRELLIS
   av1_free_ref_frame_buffers(cm->buffer_pool);
+
+  aom_free(cpi->twopass.total_stats);
+  aom_free(cpi->twopass.total_left_stats);
+
   aom_free(cpi);
 
 #ifdef OUTPUT_YUV_SKINMAP
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 94a0223..8a1be0e 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -137,11 +137,15 @@
 }
 
 void av1_init_first_pass(AV1_COMP *cpi) {
-  av1_twopass_zero_stats(&cpi->twopass.total_stats);
+  if (!cpi->lap_enabled) {
+    cpi->twopass.total_stats = aom_calloc(1, sizeof(FIRSTPASS_STATS));
+    av1_twopass_zero_stats(cpi->twopass.total_stats);
+  }
 }
 
 void av1_end_first_pass(AV1_COMP *cpi) {
-  output_stats(&cpi->twopass.total_stats, cpi->output_pkt_list);
+  if (cpi->twopass.total_stats)
+    output_stats(cpi->twopass.total_stats, cpi->output_pkt_list);
 }
 
 static aom_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
@@ -851,7 +855,8 @@
     // local variable 'fps'), and then cpi->output_pkt_list will point to it.
     *this_frame_stats = fps;
     output_stats(this_frame_stats, cpi->output_pkt_list);
-    accumulate_stats(&twopass->total_stats, &fps);
+    if (twopass->total_stats != NULL)
+      accumulate_stats(twopass->total_stats, &fps);
     /*In the case of two pass, first pass uses it as a circular buffer,
      * when LAP is enabled it is used as a linear buffer*/
     twopass->stats_buf_ctx->stats_in_end++;
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index a7a49e4..1cada53 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -136,7 +136,7 @@
 
 typedef struct {
   unsigned int section_intra_rating;
-  FIRSTPASS_STATS total_stats;
+  FIRSTPASS_STATS *total_stats;
   // Circular queue of first pass stats stored for most recent frames.
   // cpi->output_pkt_list[i].data.twopass_stats.buf points to actual data stored
   // here.
@@ -144,7 +144,7 @@
   int frame_stats_next_idx;  // Index to next unused element in frame_stats_arr.
   const FIRSTPASS_STATS *stats_in;
   STATS_BUFFER_CTX *stats_buf_ctx;
-  FIRSTPASS_STATS total_left_stats;
+  FIRSTPASS_STATS *total_left_stats;
   int first_pass_done;
   int64_t bits_left;
   double modified_error_min;
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 7285f97..d0ab8be 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -50,7 +50,10 @@
                                      const TWO_PASS *twopass,
                                      const AV1EncoderConfig *oxcf,
                                      const FIRSTPASS_STATS *this_frame) {
-  const FIRSTPASS_STATS *const stats = &twopass->total_stats;
+  const FIRSTPASS_STATS *const stats = twopass->total_stats;
+  if (stats == NULL) {
+    return 0;
+  }
   const double av_weight = stats->weight / stats->count;
   const double av_err = (stats->coded_error * av_weight) / stats->count;
   double modified_error =
@@ -1690,20 +1693,21 @@
   RATE_CONTROL *const rc = &cpi->rc;
   TWO_PASS *const twopass = &cpi->twopass;
 
-  if (cpi->oxcf.rc_mode != AOM_Q && current_frame->frame_number == 0) {
+  if (cpi->oxcf.rc_mode != AOM_Q && current_frame->frame_number == 0 &&
+      cpi->twopass.total_stats && cpi->twopass.total_left_stats) {
     const int frames_left =
-        (int)(twopass->total_stats.count - current_frame->frame_number);
+        (int)(twopass->total_stats->count - current_frame->frame_number);
 
     // Special case code for first frame.
     const int section_target_bandwidth =
         (int)(twopass->bits_left / frames_left);
-    const double section_length = twopass->total_left_stats.count;
+    const double section_length = twopass->total_left_stats->count;
     const double section_error =
-        twopass->total_left_stats.coded_error / section_length;
+        twopass->total_left_stats->coded_error / section_length;
     const double section_intra_skip =
-        twopass->total_left_stats.intra_skip_pct / section_length;
+        twopass->total_left_stats->intra_skip_pct / section_length;
     const double section_inactive_zone =
-        (twopass->total_left_stats.inactive_zone_rows * 2) /
+        (twopass->total_left_stats->inactive_zone_rows * 2) /
         ((double)cm->mb_rows * section_length);
     const int tmp_q = get_twopass_worst_quality(
         cpi, section_error, section_intra_skip + section_inactive_zone,
@@ -1738,7 +1742,8 @@
   }
 
   // Update the total stats remaining structure.
-  subtract_stats(&twopass->total_left_stats, this_frame);
+  if (twopass->total_left_stats)
+    subtract_stats(twopass->total_left_stats, this_frame);
 
   // Set the frame content type flag.
   if (this_frame->intra_skip_pct >= FC_ANIMATION_THRESH)
@@ -1894,15 +1899,17 @@
   double frame_rate;
   FIRSTPASS_STATS *stats;
 
-  av1_twopass_zero_stats(&twopass->total_stats);
-  av1_twopass_zero_stats(&twopass->total_left_stats);
+  twopass->total_stats = aom_calloc(1, sizeof(FIRSTPASS_STATS));
+  twopass->total_left_stats = aom_calloc(1, sizeof(FIRSTPASS_STATS));
+  av1_twopass_zero_stats(twopass->total_stats);
+  av1_twopass_zero_stats(twopass->total_left_stats);
 
   if (!twopass->stats_buf_ctx->stats_in_end) return;
 
-  stats = &twopass->total_stats;
+  stats = twopass->total_stats;
 
   *stats = *twopass->stats_buf_ctx->stats_in_end;
-  twopass->total_left_stats = *stats;
+  *twopass->total_left_stats = *stats;
 
   frame_rate = 10000000.0 * stats->count / stats->duration;
   // Each frame can have a different duration, as the frame rate in the source
@@ -1954,6 +1961,40 @@
   twopass->rolling_arf_group_actual_bits = 1;
 }
 
+void av1_init_single_pass_lap(AV1_COMP *cpi) {
+  TWO_PASS *const twopass = &cpi->twopass;
+
+  twopass->total_stats = NULL;
+  twopass->total_left_stats = NULL;
+
+  if (!twopass->stats_buf_ctx->stats_in_end) return;
+
+  // This variable monitors how far behind the second ref update is lagging.
+  twopass->sr_update_lag = 1;
+
+  twopass->bits_left = 0;
+  twopass->modified_error_min = 0.0;
+  twopass->modified_error_max = 0.0;
+  twopass->modified_error_left = 0.0;
+
+  // Reset the vbr bits off target counters
+  cpi->rc.vbr_bits_off_target = 0;
+  cpi->rc.vbr_bits_off_target_fast = 0;
+
+  cpi->rc.rate_error_estimate = 0;
+
+  // Static sequence monitor variables.
+  twopass->kf_zeromotion_pct = 100;
+  twopass->last_kfgroup_zeromotion_pct = 100;
+
+  // Initialize bits per macro_block estimate correction factor.
+  twopass->bpm_factor = 1.0;
+  // Initialize actual and target bits counters for ARF groups so that
+  // at the start we have a neutral bpm adjustment.
+  twopass->rolling_arf_group_target_bits = 1;
+  twopass->rolling_arf_group_actual_bits = 1;
+}
+
 #define MINQ_ADJ_LIMIT 48
 #define MINQ_ADJ_LIMIT_CQ 20
 #define HIGH_UNDERSHOOT_RATIO 2
diff --git a/av1/encoder/pass2_strategy.h b/av1/encoder/pass2_strategy.h
index bf37746a..e23994c 100644
--- a/av1/encoder/pass2_strategy.h
+++ b/av1/encoder/pass2_strategy.h
@@ -21,6 +21,8 @@
 
 void av1_init_second_pass(struct AV1_COMP *cpi);
 
+void av1_init_single_pass_lap(AV1_COMP *cpi);
+
 void av1_get_second_pass_params(struct AV1_COMP *cpi,
                                 struct EncodeFrameParams *const frame_params,
                                 unsigned int frame_flags);
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 0573f18..f43279f 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1727,8 +1727,10 @@
 static void vbr_rate_correction(AV1_COMP *cpi, int *this_frame_target) {
   RATE_CONTROL *const rc = &cpi->rc;
   int64_t vbr_bits_off_target = rc->vbr_bits_off_target;
+
+  assert(cpi->twopass.total_stats != NULL);
   const int frame_window =
-      AOMMIN(16, (int)(cpi->twopass.total_stats.count -
+      AOMMIN(16, (int)(cpi->twopass.total_stats->count -
                        cpi->common.current_frame.frame_number));
 
   if (frame_window > 0) {