Abstract wavelet energy calculations

The functions related to wavelet energy
calculation are abstracted.

Change-Id: Ie4de15bb3096fb8c437b597614fda8954c54faff
diff --git a/av1/encoder/aq_variance.c b/av1/encoder/aq_variance.c
index a73c77e..79bf9f8 100644
--- a/av1/encoder/aq_variance.c
+++ b/av1/encoder/aq_variance.c
@@ -154,15 +154,12 @@
   MACROBLOCKD *xd = &x->e_mbd;
   int stride = x->plane[0].src.stride;
   uint8_t *buf = x->plane[0].src.buf;
-  const int bw = MI_SIZE * mi_size_wide[bs];
-  const int bh = MI_SIZE * mi_size_high[bs];
+  const int num_8x8_cols = block_size_wide[bs] / 8;
+  const int num_8x8_rows = block_size_high[bs] / 8;
   const int hbd = is_cur_buf_hbd(xd);
 
-  int var = 0;
-  for (int r = 0; r < bh; r += 8)
-    for (int c = 0; c < bw; c += 8) {
-      var += av1_haar_ac_sad_8x8_uint8_input(buf + c + r * stride, stride, hbd);
-    }
+  int64_t var = av1_haar_ac_sad_mxn_uint8_input(buf, stride, hbd, num_8x8_rows,
+                                                num_8x8_cols);
 
   return (unsigned int)((uint64_t)var * 256) >> num_pels_log2_lookup[bs];
 }
diff --git a/av1/encoder/dwt.c b/av1/encoder/dwt.c
index b5ed4a3..5dfbcb6 100644
--- a/av1/encoder/dwt.c
+++ b/av1/encoder/dwt.c
@@ -147,9 +147,23 @@
   return sse - (uint32_t)(((int64_t)sum * sum) / (bw * bh));
 }
 
-int av1_haar_ac_sad_8x8_uint8_input(const uint8_t *input, int stride, int hbd) {
+static int haar_ac_sad_8x8_uint8_input(const uint8_t *input, int stride,
+                                       int hbd) {
   tran_low_t output[64];
 
   av1_fdwt8x8_uint8_input_c(input, output, stride, hbd);
   return av1_haar_ac_sad(output, 8, 8, 8);
 }
+
+int64_t av1_haar_ac_sad_mxn_uint8_input(const uint8_t *input, int stride,
+                                        int hbd, int num_8x8_rows,
+                                        int num_8x8_cols) {
+  int64_t wavelet_energy = 0;
+  for (int r8 = 0; r8 < num_8x8_rows; ++r8) {
+    for (int c8 = 0; c8 < num_8x8_cols; ++c8) {
+      wavelet_energy += haar_ac_sad_8x8_uint8_input(
+          input + c8 * 8 + r8 * 8 * stride, stride, hbd);
+    }
+  }
+  return wavelet_energy;
+}
diff --git a/av1/encoder/dwt.h b/av1/encoder/dwt.h
index 1bd32ed..443b6bc 100644
--- a/av1/encoder/dwt.h
+++ b/av1/encoder/dwt.h
@@ -19,6 +19,9 @@
 
 void av1_fdwt8x8_uint8_input_c(const uint8_t *input, tran_low_t *output,
                                int stride, int hbd);
-int av1_haar_ac_sad_8x8_uint8_input(const uint8_t *input, int stride, int hbd);
+
+int64_t av1_haar_ac_sad_mxn_uint8_input(const uint8_t *input, int stride,
+                                        int hbd, int num_8x8_rows,
+                                        int num_8x8_cols);
 
 #endif  // AOM_AV1_ENCODER_DWT_H_
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index afeec65..41122ef 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3051,6 +3051,42 @@
   return err;
 }
 
+#if !CONFIG_REALTIME_ONLY
+static void calculate_frame_avg_haar_energy(AV1_COMP *cpi) {
+  TWO_PASS *const twopass = &cpi->ppi->twopass;
+  const FIRSTPASS_STATS *const total_stats =
+      twopass->stats_buf_ctx->total_stats;
+
+  if (is_one_pass_rt_params(cpi) ||
+      (cpi->oxcf.q_cfg.deltaq_mode != DELTA_Q_PERCEPTUAL) ||
+      (is_fp_wavelet_energy_invalid(total_stats) == 0))
+    return;
+
+  const int num_mbs = (cpi->oxcf.resize_cfg.resize_mode != RESIZE_NONE)
+                          ? cpi->initial_mbs
+                          : cpi->common.mi_params.MBs;
+  const YV12_BUFFER_CONFIG *const unfiltered_source = cpi->unfiltered_source;
+  const uint8_t *const src = unfiltered_source->y_buffer;
+  const int hbd = unfiltered_source->flags & YV12_FLAG_HIGHBITDEPTH;
+  const int stride = unfiltered_source->y_stride;
+  const BLOCK_SIZE fp_block_size =
+      get_fp_block_size(cpi->is_screen_content_type);
+  const int fp_block_size_width = block_size_wide[fp_block_size];
+  const int fp_block_size_height = block_size_high[fp_block_size];
+  const int num_unit_cols =
+      get_num_blocks(unfiltered_source->y_crop_width, fp_block_size_width);
+  const int num_unit_rows =
+      get_num_blocks(unfiltered_source->y_crop_height, fp_block_size_height);
+  const int num_8x8_cols = num_unit_cols * (fp_block_size_width / 8);
+  const int num_8x8_rows = num_unit_rows * (fp_block_size_height / 8);
+  int64_t frame_avg_wavelet_energy = av1_haar_ac_sad_mxn_uint8_input(
+      src, stride, hbd, num_8x8_rows, num_8x8_cols);
+
+  twopass->frame_avg_haar_energy =
+      log(((double)frame_avg_wavelet_energy / num_mbs) + 1.0);
+}
+#endif
+
 extern void av1_print_frame_contexts(const FRAME_CONTEXT *fc,
                                      const char *filename);
 
@@ -3088,41 +3124,7 @@
   }
 
 #if !CONFIG_REALTIME_ONLY
-  if (is_one_pass_rt_params(cpi) == 0) {
-    TWO_PASS *const twopass = &cpi->ppi->twopass;
-    const FIRSTPASS_STATS *const total_stats =
-        twopass->stats_buf_ctx->total_stats;
-    if ((oxcf->q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL) &&
-        is_fp_wavelet_energy_invalid(total_stats)) {
-      const int num_mbs = (oxcf->resize_cfg.resize_mode != RESIZE_NONE)
-                              ? cpi->initial_mbs
-                              : cm->mi_params.MBs;
-      const YV12_BUFFER_CONFIG *const unfiltered_source =
-          cpi->unfiltered_source;
-      const uint8_t *const src = unfiltered_source->y_buffer;
-      const int hbd = unfiltered_source->flags & YV12_FLAG_HIGHBITDEPTH;
-      const int stride = unfiltered_source->y_stride;
-      const BLOCK_SIZE fp_block_size =
-          get_fp_block_size(cpi->is_screen_content_type);
-      const int fp_block_size_width = block_size_wide[fp_block_size];
-      const int fp_block_size_height = block_size_high[fp_block_size];
-      const int num_unit_cols =
-          get_num_blocks(unfiltered_source->y_crop_width, fp_block_size_width);
-      const int num_unit_rows = get_num_blocks(unfiltered_source->y_crop_height,
-                                               fp_block_size_height);
-      const int num_8x8_cols = num_unit_cols * (fp_block_size_width / 8);
-      const int num_8x8_rows = num_unit_rows * (fp_block_size_height / 8);
-      int64_t frame_avg_wavelet_energy = 0;
-      for (int r8 = 0; r8 < num_8x8_rows; ++r8) {
-        for (int c8 = 0; c8 < num_8x8_cols; ++c8) {
-          frame_avg_wavelet_energy += av1_haar_ac_sad_8x8_uint8_input(
-              src + c8 * 8 + r8 * 8 * stride, stride, hbd);
-        }
-      }
-      twopass->frame_avg_haar_energy =
-          log(((double)frame_avg_wavelet_energy / num_mbs) + 1.0);
-    }
-  }
+  calculate_frame_avg_haar_energy(cpi);
 #endif
 
   // frame type has been decided outside of this function call
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 900cfa0..bd43bef 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -507,12 +507,8 @@
     const int num_8x8_rows = block_size_high[fp_block_size] / 8;
     const int num_8x8_cols = block_size_wide[fp_block_size] / 8;
     const uint8_t *buf = x->plane[0].src.buf;
-    for (int r8 = 0; r8 < num_8x8_rows; ++r8) {
-      for (int c8 = 0; c8 < num_8x8_cols; ++c8) {
-        stats->frame_avg_wavelet_energy += av1_haar_ac_sad_8x8_uint8_input(
-            buf + c8 * 8 + r8 * 8 * stride, stride, hbd);
-      }
-    }
+    stats->frame_avg_wavelet_energy += av1_haar_ac_sad_mxn_uint8_input(
+        buf, stride, hbd, num_8x8_rows, num_8x8_cols);
   } else {
     stats->frame_avg_wavelet_energy = INVALID_FP_STATS_TO_PREDICT_FLAT_GOP;
   }