From a8b7c6aad3113745a391e3c24721ffe36f07e8d4 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 4 Jan 2016 16:48:15 -0800 Subject: [PATCH] vp9-skin detection: Refactoring. Add function to compute skin map for a given block, as its used in several places (cyclic refresh, noise estimation, and denoising). Change-Id: Ied622908df43b6927f7fafc6c019d1867f2a24eb --- vp9/encoder/vp9_aq_cyclicrefresh.c | 20 ++++++-------------- vp9/encoder/vp9_denoiser.c | 20 ++++++-------------- vp9/encoder/vp9_noise_estimate.c | 17 ++++++----------- vp9/encoder/vp9_skin_detection.c | 14 ++++++++++++++ vp9/encoder/vp9_skin_detection.h | 3 +++ 5 files changed, 35 insertions(+), 39 deletions(-) diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c index 7c71d9d57..63db214d1 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.c +++ b/vp9/encoder/vp9_aq_cyclicrefresh.c @@ -209,20 +209,12 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, if (refresh_this_block == 0 && bsize <= BLOCK_16X16 && cpi->oxcf.content != VP9E_CONTENT_SCREEN) { - // Take center pixel in block to determine is_skin. - const int y_width_shift = (4 << b_width_log2_lookup[bsize]) >> 1; - const int y_height_shift = (4 << b_height_log2_lookup[bsize]) >> 1; - const int uv_width_shift = y_width_shift >> 1; - const int uv_height_shift = y_height_shift >> 1; - const int stride = p[0].src.stride; - const int strideuv = p[1].src.stride; - const uint8_t ysource = - p[0].src.buf[y_height_shift * stride + y_width_shift]; - const uint8_t usource = - p[1].src.buf[uv_height_shift * strideuv + uv_width_shift]; - const uint8_t vsource = - p[2].src.buf[uv_height_shift * strideuv + uv_width_shift]; - is_skin = vp9_skin_pixel(ysource, usource, vsource); + is_skin = vp9_compute_skin_block(p[0].src.buf, + p[1].src.buf, + p[2].src.buf, + p[0].src.stride, + p[1].src.stride, + bsize); if (is_skin) refresh_this_block = 1; } diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index 93aa40ae9..6533902b3 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c @@ -333,20 +333,12 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, int is_skin = 0; if (bs <= BLOCK_16X16 && denoiser->denoising_level >= kDenLow) { - // 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); + is_skin = vp9_compute_skin_block(mb->plane[0].src.buf, + mb->plane[1].src.buf, + mb->plane[2].src.buf, + mb->plane[0].src.stride, + mb->plane[1].src.stride, + bs); } mv_col = ctx->best_sse_mv.as_mv.col; diff --git a/vp9/encoder/vp9_noise_estimate.c b/vp9/encoder/vp9_noise_estimate.c index 4befbb066..008a40afc 100644 --- a/vp9/encoder/vp9_noise_estimate.c +++ b/vp9/encoder/vp9_noise_estimate.c @@ -145,10 +145,6 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { const uint8_t *src_u = cpi->Source->u_buffer; const uint8_t *src_v = cpi->Source->v_buffer; const int src_uvstride = cpi->Source->uv_stride; - const int y_width_shift = (4 << b_width_log2_lookup[bsize]) >> 1; - const int y_height_shift = (4 << b_height_log2_lookup[bsize]) >> 1; - const int uv_width_shift = y_width_shift >> 1; - const int uv_height_shift = y_height_shift >> 1; int mi_row, mi_col; int num_low_motion = 0; int frame_low_motion = 1; @@ -173,13 +169,12 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { // been encoded as zero/low motion x (= thresh_consec_zeromv) frames // in a row. consec_zero_mv[] defined for 8x8 blocks, so consider all // 4 sub-blocks for 16x16 block. Also, avoid skin blocks. - const uint8_t ysource = - src_y[y_height_shift * src_ystride + y_width_shift]; - const uint8_t usource = - src_u[uv_height_shift * src_uvstride + uv_width_shift]; - const uint8_t vsource = - src_v[uv_height_shift * src_uvstride + uv_width_shift]; - int is_skin = vp9_skin_pixel(ysource, usource, vsource); + int is_skin = vp9_compute_skin_block(src_y, + src_u, + src_v, + src_ystride, + src_uvstride, + bsize); if (frame_low_motion && cr->consec_zero_mv[bl_index] > thresh_consec_zeromv && cr->consec_zero_mv[bl_index1] > thresh_consec_zeromv && diff --git a/vp9/encoder/vp9_skin_detection.c b/vp9/encoder/vp9_skin_detection.c index c2763b7da..0ca166536 100644 --- a/vp9/encoder/vp9_skin_detection.c +++ b/vp9/encoder/vp9_skin_detection.c @@ -48,6 +48,20 @@ int vp9_skin_pixel(const uint8_t y, const uint8_t cb, const uint8_t cr) { return (evaluate_skin_color_difference(cb, cr) < skin_threshold); } +int vp9_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, + int stride, int strideuv, int bsize) { + // Take center pixel in block to determine is_skin. + const int y_width_shift = (4 << b_width_log2_lookup[bsize]) >> 1; + const int y_height_shift = (4 << b_height_log2_lookup[bsize]) >> 1; + const int uv_width_shift = y_width_shift >> 1; + const int uv_height_shift = y_height_shift >> 1; + const uint8_t ysource = y[y_height_shift * stride + y_width_shift]; + const uint8_t usource = u[uv_height_shift * strideuv + uv_width_shift]; + const uint8_t vsource = v[uv_height_shift * strideuv + uv_width_shift]; + return vp9_skin_pixel(ysource, usource, vsource); +} + + #ifdef OUTPUT_YUV_SKINMAP // For viewing skin map on input source. void vp9_compute_skin_map(VP9_COMP *const cpi, FILE *yuv_skinmap_file) { diff --git a/vp9/encoder/vp9_skin_detection.h b/vp9/encoder/vp9_skin_detection.h index 0a87ef9f4..73f7c39d9 100644 --- a/vp9/encoder/vp9_skin_detection.h +++ b/vp9/encoder/vp9_skin_detection.h @@ -23,6 +23,9 @@ struct VP9_COMP; int vp9_skin_pixel(const uint8_t y, const uint8_t cb, const uint8_t cr); +int vp9_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, + int stride, int strideuv, int bsize); + #ifdef OUTPUT_YUV_SKINMAP // For viewing skin map on input source. void vp9_compute_skin_map(struct VP9_COMP *const cpi, FILE *yuv_skinmap_file);