From: Marco Paniconi Date: Tue, 27 May 2014 23:44:17 +0000 (-0700) Subject: vp8 denoiser: fix to zero_mv mode selection. X-Git-Tag: v1.4.0~1475^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=609e91f9b7634f0fffef385cd0bccd18ab34ae92;p=libvpx vp8 denoiser: fix to zero_mv mode selection. In the current logic, if the sse for zero motion is smaller than the sse for new_mv (i.e., best_sse), we may still end up using the non-zero mv for denoising (if the magnitude of new_mv is above threshold). This can happen for very noisy content, and can lead to artifacts. This change ensures that we always use zero_mv (over new_mv) for denoisng if sse_zero_mv <= best_sse. Change-Id: I8ef9294d837b077013b77a46c9a71d17c648b48a --- diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c index 1e645fbdf..1ea6d9a59 100644 --- a/vp8/encoder/denoising.c +++ b/vp8/encoder/denoising.c @@ -201,6 +201,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, int mv_col; unsigned int motion_magnitude2; unsigned int sse_thresh; + int sse_diff_thresh = 0; MV_REFERENCE_FRAME frame = x->best_reference_frame; MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; @@ -225,11 +226,16 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, mbmi->need_to_clamp_mvs = x->need_to_clamp_best_mvs; mv_col = x->best_sse_mv.as_mv.col; mv_row = x->best_sse_mv.as_mv.row; + // Bias to zero_mv if small amount of motion. + // Note sse_diff_thresh is intialized to zero, so this ensures + // we will always choose zero_mv for denoising if + // zero_mv_see <= best_sse (i.e., sse_diff <= 0). + if ((unsigned int)(mv_row * mv_row + mv_col * mv_col) + <= NOISE_MOTION_THRESHOLD) + sse_diff_thresh = (int)SSE_DIFF_THRESHOLD; if (frame == INTRA_FRAME || - ((unsigned int)(mv_row *mv_row + mv_col *mv_col) - <= NOISE_MOTION_THRESHOLD && - sse_diff < (int)SSE_DIFF_THRESHOLD)) + sse_diff <= sse_diff_thresh) { /* * Handle intra blocks as referring to last frame with zero motion