Changes to costing of skip.

Update the costing of skip in the recode loop and rd code.

Change-Id: I2e5ebbd7ddf201212b32441321e12626cd0423e9
This commit is contained in:
Paul Wilkins 2012-04-11 14:37:48 +01:00
parent a3392d5718
commit f2ec452fbc
3 changed files with 186 additions and 107 deletions

View File

@ -120,6 +120,56 @@ static void update_mbintra_mode_probs(VP8_COMP *cpi)
}
}
void update_skip_probs(VP8_COMP *cpi)
{
#if CONFIG_NEWENTROPY
VP8_COMMON *const pc = & cpi->common;
int prob_skip_false[3] = {0, 0, 0};
int k;
for (k=0;k<MBSKIP_CONTEXTS;++k)
{
if ( (cpi->skip_false_count[k] + cpi->skip_true_count[k]) )
{
prob_skip_false[k] =
cpi->skip_false_count[k] * 256 /
(cpi->skip_false_count[k] + cpi->skip_true_count[k]);
if (prob_skip_false[k] <= 1)
prob_skip_false[k] = 1;
if (prob_skip_false[k] > 255)
prob_skip_false[k] = 255;
}
else
prob_skip_false[k] = 128;
pc->mbskip_pred_probs[k] = prob_skip_false[k];
vp8_write_literal(w, prob_skip_false[k], 8);
}
#else
int prob_skip_false = 0;
if ( (cpi->skip_false_count + cpi->skip_true_count) )
{
prob_skip_false = cpi->skip_false_count * 256 /
(cpi->skip_false_count + cpi->skip_true_count);
if (prob_skip_false <= 1)
prob_skip_false = 1;
if (prob_skip_false > 255)
prob_skip_false = 255;
}
else
prob_skip_false = 128;
cpi->prob_skip_false = prob_skip_false;
#endif
}
static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p)
{
vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
@ -592,12 +642,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
int mb_row, mb_col;
int row, col;
#if CONFIG_NEWENTROPY
int prob_skip_false[3] = {0, 0, 0};
#else
int prob_skip_false = 0;
#endif
// Values used in prediction model coding
vp8_prob pred_prob;
unsigned char prediction_flag;
@ -616,45 +660,15 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
if (pc->mb_no_coeff_skip)
{
// Divide by 0 check. 0 case possible with segment features
#if CONFIG_NEWENTROPY
int k;
update_skip_probs( cpi );
for (k=0;k<MBSKIP_CONTEXTS;++k)
{
if ( (cpi->skip_false_count[k] + cpi->skip_true_count[k]) )
{
prob_skip_false[k] = cpi->skip_false_count[k] * 256 /
(cpi->skip_false_count[k] + cpi->skip_true_count[k]);
if (prob_skip_false[k] <= 1)
prob_skip_false[k] = 1;
if (prob_skip_false[k] > 255)
prob_skip_false[k] = 255;
}
else
prob_skip_false[k] = 255;
pc->mbskip_pred_probs[k] = prob_skip_false[k];
vp8_write_literal(w, prob_skip_false[k], 8);
}
vp8_write_literal(w, cpi->prob_skip_false[k], 8);
#else
if ( (cpi->skip_false_count + cpi->skip_true_count) )
{
prob_skip_false = cpi->skip_false_count * 256 /
(cpi->skip_false_count + cpi->skip_true_count);
if (prob_skip_false <= 1)
prob_skip_false = 1;
if (prob_skip_false > 255)
prob_skip_false = 255;
}
else
prob_skip_false = 255;
cpi->prob_skip_false = prob_skip_false;
vp8_write_literal(w, prob_skip_false, 8);
update_skip_probs( cpi );
vp8_write_literal(w, cpi->prob_skip_false, 8);
#endif
}
@ -783,7 +797,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
vp8_encode_bool(w, mi->mb_skip_coeff,
get_pred_prob(pc, xd, PRED_MBSKIP));
#else
vp8_encode_bool(w, mi->mb_skip_coeff, prob_skip_false);
vp8_encode_bool(w, mi->mb_skip_coeff, cpi->prob_skip_false);
#endif
}

View File

@ -292,6 +292,59 @@ void init_base_skip_probs()
#endif
}
}
void update_base_skip_probs(VP8_COMP *cpi)
{
VP8_COMMON *cm = &cpi->common;
if (cm->frame_type != KEY_FRAME)
{
update_skip_probs(cpi);
if (cm->refresh_alt_ref_frame)
{
#if CONFIG_NEWENTROPY
int k;
for (k=0; k<MBSKIP_CONTEXTS; ++k)
cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
#else
cpi->last_skip_false_probs[2] = cpi->prob_skip_false;
#endif
cpi->last_skip_probs_q[2] = cm->base_qindex;
}
else if (cpi->common.refresh_golden_frame)
{
#if CONFIG_NEWENTROPY
int k;
for (k=0; k<MBSKIP_CONTEXTS; ++k)
cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
#else
cpi->last_skip_false_probs[1] = cpi->prob_skip_false;
#endif
cpi->last_skip_probs_q[1] = cm->base_qindex;
}
else
{
#if CONFIG_NEWENTROPY
int k;
for (k=0; k<MBSKIP_CONTEXTS; ++k)
cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
#else
cpi->last_skip_false_probs[0] = cpi->prob_skip_false;
#endif
cpi->last_skip_probs_q[0] = cm->base_qindex;
// update the baseline table for the current q
#if CONFIG_NEWENTROPY
for (k=0; k<MBSKIP_CONTEXTS; ++k)
cpi->base_skip_false_prob[cm->base_qindex][k] =
cm->mbskip_pred_probs[k];
#else
cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false;
#endif
}
}
}
void vp8_initialize()
{
@ -3207,13 +3260,6 @@ static void encode_frame_to_data_rate
if (cpi->last_skip_false_probs[2] != 0)
cpi->prob_skip_false = cpi->last_skip_false_probs[2];
#endif
/*
if(cpi->last_skip_false_probs[2]!=0 && abs(Q- cpi->last_skip_probs_q[2])<=16 )
cpi->prob_skip_false = cpi->last_skip_false_probs[2];
else if (cpi->last_skip_false_probs[2]!=0)
cpi->prob_skip_false = (cpi->last_skip_false_probs[2] + cpi->prob_skip_false ) / 2;
*/
}
else if (cpi->common.refresh_golden_frame)
{
@ -3227,13 +3273,6 @@ static void encode_frame_to_data_rate
if (cpi->last_skip_false_probs[1] != 0)
cpi->prob_skip_false = cpi->last_skip_false_probs[1];
#endif
/*
if(cpi->last_skip_false_probs[1]!=0 && abs(Q- cpi->last_skip_probs_q[1])<=16 )
cpi->prob_skip_false = cpi->last_skip_false_probs[1];
else if (cpi->last_skip_false_probs[1]!=0)
cpi->prob_skip_false = (cpi->last_skip_false_probs[1] + cpi->prob_skip_false ) / 2;
*/
}
else
{
@ -3248,13 +3287,6 @@ static void encode_frame_to_data_rate
if (cpi->last_skip_false_probs[0] != 0)
cpi->prob_skip_false = cpi->last_skip_false_probs[0];
#endif
/*
if(cpi->last_skip_false_probs[0]!=0 && abs(Q- cpi->last_skip_probs_q[0])<=16 )
cpi->prob_skip_false = cpi->last_skip_false_probs[0];
else if(cpi->last_skip_false_probs[0]!=0)
cpi->prob_skip_false = (cpi->last_skip_false_probs[0] + cpi->prob_skip_false ) / 2;
*/
}
// as this is for cost estimate, let's make sure it does not
@ -3298,6 +3330,10 @@ static void encode_frame_to_data_rate
// transform / motion compensation build reconstruction frame
vp8_encode_frame(cpi);
// Update the skip mb flag probabilities based on the distribution
// seen in the last encoder iteration.
update_base_skip_probs( cpi );
cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
@ -3706,6 +3742,10 @@ static void encode_frame_to_data_rate
cpi->twopass.gf_group_bits = 0 ;
}
// Update the skip mb flag probabilities based on the distribution seen
// in this frame.
update_base_skip_probs( cpi );
/*
if (cm->frame_type != KEY_FRAME)
{
if (cpi->common.refresh_alt_ref_frame)
@ -3751,7 +3791,7 @@ static void encode_frame_to_data_rate
}
}
*/
#if 0 && CONFIG_INTERNAL_STATS
{
FILE *f = fopen("tmp.stt", "a");

View File

@ -1514,13 +1514,26 @@ int vp8_cost_mv_ref(VP8_COMP *cpi,
MB_PREDICTION_MODE m,
const int near_mv_ref_ct[4])
{
VP8_COMMON *pc = &cpi->common;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
int segment_id = xd->mode_info_context->mbmi.segment_id;
vp8_prob p [VP8_MVREFS-1];
assert(NEARESTMV <= m && m <= SPLITMV);
vp8_mv_ref_probs(pc, p, near_mv_ref_ct);
return vp8_cost_token(vp8_mv_ref_tree, p,
vp8_mv_ref_encoding_array - NEARESTMV + m);
// If the mode coding is done entirely at the segment level
// we should not account for it at the per mb level in rd code.
// Note that if the segment level coding is expanded from single mode
// to multiple mode masks as per reference frame coding we will need
// to do something different here.
if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE) )
{
VP8_COMMON *pc = &cpi->common;
vp8_prob p [VP8_MVREFS-1];
assert(NEARESTMV <= m && m <= SPLITMV);
vp8_mv_ref_probs(pc, p, near_mv_ref_ct);
return vp8_cost_token(vp8_mv_ref_tree, p,
vp8_mv_ref_encoding_array - NEARESTMV + m);
}
else
return 0;
}
void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv)
@ -3241,21 +3254,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
vp8_cost_bit( get_pred_prob( cm, xd, PRED_COMP ), 1 );
}
// Where skip is allowable add in the default per mb cost for the no skip case.
// where we then decide to skip we have to delete this and replace it with the
// cost of signaling a skip
if (cpi->common.mb_no_coeff_skip)
{
#if CONFIG_NEWENTROPY
int prob_skip_cost = vp8_cost_bit(
get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP), 0);
#else
int prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 0);
#endif
other_cost += prob_skip_cost;
rate2 += prob_skip_cost;
}
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
{
rate2 += compmode_cost;
@ -3268,13 +3266,18 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
if (!disable_skip)
{
// Test for the condition where skip block will be activated because there are no non zero coefficients and make any necessary adjustment for rate
if (cpi->common.mb_no_coeff_skip)
// Test for the condition where skip block will be activated
// because there are no non zero coefficients and make any
// necessary adjustment for rate. Ignore if skip is coded at
// segment level as the cost wont have been added in.
if ( cpi->common.mb_no_coeff_skip )
{
int mb_skippable;
int mb_skip_allowed;
int has_y2 = ( this_mode!=SPLITMV
&&this_mode!=B_PRED
&&this_mode!=I8X8_PRED);
if((cpi->common.txfm_mode == ALLOW_8X8) && has_y2)
{
if(x->e_mbd.mode_info_context->mbmi.ref_frame!=INTRA_FRAME)
@ -3292,37 +3295,59 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
& mby_is_skippable(&x->e_mbd, has_y2);
}
// Is Mb level skip allowed for this mb.
mb_skip_allowed =
!segfeature_active( xd, segment_id, SEG_LVL_EOB ) ||
get_segdata( xd, segment_id, SEG_LVL_EOB );
if (mb_skippable)
{
#if CONFIG_NEWENTROPY
vp8_prob skip_prob = get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP);
#endif
int prob_skip_cost;
// Back out the coefficient coding costs
rate2 -= (rate_y + rate_uv);
//for best_yrd calculation
rate_uv = 0;
if ( mb_skip_allowed )
{
int prob_skip_cost;
// Cost the skip mb case
#if CONFIG_NEWENTROPY
if (skip_prob)
{
prob_skip_cost = vp8_cost_bit(skip_prob, 1);
prob_skip_cost -= vp8_cost_bit(skip_prob, 0);
rate2 += prob_skip_cost;
other_cost += prob_skip_cost;
}
vp8_prob skip_prob =
get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP);
if (skip_prob)
{
prob_skip_cost = vp8_cost_bit(skip_prob, 1);
rate2 += prob_skip_cost;
other_cost += prob_skip_cost;
}
#else
// Back out no skip flag costing and add in skip flag costing
if (cpi->prob_skip_false)
{
prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 1);
prob_skip_cost -= vp8_cost_bit(cpi->prob_skip_false, 0);
rate2 += prob_skip_cost;
other_cost += prob_skip_cost;
}
if (cpi->prob_skip_false)
{
prob_skip_cost =
vp8_cost_bit(cpi->prob_skip_false, 1);
rate2 += prob_skip_cost;
other_cost += prob_skip_cost;
}
#endif
}
}
// Add in the cost of the no skip flag.
else if ( mb_skip_allowed )
{
#if CONFIG_NEWENTROPY
int prob_skip_cost = vp8_cost_bit(
get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP), 0);
#else
int prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 0);
#endif
rate2 += prob_skip_cost;
other_cost += prob_skip_cost;
}
}
// Calculate the final RD estimate for this mode
// Calculate the final RD estimate for this mode.
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
}