diff options
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_denoiser.c | 49 | ||||
-rw-r--r-- | vp9/encoder/vp9_denoiser.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 47 | ||||
-rw-r--r-- | vp9/encoder/vp9_pickmode.c | 4 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.c | 2 |
5 files changed, 79 insertions, 25 deletions
diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index 9bc9f26c1..9eca2a229 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c @@ -316,13 +316,14 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser, return FILTER_BLOCK; } -void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, +void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx, VP9_DENOISER_DECISION *denoiser_decision) { int mv_col, mv_row; int motion_magnitude = 0; int zeromv_filter = 0; + VP9_DENOISER *denoiser = &cpi->denoiser; 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; @@ -331,21 +332,53 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, mi_row, mi_col); struct buf_2d src = mb->plane[0].src; int is_skin = 0; + mv_col = ctx->best_sse_mv.as_mv.col; + mv_row = ctx->best_sse_mv.as_mv.row; + motion_magnitude = mv_row * mv_row + mv_col * mv_col; - if (bs <= BLOCK_32X32 && denoiser->denoising_level >= kDenLow) { + if (cpi->use_skin_detection && + bs <= BLOCK_32X32 && + denoiser->denoising_level >= kDenLow) { + int motion_level = (motion_magnitude < 16) ? 0 : 1; + // If motion for current block is small/zero, compute consec_zeromv for + // skin detection (early exit in skin detection is done for large + // consec_zeromv when current block has small/zero motion). + int consec_zeromv = 0; + if (motion_level == 0) { + CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; + VP9_COMMON * const cm = &cpi->common; + int j, i; + // Loop through the 8x8 sub-blocks. + const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; + const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; + const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); + const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); + const int block_index = mi_row * cm->mi_cols + mi_col; + consec_zeromv = 100; + for (i = 0; i < ymis; i++) { + for (j = 0; j < xmis; j++) { + int bl_index = block_index + i * cm->mi_cols + j; + consec_zeromv = VPXMIN(cr->consec_zero_mv[bl_index], consec_zeromv); + // No need to keep checking 8x8 blocks if any of the sub-blocks + // has small consec_zeromv (since threshold for no_skin based on + // zero/small motion in skin detection is high, i.e, > 5). + if (consec_zeromv < 5) { + i = ymis; + j = xmis; + } + } + } + } + // TODO(marpan): Compute skin detection over sub-blocks. 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, - 0, - 0); + consec_zeromv, + motion_level); } - - mv_col = ctx->best_sse_mv.as_mv.col; - mv_row = ctx->best_sse_mv.as_mv.row; - motion_magnitude = mv_row * mv_row + mv_col * mv_col; if (!is_skin && denoiser->denoising_level == kDenHigh && motion_magnitude < 16) { diff --git a/vp9/encoder/vp9_denoiser.h b/vp9/encoder/vp9_denoiser.h index 9f13bd533..a0e201781 100644 --- a/vp9/encoder/vp9_denoiser.h +++ b/vp9/encoder/vp9_denoiser.h @@ -53,7 +53,7 @@ void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser, int refresh_last_frame, int resized); -void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, +void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx , VP9_DENOISER_DECISION *denoiser_decision); diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 84593836c..40b332ac8 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -772,36 +772,55 @@ static int choose_partitioning(VP9_COMP *cpi, vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_64X64); // Check if most of the superblock is skin content, and if so, force split - // to 32x32. Avoid checking superblocks on/near boundary and avoid low - // resolutons for now. + // to 32x32, and set x->sb_is_skin for use in mode selection. + // Avoid checking superblocks on/near boundary and avoid low resolutions. // Note superblock may still pick 64X64 if y_sad is very small // (i.e., y_sad < cpi->vbp_threshold_sad) below. For now leave this as is. x->sb_is_skin = 0; #if !CONFIG_VP9_HIGHBITDEPTH if (cpi->use_skin_detection && !low_res && (mi_col >= 8 && mi_col + 8 < cm->mi_cols && mi_row >= 8 && mi_row + 8 < cm->mi_rows)) { + CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; + int bl_index1, bl_index2, bl_index3; int num_16x16_skin = 0; int num_16x16_nonskin = 0; + int is_skin = 0; + int consec_zeromv = 0; uint8_t *ysignal = x->plane[0].src.buf; uint8_t *usignal = x->plane[1].src.buf; uint8_t *vsignal = x->plane[2].src.buf; int spuv = x->plane[1].src.stride; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - int is_skin = vp9_compute_skin_block(ysignal, - usignal, - vsignal, - sp, - spuv, - BLOCK_16X16, - 0, - 0); + const int block_index = mi_row * cm->mi_cols + mi_col; + const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; + const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; + const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); + const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); + // Loop through the 16x16 sub-blocks. + int j, i; + for (i = 0; i < ymis; i+=2) { + for (j = 0; j < xmis; j+=2) { + int bl_index = block_index + i * cm->mi_cols + j; + bl_index1 = bl_index + 1; + bl_index2 = bl_index + cm->mi_cols; + bl_index3 = bl_index2 + 1; + consec_zeromv = VPXMIN(cr->consec_zero_mv[bl_index], + VPXMIN(cr->consec_zero_mv[bl_index1], + VPXMIN(cr->consec_zero_mv[bl_index2], + cr->consec_zero_mv[bl_index3]))); + is_skin = vp9_compute_skin_block(ysignal, + usignal, + vsignal, + sp, + spuv, + BLOCK_16X16, + consec_zeromv, + 0); num_16x16_skin += is_skin; num_16x16_nonskin += (1 - is_skin); if (num_16x16_nonskin > 3) { // Exit loop if at least 4 of the 16x16 blocks are not skin. - i = 4; - j = 4; + i = ymis; + j = xmis; } ysignal += 16; usignal += 8; diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 3ea2ccd88..8b2e98549 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -1825,8 +1825,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (cpi->oxcf.noise_sensitivity > 0 && cpi->resize_pending == 0) { VP9_DENOISER_DECISION decision = COPY_BLOCK; - vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col, - VPXMAX(BLOCK_8X8, bsize), ctx, &decision); + vp9_denoiser_denoise(cpi, x, mi_row, mi_col, VPXMAX(BLOCK_8X8, bsize), + ctx, &decision); // If INTRA or GOLDEN reference was selected, re-evaluate ZEROMV on denoised // result. Only do this under noise conditions, and if rdcost of ZEROMV on // original source is not significantly higher than rdcost of best mode. diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index c014ca174..02be3c3f9 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -400,6 +400,8 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH; sf->tx_size_search_method = is_keyframe ? USE_LARGESTALL : USE_TX_8X8; sf->simple_model_rd_from_var = 1; + if (cpi->oxcf.rc_mode == VPX_VBR) + sf->mv.search_method = NSTEP; if (!is_keyframe) { int i; |