Commit 8266abfe authored by Paul Wilkins's avatar Paul Wilkins
Browse files

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
parent 59a200f1
......@@ -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 */
......
......@@ -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
......
......@@ -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 */
......
......@@ -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])
{
......
......@@ -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;
}
......
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment