From ba1a6619b3e06324354b728ec28d1b0750a7cc32 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Thu, 8 Dec 2011 11:43:09 -0800 Subject: [PATCH] Revised coding using adaptive mode context to depend on frame type A previous commit 76feb965 made the vp8_mode_context adaptive on a frame frame basis, this commit further made the coding context adaptive to two frame types separately. Tests on derf set showed a further small gain on all metrics: avg psnr 0.10%, glb psnr: 0.11%, ssim: 0.08% http://www.corp.google.com/~yaowu/no_crawl/newNearMode_1209.html Change-Id: I7b3e32ec8729de1903d14a3f1213f1624b78cdee --- vp8/common/alloccommon.c | 6 ---- vp8/common/entropymode.c | 74 +++++++++++++++++++++++++++++++--------- vp8/common/entropymode.h | 2 ++ vp8/common/modecont.c | 34 +++++++++++++++++- vp8/common/modecont.h | 4 ++- vp8/common/onyxc_int.h | 3 +- vp8/decoder/decodframe.c | 44 +++++++++++++----------- vp8/encoder/bitstream.c | 20 +---------- vp8/encoder/mcomp.h | 1 - vp8/encoder/onyx_if.c | 6 +++- vp8/encoder/ratectrl.c | 33 +++++++++++++++--- 11 files changed, 158 insertions(+), 69 deletions(-) diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c index 0c7a9ef8d..4457c8821 100644 --- a/vp8/common/alloccommon.c +++ b/vp8/common/alloccommon.c @@ -190,12 +190,6 @@ void vp8_create_common(VP8_COMMON *oci) vp8_machine_specific_config(oci); vp8_init_mbmode_probs(oci); -#if CONFIG_NEWNEAR - vp8_init_mv_ref_counts(oci); -#endif - vpx_memcpy( oci->vp8_mode_contexts, - default_vp8_mode_contexts, - sizeof(default_vp8_mode_contexts)); vp8_default_bmode_probs(oci->fc.bmode_prob); diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c index 5b1a6d35c..a83c1d4bb 100644 --- a/vp8/common/entropymode.c +++ b/vp8/common/entropymode.c @@ -9,10 +9,12 @@ */ +#include "modecont.h" #include "entropymode.h" #include "entropy.h" #include "vpx_mem/vpx_mem.h" + #if CONFIG_QIMODE const unsigned int kf_y_mode_cts[8][VP8_YMODES] = { @@ -356,43 +358,59 @@ void vp8_entropy_mode_init() } #if CONFIG_NEWNEAR -void vp8_init_mv_ref_counts(VP8_COMMON *pc) +void vp8_init_mode_contexts(VP8_COMMON *pc) { vpx_memset(pc->mv_ref_ct, 0, sizeof(pc->mv_ref_ct)); + vpx_memset(pc->mv_ref_ct_a, 0, sizeof(pc->mv_ref_ct_a)); + + vpx_memcpy( pc->mode_context, + default_vp8_mode_contexts, + sizeof (pc->mode_context)); + vpx_memcpy( pc->mode_context_a, + default_vp8_mode_contexts, + sizeof (pc->mode_context_a)); + } void vp8_accum_mv_refs(VP8_COMMON *pc, MB_PREDICTION_MODE m, const int ct[4]) { + int (*mv_ref_ct)[4][2]; + + if(pc->refresh_alt_ref_frame) + mv_ref_ct = pc->mv_ref_ct_a; + else + mv_ref_ct = pc->mv_ref_ct; + if (m == ZEROMV) { - ++pc->mv_ref_ct [ct[0]] [0] [0]; + ++mv_ref_ct [ct[0]] [0] [0]; } else { - ++pc->mv_ref_ct [ct[0]] [0] [1]; + ++mv_ref_ct [ct[0]] [0] [1]; if (m == NEARESTMV) { - ++pc->mv_ref_ct [ct[1]] [1] [0]; + ++mv_ref_ct [ct[1]] [1] [0]; } else { - ++pc->mv_ref_ct [ct[1]] [1] [1]; + ++mv_ref_ct [ct[1]] [1] [1]; if (m == NEARMV) { - ++pc->mv_ref_ct [ct[2]] [2] [0]; + ++mv_ref_ct [ct[2]] [2] [0]; } else { - ++pc->mv_ref_ct [ct[2]] [2] [1]; + ++mv_ref_ct [ct[2]] [2] [1]; if (m == NEWMV) { - ++pc->mv_ref_ct [ct[3]] [3] [0]; + ++mv_ref_ct [ct[3]] [3] [0]; } else { - ++pc->mv_ref_ct [ct[3]] [3] [1]; + ++mv_ref_ct [ct[3]] [3] [1]; } } } @@ -402,24 +420,37 @@ void vp8_accum_mv_refs(VP8_COMMON *pc, void vp8_update_mode_context(VP8_COMMON *pc) { int i, j; + int (*mv_ref_ct)[4][2]; + int (*mode_context)[4]; + + if(pc->refresh_alt_ref_frame) + { + mv_ref_ct = pc->mv_ref_ct_a; + mode_context = pc->mode_context_a; + } + else + { + mv_ref_ct = pc->mv_ref_ct; + mode_context = pc->mode_context; + } + for (j = 0; j < 6; j++) { for (i = 0; i < 4; i++) { int this_prob; - int count; - // context probs - count = pc->mv_ref_ct[j][i][0] + pc->mv_ref_ct[j][i][1]; + int count = mv_ref_ct[j][i][0] + mv_ref_ct[j][i][1]; + if (count) - this_prob = 256 * pc->mv_ref_ct[j][i][0] / count; + this_prob = 256 * mv_ref_ct[j][i][0] / count; else this_prob = 128; + this_prob = this_prob? (this_prob<255?this_prob:255):1; if (this_prob == 0) this_prob = 1; if (this_prob == 256) this_prob = 255; - - pc->mode_context[j][i] = this_prob; + mode_context[j][i] = this_prob; } } } @@ -427,14 +458,25 @@ void vp8_update_mode_context(VP8_COMMON *pc) void print_mode_contexts(VP8_COMMON *pc) { int j, i; + printf("====================\n"); for(j=0; j<6; j++) { for (i = 0; i < 4; i++) { - printf( "%4d ", pc->vp8_mode_contexts[j][i]); + printf( "%4d ", pc->mode_context[j][i]); } printf("\n"); } + printf("====================\n"); + for(j=0; j<6; j++) + { + for (i = 0; i < 4; i++) + { + printf( "%4d ", pc->mode_context_a[j][i]); + } + printf("\n"); + } + } void print_mv_ref_cts(VP8_COMMON *pc) { diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h index 7f5bdf901..1c6d23560 100644 --- a/vp8/common/entropymode.h +++ b/vp8/common/entropymode.h @@ -63,6 +63,8 @@ void vp8_entropy_mode_init(void); void vp8_init_mbmode_probs(VP8_COMMON *x); +extern void vp8_update_mode_context(VP8_COMMON *pc);; + 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/common/modecont.c b/vp8/common/modecont.c index d7491f241..c7f903b16 100644 --- a/vp8/common/modecont.c +++ b/vp8/common/modecont.c @@ -10,7 +10,38 @@ #include "entropy.h" - +#if CONFIG_NEWNEAR +const int default_vp8_mode_contexts[6][4] = +{ + { /* 0 */ + 7, 1, 1, 183}, + { /* 1 */ + 14, 18, 14, 147}, + {/* 2 */ + 135, 64, 57, 68}, + { /* 3 */ + 60, 56, 128, 65}, + {/* 4 */ + 159, 134, 128, 34}, + { /* 5 */ + 234, 188, 128, 28}, +}; +const int default_vp8_mode_contexts_a[6][4] = +{ + { /* 0 */ + 4, 1, 1, 143}, + { /* 1 */ + 7, 9, 7, 107}, + {/* 2 */ + 95, 34, 57, 68}, + { /* 3 */ + 95, 56, 128, 65}, + {/* 4 */ + 159, 67, 128, 34}, + { /* 5 */ + 234, 94, 128, 28}, +}; +#else const int default_vp8_mode_contexts[6][4] = { { @@ -38,3 +69,4 @@ const int default_vp8_mode_contexts[6][4] = 234, 188, 128, 28, }, }; +#endif \ No newline at end of file diff --git a/vp8/common/modecont.h b/vp8/common/modecont.h index 476ae3fa9..8117e6391 100644 --- a/vp8/common/modecont.h +++ b/vp8/common/modecont.h @@ -13,5 +13,7 @@ #define __INC_MODECONT_H extern const int default_vp8_mode_contexts[6][4]; - +#if CONFIG_NEWNEAR +extern const int default_vp8_mode_contexts_a[6][4]; +#endif #endif diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 4bca5af87..3cb63d5af 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -218,12 +218,13 @@ typedef struct VP8Common #if CONFIG_NEWNEAR int mv_ref_ct[6][4][2]; int mode_context[6][4]; + int mv_ref_ct_a[6][4][2]; + int mode_context_a[6][4]; #endif int vp8_mode_contexts[6][4]; unsigned int current_video_frame; - int near_boffset[3]; int version; diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 661c28d2d..0659f9308 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -848,8 +848,16 @@ static void init_frame(VP8D_COMP *pbi) vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc)); #if CONFIG_NEWNEAR - vp8_init_mv_ref_counts(&pbi->common); -#endif + vp8_init_mode_contexts(&pbi->common); + vpx_memcpy( pbi->common.vp8_mode_contexts, + pbi->common.mode_context, + sizeof(pbi->common.mode_context)); + +#else + vpx_memcpy( pbi->common.vp8_mode_contexts, + default_vp8_mode_contexts, + sizeof(default_vp8_mode_contexts)); +#endif /* CONFIG_NEWNEAR */ } else { @@ -1236,9 +1244,23 @@ int vp8_decode_frame(VP8D_COMP *pbi) #endif if(pc->refresh_alt_ref_frame) + { vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc)); +#if CONFIG_NEWNEAR + vpx_memcpy( pc->vp8_mode_contexts, + pc->mode_context_a, + sizeof(pc->vp8_mode_contexts)); +#endif + } else + { vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc)); +#if CONFIG_NEWNEAR + vpx_memcpy( pc->vp8_mode_contexts, + pc->mode_context, + sizeof(pc->vp8_mode_contexts)); +#endif + } /* Buffer to buffer copy flags. */ pc->copy_buffer_to_gf = 0; @@ -1351,25 +1373,9 @@ int vp8_decode_frame(VP8D_COMP *pbi) vp8_decode_mode_mvs(pbi); #if CONFIG_NEWNEAR - if(!pbi->common.refresh_alt_ref_frame) + if(pbi->common.frame_type != KEY_FRAME) { vp8_update_mode_context(&pbi->common); - vpx_memcpy( pc->vp8_mode_contexts, - pbi->common.mode_context, - sizeof(pbi->common.mode_context)); - - if(0) //pbi->common.current_video_frame<2) - { - printf("mv_ref_ct on frame %d:\n", - pbi->common.current_video_frame); - print_mv_ref_cts(&pbi->common); - - printf("mode_contexts on frame %d:\n", - pbi->common.current_video_frame); - print_mode_contexts(); - } - - } #endif diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 3b9637dc1..46498c758 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -2319,25 +2319,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) pack_inter_mode_mvs(cpi); #if CONFIG_NEWNEAR - if(!cpi->common.refresh_alt_ref_frame) - { - vp8_update_mode_context(&cpi->common); - vpx_memcpy( pc->vp8_mode_contexts, - cpi->common.mode_context, - sizeof(cpi->common.mode_context)); - - if(0) //(cpi->common.current_video_frame<2) - { - - printf("mv_ref_ct on frame %d:\n", - cpi->common.current_video_frame); - print_mv_ref_cts(&cpi->common); - - printf("mode_contexts on frame %d:\n", - cpi->common.current_video_frame); - print_mode_contexts(); - } - } + vp8_update_mode_context(&cpi->common); #endif #ifdef ENTROPY_STATS diff --git a/vp8/encoder/mcomp.h b/vp8/encoder/mcomp.h index 416c4d5eb..f9b450e3c 100644 --- a/vp8/encoder/mcomp.h +++ b/vp8/encoder/mcomp.h @@ -25,7 +25,6 @@ extern void accum_mv_refs(MB_PREDICTION_MODE, const int near_mv_ref_cts[4]); #define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1) // Max full pel mv specified in 1 pel units #define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1)) // Maximum size of the first step in full pel units -extern void print_mode_context(void); extern int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight); extern void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride); extern void vp8_init3smotion_compensation(MACROBLOCK *x, int stride); diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 6d9290675..f9a8f274d 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2630,7 +2630,9 @@ void vp8_remove_compressor(VP8_PTR *ptr) - cpi->first_time_stamp_ever) / 10000000.000; double total_encode_time = (cpi->time_receive_data + cpi->time_compress_data) / 1000.000; double dr = (double)cpi->bytes * (double) 8 / (double)1000 / time_encoded; - +#if CONFIG_NEWNEAR&&defined(MODE_STATS) + print_mode_contexts(&cpi->common); +#endif if (cpi->b_calculate_psnr) { YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx]; @@ -4361,6 +4363,8 @@ static void encode_frame_to_data_rate /* setup entropy for nonkey frame */ vp8_setup_inter_frame(cpi); } + + // transform / motion compensation build reconstruction frame vp8_encode_frame(cpi); diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index 62735d5d3..bc1145748 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -266,15 +266,40 @@ void vp8_setup_key_frame(VP8_COMP *cpi) vpx_memcpy(&cpi->common.lfc_a, &cpi->common.fc, sizeof(cpi->common.fc)); #if CONFIG_NEWNEAR - vp8_init_mv_ref_counts(&cpi->common); -#endif + vp8_init_mode_contexts(&cpi->common); + vpx_memcpy( cpi->common.vp8_mode_contexts, + cpi->common.mode_context, + sizeof(cpi->common.mode_context)); +#else + vpx_memcpy( cpi->common.vp8_mode_contexts, + default_vp8_mode_contexts, + sizeof(default_vp8_mode_contexts)); +#endif /* CONFIG_NEWNEAR */ } void vp8_setup_inter_frame(VP8_COMP *cpi) { if(cpi->common.refresh_alt_ref_frame) - vpx_memcpy(&cpi->common.fc, &cpi->common.lfc_a, sizeof(cpi->common.fc)); + { + vpx_memcpy( &cpi->common.fc, + &cpi->common.lfc_a, + sizeof(cpi->common.fc)); +#if CONFIG_NEWNEAR + vpx_memcpy( cpi->common.vp8_mode_contexts, + cpi->common.mode_context_a, + sizeof(cpi->common.vp8_mode_contexts)); +#endif /* CONFIG_NEWNEAR */ + } else - vpx_memcpy(&cpi->common.fc, &cpi->common.lfc, sizeof(cpi->common.fc)); + { + vpx_memcpy( &cpi->common.fc, + &cpi->common.lfc, + sizeof(cpi->common.fc)); +#if CONFIG_NEWNEAR + vpx_memcpy( cpi->common.vp8_mode_contexts, + cpi->common.mode_context, + sizeof(cpi->common.vp8_mode_contexts)); +#endif /* CONFIG_NEWNEAR */ + } } -- 2.40.0