From 6898e8b7ab73d0b0a77d4939fd9566d3f5308ed0 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Tue, 21 Feb 2012 18:10:18 -0800 Subject: [PATCH] Changed how UV r/d estimates are done for Intra Modes The commit changed to compute UV intra RD estimates for 4x4 and 8x8 separately to be used in mode decision for MB modes associated with the appropriate transform size respectively. Now finally after many other changes related 8x8 quantizer zbin boost and zbin_mode_boost, this change overall helps the HD(with 8x8) by around ~.13%. (avg .13% glb .13% ssim .17%) The commit also has a few changes for eliminating compiler warnings. Change-Id: Ibab35dad44820c87e6b44799c66f8d519cc37344 --- vp8/common/entropymode.h | 5 +- vp8/decoder/decodemv.c | 1 - vp8/decoder/detokenize.c | 4 +- vp8/encoder/quantize.h | 3 ++ vp8/encoder/rdopt.c | 99 +++++++++++++++++++++++++++++++---- vp8/encoder/temporal_filter.c | 2 +- vp8/encoder/tokenize.h | 7 +++ 7 files changed, 105 insertions(+), 16 deletions(-) diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h index 5c14ccade..09d5c7704 100644 --- a/vp8/common/entropymode.h +++ b/vp8/common/entropymode.h @@ -65,8 +65,11 @@ extern struct vp8_token_struct vp8_small_mvencodings_hp [16]; void vp8_entropy_mode_init(void); void vp8_init_mbmode_probs(VP8_COMMON *x); - +extern void vp8_init_mode_contexts(VP8_COMMON *pc); extern void vp8_update_mode_context(VP8_COMMON *pc);; +extern void vp8_accum_mv_refs(VP8_COMMON *pc, + MB_PREDICTION_MODE m, + const int ct[4]); void vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]); void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1]); diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 0f5a64725..a70d1113b 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -644,7 +644,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, const int mis = pbi->common.mode_info_stride; MACROBLOCKD *const xd = & pbi->mb; - int pred_context; int index = mb_row * pbi->common.mb_cols + mb_col; int_mv *const mv = & mbmi->mv; int mb_to_left_edge; diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c index d3566fae5..ae105b139 100644 --- a/vp8/decoder/detokenize.c +++ b/vp8/decoder/detokenize.c @@ -265,8 +265,8 @@ int vp8_decode_mb_tokens_8x8(VP8D_COMP *dx, MACROBLOCKD *x) char *eobs = x->eobs; - ENTROPY_CONTEXT *a, *a1; - ENTROPY_CONTEXT *l, *l1; + ENTROPY_CONTEXT *a; + ENTROPY_CONTEXT *l; int i; int eobtotal = 0; diff --git a/vp8/encoder/quantize.h b/vp8/encoder/quantize.h index 93a1b714c..37221839e 100644 --- a/vp8/encoder/quantize.h +++ b/vp8/encoder/quantize.h @@ -108,6 +108,9 @@ extern prototype_quantize_mb(vp8_quantize_mby); extern void vp8_strict_quantize_b(BLOCK *b,BLOCKD *d); extern void vp8_strict_quantize_b_8x8(BLOCK *b,BLOCKD *d); extern void vp8_strict_quantize_b_2x2(BLOCK *b,BLOCKD *d); +extern prototype_quantize_mb(vp8_quantize_mby_8x8); +extern prototype_quantize_mb(vp8_quantize_mbuv_8x8); + struct VP8_COMP; extern void vp8_set_quantizer(struct VP8_COMP *cpi, int Q); extern void vp8cx_frame_init_quantizer(struct VP8_COMP *cpi); diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 085d8c4cf..fd64182f2 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -759,12 +759,10 @@ static void macro_block_yrd_8x8( MACROBLOCK *mb, int *Distortion, const VP8_ENCODER_RTCD *rtcd) { - int b; MACROBLOCKD *const x = &mb->e_mbd; BLOCK *const mb_y2 = mb->block + 24; BLOCKD *const x_y2 = x->block + 24; short *Y2DCPtr = mb_y2->src_diff; - BLOCK *beptr; int d; ENCODEMB_INVOKE(&rtcd->encodemb, submby) @@ -1365,7 +1363,11 @@ static int rd_inter4x4_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, return RDCOST(x->rdmult, x->rddiv, *rate, *distortion); } -static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly, int *distortion) +static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi, + MACROBLOCK *x, + int *rate, + int *rate_tokenonly, + int *distortion) { MB_PREDICTION_MODE mode; MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected); @@ -1441,6 +1443,55 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int #endif } +static void rd_pick_intra_mbuv_mode_8x8(VP8_COMP *cpi, + MACROBLOCK *x, + int *rate, + int *rate_tokenonly, + int *distortion) +{ + MB_PREDICTION_MODE mode; + MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected); + int best_rd = INT_MAX; + int UNINITIALIZED_IS_SAFE(d), UNINITIALIZED_IS_SAFE(r); + int rate_to; + + for (mode = DC_PRED; mode <= TM_PRED; mode++) + { + int rate; + int distortion; + int this_rd; + + x->e_mbd.mode_info_context->mbmi.uv_mode = mode; + RECON_INVOKE(&cpi->rtcd.common->recon, build_intra_predictors_mbuv) + (&x->e_mbd); + ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), submbuv)(x->src_diff, + x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, + x->src.uv_stride); + vp8_transform_mbuv_8x8(x); + + vp8_quantize_mbuv_8x8(x); + + rate_to = rd_cost_mbuv_8x8(x); + rate = rate_to + x->intra_uv_mode_cost[x->e_mbd.frame_type] + [x->e_mbd.mode_info_context->mbmi.uv_mode]; + + distortion = ENCODEMB_INVOKE(&cpi->rtcd.encodemb, mbuverr)(x) / 4; + this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); + + if (this_rd < best_rd) + { + best_rd = this_rd; + d = distortion; + r = rate; + *rate_tokenonly = rate_to; + mode_selected = mode; + } + } + *rate = r; + *distortion = d; + x->e_mbd.mode_info_context->mbmi.uv_mode = mode_selected; +} + int vp8_cost_mv_ref(VP8_COMMON *pc, MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]) @@ -2466,6 +2517,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int int rate2, distortion2; int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly; int uv_intra_skippable = 0; + int uv_intra_rate_8x8, uv_intra_distortion_8x8, uv_intra_rate_tokenonly_8x8; int uv_intra_skippable_8x8=0; int rate_y, UNINITIALIZED_IS_SAFE(rate_uv); int distortion_uv; @@ -2477,6 +2529,8 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int //int intermodecost[MAX_MODES]; MB_PREDICTION_MODE uv_intra_mode; + MB_PREDICTION_MODE uv_intra_mode_8x8; + int_mv mvp; int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7}; int saddone=0; @@ -2556,13 +2610,21 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int /* Initialize zbin mode boost for uv costing */ cpi->zbin_mode_boost = 0; vp8_update_zbin_extra(cpi, x); - rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion); - uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode; + rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, + &uv_intra_rate_tokenonly, &uv_intra_distortion); + uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode; uv_intra_skippable = mbuv_is_skippable(&x->e_mbd); /* rough estimate for now */ - uv_intra_skippable_8x8 = uv_intra_skippable; + if(cpi->common.txfm_mode==ALLOW_8X8) + { + rd_pick_intra_mbuv_mode_8x8(cpi, x, &uv_intra_rate_8x8, + &uv_intra_rate_tokenonly_8x8, + &uv_intra_distortion_8x8); + uv_intra_mode_8x8 = x->e_mbd.mode_info_context->mbmi.uv_mode; + uv_intra_skippable_8x8 = mbuv_is_skippable_8x8(&x->e_mbd); + } // Get estimates of reference frame costs for each reference frame // that depend on the current prediction etc. @@ -2775,10 +2837,20 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int rate2 += rate_y; distortion2 += distortion; rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mode_info_context->mbmi.mode]; - rate2 += uv_intra_rate; - rate_uv = uv_intra_rate_tokenonly; - distortion2 += uv_intra_distortion; - distortion_uv = uv_intra_distortion; + if(cpi->common.txfm_mode == ALLOW_8X8) + { + rate2 += uv_intra_rate_8x8; + rate_uv = uv_intra_rate_tokenonly_8x8; + distortion2 += uv_intra_distortion_8x8; + distortion_uv = uv_intra_distortion_8x8; + } + else + { + rate2 += uv_intra_rate; + rate_uv = uv_intra_rate_tokenonly; + distortion2 += uv_intra_distortion; + distortion_uv = uv_intra_distortion; + } break; case NEWMV: @@ -3250,7 +3322,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int if (this_mode <= B_PRED) { - x->e_mbd.mode_info_context->mbmi.uv_mode = uv_intra_mode; + if( cpi->common.txfm_mode == ALLOW_8X8 + && this_mode != B_PRED + && this_mode != I8X8_PRED) + x->e_mbd.mode_info_context->mbmi.uv_mode = uv_intra_mode_8x8; + else + x->e_mbd.mode_info_context->mbmi.uv_mode = uv_intra_mode; /* required for left and above block mv */ x->e_mbd.mode_info_context->mbmi.mv.as_int = 0; } diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c index 6c8b45857..7440883e0 100644 --- a/vp8/encoder/temporal_filter.c +++ b/vp8/encoder/temporal_filter.c @@ -116,7 +116,7 @@ void vp8_temporal_filter_apply_c unsigned short *count ) { - int i, j, k; + unsigned int i, j, k; int modifier; int byte = 0; diff --git a/vp8/encoder/tokenize.h b/vp8/encoder/tokenize.h index 545c5d045..0608102d0 100644 --- a/vp8/encoder/tokenize.h +++ b/vp8/encoder/tokenize.h @@ -33,6 +33,13 @@ typedef struct int rd_cost_mby(MACROBLOCKD *); +extern int mby_is_skippable(MACROBLOCKD *x,int has_y2_block); +extern int mbuv_is_skippable(MACROBLOCKD *x); +extern int mb_is_skippable(MACROBLOCKD *x,int has_y2_block); +extern int mby_is_skippable_8x8(MACROBLOCKD *x); +extern int mbuv_is_skippable_8x8(MACROBLOCKD *x); +extern int mb_is_skippable_8x8(MACROBLOCKD *x); + #ifdef ENTROPY_STATS void init_context_counters(); void print_context_counters();