summaryrefslogtreecommitdiff
path: root/vp8
diff options
context:
space:
mode:
authorJackyChen <jackychen@google.com>2014-09-10 13:19:42 -0700
committerJackyChen <jackychen@google.com>2014-09-10 16:18:43 -0700
commit47380c335071517b57ebb5c67248831402562ead (patch)
treed90e3eb6dd0727837e4976a736f55683d5ce1b95 /vp8
parent0e66848081c19e75bf68ace1ac8f93220c4af68e (diff)
downloadlibvpx-47380c335071517b57ebb5c67248831402562ead.tar.gz
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
Diffstat (limited to 'vp8')
-rw-r--r--vp8/encoder/denoising.c42
1 files changed, 36 insertions, 6 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 {