From b28fc490aa459e0d5a23067d863ab45af3fd2048 Mon Sep 17 00:00:00 2001 From: Jerome Jiang Date: Wed, 21 Jun 2017 15:02:31 -0700 Subject: vp8: Compute skinmap only once before encoding. Get ready for other uses (i.e. cyclic refresh). Then use it when needed. Change-Id: Id0519a9921045e5fb7f3badb54e9f04e903f28f9 --- vp8/encoder/onyx_if.c | 37 +++++++++++++++++++++++++++++++++++++ vp8/encoder/onyx_int.h | 2 ++ vp8/encoder/pickinter.c | 4 +--- 3 files changed, 40 insertions(+), 3 deletions(-) (limited to 'vp8/encoder') diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 66d441f0c..7eaff5a0c 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -620,6 +620,37 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) { set_segment_data(cpi, &feature_data[0][0], SEGMENT_DELTADATA); } +static void compute_skin_map(VP8_COMP *cpi) { + int mb_row, mb_col, num_bl; + VP8_COMMON *cm = &cpi->common; + const uint8_t *src_y = cpi->Source->y_buffer; + const uint8_t *src_u = cpi->Source->u_buffer; + const uint8_t *src_v = cpi->Source->v_buffer; + const int src_ystride = cpi->Source->y_stride; + const int src_uvstride = cpi->Source->uv_stride; + + const SKIN_DETECTION_BLOCK_SIZE bsize = + (cm->Width * cm->Height <= 352 * 288) ? SKIN_8X8 : SKIN_16X16; + int offset = 0; + for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { + num_bl = 0; + for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { + const int bl_index = mb_row * cm->mb_cols + mb_col; + cpi->skin_map[offset] = + vp8_compute_skin_block(src_y, src_u, src_v, src_ystride, src_uvstride, + bsize, cpi->consec_zero_last[bl_index], 0); + num_bl++; + offset++; + src_y += 16; + src_u += 8; + src_v += 8; + } + src_y += (src_ystride << 4) - (num_bl << 4); + src_u += (src_uvstride << 3) - (num_bl << 3); + src_v += (src_uvstride << 3) - (num_bl << 3); + } +} + static void set_default_lf_deltas(VP8_COMP *cpi) { cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 1; cpi->mb.e_mbd.mode_ref_lf_delta_update = 1; @@ -1861,6 +1892,9 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) { cpi->cyclic_refresh_map = (signed char *)NULL; } + CHECK_MEM_ERROR(cpi->skin_map, vpx_calloc(cm->mb_rows * cm->mb_cols, + sizeof(cpi->skin_map[0]))); + CHECK_MEM_ERROR(cpi->consec_zero_last, vpx_calloc(cm->mb_rows * cm->mb_cols, 1)); CHECK_MEM_ERROR(cpi->consec_zero_last_mvbias, @@ -2291,6 +2325,7 @@ void vp8_remove_compressor(VP8_COMP **ptr) { dealloc_compressor_data(cpi); vpx_free(cpi->mb.ss); vpx_free(cpi->tok); + vpx_free(cpi->skin_map); vpx_free(cpi->cyclic_refresh_map); vpx_free(cpi->consec_zero_last); vpx_free(cpi->consec_zero_last_mvbias); @@ -3770,6 +3805,8 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, } #endif + compute_skin_map(cpi); + /* Setup background Q adjustment for error resilient mode. * For multi-layer encodes only enable this for the base layer. */ diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index fe775064a..53e8be84f 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -471,6 +471,8 @@ typedef struct VP8_COMP { int zeromv_count; int lf_zeromv_pct; + unsigned char *skin_map; + unsigned char *segmentation_map; signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; int segment_encode_breakout[MAX_MB_SEGMENTS]; diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index d399839dd..a9943eb6a 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -691,9 +691,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, x->is_skin = 0; if (!cpi->oxcf.screen_content_mode) { int block_index = mb_row * cpi->common.mb_cols + mb_col; - x->is_skin = vp8_compute_skin_block( - x->src.y_buffer, x->src.u_buffer, x->src.v_buffer, x->src.y_stride, - x->src.uv_stride, SKIN_16X16, cpi->consec_zero_last[block_index], 0); + x->is_skin = cpi->skin_map[block_index]; } #if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { -- cgit v1.2.3