]> granicus.if.org Git - libvpx/commitdiff
vp8 denoiser: fix to zero_mv mode selection.
authorMarco Paniconi <marpan@google.com>
Tue, 27 May 2014 23:44:17 +0000 (16:44 -0700)
committerMarco Paniconi <marpan@google.com>
Wed, 28 May 2014 18:23:52 +0000 (11:23 -0700)
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

vp8/encoder/denoising.c

index 1e645fbdfff74cab4808812c4ccf49c98c5036ee..1ea6d9a595a77aa45a478be744b8151f4322adea 100644 (file)
@@ -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