ref: 66bf68697591047c46543ecdb72da61e1d3dd62a
parent: 95f8b819626790945f4be387554e0fab866a39b4
parent: bafe1a2d67d85fc0a4b6fe5574aabac4503fbd28
author: Jacky Chen <[email protected]>
date: Thu Oct 8 17:02:46 EDT 2015
Merge "VP9 denoiser: use skin map to improve denoising."
--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -195,8 +195,8 @@
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 @@
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,7 +316,7 @@
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);
@@ -320,11 +323,30 @@
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,
--- 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