From: jackychen Date: Wed, 7 Oct 2015 22:08:20 +0000 (-0700) Subject: VP9 denoiser: use skin map to improve denoising. X-Git-Tag: v1.5.0~60^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bafe1a2d67d85fc0a4b6fe5574aabac4503fbd28;p=libvpx VP9 denoiser: use skin map to improve denoising. Only denoise at small motion if it's a skin block. Change-Id: I6235cad9dd7f76ab40e7d9cdfe6180e619c20c6e --- diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index 4cac388ba..678e3123f 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c @@ -195,8 +195,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx, - int *motion_magnitude - ) { + int *motion_magnitude, + int is_skin) { int mv_col, mv_row; int sse_diff = ctx->zeromv_sse - ctx->newmv_sse; MV_REFERENCE_FRAME frame; @@ -214,6 +214,9 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser, saved_mbmi = *mbmi; + if (is_skin && *motion_magnitude > 16) + return COPY_BLOCK; + // If the best reference frame uses inter-prediction and there is enough of a // difference in sum-squared-error, use it. if (frame != INTRA_FRAME && @@ -313,18 +316,37 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, int mi_row, int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx) { int motion_magnitude = 0; - VP9_DENOISER_DECISION decision = FILTER_BLOCK; + VP9_DENOISER_DECISION decision = COPY_BLOCK; YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME]; YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y; uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col); uint8_t *mc_avg_start = block_start(mc_avg.y_buffer, mc_avg.y_stride, mi_row, mi_col); struct buf_2d src = mb->plane[0].src; + int is_skin = 0; + + if (bs <= BLOCK_16X16) { + // Take center pixel in block to determine is_skin. + const int y_width_shift = (4 << b_width_log2_lookup[bs]) >> 1; + const int y_height_shift = (4 << b_height_log2_lookup[bs]) >> 1; + const int uv_width_shift = y_width_shift >> 1; + const int uv_height_shift = y_height_shift >> 1; + const int stride = mb->plane[0].src.stride; + const int strideuv = mb->plane[1].src.stride; + const uint8_t ysource = + mb->plane[0].src.buf[y_height_shift * stride + y_width_shift]; + const uint8_t usource = + mb->plane[1].src.buf[uv_height_shift * strideuv + uv_width_shift]; + const uint8_t vsource = + mb->plane[2].src.buf[uv_height_shift * strideuv + uv_width_shift]; + is_skin = vp9_skin_pixel(ysource, usource, vsource); + } decision = perform_motion_compensation(denoiser, mb, bs, denoiser->increase_denoising, mi_row, mi_col, ctx, - &motion_magnitude); + &motion_magnitude, + is_skin); if (decision == FILTER_BLOCK) { decision = vp9_denoiser_filter(src.buf, src.stride, diff --git a/vp9/encoder/vp9_denoiser.h b/vp9/encoder/vp9_denoiser.h index c66fdf426..ec0b25e01 100644 --- a/vp9/encoder/vp9_denoiser.h +++ b/vp9/encoder/vp9_denoiser.h @@ -12,6 +12,7 @@ #define VP9_ENCODER_DENOISER_H_ #include "vp9/encoder/vp9_block.h" +#include "vp9/encoder/vp9_skin_detection.h" #include "vpx_scale/yv12config.h" #ifdef __cplusplus