From 6da66e111495ca03e5710f9cec3da3e97718367e Mon Sep 17 00:00:00 2001 From: Marco Paniconi <marpan@google.com> Date: Fri, 16 May 2014 14:32:04 -0700 Subject: [PATCH] vp8: Add increase_denoising parameter to denoiser. Change-Id: I96ed73e109c4f89dd06f3583cf7ecf9277401fae --- vp8/common/rtcd_defs.pl | 2 +- vp8/encoder/arm/neon/denoising_neon.c | 3 +- vp8/encoder/block.h | 1 + vp8/encoder/denoising.c | 41 +++++++++++++++++++-------- vp8/encoder/denoising.h | 1 + vp8/encoder/pickinter.c | 1 + vp8/encoder/x86/denoising_sse2.c | 15 +++++++--- 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/vp8/common/rtcd_defs.pl b/vp8/common/rtcd_defs.pl index eb5de47dc3..cbfd76a8d1 100644 --- a/vp8/common/rtcd_defs.pl +++ b/vp8/common/rtcd_defs.pl @@ -552,7 +552,7 @@ $vp8_yv12_copy_partial_frame_neon_asm=vp8_yv12_copy_partial_frame_neon; # Denoiser filter # if (vpx_config("CONFIG_TEMPORAL_DENOISING") eq "yes") { - add_proto qw/int vp8_denoiser_filter/, "unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude"; + add_proto qw/int vp8_denoiser_filter/, "unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising"; specialize qw/vp8_denoiser_filter sse2 neon/; } diff --git a/vp8/encoder/arm/neon/denoising_neon.c b/vp8/encoder/arm/neon/denoising_neon.c index 1bebe8fbad..32ce65abf4 100644 --- a/vp8/encoder/arm/neon/denoising_neon.c +++ b/vp8/encoder/arm/neon/denoising_neon.c @@ -50,7 +50,8 @@ int vp8_denoiser_filter_neon(unsigned char *mc_running_avg_y, unsigned char *running_avg_y, int running_avg_y_stride, unsigned char *sig, int sig_stride, - unsigned int motion_magnitude) { + unsigned int motion_magnitude, + int increase_denoising) { /* If motion_magnitude is small, making the denoiser more aggressive by * increasing the adjustment for each level, level1 adjustment is * increased, the deltas stay the same. diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h index dd733e55a9..34879cf2ab 100644 --- a/vp8/encoder/block.h +++ b/vp8/encoder/block.h @@ -125,6 +125,7 @@ typedef struct macroblock int optimize; int q_index; + int increase_denoising; #if CONFIG_TEMPORAL_DENOISING MB_PREDICTION_MODE best_sse_inter_mode; diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c index bfce28052d..1e645fbdff 100644 --- a/vp8/encoder/denoising.c +++ b/vp8/encoder/denoising.c @@ -21,6 +21,7 @@ static const unsigned int NOISE_MOTION_THRESHOLD = 25 * 25; */ static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20; static const unsigned int SSE_THRESHOLD = 16 * 16 * 40; +static const unsigned int SSE_THRESHOLD_HIGH = 16 * 16 * 60; /* * The filter function was modified to reduce the computational complexity. @@ -54,20 +55,29 @@ static const unsigned int SSE_THRESHOLD = 16 * 16 * 40; int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, - unsigned int motion_magnitude) + unsigned int motion_magnitude, + int increase_denoising) { unsigned char *running_avg_y_start = running_avg_y; unsigned char *sig_start = sig; - int r, c, i; + int sum_diff_thresh; + int r, c; int sum_diff = 0; int adj_val[3] = {3, 4, 6}; - + int shift_inc1 = 0; + int shift_inc2 = 1; /* If motion_magnitude is small, making the denoiser more aggressive by - * increasing the adjustment for each level. */ + * increasing the adjustment for each level. Add another increment for + * blocks that are labeled for increase denoising. */ if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { - for (i = 0; i < 3; i++) - adj_val[i] += 1; + if (increase_denoising) { + shift_inc1 = 1; + shift_inc2 = 2; + } + adj_val[0] += shift_inc2; + adj_val[1] += shift_inc2; + adj_val[2] += shift_inc2; } for (r = 0; r < 16; ++r) @@ -81,8 +91,9 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, diff = mc_running_avg_y[c] - sig[c]; absdiff = abs(diff); - /* When |diff| < 4, use pixel value from last denoised raw. */ - if (absdiff <= 3) + // When |diff| <= |3 + shift_inc1|, use pixel value from + // last denoised raw. + if (absdiff <= 3 + shift_inc1) { running_avg_y[c] = mc_running_avg_y[c]; sum_diff += diff; @@ -123,7 +134,9 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, running_avg_y += avg_y_stride; } - if (abs(sum_diff) > SUM_DIFF_THRESHOLD) + sum_diff_thresh= SUM_DIFF_THRESHOLD; + if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; + if (abs(sum_diff) > sum_diff_thresh) return COPY_BLOCK; vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); @@ -187,7 +200,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, int mv_row; int mv_col; unsigned int motion_magnitude2; - + unsigned int sse_thresh; MV_REFERENCE_FRAME frame = x->best_reference_frame; MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; @@ -272,7 +285,10 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, mv_row = x->best_sse_mv.as_mv.row; mv_col = x->best_sse_mv.as_mv.col; motion_magnitude2 = mv_row * mv_row + mv_col * mv_col; - if (best_sse > SSE_THRESHOLD || motion_magnitude2 + sse_thresh = SSE_THRESHOLD; + if (x->increase_denoising) sse_thresh = SSE_THRESHOLD_HIGH; + + if (best_sse > sse_thresh || motion_magnitude2 > 8 * NOISE_MOTION_THRESHOLD) { decision = COPY_BLOCK; @@ -290,7 +306,8 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, /* Filter. */ decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride, running_avg_y, avg_y_stride, - x->thismb, 16, motion_magnitude2); + x->thismb, 16, motion_magnitude2, + x->increase_denoising); } if (decision == COPY_BLOCK) { diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h index cc9913afa2..ae744d2efc 100644 --- a/vp8/encoder/denoising.h +++ b/vp8/encoder/denoising.h @@ -18,6 +18,7 @@ extern "C" { #endif #define SUM_DIFF_THRESHOLD (16 * 16 * 2) +#define SUM_DIFF_THRESHOLD_HIGH (16 * 16 * 3) #define MOTION_MAGNITUDE_THRESHOLD (8*3) enum vp8_denoiser_decision diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index 39a3baf10b..cf6a82f5a8 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -1177,6 +1177,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, x->best_reference_frame = best_mbmode.ref_frame; best_sse = best_rd_sse; } + x->increase_denoising = 0; vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, recon_yoffset, recon_uvoffset); diff --git a/vp8/encoder/x86/denoising_sse2.c b/vp8/encoder/x86/denoising_sse2.c index d1f76b2cbd..5112f891e9 100644 --- a/vp8/encoder/x86/denoising_sse2.c +++ b/vp8/encoder/x86/denoising_sse2.c @@ -26,19 +26,24 @@ int vp8_denoiser_filter_sse2(unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, - unsigned int motion_magnitude) + unsigned int motion_magnitude, + int increase_denoising) { unsigned char *running_avg_y_start = running_avg_y; unsigned char *sig_start = sig; + int sum_diff_thresh; int r; + int shift_inc = (increase_denoising && + motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 1 : 0; __m128i acc_diff = _mm_setzero_si128(); const __m128i k_0 = _mm_setzero_si128(); - const __m128i k_4 = _mm_set1_epi8(4); + const __m128i k_4 = _mm_set1_epi8(4 + shift_inc); const __m128i k_8 = _mm_set1_epi8(8); const __m128i k_16 = _mm_set1_epi8(16); /* Modify each level's adjustment according to motion_magnitude. */ const __m128i l3 = _mm_set1_epi8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 7 : 6); + (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? + 7 + shift_inc : 6); /* Difference between level 3 and level 2 is 2. */ const __m128i l32 = _mm_set1_epi8(2); /* Difference between level 2 and level 1 is 1. */ @@ -105,7 +110,9 @@ int vp8_denoiser_filter_sse2(unsigned char *mc_running_avg_y, + s.e[6] + s.e[7] + s.e[8] + s.e[9] + s.e[10] + s.e[11] + s.e[12] + s.e[13] + s.e[14] + s.e[15]; - if (abs(sum_diff) > SUM_DIFF_THRESHOLD) + sum_diff_thresh = SUM_DIFF_THRESHOLD; + if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; + if (abs(sum_diff) > sum_diff_thresh) { return COPY_BLOCK; } -- GitLab