Normalize SB QP scaling
Calculate the SB level statistics across the entire frame. Use
their geometric means for the frame level normalization.
Change-Id: I990b188ab9d8100f96c33c42e1c5305388c6a7a9
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index ce9fdcc..234acb0 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3132,7 +3132,39 @@
sizeof(*cpi->mb_wiener_variance)));
}
+static int get_var_perceptual_ai(AV1_COMP *const cpi, BLOCK_SIZE bsize,
+ int mi_row, int mi_col) {
+ AV1_COMMON *const cm = &cpi->common;
+ const int mi_wide = mi_size_wide[bsize];
+ const int mi_high = mi_size_high[bsize];
+
+ const int mi_step = mi_size_wide[BLOCK_16X16];
+ int sb_wiener_var = 0;
+ int mb_stride = cpi->frame_info.mb_cols;
+ int mb_count = 0;
+ int mb_wiener_var[64];
+
+ for (int row = mi_row; row < mi_row + mi_high; row += mi_step) {
+ for (int col = mi_col; col < mi_col + mi_wide; col += mi_step) {
+ if (row >= cm->mi_params.mi_rows || col >= cm->mi_params.mi_cols)
+ continue;
+
+ mb_wiener_var[mb_count] =
+ (int)cpi->mb_wiener_variance[(row / mi_step) * mb_stride +
+ (col / mi_step)];
+ ++mb_count;
+ }
+ }
+ qsort(mb_wiener_var, mb_count - 1, sizeof(*mb_wiener_var), qsort_comp);
+
+ sb_wiener_var = mb_wiener_var[mb_count / 3];
+ sb_wiener_var = AOMMAX(1, sb_wiener_var);
+
+ return sb_wiener_var;
+}
+
static void set_mb_wiener_variance(AV1_COMP *cpi) {
+ AV1_COMMON *const cm = &cpi->common;
uint8_t *buffer = cpi->source->y_buffer;
int buf_stride = cpi->source->y_stride;
ThreadData *td = &cpi->td;
@@ -3208,45 +3240,36 @@
}
}
- if (count) cpi->norm_wiener_variance /= count;
+ int sb_step = mi_size_wide[cm->seq_params->sb_size];
+ double sb_wiener_log = 0;
+ int sb_count = 0;
+
+ for (int mi_row = 0; mi_row < cm->mi_params.mi_rows; mi_row += sb_step) {
+ for (int mi_col = 0; mi_col < cm->mi_params.mi_cols; mi_col += sb_step) {
+ int sb_wiener_var =
+ get_var_perceptual_ai(cpi, cm->seq_params->sb_size, mi_row, mi_col);
+ sb_wiener_log += log(sb_wiener_var);
+ ++sb_count;
+ }
+ }
+
+ if (sb_count)
+ cpi->norm_wiener_variance = (int64_t)(exp(sb_wiener_log / sb_count));
cpi->norm_wiener_variance = AOMMAX(1, cpi->norm_wiener_variance);
}
int av1_get_sbq_perceptual_ai(AV1_COMP *const cpi, BLOCK_SIZE bsize, int mi_row,
int mi_col) {
AV1_COMMON *const cm = &cpi->common;
- const int mi_wide = mi_size_wide[bsize];
- const int mi_high = mi_size_high[bsize];
const int base_qindex = cm->quant_params.base_qindex;
-
- const int mi_step = mi_size_wide[BLOCK_16X16];
- int64_t sb_wiener_var;
- int mb_stride = cpi->frame_info.mb_cols;
- int mb_count = 0;
- int mb_wiener_var[64];
-
- for (int row = mi_row; row < mi_row + mi_high; row += mi_step) {
- for (int col = mi_col; col < mi_col + mi_wide; col += mi_step) {
- if (row >= cm->mi_params.mi_rows || col >= cm->mi_params.mi_cols)
- continue;
-
- mb_wiener_var[mb_count] =
- (int)cpi->mb_wiener_variance[(row / mi_step) * mb_stride +
- (col / mi_step)];
- ++mb_count;
- }
- }
- qsort(mb_wiener_var, mb_count - 1, sizeof(*mb_wiener_var), qsort_comp);
-
- sb_wiener_var = mb_wiener_var[mb_count / 2];
- sb_wiener_var = AOMMAX(1, sb_wiener_var);
-
+ int sb_wiener_var = get_var_perceptual_ai(cpi, bsize, mi_row, mi_col);
int offset = 0;
double beta = (double)cpi->norm_wiener_variance / sb_wiener_var;
offset = av1_get_deltaq_offset(cm->seq_params->bit_depth, base_qindex, beta);
+
const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
- offset = AOMMIN(offset, delta_q_info->delta_q_res * 9 - 1);
- offset = AOMMAX(offset, -delta_q_info->delta_q_res * 9 + 1);
+ offset = AOMMIN(offset, delta_q_info->delta_q_res * 20 - 1);
+ offset = AOMMAX(offset, -delta_q_info->delta_q_res * 20 + 1);
int qindex = cm->quant_params.base_qindex + offset;
qindex = AOMMIN(qindex, MAXQ);
qindex = AOMMAX(qindex, MINQ);
@@ -3436,8 +3459,10 @@
aom_clear_system_state();
- init_mb_wiener_var_buffer(cpi);
- set_mb_wiener_variance(cpi);
+ if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL_AI) {
+ init_mb_wiener_var_buffer(cpi);
+ set_mb_wiener_variance(cpi);
+ }
#if CONFIG_INTERNAL_STATS
memset(cpi->mode_chosen_counts, 0,