From c2bd46bf455a4986756f75e82a08063e4d43d2a2 Mon Sep 17 00:00:00 2001 From: John Koleszar <jkoleszar@google.com> Date: Thu, 11 Apr 2013 11:14:31 -0700 Subject: [PATCH] tokenize: convert skippable functions Use the common block walker to calculate skippability. Change-Id: I6721e42f065df237426c91c1d871ec226ba7cdcb --- vp9/common/vp9_blockd.h | 15 +++++ vp9/encoder/vp9_rdopt.c | 28 ++++---- vp9/encoder/vp9_tokenize.c | 131 ++++++++----------------------------- vp9/encoder/vp9_tokenize.h | 12 +--- 4 files changed, 59 insertions(+), 127 deletions(-) diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 2987019595..29d1bbc766 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -831,4 +831,19 @@ static INLINE void foreach_transformed_block( } } +static INLINE void foreach_transformed_block_uv( + const MACROBLOCKD* const xd, int block_size, + foreach_transformed_block_visitor visit, void *arg) { + const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode; + const int is_split = + xd->mode_info_context->mbmi.txfm_size == TX_8X8 && + (mode == I8X8_PRED || mode == SPLITMV); + int plane; + + for (plane = 1; plane < MAX_MB_PLANE; plane++) { + foreach_transformed_block_in_plane(xd, block_size, plane, is_split, + visit, arg); + } +} + #endif // VP9_COMMON_VP9_BLOCKD_H_ diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 13df98801a..52a21c5a4e 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -766,7 +766,7 @@ static void super_block_yrd_4x4(VP9_COMMON *const cm, MACROBLOCK *x, *distortion = vp9_sb_block_error_c(x->coeff, xd->plane[0].dqcoeff, 16 << (bwl + bhl), 2); *rate = rdcost_sby_4x4(cm, x, bsize); - *skippable = vp9_sby_is_skippable(xd, bsize, TX_4X4); + *skippable = vp9_sby_is_skippable(xd, bsize); } static int rdcost_sby_8x8(VP9_COMMON *const cm, MACROBLOCK *x, @@ -806,7 +806,7 @@ static void super_block_yrd_8x8(VP9_COMMON *const cm, MACROBLOCK *x, *distortion = vp9_sb_block_error_c(x->coeff, xd->plane[0].dqcoeff, 64 << (bhl + bwl), 2); *rate = rdcost_sby_8x8(cm, x, bsize); - *skippable = vp9_sby_is_skippable(xd, bsize, TX_8X8); + *skippable = vp9_sby_is_skippable(xd, bsize); } static int rdcost_sby_16x16(VP9_COMMON *const cm, MACROBLOCK *x, @@ -844,7 +844,7 @@ static void super_block_yrd_16x16(VP9_COMMON *const cm, MACROBLOCK *x, *distortion = vp9_sb_block_error_c(x->coeff, xd->plane[0].dqcoeff, 256 << (bwl + bhl), 2); *rate = rdcost_sby_16x16(cm, x, bsize); - *skippable = vp9_sby_is_skippable(xd, bsize, TX_16X16); + *skippable = vp9_sby_is_skippable(xd, bsize); } static int rdcost_sby_32x32(VP9_COMMON *const cm, MACROBLOCK *x, @@ -884,7 +884,7 @@ static void super_block_yrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x, *distortion = vp9_sb_block_error_c(x->coeff, xd->plane[0].dqcoeff, 1024 << (bwl + bhl), 0); *rate = rdcost_sby_32x32(cm, x, bsize); - *skippable = vp9_sby_is_skippable(xd, bsize, TX_32X32); + *skippable = vp9_sby_is_skippable(xd, bsize); } static void super_block_yrd(VP9_COMP *cpi, @@ -1446,7 +1446,7 @@ static void super_block_uvrd_4x4(VP9_COMMON *const cm, MACROBLOCK *x, xd->plane[1].dqcoeff, xd->plane[2].dqcoeff, 32 << (bwl + bhl - 2), 2); - *skip = vp9_sbuv_is_skippable(xd, bsize, TX_4X4); + *skip = vp9_sbuv_is_skippable(xd, bsize); } static int rd_cost_sbuv_8x8(VP9_COMMON *const cm, MACROBLOCK *x, @@ -1491,7 +1491,7 @@ static void super_block_uvrd_8x8(VP9_COMMON *const cm, MACROBLOCK *x, xd->plane[1].dqcoeff, xd->plane[2].dqcoeff, 128 << (bwl + bhl - 2), 2); - *skip = vp9_sbuv_is_skippable(xd, bsize, TX_8X8); + *skip = vp9_sbuv_is_skippable(xd, bsize); } static int rd_cost_sbuv_16x16(VP9_COMMON *const cm, MACROBLOCK *x, @@ -1536,7 +1536,7 @@ static void super_block_uvrd_16x16(VP9_COMMON *const cm, MACROBLOCK *x, xd->plane[1].dqcoeff, xd->plane[2].dqcoeff, 512 << (bwl + bhl - 2), 2); - *skip = vp9_sbuv_is_skippable(xd, bsize, TX_16X16); + *skip = vp9_sbuv_is_skippable(xd, bsize); } static int rd_cost_sbuv_32x32(VP9_COMMON *const cm, MACROBLOCK *x, @@ -1582,7 +1582,7 @@ static void super_block_uvrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x, xd->plane[1].dqcoeff, xd->plane[2].dqcoeff, 2048 << (bwl + bhl - 2), 0); - *skip = vp9_sbuv_is_skippable(xd, bsize, TX_32X32); + *skip = vp9_sbuv_is_skippable(xd, bsize); } static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x, @@ -2507,13 +2507,6 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, x->e_mbd.plane[0].eobs[i] = bsi.eobs[i]; } - *returntotrate = bsi.r; - *returndistortion = bsi.d; - *returnyrate = bsi.segment_yrate; - *skippable = bsi.txfm_size == TX_4X4 ? - vp9_mby_is_skippable_4x4(&x->e_mbd) : - vp9_mby_is_skippable_8x8(&x->e_mbd); - /* save partitions */ mbmi->txfm_size = bsi.txfm_size; mbmi->partitioning = bsi.segment_num; @@ -2536,6 +2529,11 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, if (mbmi->second_ref_frame > 0) x->partition_info->bmi[15].second_mv.as_int = bsi.second_mvs[15].as_int; + *returntotrate = bsi.r; + *returndistortion = bsi.d; + *returnyrate = bsi.segment_yrate; + *skippable = vp9_sby_is_skippable(&x->e_mbd, BLOCK_SIZE_MB16X16); + return (int)(bsi.segment_rd); } diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c index e85f85193c..4ad04ecefe 100644 --- a/vp9/encoder/vp9_tokenize.c +++ b/vp9/encoder/vp9_tokenize.c @@ -339,95 +339,38 @@ static void tokenize_b(VP9_COMP *cpi, } } -int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd) { - int skip = 1; - int i = 0; - - for (i = 0; i < 16; i++) - skip &= (!xd->plane[0].eobs[i]); - - return skip; -} - -int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) { - int skip = 1; - int i; - - for (i = 0; i < 4; i++) - skip &= (!xd->plane[1].eobs[i]); - for (i = 0; i < 4; i++) - skip &= (!xd->plane[2].eobs[i]); - return skip; -} - -static int mb_is_skippable_4x4(MACROBLOCKD *xd) { - return (vp9_mby_is_skippable_4x4(xd) & - vp9_mbuv_is_skippable_4x4(xd)); -} - -int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd) { - int skip = 1; - int i = 0; - - for (i = 0; i < 16; i += 4) - skip &= (!xd->plane[0].eobs[i]); - - return skip; -} - -int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) { - return (!xd->plane[1].eobs[0]) & (!xd->plane[2].eobs[0]); -} - -static int mb_is_skippable_8x8(MACROBLOCKD *xd) { - return (vp9_mby_is_skippable_8x8(xd) & - vp9_mbuv_is_skippable_8x8(xd)); +struct is_skippable_args { + MACROBLOCKD *xd; + int *skippable; +}; +static void is_skippable(int plane, int block, + int block_size_b, int ss_txfrm_size, void *argv) { + struct is_skippable_args *args = argv; + args->skippable[0] &= (!args->xd->plane[plane].eobs[block]); } -static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd) { - return (vp9_mby_is_skippable_8x8(xd) & - vp9_mbuv_is_skippable_4x4(xd)); -} - -int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) { - return (!xd->plane[0].eobs[0]); -} - -static int mb_is_skippable_16x16(MACROBLOCKD *xd) { - return (vp9_mby_is_skippable_16x16(xd) & vp9_mbuv_is_skippable_8x8(xd)); -} - -int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, - TX_SIZE sz) { - const int inc = 1 << (sz * 2); +int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) { const int bwl = mb_width_log2(bsize) + 2, bhl = mb_height_log2(bsize) + 2; - int skip = 1; - int i = 0; - - for (i = 0; i < (1 << (bwl + bhl)); i += inc) - skip &= (!xd->plane[0].eobs[i]); - - return skip; + int result = 1; + struct is_skippable_args args = {xd, &result}; + foreach_transformed_block(xd, bwl + bhl, is_skippable, &args); + return result; } -int vp9_sbuv_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, TX_SIZE sz) { - const int inc = 1 << (sz * 2); - const int bwl = mb_width_log2(bsize) + 1, bhl = mb_height_log2(bsize) + 1; - int skip = 1; - int i = 0; - - for (i = 0; i < (1 << (bwl + bhl)); i += inc) { - skip &= (!xd->plane[1].eobs[i]); - skip &= (!xd->plane[2].eobs[i]); - } - - return skip; +int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) { + const int bwl = mb_width_log2(bsize) + 2, bhl = mb_height_log2(bsize) + 2; + int result = 1; + struct is_skippable_args args = {xd, &result}; + foreach_transformed_block_in_plane(xd, bwl + bhl, 0, 0, is_skippable, &args); + return result; } -static int sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, - TX_SIZE ysz, TX_SIZE uvsz) { - return vp9_sby_is_skippable(xd, bsize, ysz) & - vp9_sbuv_is_skippable(xd, bsize, uvsz); +int vp9_sbuv_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) { + const int bwl = mb_width_log2(bsize) + 2, bhl = mb_height_log2(bsize) + 2; + int result = 1; + struct is_skippable_args args = {xd, &result}; + foreach_transformed_block_uv(xd, bwl + bhl, is_skippable, &args); + return result; } void vp9_tokenize_sb(VP9_COMP *cpi, @@ -449,7 +392,7 @@ void vp9_tokenize_sb(VP9_COMP *cpi, int b; const int n_y = (1 << (bwl + bhl)), n_uv = (n_y * 3) >> 1; - mbmi->mb_skip_coeff = sb_is_skippable(xd, bsize, txfm_size, uv_txfm_size); + mbmi->mb_skip_coeff = vp9_sb_is_skippable(xd, bsize); if (mbmi->mb_skip_coeff) { if (!dry_run) @@ -541,26 +484,8 @@ void vp9_tokenize_mb(VP9_COMP *cpi, } else skip_inc = 0; - switch (tx_size) { - case TX_16X16: - - xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd); - break; - case TX_8X8: - if (xd->mode_info_context->mbmi.mode == I8X8_PRED || - xd->mode_info_context->mbmi.mode == SPLITMV) - xd->mode_info_context->mbmi.mb_skip_coeff = - mb_is_skippable_8x8_4x4uv(xd); - else - xd->mode_info_context->mbmi.mb_skip_coeff = - mb_is_skippable_8x8(xd); - break; - - default: - xd->mode_info_context->mbmi.mb_skip_coeff = - mb_is_skippable_4x4(xd); - break; - } + xd->mode_info_context->mbmi.mb_skip_coeff = vp9_sb_is_skippable(xd, + BLOCK_SIZE_MB16X16); if (xd->mode_info_context->mbmi.mb_skip_coeff) { if (!dry_run) diff --git a/vp9/encoder/vp9_tokenize.h b/vp9/encoder/vp9_tokenize.h index decb34a4a7..2dcbd3002e 100644 --- a/vp9/encoder/vp9_tokenize.h +++ b/vp9/encoder/vp9_tokenize.h @@ -31,15 +31,9 @@ typedef struct { typedef int64_t vp9_coeff_accum[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS + 1]; -int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd); -int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd); -int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd); -int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd); -int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd); - -int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, TX_SIZE sz); -int vp9_sbuv_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, TX_SIZE sz); - +int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize); +int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize); +int vp9_sbuv_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize); struct VP9_COMP; void vp9_tokenize_mb(struct VP9_COMP *cpi, MACROBLOCKD *xd, -- GitLab