From be360d47f412424e1bf1d645860ccabdad2f3343 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Thu, 8 Dec 2011 11:43:09 -0800 Subject: [PATCH] Enabled adaptive UV intra coding for inter frames Previously, Y-adaptive UV intra coding only enabled on key frames in UVINTRA experiment. This commit enabled the same coding for inter frames, so the encoding of UV intra modes are consistent cross all frame types. Tests on derf set showed a very small overall gain around .04%: http://www.corp.google.com/~yaowu/no_crawl/interUVintra.html The gain looks to be reasonable given inta coded MBs is only a small portion of MBs in inter frames. Change-Id: Ic6fc261923f2c253f4a0c9f8bccf4797557b9e16 --- vp8/common/entropymode.c | 46 +++++++++++++++++++++------------------- vp8/common/onyxc_int.h | 4 ++++ vp8/decoder/decodemv.c | 14 +++++++++--- vp8/encoder/bitstream.c | 17 ++++++++++++++- vp8/encoder/modecosts.c | 20 +++++++++++------ vp8/encoder/onyx_if.c | 19 ++++++++++++++++- vp8/encoder/onyx_int.h | 10 ++++++++- 7 files changed, 96 insertions(+), 34 deletions(-) diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c index a83c1d4bb..6d0f562c1 100644 --- a/vp8/common/entropymode.c +++ b/vp8/common/entropymode.c @@ -28,38 +28,35 @@ const unsigned int kf_y_mode_cts[8][VP8_YMODES] = {99, 42, 43, 21, 12, 39}, }; #else -static const unsigned int kf_y_mode_cts[VP8_YMODES] = { 49, 22, 23, 11, 23, 128}; +static const unsigned int kf_y_mode_cts[VP8_YMODES] = { + 49, 22, 23, 11, 23, 128}; #endif -/* TODO: calibrate the baseline distribution */ -static const unsigned int y_mode_cts [VP8_YMODES] = { 8080, 1908, 1582, 1007, 2000, 5874}; + +static const unsigned int y_mode_cts [VP8_YMODES] = { + 106, 25, 21, 13, 16, 74}; #if CONFIG_UVINTRA -static const unsigned int uv_mode_cts [VP8_UV_MODES] ={ 162, 41, 41, 12}; -/* static const unsigned int uv_mode_cts [VP8_YMODES] [VP8_UV_MODES] ={ - { 180, 35, 35, 6}, - { 152, 76, 20, 8}, - { 152, 20, 76, 8}, - { 172, 36, 36, 12}, - { 162, 41, 41, 12}, - { 162, 41, 41, 12}, + { 210, 20, 20, 6}, + { 180, 60, 10, 6}, + { 150, 20, 80, 6}, + { 170, 35, 35, 16}, + { 142, 51, 45, 18}, /* never used */ + { 160, 40, 46, 10}, }; -*/ #else static const unsigned int uv_mode_cts [VP8_UV_MODES] = { 59483, 13605, 16492, 4230}; #endif - static const unsigned int i8x8_mode_cts [VP8_UV_MODES] = {93, 69, 81, 13}; - #if CONFIG_UVINTRA static const unsigned int kf_uv_mode_cts [VP8_YMODES] [VP8_UV_MODES] ={ { 180, 34, 34, 8}, { 132, 74, 40, 10}, { 132, 40, 74, 10}, { 152, 46, 40, 18}, - { 142, 51, 45, 18}, + { 142, 51, 45, 18}, /* never used */ { 142, 51, 45, 18}, }; #else @@ -268,26 +265,31 @@ void vp8_init_mbmode_probs(VP8_COMMON *x) 256, 1 ); #endif - vp8_tree_probs_from_distribution( - VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, - x->fc.uv_mode_prob, bct, uv_mode_cts, - 256, 1 - ); #if CONFIG_UVINTRA { int i; for (i=0;ikf_uv_mode_prob[i], bct, kf_uv_mode_cts[i], 256, 1); + vp8_tree_probs_from_distribution( + VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, + x->fc.uv_mode_prob[i], bct, uv_mode_cts[i], + 256, 1); + } } #else + vp8_tree_probs_from_distribution( + VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, + x->fc.uv_mode_prob, bct, uv_mode_cts, + 256, 1); + vp8_tree_probs_from_distribution( VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, x->kf_uv_mode_prob, bct, kf_uv_mode_cts, - 256, 1 - ); + 256, 1); #endif vp8_tree_probs_from_distribution( VP8_UV_MODES, vp8_i8x8_mode_encodings, vp8_i8x8_mode_tree, diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 3cb63d5af..01759b033 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -43,7 +43,11 @@ typedef struct frame_contexts { vp8_prob bmode_prob [VP8_BINTRAMODES-1]; vp8_prob ymode_prob [VP8_YMODES-1]; /* interframe intra mode probs */ +#if CONFIG_UVINTRA + vp8_prob uv_mode_prob [VP8_YMODES][VP8_UV_MODES-1]; +#else vp8_prob uv_mode_prob [VP8_UV_MODES-1]; +#endif vp8_prob sub_mv_ref_prob [VP8_SUBMVREFS-1]; vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; #if CONFIG_T8X8 diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 2696c2f43..d8b93a8ff 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -410,7 +410,9 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) } while (++i < 4); } - +#if CONFIG_UVINTRA + //vp8_read_bit(bc); +#else if (vp8_read_bit(bc)) { int i = 0; @@ -421,7 +423,7 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) } while (++i < 3); } - +#endif /* CONFIG_UVINTRA */ read_mvcontexts(bc, mvc); } } @@ -798,7 +800,13 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, } } else - mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.fc.uv_mode_prob); +#if CONFIG_UVINTRA + mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, + pbi->common.fc.uv_mode_prob[mbmi->mode]); +#else + mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, + pbi->common.fc.uv_mode_prob); +#endif /*CONFIG_UVINTRA*/ } } diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 46498c758..c49e2bd3e 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -128,13 +128,16 @@ static void update_mbintra_mode_probs(VP8_COMP *cpi) ); } { +#if CONFIG_UVINTRA + //vp8_write_bit(w, 0); +#else vp8_prob Pnew [VP8_UV_MODES-1]; unsigned int bct [VP8_UV_MODES-1] [2]; - update_mode( w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, Pnew, x->fc.uv_mode_prob, bct, (unsigned int *)cpi->uv_mode_count ); +#endif } } @@ -1147,7 +1150,19 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) write_i8x8_mode(w, m->bmi[10].as_mode, pc->i8x8_mode_prob); } else + { +#if CONFIG_UVINTRA + write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob[mode]); +#ifdef MODE_STATS + if(mode!=B_PRED) + ++cpi->y_uv_mode_count[mode][mi->uv_mode]; +#endif + +#else write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob); +#endif /*CONFIG_UVINTRA*/ + + } } else { diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c index 36fea9f9f..b6f77e1a1 100644 --- a/vp8/encoder/modecosts.c +++ b/vp8/encoder/modecosts.c @@ -37,20 +37,28 @@ void vp8_init_mode_costs(VP8_COMP *c) vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.bmode_prob, T); } - vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_tree); + vp8_cost_tokens((int *)c->mb.inter_bmode_costs, + x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_tree); vp8_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree); #if CONFIG_QIMODE vp8_cost_tokens(c->mb.mbmode_cost[0], - x->kf_ymode_prob[c->common.kf_ymode_probs_index], vp8_kf_ymode_tree); + x->kf_ymode_prob[c->common.kf_ymode_probs_index], + vp8_kf_ymode_tree); #else - vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree); + vp8_cost_tokens(c->mb.mbmode_cost[0], + x->kf_ymode_prob, vp8_kf_ymode_tree); #endif - vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], x->fc.uv_mode_prob, vp8_uv_mode_tree); #if CONFIG_UVINTRA - vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob[VP8_YMODES-1], vp8_uv_mode_tree); + vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], + x->fc.uv_mode_prob[VP8_YMODES-1], vp8_uv_mode_tree); + vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], + x->kf_uv_mode_prob[VP8_YMODES-1], vp8_uv_mode_tree); #else - vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob, vp8_uv_mode_tree); + vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], + x->fc.uv_mode_prob, vp8_uv_mode_tree); + vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], + x->kf_uv_mode_prob, vp8_uv_mode_tree); #endif vp8_cost_tokens(c->mb.i8x8_mode_costs, x->i8x8_mode_prob,vp8_i8x8_mode_tree); diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index f9a8f274d..0b3e83bb3 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2591,6 +2591,12 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) vp8_loop_filter_init(cm); cpi->common.error.setjmp = 0; + +#if CONFIG_UVINTRA + vp8_zero(cpi->y_uv_mode_count) +#endif + + return (VP8_PTR) cpi; } @@ -2698,7 +2704,7 @@ void vp8_remove_compressor(VP8_PTR *ptr) fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4], y_modes[5]); fprintf(f, "I8:%8d, %8d, %8d, %8d\n", i8x8_modes[0], i8x8_modes[1], i8x8_modes[2], i8x8_modes[3]); fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], uv_modes[2], uv_modes[3]); - fprintf(f, "Y-UV:\n"); + fprintf(f, "KeyFrame Y-UV:\n"); { int i; for(i=0;iy_uv_mode_count[i][0], + cpi->y_uv_mode_count[i][1], cpi->y_uv_mode_count[i][2], cpi->y_uv_mode_count[i][3]); + } + } +#endif fprintf(f, "B: "); { int i; diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 9f026dc90..e2c4db6b9 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -83,7 +83,7 @@ typedef struct int inter_b_modes[B_MODE_COUNT]; #endif /* interframe intra mode probs */ - vp8_prob ymode_prob[VP8_YMODES-1], uv_mode_prob[VP8_UV_MODES-1]; + vp8_prob ymode_prob[VP8_YMODES-1]; /* keyframe intra mode probs */ #if CONFIG_QIMODE vp8_prob kf_ymode_prob[8][VP8_YMODES-1]; @@ -93,8 +93,10 @@ typedef struct #if CONFIG_UVINTRA vp8_prob kf_uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1]; + vp8_prob uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1]; #else vp8_prob kf_uv_mode_prob[VP8_UV_MODES-1]; + vp8_prob uv_mode_prob[VP8_UV_MODES-1]; #endif /* intra MB type cts this frame */ int ymode_count[VP8_YMODES], uv_mode_count[VP8_UV_MODES]; @@ -539,6 +541,12 @@ typedef struct VP8_COMP int t8x8_count; #endif +#if CONFIG_UVINTRA + int y_uv_mode_count[VP8_YMODES][VP8_UV_MODES]; +#endif + + + unsigned char *segmentation_map; unsigned char *last_segmentation_map; -- 2.40.0