From 47380c335071517b57ebb5c67248831402562ead Mon Sep 17 00:00:00 2001 From: JackyChen Date: Wed, 10 Sep 2014 13:19:42 -0700 Subject: [PATCH] Fix the bug which made VP8 denoiser not bit-exact between C code and SSE code. This issue is found when the denoising mode is set to kDenoiserOnYUVAggressive. Updated the C code to make it the same with SSE version. I also changed several lines in VP9 denoiser for the code style. Change-Id: I640d48cf946fe8c6a400e6e252107501d1e226d3 --- vp8/encoder/denoising.c | 42 ++++++++++++++++++++++++++++++++------ vp9/encoder/vp9_denoiser.c | 6 +++--- vp9/encoder/vp9_denoiser.h | 2 +- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c index d4f68a9da..2f33d4ace 100644 --- a/vp8/encoder/denoising.c +++ b/vp8/encoder/denoising.c @@ -68,6 +68,10 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, int adj_val[3] = {3, 4, 6}; int shift_inc1 = 0; int shift_inc2 = 1; + int col_sum[16] = {0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}; /* If motion_magnitude is small, making the denoiser more aggressive by * increasing the adjustment for each level. Add another increment for * blocks that are labeled for increase denoising. */ @@ -98,11 +102,11 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, if (absdiff <= 3 + shift_inc1) { running_avg_y[c] = mc_running_avg_y[c]; - sum_diff += diff; + col_sum[c] += diff; } else { - if (absdiff >= 4 && absdiff <= 7) + if (absdiff >= 4 + shift_inc1 && absdiff <= 7) adjustment = adj_val[0]; else if (absdiff >= 8 && absdiff <= 15) adjustment = adj_val[1]; @@ -116,7 +120,7 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, else running_avg_y[c] = sig[c] + adjustment; - sum_diff += adjustment; + col_sum[c] += adjustment; } else { @@ -125,7 +129,7 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, else running_avg_y[c] = sig[c] - adjustment; - sum_diff -= adjustment; + col_sum[c] -= adjustment; } } } @@ -136,6 +140,23 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, running_avg_y += avg_y_stride; } + for (c = 0; c < 16; ++c) { + // Below we clip the value in the same way which SSE code use. + // When adopting aggressive denoiser, the adj_val for each pixel + // could be at most 8 (this is current max adjustment of the map). + // In SSE code, we calculate the sum of adj_val for + // the columns, so the sum could be upto 128(16 rows). However, + // the range of the value is -128 ~ 127 in SSE code, that's why + // we do this change in C code. + // We don't do this for UV denoiser, since there are only 8 rows, + // and max adjustments <= 8, so the sum of the columns will not + // exceed 64. + if (col_sum[c] >= 128) { + col_sum[c] = 127; + } + sum_diff += col_sum[c]; + } + sum_diff_thresh= SUM_DIFF_THRESHOLD; if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; if (abs(sum_diff) > sum_diff_thresh) { @@ -166,14 +187,14 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, running_avg_y[c] = 0; else running_avg_y[c] = running_avg_y[c] - adjustment; - sum_diff -= adjustment; + col_sum[c] -= adjustment; } else if (diff < 0) { // Bring denoised signal up. if (running_avg_y[c] + adjustment > 255) running_avg_y[c] = 255; else running_avg_y[c] = running_avg_y[c] + adjustment; - sum_diff += adjustment; + col_sum[c] += adjustment; } } // TODO(marpan): Check here if abs(sum_diff) has gone below the @@ -182,6 +203,15 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, mc_running_avg_y += mc_avg_y_stride; running_avg_y += avg_y_stride; } + + sum_diff = 0; + for (c = 0; c < 16; ++c) { + if (col_sum[c] >= 128) { + col_sum[c] = 127; + } + sum_diff += col_sum[c]; + } + if (abs(sum_diff) > sum_diff_thresh) return COPY_BLOCK; } else { diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index c4cf5eeb6..75b94499d 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c @@ -89,9 +89,9 @@ static VP9_DENOISER_DECISION denoiser_filter(const uint8_t *sig, int sig_stride, int total_adj = 0; int shift_inc = 1; - /* If motion_magnitude is small, making the denoiser more aggressive by - * increasing the adjustment for each level. Add another increment for - * blocks that are labeled for increase denoising. */ + // If motion_magnitude is small, making the denoiser more aggressive by + // increasing the adjustment for each level. Add another increment for + // blocks that are labeled for increase denoising. if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { if (increase_denoising) { shift_inc = 2; diff --git a/vp9/encoder/vp9_denoiser.h b/vp9/encoder/vp9_denoiser.h index a913add86..fa714b132 100644 --- a/vp9/encoder/vp9_denoiser.h +++ b/vp9/encoder/vp9_denoiser.h @@ -18,7 +18,7 @@ extern "C" { #endif -#define MOTION_MAGNITUDE_THRESHOLD (8*3) +#define MOTION_MAGNITUDE_THRESHOLD (8 * 3) typedef enum vp9_denoiser_decision { COPY_BLOCK, -- 2.40.0