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;
}