From 8266abfe96cb1b46f537aec66b3dfcf22da2bb1c Mon Sep 17 00:00:00 2001 From: Paul Wilkins <paulwilkins@google.com> Date: Thu, 9 Feb 2012 15:44:18 +0000 Subject: [PATCH] Dual pred flag Further changes to make experiments with the context used for coding the dual pred flag easier. Current best performing method tested on derf is a two element context based on reference frame. I also tried various combinations of mode and reference frame as shown in commented out case using up to 6 contexts. Derf +0.26 overall psnr +0.15% ssim vs original method. Change-Id: I64c21ddec0abbb27feaaeaa1da2e9f164ebaca03 --- vp8/common/onyxc_int.h | 10 +++++++++- vp8/common/pred_common.c | 19 ++++++++---------- vp8/decoder/decodemv.c | 6 +++--- vp8/encoder/bitstream.c | 8 ++++---- vp8/encoder/encodeframe.c | 41 +++++++++++++++++++++++++-------------- vp8/encoder/onyx_if.c | 5 ++--- vp8/encoder/onyx_int.h | 3 ++- 7 files changed, 54 insertions(+), 38 deletions(-) diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index b05bf2596c..d6f5b13152 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -48,6 +48,14 @@ void vp8_initialize_common(void); #define MAX_PARTITIONS 9 +#if CONFIG_DUALPRED +#if CONFIG_COMPRED +#define DUAL_PRED_CONTEXTS 2 +#else +#define DUAL_PRED_CONTEXTS 3 +#endif +#endif /* CONFIG_DUALPRED */ + typedef struct frame_contexts { vp8_prob bmode_prob [VP8_BINTRAMODES-1]; @@ -242,7 +250,7 @@ typedef struct VP8Common #endif #if CONFIG_DUALPRED - vp8_prob prob_dualpred[3]; + vp8_prob prob_dualpred[DUAL_PRED_CONTEXTS]; #endif /* CONFIG_DUALPRED */ FRAME_CONTEXT lfc_a; /* last alt ref entropy */ diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c index 810c11d2fe..6d82568127 100644 --- a/vp8/common/pred_common.c +++ b/vp8/common/pred_common.c @@ -41,24 +41,21 @@ unsigned char get_pred_context( VP8_COMMON *const cm, case PRED_DUAL: // Context based on use of dual pred flag by neighbours //pred_context = - // ((m - 1)->mbmi.second_ref_frame != INTRA_FRAME) + + // ((m - 1)->mbmi.second_ref_frame != INTRA_FRAME) + // ((m - cm->mode_info_stride)->mbmi.second_ref_frame != INTRA_FRAME); - // Context based on mode - //if ( m->mbmi.mode == ZEROMV ) - // pred_context = 0; - //else if ( (m->mbmi.mode == NEARESTMV) || (m->mbmi.mode == NEARMV) ) - // pred_context = 1; + // Context based on mode and reference frame + //if ( m->mbmi.ref_frame == LAST_FRAME ) + // pred_context = 0 + (m->mbmi.mode != ZEROMV); + //else if ( m->mbmi.ref_frame == GOLDEN_FRAME ) + // pred_context = 2 + (m->mbmi.mode != ZEROMV); //else - // pred_context = 2; + // pred_context = 4 + (m->mbmi.mode != ZEROMV); - // Context based on reference frame if ( m->mbmi.ref_frame == LAST_FRAME ) pred_context = 0; - else if ( m->mbmi.ref_frame == GOLDEN_FRAME ) - pred_context = 1; else - pred_context = 2; + pred_context = 1; break; #endif diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index d87c328ed1..23d22c09a6 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -521,9 +521,9 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) cm->dual_pred_mode += vp8_read(bc, 128); if (cm->dual_pred_mode == HYBRID_PREDICTION) { - cm->prob_dualpred[0] = (vp8_prob)vp8_read_literal(bc, 8); - cm->prob_dualpred[1] = (vp8_prob)vp8_read_literal(bc, 8); - cm->prob_dualpred[2] = (vp8_prob)vp8_read_literal(bc, 8); + int i; + for ( i = 0; i < DUAL_PRED_CONTEXTS; i++ ) + cm->prob_dualpred[i] = (vp8_prob)vp8_read_literal(bc, 8); } #endif /* CONFIG_DUALPRED */ diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 2d4bb4badb..dd8d3d7a6a 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1060,7 +1060,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #if CONFIG_DUALPRED #if !CONFIG_COMPRED - int prob_dual_pred[3]; + int prob_dual_pred[DUAL_PRED_CONTEXTS]; #endif #endif /* CONFIG_DUALPRED */ @@ -1110,7 +1110,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { vp8_write(w, 1, 128); vp8_write(w, 1, 128); - for (i = 0; i < 3; i++) + for (i = 0; i < DUAL_PRED_CONTEXTS; i++) { if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) { @@ -1470,7 +1470,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #if CONFIG_DUALPRED #if !CONFIG_COMPRED - int prob_dual_pred[3]; + int prob_dual_pred[DUAL_PRED_CONTEXTS]; #endif #endif /* CONFIG_DUALPRED */ @@ -1517,7 +1517,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { vp8_write(w, 1, 128); vp8_write(w, 1, 128); - for (i = 0; i < 3; i++) + for (i = 0; i < DUAL_PRED_CONTEXTS; i++) { if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) { diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index b12a41aa04..c79ce67dfa 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -1284,8 +1284,8 @@ static void encode_frame_internal(VP8_COMP *cpi) init_encode_frame_mb_context(cpi); #if CONFIG_DUALPRED cpi->rd_single_diff = cpi->rd_dual_diff = cpi->rd_hybrid_diff = 0; - cpi->single_pred_count[0] = cpi->single_pred_count[1] = cpi->single_pred_count[2] = 0; - cpi->dual_pred_count[0] = cpi->dual_pred_count[1] = cpi->dual_pred_count[2] = 0; + vpx_memset(cpi->single_pred_count, 0, sizeof(cpi->single_pred_count)); + vpx_memset(cpi->dual_pred_count, 0, sizeof(cpi->dual_pred_count)); #endif /* CONFIG_DUALPRED */ { @@ -1513,15 +1513,21 @@ void vp8_encode_frame(VP8_COMP *cpi) } else if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { - if (cpi->dual_pred_count[0] == 0 && - cpi->dual_pred_count[1] == 0 && - cpi->dual_pred_count[2] == 0) + int single_count_zero = 0; + int dual_count_zero = 0; + int i; + + for ( i = 0; i < DUAL_PRED_CONTEXTS; i++ ) + { + single_count_zero += cpi->single_pred_count[i]; + dual_count_zero += cpi->dual_pred_count[i]; + } + + if (dual_count_zero == 0) { cpi->common.dual_pred_mode = SINGLE_PREDICTION_ONLY; } - else if (cpi->single_pred_count[0] == 0 && - cpi->single_pred_count[1] == 0 && - cpi->single_pred_count[2] == 0) + else if (single_count_zero == 0) { cpi->common.dual_pred_mode = DUAL_PREDICTION_ONLY; } @@ -1533,22 +1539,27 @@ void vp8_encode_frame(VP8_COMP *cpi) } } - if (redo) { encode_frame_internal(cpi); if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { - if (cpi->dual_pred_count[0] == 0 && - cpi->dual_pred_count[1] == 0 && - cpi->dual_pred_count[2] == 0) + int single_count_zero = 0; + int dual_count_zero = 0; + int i; + + for ( i = 0; i < DUAL_PRED_CONTEXTS; i++ ) + { + single_count_zero += cpi->single_pred_count[i]; + dual_count_zero += cpi->dual_pred_count[i]; + } + + if (dual_count_zero == 0) { cpi->common.dual_pred_mode = SINGLE_PREDICTION_ONLY; } - else if (cpi->single_pred_count[0] == 0 && - cpi->single_pred_count[1] == 0 && - cpi->single_pred_count[2] == 0) + else if (single_count_zero == 0) { cpi->common.dual_pred_mode = DUAL_PREDICTION_ONLY; } diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index b427f96ad1..a4b730442a 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2354,9 +2354,8 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) cm->prob_gf_coded = 128; cm->prob_intra_coded = 63; #if CONFIG_DUALPRED - cm->prob_dualpred[0] = 128; - cm->prob_dualpred[1] = 128; - cm->prob_dualpred[2] = 128; + for ( i = 0; i < DUAL_PRED_CONTEXTS; i++ ) + cm->prob_dualpred[i] = 128; #endif /* CONFIG_DUALPRED */ // Prime the recent reference frame useage counters. diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 892d514ebc..ad5592fc18 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -365,7 +365,8 @@ typedef struct VP8_COMP #if CONFIG_DUALPRED int rd_single_diff, rd_dual_diff, rd_hybrid_diff; int rd_prediction_type_threshes[4][NB_PREDICTION_TYPES]; - int dual_pred_count[3], single_pred_count[3]; + int dual_pred_count[DUAL_PRED_CONTEXTS]; + int single_pred_count[DUAL_PRED_CONTEXTS]; #endif /* CONFIG_DUALPRED */ int RDMULT; -- GitLab