Update the model used in delta-q mode 4 Use geometric mean of variance as the feature. Change-Id: Ie500a8fb75a624979d6d1b3076eaf9018186a8de
diff --git a/av1/encoder/allintra_vis.c b/av1/encoder/allintra_vis.c index 142bb6b..6db68ad 100644 --- a/av1/encoder/allintra_vis.c +++ b/av1/encoder/allintra_vis.c
@@ -480,11 +480,11 @@ void av1_init_mb_ur_var_buffer(AV1_COMP *cpi) { AV1_COMMON *cm = &cpi->common; - if (cpi->mb_variance) return; + if (cpi->mb_delta_q) return; - CHECK_MEM_ERROR(cm, cpi->mb_variance, + CHECK_MEM_ERROR(cm, cpi->mb_delta_q, aom_calloc(cpi->frame_info.mb_rows * cpi->frame_info.mb_cols, - sizeof(*cpi->mb_variance))); + sizeof(*cpi->mb_delta_q))); } void av1_set_mb_ur_variance(AV1_COMP *cpi) { @@ -502,6 +502,8 @@ const int num_rows = (mi_params->mi_rows + num_mi_h - 1) / num_mi_h; const int use_hbd = cpi->source->flags & YV12_FLAG_HIGHBITDEPTH; + double a = -23.06 * 4.0, b = 0.004065, c = 30.516 * 4.0; + int delta_q_avg = 0; // Loop through each SB block. for (int row = 0; row < num_rows; ++row) { for (int col = 0; col < num_cols; ++col) { @@ -522,18 +524,32 @@ buf.buf = y_buffer + row_offset_y * y_stride + col_offset_y; buf.stride = y_stride; + double block_variance; if (use_hbd) { - var += av1_high_get_sby_perpixel_variance(cpi, &buf, BLOCK_8X8, - xd->bd); + block_variance = av1_high_get_sby_perpixel_variance( + cpi, &buf, BLOCK_8X8, xd->bd); } else { - var += av1_get_sby_perpixel_variance(cpi, &buf, BLOCK_8X8); + block_variance = + av1_get_sby_perpixel_variance(cpi, &buf, BLOCK_8X8); } + block_variance = block_variance < 1.0 ? 1.0 : block_variance; + var += log(block_variance); num_of_var += 1.0; } } - var = var / num_of_var; - cpi->mb_variance[index] = var; + var = exp(var / num_of_var); + cpi->mb_delta_q[index] = (int)(a * exp(-b * var) + c + 0.5); + delta_q_avg += cpi->mb_delta_q[index]; + } + } + + delta_q_avg = (int)((double)delta_q_avg / (num_rows * num_cols) + 0.5); + + for (int row = 0; row < num_rows; ++row) { + for (int col = 0; col < num_cols; ++col) { + const int index = row * num_cols + col; + cpi->mb_delta_q[index] -= delta_q_avg; } } } @@ -549,21 +565,9 @@ const int num_mi_h = mi_size_high[bsize]; const int num_cols = (mi_params->mi_cols + num_mi_w - 1) / num_mi_w; const int index = (mi_row / num_mi_h) * num_cols + (mi_col / num_mi_w); - const double var = cpi->mb_variance[index]; + const int delta_q = cpi->mb_delta_q[index]; - const int beta = 80; - double a = -23.5 * 4.0, b = 0.00198, c = 30.65 * 4.0; - if (base_qindex <= beta) { - const double alpha = (double)base_qindex / (double)beta; - a *= alpha; - c *= alpha; - } else { - const double alpha = (double)(base_qindex - beta) / (double)(MAXQ - beta); - a = a - a * alpha; - c = c + ((double)MAXQ - c) * alpha; - } - - int qindex = (int)(a * exp(-b * var) + c + 0.5); + int qindex = base_qindex + delta_q; qindex = AOMMIN(qindex, MAXQ); qindex = AOMMAX(qindex, MINQ + 1);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 13e8f38..7df1a7f 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -1367,7 +1367,7 @@ sizeof(*cpi->consec_zero_mv))); cpi->mb_weber_stats = NULL; - cpi->mb_variance = NULL; + cpi->mb_delta_q = NULL; { const int bsize = BLOCK_16X16;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 074ff64..074e271 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -3148,9 +3148,9 @@ int64_t norm_wiener_variance; /*! - * Buffer to store MB variance. + * Buffer to store delta-q values for delta-q mode 4. */ - double *mb_variance; + int *mb_delta_q; /*! * Flag to indicate that current frame is dropped.
diff --git a/av1/encoder/encoder_alloc.h b/av1/encoder/encoder_alloc.h index 5eb485c..01719c5 100644 --- a/av1/encoder/encoder_alloc.h +++ b/av1/encoder/encoder_alloc.h
@@ -295,8 +295,8 @@ aom_free(cpi->mb_weber_stats); cpi->mb_weber_stats = NULL; - aom_free(cpi->mb_variance); - cpi->mb_variance = NULL; + aom_free(cpi->mb_delta_q); + cpi->mb_delta_q = NULL; } static AOM_INLINE void allocate_gradient_info_for_hog(