Make GOP decision ahead of frame processing stage

Decide the GOP structure before the frame processing and coding
stages. This will cause slight coding performance change due to
fixes for prior issues in inter GOP assumptions. The average changes
are within 0.1% range.

STATS_CHANGED

Change-Id: Ib61baa33cb8d58f944aca5d50b66546b8b315b00
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 480d8fa..d9a15b1 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -397,7 +397,7 @@
   // If this is a key frame and keyframe filtering is enabled with overlay,
   // then do not pop.
   if (pop_lookahead && cpi->oxcf.kf_cfg.enable_keyframe_filtering > 1 &&
-      cpi->rc.frames_to_key == 0 && cpi->rc.frames_till_gf_update_due == 0 &&
+      gf_group->update_type[gf_group->index] == ARF_UPDATE &&
       !is_stat_generation_stage(cpi) && cpi->lookahead) {
     if (cpi->lookahead->read_ctxs[cpi->compressor_stage].sz &&
         (*flush ||
@@ -1093,6 +1093,16 @@
     if (srcbuf_size < pop_size) return -1;
   }
 
+  if (!av1_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage)) {
+#if !CONFIG_REALTIME_ONLY
+    if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
+      av1_end_first_pass(cpi); /* get last stats packet */
+      cpi->twopass.first_pass_done = 1;
+    }
+#endif
+    return -1;
+  }
+
   // TODO(sarahparker) finish bit allocation for one pass pyramid
   if (has_no_stats_stage(cpi)) {
     gf_cfg->gf_max_pyr_height =
@@ -1101,6 +1111,15 @@
         AOMMIN(gf_cfg->gf_min_pyr_height, gf_cfg->gf_max_pyr_height);
   }
 
+#if !CONFIG_REALTIME_ONLY
+  const int use_one_pass_rt_params = has_no_stats_stage(cpi) &&
+                                     oxcf->mode == REALTIME &&
+                                     gf_cfg->lag_in_frames == 0;
+  if (!use_one_pass_rt_params && !is_stat_generation_stage(cpi)) {
+    av1_get_second_pass_params(cpi, &frame_params, &frame_input, *frame_flags);
+  }
+#endif
+
   if (!is_stat_generation_stage(cpi)) {
     // If this is a forward keyframe, mark as a show_existing_frame
     // TODO(bohanli): find a consistent condition for fwd keyframes
@@ -1157,6 +1176,7 @@
   }
 
   av1_apply_encoding_flags(cpi, source->flags);
+
   if (!frame_params.show_existing_frame)
     *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
 
@@ -1181,16 +1201,18 @@
 
 #if CONFIG_REALTIME_ONLY
   av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
+  if (cpi->oxcf.speed >= 6 && cm->number_spatial_layers == 1 &&
+      cm->number_temporal_layers == 1)
+    av1_set_reference_structure_one_pass_rt(cpi, gf_group->index == 0);
 #else
-  const int use_one_pass_rt_params = has_no_stats_stage(cpi) &&
-                                     oxcf->mode == REALTIME &&
-                                     gf_cfg->lag_in_frames == 0;
   if (use_one_pass_rt_params) {
     av1_get_one_pass_rt_params(cpi, &frame_params, *frame_flags);
-  } else if (!is_stat_generation_stage(cpi)) {
-    av1_get_second_pass_params(cpi, &frame_params, &frame_input, *frame_flags);
+    if (cpi->oxcf.speed >= 6 && cm->number_spatial_layers == 1 &&
+        cm->number_temporal_layers == 1)
+      av1_set_reference_structure_one_pass_rt(cpi, gf_group->index == 0);
   }
 #endif
+
   FRAME_UPDATE_TYPE frame_update_type = get_frame_update_type(gf_group);
 
   if (frame_params.show_existing_frame &&
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index bc7a4cb..a504d48 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -2796,7 +2796,7 @@
   }
 
   // Keyframe and section processing.
-  if (rc->frames_to_key <= 0 || (frame_flags & FRAMEFLAGS_KEY)) {
+  if (rc->frames_to_key <= 0) {
     assert(rc->frames_to_key >= -1);
     FIRSTPASS_STATS this_frame_copy;
     this_frame_copy = this_frame;
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index afc801e..2a46a4a 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -2169,7 +2169,7 @@
  * (for each of 7 references) and refresh flags (for each of the 8 slots)
  * are set in \c cpi->svc.ref_idx[] and \c cpi->svc.refresh[].
  */
-static void set_reference_structure_one_pass_rt(AV1_COMP *cpi, int gf_update) {
+void av1_set_reference_structure_one_pass_rt(AV1_COMP *cpi, int gf_update) {
   AV1_COMMON *const cm = &cpi->common;
   ExternalFlags *const ext_flags = &cpi->ext_flags;
   ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
@@ -2557,14 +2557,12 @@
   SVC *const svc = &cpi->svc;
   ResizePendingParams *const resize_pending_params =
       &cpi->resize_pending_params;
-  int gf_update = 0;
   int target;
   const int layer =
       LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id,
                        svc->number_temporal_layers);
   // Turn this on to explicitly set the reference structure rather than
   // relying on internal/default structure.
-  const int set_reference_structure = 1;
   if (cpi->use_svc) {
     av1_update_temporal_layer_framerate(cpi);
     av1_restore_layer_context(cpi);
@@ -2623,7 +2621,7 @@
                     resize_pending_params->height, cm->width, cm->height);
   }
   // Set the GF interval and update flag.
-  gf_update = set_gf_interval_update_onepass_rt(cpi, frame_params->frame_type);
+  set_gf_interval_update_onepass_rt(cpi, frame_params->frame_type);
   // Set target size.
   if (cpi->oxcf.rc_cfg.mode == AOM_CBR) {
     if (frame_params->frame_type == KEY_FRAME) {
@@ -2642,10 +2640,6 @@
   }
   av1_rc_set_frame_target(cpi, target, cm->width, cm->height);
   rc->base_frame_target = target;
-  // Set reference strucutre for 1 layer.
-  if (set_reference_structure && cpi->oxcf.speed >= 6 &&
-      cm->number_spatial_layers == 1 && cm->number_temporal_layers == 1)
-    set_reference_structure_one_pass_rt(cpi, gf_update);
   cm->current_frame.frame_type = frame_params->frame_type;
 }
 
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 7f26f38..173eb68 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -458,6 +458,9 @@
 void av1_rc_set_frame_target(struct AV1_COMP *cpi, int target, int width,
                              int height);
 
+void av1_set_reference_structure_one_pass_rt(struct AV1_COMP *cpi,
+                                             int gf_update);
+
 /*!\endcond */
 /*!\brief Calculates how many bits to use for a P frame in one pass vbr
  *
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 146daa0..c43e0bd 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -995,10 +995,9 @@
 
     if (gf_index == cur_frame_idx) {
       struct lookahead_entry *buf =
-          av1_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage);
+          av1_lookahead_peek(cpi->lookahead, 1, cpi->compressor_stage);
       if (buf == NULL) break;
-      tpl_frame->gf_picture =
-          frame_input->source == NULL ? &buf->img : frame_input->source;
+      tpl_frame->gf_picture = gop_eval ? &buf->img : frame_input->source;
     } else {
       struct lookahead_entry *buf = av1_lookahead_peek(
           cpi->lookahead, frame_display_index - anc_frame_offset,
diff --git a/test/fwd_kf_test.cc b/test/fwd_kf_test.cc
index fb12402..edacf6c 100644
--- a/test/fwd_kf_test.cc
+++ b/test/fwd_kf_test.cc
@@ -25,7 +25,7 @@
 } FwdKfTestParam;
 
 const FwdKfTestParam kTestParams[] = {
-  { 4, 33.4 },  { 6, 32.9 },  { 8, 32.6 },
+  { 4, 32.8 },  { 6, 32.9 },  { 8, 32.6 },
   { 12, 32.4 }, { 16, 32.3 }, { 18, 32.1 }
 };