Unify temporal filtering of ARF and KF.

Put temporal filtering of the two both in denoise_and_encode.
This makes it easier to maintain which frame to filter and
also which frame to perform TPL on.

Change-Id: I529d8c1ee46aa3a34c688c5375aead63aad1e568
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index d314663..eb5c863 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -359,57 +359,6 @@
   return arf_src_index;
 }
 
-// Called if this frame is an ARF or ARF2. Also handles forward-keyframes
-// For an ARF set arf2=0, for ARF2 set arf2=1
-// temporal_filtered is set to 1 if we temporally filter the ARF frame, so that
-// the correct post-filter buffer can be used.
-static struct lookahead_entry *setup_arf_frame(
-    AV1_COMP *const cpi, const int arf_src_index, int *code_arf,
-    EncodeFrameParams *const frame_params, int *show_existing_alt_ref) {
-  AV1_COMMON *const cm = &cpi->common;
-  RATE_CONTROL *const rc = &cpi->rc;
-#if !CONFIG_REALTIME_ONLY
-  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
-#endif
-
-  assert(arf_src_index <= rc->frames_to_key);
-  *code_arf = 0;
-
-  struct lookahead_entry *source =
-      av1_lookahead_peek(cpi->lookahead, arf_src_index, cpi->compressor_stage);
-
-  if (source != NULL) {
-    cm->showable_frame = 1;
-
-    // When arf_src_index == rc->frames_to_key, it indicates a fwd_kf
-    if (arf_src_index == rc->frames_to_key) {
-      // Skip temporal filtering and mark as intra_only if we have a fwd_kf
-      cpi->no_show_kf = 1;
-    } else {
-#if !CONFIG_REALTIME_ONLY
-      if (oxcf->algo_cfg.arnr_max_frames > 0) {
-        // Produce the filtered ARF frame.
-        cm->current_frame.frame_type = INTER_FRAME;
-        FRAME_UPDATE_TYPE frame_update_type =
-            get_frame_update_type(&cpi->gf_group);
-        av1_configure_buffer_updates(cpi, &frame_params->refresh_frame,
-                                     frame_update_type, 0);
-        *code_arf =
-            av1_temporal_filter(cpi, arf_src_index, show_existing_alt_ref);
-        if (*code_arf) {
-          aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
-        }
-      }
-#else
-      (void)show_existing_alt_ref;
-#endif
-    }
-    frame_params->show_frame = 0;
-  }
-  rc->source_alt_ref_pending = 0;
-  return source;
-}
-
 // Determine whether there is a forced keyframe pending in the lookahead buffer
 int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
                                const int up_to_index,
@@ -435,29 +384,31 @@
 // temporal_filtered, flush, and frame_update_type are outputs.
 // Return the frame source, or NULL if we couldn't find one
 static struct lookahead_entry *choose_frame_source(
-    AV1_COMP *const cpi, int *const code_arf, int *const flush,
-    struct lookahead_entry **last_source, EncodeFrameParams *const frame_params,
-    int *show_existing_alt_ref) {
+    AV1_COMP *const cpi, int *const flush, struct lookahead_entry **last_source,
+    EncodeFrameParams *const frame_params) {
   AV1_COMMON *const cm = &cpi->common;
   struct lookahead_entry *source = NULL;
-  *code_arf = 0;
 
-  // Should we encode an alt-ref frame.
-  int arf_src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
+  // Source index in lookahead buffer.
+  int src_index = get_arf_src_index(&cpi->gf_group, cpi->oxcf.pass);
+
   // TODO(Aasaipriya): Forced key frames need to be fixed when rc_mode != AOM_Q
-  if (arf_src_index &&
-      (is_forced_keyframe_pending(cpi->lookahead, arf_src_index,
+  if (src_index &&
+      (is_forced_keyframe_pending(cpi->lookahead, src_index,
                                   cpi->compressor_stage) != -1) &&
       cpi->oxcf.rc_cfg.mode != AOM_Q) {
-    arf_src_index = 0;
+    src_index = 0;
     *flush = 1;
   }
 
-  if (arf_src_index)
-    source = setup_arf_frame(cpi, arf_src_index, code_arf, frame_params,
-                             show_existing_alt_ref);
-
-  if (!source) {
+  // If the current frame is arf, then we should not pop from the lookahead
+  // buffer. If the current frame is not arf, then pop it. This assumes the
+  // first frame in the GF group is not arf. May need to change if it is not
+  // true.
+  const int pop_lookahead = (src_index == 0);
+  frame_params->show_frame = pop_lookahead;
+  if (pop_lookahead) {
+    // show frame, pop from buffer
     // Get last frame source.
     if (cm->current_frame.frame_number > 0) {
       *last_source =
@@ -465,8 +416,18 @@
     }
     // Read in the source frame.
     source = av1_lookahead_pop(cpi->lookahead, *flush, cpi->compressor_stage);
-    if (source == NULL) return NULL;
-    frame_params->show_frame = 1;
+  } else {
+    // no show frames are arf frames
+    source =
+        av1_lookahead_peek(cpi->lookahead, src_index, cpi->compressor_stage);
+    cpi->rc.source_alt_ref_pending = 0;
+    // When src_index == rc->frames_to_key, it indicates a fwd_kf
+    if (src_index == cpi->rc.frames_to_key) {
+      cpi->no_show_kf = 1;
+    }
+    if (source != NULL) {
+      cm->showable_frame = 1;
+    }
   }
   return source;
 }
@@ -871,9 +832,9 @@
   set_mi_offsets(&cm->mi_params, xd, 0, 0);
 }
 
-// Apply temporal filtering to key frames and encode the filtered frame.
-// If the current frame is not key frame, this function is identical to
-// av1_encode().
+// Apply temporal filtering to source frames and encode the filtered frame.
+// If the current frame does not require filtering, this function is identical
+// to av1_encode() except that tpl is not performed.
 static int denoise_and_encode(AV1_COMP *const cpi, uint8_t *const dest,
                               EncodeFrameInput *const frame_input,
                               EncodeFrameParams *const frame_params,
@@ -882,63 +843,98 @@
   AV1_COMMON *const cm = &cpi->common;
 
   // Decide whether to apply temporal filtering to the source frame.
-  int apply_filtering =
-      frame_params->frame_type == KEY_FRAME &&
-      oxcf->kf_cfg.enable_keyframe_filtering &&
-      !is_stat_generation_stage(cpi) && !frame_params->show_existing_frame &&
-      cpi->rc.frames_to_key > cpi->oxcf.algo_cfg.arnr_max_frames &&
-      !is_lossless_requested(&oxcf->rc_cfg) &&
-      oxcf->algo_cfg.arnr_max_frames > 0;
-  if (apply_filtering) {
-    const double y_noise_level = av1_estimate_noise_from_single_plane(
-        frame_input->source, 0, cm->seq_params.bit_depth);
-    apply_filtering = y_noise_level > 0;
-  }
-
-  // Save the pointer to the original source image.
-  YV12_BUFFER_CONFIG *source_kf_buffer = frame_input->source;
-
-  // Apply filtering to key frame.
-  if (apply_filtering) {
-    // Initialization for frame motion estimation.
-    MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
-    av1_init_mi_buffers(&cm->mi_params);
-    setup_mi(cpi, frame_input->source);
-    av1_init_macroblockd(cm, xd);
-    memset(
-        cpi->mbmi_ext_info.frame_base, 0,
-        cpi->mbmi_ext_info.alloc_size * sizeof(*cpi->mbmi_ext_info.frame_base));
-
-    av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
-    av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
-    av1_set_rd_speed_thresholds(cpi);
-    av1_setup_frame_buf_refs(cm);
-    av1_setup_frame_sign_bias(cm);
-    av1_frame_init_quantizer(cpi);
-    av1_setup_past_independence(cm);
-
-    if (!frame_params->show_frame) {
-      int arf_src_index = get_arf_src_index(&cpi->gf_group, oxcf->pass);
-      av1_temporal_filter(cpi, -1 * arf_src_index, NULL);
+  int apply_filtering = 0;
+  int arf_src_index = -1;
+  if (frame_params->frame_type == KEY_FRAME) {
+    // Decide whether it is allowed to perform key frame filtering
+    int allow_kf_filtering =
+        oxcf->kf_cfg.enable_keyframe_filtering &&
+        !is_stat_generation_stage(cpi) && !frame_params->show_existing_frame &&
+        cpi->rc.frames_to_key > cpi->oxcf.algo_cfg.arnr_max_frames &&
+        !is_lossless_requested(&oxcf->rc_cfg) &&
+        oxcf->algo_cfg.arnr_max_frames > 0;
+    if (allow_kf_filtering) {
+      const double y_noise_level = av1_estimate_noise_from_single_plane(
+          frame_input->source, 0, cm->seq_params.bit_depth);
+      apply_filtering = y_noise_level > 0;
     } else {
-      av1_temporal_filter(cpi, -1, NULL);
+      apply_filtering = 0;
     }
-    aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
-    // Use the filtered frame for encoding.
-    frame_input->source = &cpi->alt_ref_buffer;
-    // Copy metadata info to alt-ref buffer.
-    aom_remove_metadata_from_frame_buffer(frame_input->source);
+    // If we are doing kf filtering, set up a few things.
+    if (apply_filtering) {
+      MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
+      av1_init_mi_buffers(&cm->mi_params);
+      setup_mi(cpi, frame_input->source);
+      av1_init_macroblockd(cm, xd);
+      memset(cpi->mbmi_ext_info.frame_base, 0,
+             cpi->mbmi_ext_info.alloc_size *
+                 sizeof(*cpi->mbmi_ext_info.frame_base));
+
+      av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
+      av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);
+      av1_set_rd_speed_thresholds(cpi);
+      av1_setup_frame_buf_refs(cm);
+      av1_setup_frame_sign_bias(cm);
+      av1_frame_init_quantizer(cpi);
+      av1_setup_past_independence(cm);
+
+      if (!frame_params->show_frame) {
+        arf_src_index = -1 * get_arf_src_index(&cpi->gf_group, oxcf->pass);
+      } else {
+        arf_src_index = -1;
+      }
+    }
+  } else if (get_frame_update_type(&cpi->gf_group) == ARF_UPDATE ||
+             get_frame_update_type(&cpi->gf_group) == INTNL_ARF_UPDATE) {
+    // ARF
+    apply_filtering = oxcf->algo_cfg.arnr_max_frames > 0;
+    if (apply_filtering) {
+      arf_src_index = get_arf_src_index(&cpi->gf_group, oxcf->pass);
+    }
+  }
+  // Save the pointer to the original source image.
+  YV12_BUFFER_CONFIG *source_buffer = frame_input->source;
+  // apply filtering to frame
+  if (apply_filtering) {
+    int show_existing_alt_ref = 0;
+    // TODO(bohanli): figure out why we need frame_type in cm here.
+    cm->current_frame.frame_type = frame_params->frame_type;
+    const int code_arf =
+        av1_temporal_filter(cpi, arf_src_index, &show_existing_alt_ref);
+    if (code_arf) {
+      aom_extend_frame_borders(&cpi->alt_ref_buffer, av1_num_planes(cm));
+      frame_input->source = &cpi->alt_ref_buffer;
+    }
+    if (get_frame_update_type(&cpi->gf_group) == ARF_UPDATE) {
+      cpi->show_existing_alt_ref = show_existing_alt_ref;
+    }
     aom_copy_metadata_to_frame_buffer(frame_input->source,
-                                      source_kf_buffer->metadata);
+                                      source_buffer->metadata);
   }
 
-  if (!cpi->sf.tpl_sf.disable_filtered_key_tpl) {
-    if (frame_params->frame_type == KEY_FRAME &&
-        !is_stat_generation_stage(cpi) && oxcf->algo_cfg.enable_tpl_model &&
-        oxcf->gf_cfg.lag_in_frames > 0 && frame_params->show_frame) {
-      av1_tpl_setup_stats(cpi, 0, frame_params, frame_input);
+  // perform tpl after filtering
+  int allow_tpl = oxcf->gf_cfg.lag_in_frames > 0 &&
+                  !is_stat_generation_stage(cpi) &&
+                  oxcf->algo_cfg.enable_tpl_model;
+  if (frame_params->frame_type == KEY_FRAME) {
+    // Don't do tpl for fwd key frames
+    allow_tpl = allow_tpl && !cpi->sf.tpl_sf.disable_filtered_key_tpl &&
+                frame_params->show_frame;
+  } else {
+    // Do tpl after ARF is filtered, or if no ARF, at the second frame of GF
+    // group.
+    // TODO(bohanli): if no ARF, just do it at the first frame.
+    int which_frame_tpl = AOMMAX(cpi->gf_group.arf_index, 1);
+    allow_tpl = allow_tpl && (cpi->gf_group.index == which_frame_tpl);
+    if (allow_tpl) {
+      // Need to set the size for TPL for ARF
+      // TODO(bohanli): Why is this? what part of it is necessary?
+      av1_set_frame_size(cpi, cm->width, cm->height);
     }
   }
+  if (allow_tpl) {
+    av1_tpl_setup_stats(cpi, 0, frame_params, frame_input);
+  }
 
   if (av1_encode(cpi, dest, frame_input, frame_params, frame_results) !=
       AOM_CODEC_OK) {
@@ -947,10 +943,9 @@
 
   // Set frame_input source to true source for psnr calculation.
   if (apply_filtering && is_psnr_calc_enabled(cpi)) {
-    cpi->source =
-        av1_scale_if_required(cm, source_kf_buffer, &cpi->scaled_source,
-                              cm->features.interp_filter, 0, 0);
-    cpi->unscaled_source = source_kf_buffer;
+    cpi->source = av1_scale_if_required(cm, source_buffer, &cpi->scaled_source,
+                                        cm->features.interp_filter, 0, 0);
+    cpi->unscaled_source = source_buffer;
   }
 
   return AOM_CODEC_OK;
@@ -1099,18 +1094,13 @@
     frame_params.show_existing_frame = 0;
   }
 
-  int code_arf = 0;
   struct lookahead_entry *source = NULL;
   struct lookahead_entry *last_source = NULL;
   if (frame_params.show_existing_frame) {
     source = av1_lookahead_pop(cpi->lookahead, flush, cpi->compressor_stage);
     frame_params.show_frame = 1;
   } else {
-    int show_existing_alt_ref = 0;
-    source = choose_frame_source(cpi, &code_arf, &flush, &last_source,
-                                 &frame_params, &show_existing_alt_ref);
-    if (gf_group->update_type[gf_group->index] == ARF_UPDATE)
-      cpi->show_existing_alt_ref = show_existing_alt_ref;
+    source = choose_frame_source(cpi, &flush, &last_source, &frame_params);
   }
 
   if (source == NULL) {  // If no source was found, we can't encode a frame.
@@ -1122,8 +1112,8 @@
 #endif
     return -1;
   }
-
-  frame_input.source = code_arf ? &cpi->alt_ref_buffer : &source->img;
+  // Source may be changed if temporal filtered later.
+  frame_input.source = &source->img;
   frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
   frame_input.ts_duration = source->ts_end - source->ts_start;
   // Save unfiltered source. It is used in av1_get_second_pass_params().
@@ -1275,29 +1265,7 @@
 
   if (!frame_params.show_existing_frame) {
     cm->quant_params.using_qmatrix = oxcf->q_cfg.using_qm;
-#if !CONFIG_REALTIME_ONLY
-    // Perform TPL when finished with arf filtering if arf is used.
-    // Otherwise perform it at the start of the gf group.
-    if (gf_cfg->lag_in_frames > 0 && !is_stat_generation_stage(cpi)) {
-      // Try performing tpl after arf is initialized.
-      int which_frame_tpl = cpi->gf_group.arf_index;
-      // TODO(any): If no arf in the GF group, we can do tpl at the first
-      // frame.
-      // TODO(bohanli): Unify it with tpl for kf.
-      if (which_frame_tpl < 0) {
-        which_frame_tpl = 1;
-      }
-      if (cpi->gf_group.index == which_frame_tpl &&
-          oxcf->algo_cfg.enable_tpl_model) {
-        av1_configure_buffer_updates(cpi, &frame_params.refresh_frame,
-                                     frame_update_type, 0);
-        av1_set_frame_size(cpi, cm->width, cm->height);
-        av1_tpl_setup_stats(cpi, 0, &frame_params, &frame_input);
-      }
-    }
-#endif
   }
-
 #if CONFIG_REALTIME_ONLY
   if (av1_encode(cpi, dest, &frame_input, &frame_params, &frame_results) !=
       AOM_CODEC_OK) {