ref: 609e91f9b7634f0fffef385cd0bccd18ab34ae92
parent: debd0485311e455e9aa4394fb0586769704c06b3
author: Marco Paniconi <marpan@google.com>
date: Tue May 27 12:44:17 EDT 2014
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
--- a/vp8/encoder/denoising.c
+++ b/vp8/encoder/denoising.c
@@ -201,6 +201,7 @@
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 @@
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