Adding contextual coding of mb_skip_coeff flag.

Using contextual coding of the mkb_skip_coeff flag using the
values of this flag from the left and above. There is a small
improvement of about 0.15% on Derf:
http://www.corp.google.com/~debargha/vp8_results/mbskipcontext.html

Refactored to use pred_common.c by adding a new context type.

Results on HD set (about 0.66% improvement):
http://www.corp.google.com/~debargha/vp8_results/mbskipcontext_hd.html

Incliding missing refactoring to use the pred_common utilities.

Change-Id: I95373382d429b5a59610d77f69a0fea2be628278
This commit is contained in:
Deb Mukherjee 2012-03-19 11:02:04 -07:00
parent 21d3612a2f
commit 57d953479b
18 changed files with 386 additions and 71 deletions

1
configure vendored
View File

@ -223,6 +223,7 @@ EXPERIMENT_LIST="
high_precision_mv
sixteenth_subpel_uv
comp_intra_pred
newentropy
"
CONFIG_LIST="
external_build

View File

@ -40,6 +40,7 @@ void vp8_arch_arm_common_init(VP8_COMMON *ctx)
rtcd->subpix.sixtap8x8 = vp8_sixtap_predict8x8_armv6;
rtcd->subpix.sixtap8x4 = vp8_sixtap_predict8x4_armv6;
rtcd->subpix.sixtap4x4 = vp8_sixtap_predict_armv6;
rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_armv6;
rtcd->subpix.bilinear8x8 = vp8_bilinear_predict8x8_armv6;
rtcd->subpix.bilinear8x4 = vp8_bilinear_predict8x4_armv6;
@ -77,6 +78,7 @@ void vp8_arch_arm_common_init(VP8_COMMON *ctx)
rtcd->subpix.sixtap8x8 = vp8_sixtap_predict8x8_neon;
rtcd->subpix.sixtap8x4 = vp8_sixtap_predict8x4_neon;
rtcd->subpix.sixtap4x4 = vp8_sixtap_predict_neon;
rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_neon;
rtcd->subpix.bilinear8x8 = vp8_bilinear_predict8x8_neon;
rtcd->subpix.bilinear8x4 = vp8_bilinear_predict8x4_neon;

View File

@ -34,6 +34,10 @@ void vpx_log(const char *format, ...);
#define MB_FEATURE_TREE_PROBS 3
#define PREDICTION_PROBS 3
#if CONFIG_NEWENTROPY
#define MBSKIP_CONTEXTS 3
#endif
#define MAX_MB_SEGMENTS 4
#define MAX_REF_LF_DELTAS 4

View File

@ -233,6 +233,10 @@ typedef struct VP8Common
vp8_prob prob_comppred[COMP_PRED_CONTEXTS];
#if CONFIG_NEWENTROPY
vp8_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
#endif
FRAME_CONTEXT lfc_a; /* last alt ref entropy */
FRAME_CONTEXT lfc; /* last frame entropy */
FRAME_CONTEXT fc; /* this frame entropy */

View File

@ -58,6 +58,13 @@ unsigned char get_pred_context( VP8_COMMON *const cm,
break;
#if CONFIG_NEWENTROPY
case PRED_MBSKIP:
pred_context = (m - 1)->mbmi.mb_skip_coeff +
(m - cm->mode_info_stride)->mbmi.mb_skip_coeff;
break;
#endif
default:
// TODO *** add error trap code.
pred_context = 0;
@ -96,6 +103,12 @@ vp8_prob get_pred_prob( VP8_COMMON *const cm,
pred_probability = cm->prob_comppred[pred_context];
break;
#if CONFIG_NEWENTROPY
case PRED_MBSKIP:
pred_probability = cm->mbskip_pred_probs[pred_context];
break;
#endif
default:
// TODO *** add error trap code.
pred_probability = 128;
@ -122,6 +135,12 @@ unsigned char get_pred_flag( MACROBLOCKD *const xd,
pred_flag = xd->mode_info_context->mbmi.ref_predicted;
break;
#if CONFIG_NEWENTROPY
case PRED_MBSKIP:
pred_flag = xd->mode_info_context->mbmi.mb_skip_coeff;
break;
#endif
default:
// TODO *** add error trap code.
pred_flag = 0;
@ -147,6 +166,12 @@ void set_pred_flag( MACROBLOCKD *const xd,
xd->mode_info_context->mbmi.ref_predicted = pred_flag;
break;
#if CONFIG_NEWENTROPY
case PRED_MBSKIP:
xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag;
break;
#endif
default:
// TODO *** add error trap code.
break;

View File

@ -21,7 +21,10 @@ typedef enum
{
PRED_SEG_ID = 0, // Segment identifier
PRED_REF = 1,
PRED_COMP = 2
PRED_COMP = 2,
#if CONFIG_NEWENTROPY
PRED_MBSKIP = 3,
#endif
} PRED_ID;

View File

@ -17,6 +17,7 @@
#include "vp8/common/seg_common.h"
#include "vp8/common/pred_common.h"
#include "vp8/common/entropy.h"
#if CONFIG_DEBUG
#include <assert.h>
@ -77,12 +78,14 @@ static void vp8_read_mb_segid(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x)
mi->segment_id = (unsigned char)(vp8_read(r, x->mb_segment_tree_probs[1]));
}
}
extern const int vp8_i8x8_block[4];
static void vp8_kfread_modes(VP8D_COMP *pbi,
MODE_INFO *m,
int mb_row,
int mb_col)
{
VP8_COMMON *const cm = & pbi->common;
vp8_reader *const bc = & pbi->bc;
const int mis = pbi->common.mode_info_stride;
int map_index = mb_row * pbi->common.mb_cols + mb_col;
@ -97,13 +100,20 @@ static void vp8_kfread_modes(VP8D_COMP *pbi,
pbi->common.last_frame_seg_map[map_index] = m->mbmi.segment_id;
}
m->mbmi.mb_skip_coeff = 0;
if ( pbi->common.mb_no_coeff_skip &&
( !segfeature_active( &pbi->mb,
m->mbmi.segment_id, SEG_LVL_EOB ) ||
( get_segdata( &pbi->mb,
m->mbmi.segment_id, SEG_LVL_EOB ) != 0 ) ) )
{
#if CONFIG_NEWENTROPY
MACROBLOCKD *const xd = & pbi->mb;
xd->mode_info_context = m;
m->mbmi.mb_skip_coeff = vp8_read(bc, get_pred_prob(cm, xd, PRED_MBSKIP));
#else
m->mbmi.mb_skip_coeff = vp8_read(bc, pbi->prob_skip_false);
#endif
}
else
{
@ -511,9 +521,21 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
MACROBLOCKD *const xd = & pbi->mb;
#endif
#if CONFIG_NEWENTROPY
vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
#else
pbi->prob_skip_false = 0;
#endif
if (pbi->common.mb_no_coeff_skip)
{
#if CONFIG_NEWENTROPY
int k;
for (k=0; k<MBSKIP_CONTEXTS; ++k)
cm->mbskip_pred_probs[k] = (vp8_prob)vp8_read_literal(bc, 8);
#else
pbi->prob_skip_false = (vp8_prob)vp8_read_literal(bc, 8);
#endif
}
if(pbi->common.frame_type != KEY_FRAME)
{
@ -683,7 +705,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
{
// Read the macroblock coeff skip flag if this feature is in use,
// else default to 0
#if CONFIG_NEWENTROPY
mbmi->mb_skip_coeff = vp8_read(bc, get_pred_prob(cm, xd, PRED_MBSKIP));
#else
mbmi->mb_skip_coeff = vp8_read(bc, pbi->prob_skip_false);
#endif
}
else
{
@ -1034,11 +1060,16 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
{
/*read_mb_modes_mv(pbi, xd->mode_info_context, &xd->mode_info_context->mbmi, mb_row, mb_col);*/
if(pbi->common.frame_type == KEY_FRAME)
{
//printf("<%d %d> \n", mb_row, mb_col);
vp8_kfread_modes(pbi, mi, mb_row, mb_col);
}
else
{
read_mb_modes_mv(pbi, mi, &mi->mbmi,
prev_mi,
mb_row, mb_col);
}
//printf("%3d", mi->mbmi.mode);

View File

@ -97,6 +97,7 @@ void vp8_reset_mb_tokens_context(MACROBLOCKD *x)
}
DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
#define FILL \
if(count < 0) \
VP8DX_BOOL_DECODER_FILL(count, value, bufptr, bufend);
@ -289,7 +290,7 @@ int vp8_decode_mb_tokens_8x8(VP8D_COMP *dx, MACROBLOCKD *x)
INT16 val, bits_count;
INT16 c;
INT16 v;
const vp8_prob *Prob;//
const vp8_prob *Prob;
int seg_eob;
int segment_id = x->mode_info_context->mbmi.segment_id;
@ -323,6 +324,7 @@ BLOCK_LOOP_8x8:
a = A + vp8_block2above_8x8[i];
l = L + vp8_block2left_8x8[i];
c = (INT16)(!type);
// Dest = ((A)!=0) + ((B)!=0);
@ -516,6 +518,7 @@ ONE_CONTEXT_NODE_0_8x8_:
{
qcoeff_ptr [ scan[c] ] = (INT16) v;
++c;
goto DO_WHILE_8x8;
}
}
@ -757,6 +760,7 @@ ONE_CONTEXT_NODE_0_:
qcoeff_ptr [ 15 ] = (INT16) v;
BLOCK_FINISHED:
*a = *l = ((eobs[i] = c) != !type); /* any nonzero data? */
eobtotal += c;
qcoeff_ptr += 16;

View File

@ -151,6 +151,18 @@ static void write_split(vp8_writer *bc, int x)
);
}
static int prob_update_savings(const unsigned int *ct,
const vp8_prob oldp, const vp8_prob newp,
const vp8_prob upd)
{
const int old_b = vp8_cost_branch(ct, oldp);
const int new_b = vp8_cost_branch(ct, newp);
const int update_b = 8 +
((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
return old_b - new_b - update_b;
}
static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
{
const TOKENEXTRA *const stop = p + xcount;
@ -170,10 +182,11 @@ static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
int v = a->value;
int n = a->Len;
/* skip one or two nodes */
if (p->skip_eob_node)
{
n--;
i = 2;
n-=p->skip_eob_node;
i = 2*p->skip_eob_node;
}
do
@ -581,7 +594,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
const int mis = pc->mode_info_stride;
int mb_row = -1;
#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;
@ -599,6 +616,28 @@ 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;
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);
}
#else
if ( (cpi->skip_false_count + cpi->skip_true_count) )
{
prob_skip_false = cpi->skip_false_count * 256 /
@ -615,6 +654,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
cpi->prob_skip_false = prob_skip_false;
vp8_write_literal(w, prob_skip_false, 8);
#endif
}
vp8_write_literal(w, pc->prob_intra_coded, 8);
@ -715,7 +755,12 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
( !segfeature_active( xd, segment_id, SEG_LVL_EOB ) ||
( get_segdata( xd, segment_id, SEG_LVL_EOB ) != 0 ) ) )
{
#if CONFIG_NEWENTROPY
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);
#endif
}
// Encode the reference frame.
@ -920,17 +965,44 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
static void write_kfmodes(VP8_COMP *cpi)
{
vp8_writer *const bc = & cpi->bc;
const VP8_COMMON *const c = & cpi->common;
VP8_COMMON *const c = & cpi->common;
const int mis = c->mode_info_stride;
/* const */
MODE_INFO *m = c->mi;
int mb_row = -1;
#if CONFIG_NEWENTROPY
int prob_skip_false[3] = {0, 0, 0};
#else
int prob_skip_false = 0;
#endif
MACROBLOCKD *xd = &cpi->mb.e_mbd;
if (c->mb_no_coeff_skip)
{
// Divide by 0 check. 0 case possible with segment features
#if CONFIG_NEWENTROPY
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] = 255;
c->mbskip_pred_probs[k] = prob_skip_false[k];
vp8_write_literal(bc, prob_skip_false[k], 8);
}
#else
if ( (cpi->skip_false_count + cpi->skip_true_count) )
{
prob_skip_false = cpi->skip_false_count * 256 /
@ -947,6 +1019,7 @@ static void write_kfmodes(VP8_COMP *cpi)
cpi->prob_skip_false = prob_skip_false;
vp8_write_literal(bc, prob_skip_false, 8);
#endif
}
#if CONFIG_QIMODE
@ -965,6 +1038,8 @@ static void write_kfmodes(VP8_COMP *cpi)
const int ym = m->mbmi.mode;
int segment_id = m->mbmi.segment_id;
xd->mode_info_context = m;
if (cpi->mb.e_mbd.update_mb_segmentation_map)
{
write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
@ -974,7 +1049,12 @@ static void write_kfmodes(VP8_COMP *cpi)
( !segfeature_active( xd, segment_id, SEG_LVL_EOB ) ||
(get_segdata( xd, segment_id, SEG_LVL_EOB ) != 0) ) )
{
#if CONFIG_NEWENTROPY
vp8_encode_bool(bc, m->mbmi.mb_skip_coeff,
get_pred_prob(c, xd, PRED_MBSKIP));
#else
vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
#endif
}
#if CONFIG_QIMODE
kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->kf_ymode_probs_index]);
@ -1018,14 +1098,15 @@ static void write_kfmodes(VP8_COMP *cpi)
write_i8x8_mode(bc, m->bmi[2].as_mode.first, c->i8x8_mode_prob);
write_i8x8_mode(bc, m->bmi[8].as_mode.first, c->i8x8_mode_prob);
write_i8x8_mode(bc, m->bmi[10].as_mode.first, c->i8x8_mode_prob);
m++;
}
else
#if CONFIG_UVINTRA
write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
#else
write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob);
write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob);
#endif
m++;
}
//printf("\n");
m++; // skip L prediction border
@ -1083,18 +1164,6 @@ static void sum_probs_over_prev_coef_context(
}
}
static int prob_update_savings(const unsigned int *ct,
const vp8_prob oldp, const vp8_prob newp,
const vp8_prob upd)
{
const int old_b = vp8_cost_branch(ct, oldp);
const int new_b = vp8_cost_branch(ct, newp);
const int update_b = 8 +
((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
return old_b - new_b - update_b;
}
static int default_coef_context_savings(VP8_COMP *cpi)
{
int savings = 0;
@ -1599,7 +1668,7 @@ static void decide_kf_ymode_entropy(VP8_COMP *cpi)
}
#endif
static segment_reference_frames(VP8_COMP *cpi)
static void segment_reference_frames(VP8_COMP *cpi)
{
VP8_COMMON *oci = &cpi->common;
MODE_INFO *mi = oci->mi;
@ -1624,6 +1693,7 @@ static segment_reference_frames(VP8_COMP *cpi)
}
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
{
int i, j;

View File

@ -693,8 +693,13 @@ static void encode_frame_internal(VP8_COMP *cpi)
cpi->prediction_error = 0;
cpi->intra_error = 0;
#if CONFIG_NEWENTROPY
cpi->skip_true_count[0] = cpi->skip_true_count[1] = cpi->skip_true_count[2] = 0;
cpi->skip_false_count[0] = cpi->skip_false_count[1] = cpi->skip_false_count[2] = 0;
#else
cpi->skip_true_count = 0;
cpi->skip_false_count = 0;
#endif
#if 0
// Experimental code
@ -1052,7 +1057,8 @@ static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x )
int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
{
int rate;
int rate, i;
int mb_skip_context;
// Non rd path deprecated in test code base
//if (cpi->sf.RD && cpi->compressor_speed != 2)
@ -1094,7 +1100,6 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
sum_intra_stats(cpi, x);
vp8_tokenize_mb(cpi, &x->e_mbd, t);
return rate;
}
#ifdef SPEEDSTATS
@ -1363,17 +1368,32 @@ int vp8cx_encode_inter_macroblock
}
else
{
#if CONFIG_NEWENTROPY
int mb_skip_context =
cpi->common.mb_no_coeff_skip ?
(x->e_mbd.mode_info_context-1)->mbmi.mb_skip_coeff +
(x->e_mbd.mode_info_context-cpi->common.mode_info_stride)->mbmi.mb_skip_coeff :
0;
#endif
if (cpi->common.mb_no_coeff_skip)
{
xd->mode_info_context->mbmi.mb_skip_coeff = 1;
#if CONFIG_NEWENTROPY
cpi->skip_true_count[mb_skip_context] ++;
#else
cpi->skip_true_count ++;
#endif
vp8_fix_contexts(xd);
}
else
{
vp8_stuff_mb(cpi, xd, t);
xd->mode_info_context->mbmi.mb_skip_coeff = 0;
#if CONFIG_NEWENTROPY
cpi->skip_false_count[mb_skip_context] ++;
#else
cpi->skip_false_count ++;
#endif
}
}
return rate;

View File

@ -166,7 +166,11 @@ extern void (*vp8_short_fdct8x4)(short *input, short *output, int pitch);
extern void vp8cx_init_quantizer(VP8_COMP *cpi);
#if CONFIG_NEWENTROPY
int vp8cx_base_skip_false_prob[QINDEX_RANGE][3];
#else
int vp8cx_base_skip_false_prob[QINDEX_RANGE];
#endif
// Tables relating active max Q to active min Q
static int kf_low_motion_minq[QINDEX_RANGE];
@ -253,7 +257,7 @@ void init_base_skip_probs()
{
int i;
double q;
int skip_prob;
int skip_prob, t;
for ( i = 0; i < QINDEX_RANGE; i++ )
{
@ -261,13 +265,32 @@ void init_base_skip_probs()
// Exponential decay caluclation of baseline skip prob with clamping
// Based on crude best fit of old table.
skip_prob = (int)( 564.25 * pow( 2.71828, (-0.012*q) ) );
t = (int)( 564.25 * pow( 2.71828, (-0.012*q) ) );
skip_prob = t;
if ( skip_prob < 1 )
skip_prob = 1;
else if ( skip_prob > 255 )
skip_prob = 255;
#if CONFIG_NEWENTROPY
vp8cx_base_skip_false_prob[i][1] = skip_prob;
skip_prob = t * 0.75;
if ( skip_prob < 1 )
skip_prob = 1;
else if ( skip_prob > 255 )
skip_prob = 255;
vp8cx_base_skip_false_prob[i][2] = skip_prob;
skip_prob = t * 1.25;
if ( skip_prob < 1 )
skip_prob = 1;
else if ( skip_prob > 255 )
skip_prob = 255;
vp8cx_base_skip_false_prob[i][0] = skip_prob;
#else
vp8cx_base_skip_false_prob[i] = skip_prob;
#endif
}
}
@ -1826,12 +1849,10 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
vp8_zero(cpi->y_uv_mode_count)
#endif
return (VP8_PTR) cpi;
}
void vp8_remove_compressor(VP8_PTR *ptr)
{
VP8_COMP *cpi = (VP8_COMP *)(*ptr);
@ -1857,7 +1878,7 @@ void vp8_remove_compressor(VP8_PTR *ptr)
vp8_clear_system_state();
printf("\n8x8-4x4:%d-%d\n", cpi->t8x8_count, cpi->t4x4_count);
//printf("\n8x8-4x4:%d-%d\n", cpi->t8x8_count, cpi->t4x4_count);
if (cpi->pass != 1)
{
FILE *f = fopen("opsnr.stt", "a");
@ -3120,14 +3141,28 @@ static void encode_frame_to_data_rate
// setup skip prob for costing in mode/mv decision
if (cpi->common.mb_no_coeff_skip)
{
#if CONFIG_NEWENTROPY
int k;
for (k=0; k<MBSKIP_CONTEXTS; k++)
cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
#else
cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
#endif
if (cm->frame_type != KEY_FRAME)
{
if (cpi->common.refresh_alt_ref_frame)
{
#if CONFIG_NEWENTROPY
for (k=0; k<MBSKIP_CONTEXTS; k++)
{
if (cpi->last_skip_false_probs[2][k] != 0)
cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
}
#else
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 )
@ -3138,8 +3173,16 @@ static void encode_frame_to_data_rate
}
else if (cpi->common.refresh_golden_frame)
{
#if CONFIG_NEWENTROPY
for (k=0; k<MBSKIP_CONTEXTS; k++)
{
if (cpi->last_skip_false_probs[1][k] != 0)
cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
}
#else
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 )
@ -3150,8 +3193,17 @@ static void encode_frame_to_data_rate
}
else
{
#if CONFIG_NEWENTROPY
int k;
for (k=0; k<MBSKIP_CONTEXTS; k++)
{
if (cpi->last_skip_false_probs[0][k] != 0)
cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
}
#else
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 )
@ -3163,6 +3215,22 @@ static void encode_frame_to_data_rate
// as this is for cost estimate, let's make sure it does not
// get extreme either way
#if CONFIG_NEWENTROPY
{
int k;
for (k=0; k<MBSKIP_CONTEXTS; ++k)
{
if (cm->mbskip_pred_probs[k] < 5)
cm->mbskip_pred_probs[k] = 5;
if (cm->mbskip_pred_probs[k] > 250)
cm->mbskip_pred_probs[k] = 250;
if (cpi->is_src_frame_alt_ref)
cm->mbskip_pred_probs[k] = 1;
}
}
#else
if (cpi->prob_skip_false < 5)
cpi->prob_skip_false = 5;
@ -3171,6 +3239,7 @@ static void encode_frame_to_data_rate
if (cpi->is_src_frame_alt_ref)
cpi->prob_skip_false = 1;
#endif
}
@ -3588,21 +3657,44 @@ static void encode_frame_to_data_rate
{
if (cpi->common.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
#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
}
}

View File

@ -491,8 +491,12 @@ typedef struct VP8_COMP
int vert_scale;
int pass;
#if CONFIG_NEWENTROPY
int last_skip_false_probs[3][MBSKIP_CONTEXTS];
#else
int prob_skip_false;
int last_skip_false_probs[3];
#endif
int last_skip_probs_q[3];
int recent_ref_frame_usage[MAX_REF_FRAMES];
@ -510,8 +514,13 @@ typedef struct VP8_COMP
int inter_zz_count;
int gf_bad_count;
int gf_update_recommended;
#if CONFIG_NEWENTROPY
int skip_true_count[3];
int skip_false_count[3];
#else
int skip_true_count;
int skip_false_count;
#endif
int t4x4_count;
int t8x8_count;
@ -539,7 +548,11 @@ typedef struct VP8_COMP
unsigned int time_pick_lpf;
unsigned int time_encode_mb_row;
#if CONFIG_NEWENTROPY
int base_skip_false_prob[QINDEX_RANGE][3];
#else
int base_skip_false_prob[QINDEX_RANGE];
#endif
struct twopass_rc
{

View File

@ -25,7 +25,7 @@ extern int enc_debug;
#define EXACT_QUANT
void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
{
int i, rc, eob, nonzeros;
int i, rc, eob;
int x, y, z, sz;
short *coeff_ptr = b->coeff;
short *round_ptr = b->round;
@ -33,7 +33,6 @@ void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
short *qcoeff_ptr = d->qcoeff;
short *dqcoeff_ptr = d->dqcoeff;
short *dequant_ptr = d->dequant;
vpx_memset(qcoeff_ptr, 0, 32);
vpx_memset(dqcoeff_ptr, 0, 32);
@ -165,9 +164,11 @@ void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d)
dqcoeff_ptr[rc] = x * dq;
/* Remember the last non-zero coefficient. */
if (y)
{
eob = i;
}
}
}
d->eob = eob + 1;
}
@ -264,9 +265,6 @@ void vp8_quantize_mbuv_c(MACROBLOCK *x)
x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
}
void vp8_fast_quantize_b_2x2_c(BLOCK *b, BLOCKD *d)
{
int i, rc, eob;
@ -312,7 +310,6 @@ void vp8_fast_quantize_b_2x2_c(BLOCK *b, BLOCKD *d)
}
}
d->eob = eob + 1;
//if (d->eob > 4) printf("Flag Fast 2 (%d)\n", d->eob);
}
void vp8_fast_quantize_b_8x8_c(BLOCK *b, BLOCKD *d)
@ -537,9 +534,11 @@ void vp8_strict_quantize_b_2x2(BLOCK *b, BLOCKD *d)
dqcoeff_ptr[rc] = x * dq;
/* Remember the last non-zero coefficient. */
if (y)
{
eob = i;
}
}
}
d->eob = eob + 1;
}
@ -596,14 +595,14 @@ void vp8_strict_quantize_b_8x8(BLOCK *b, BLOCKD *d)
dqcoeff_ptr[rc] = x * dq;
/* Remember the last non-zero coefficient. */
if (y)
{
eob = i;
}
}
}
d->eob = eob + 1;
}
void vp8_quantize_mby_8x8(MACROBLOCK *x)
{
int i;

View File

@ -3225,7 +3225,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// cost of signallying 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;
}
@ -3268,20 +3273,32 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
if (mb_skippable)
{
#if CONFIG_NEWENTROPY
vp8_prob skip_prob = get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP);
#endif
int prob_skip_cost;
rate2 -= (rate_y + rate_uv);
//for best_yrd calculation
rate_uv = 0;
#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;
}
#else
// Back out no skip flag costing and add in skip flag costing
if (cpi->prob_skip_false)
{
int prob_skip_cost;
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;
}
#endif
}
}
// Calculate the final RD estimate for this mode

View File

@ -17,14 +17,15 @@
#include "tokenize.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/pred_common.h"
#include "vp8/common/seg_common.h"
/* Global event counters used for accumulating statistics across several
compressions, then generating context.c = initial stats. */
#ifdef ENTROPY_STATS
_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
_int64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
INT64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
#endif
void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
void vp8_stuff_mb_8x8(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
@ -127,7 +128,6 @@ static void tokenize2nd_order_b_8x8
seg_eob = get_segdata( xd, segment_id, SEG_LVL_EOB );
}
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
assert(eob<=4);
@ -135,11 +135,12 @@ static void tokenize2nd_order_b_8x8
do
{
const int band = vp8_coef_bands[c];
int v = 0;
if (c < eob)
{
int rc = vp8_default_zig_zag1d[c];
const int v = qcoeff_ptr[rc];
v = qcoeff_ptr[rc];
assert(-DCT_MAX_VALUE <= v && v < (DCT_MAX_VALUE));
@ -166,6 +167,7 @@ static void tokenize2nd_order_b_8x8
}
while (pt = vp8_prev_token_class[x], ++t, c < eob && ++c <seg_eob);
*tp = t;
pt = (c != !type); /* 0 <-> all coeff data is zero */
*a = *l = pt;
@ -236,6 +238,7 @@ static void tokenize2nd_order_b
t++;
}
*tp = t;
pt = (c != 0); /* 0 <-> all coeff data is zero */
*a = *l = pt;
@ -274,13 +277,14 @@ static void tokenize1st_order_b_8x8
do
{
const int band = vp8_coef_bands_8x8[c];
int v;
x = DCT_EOB_TOKEN;
if (c < eob)
{
int rc = vp8_default_zig_zag1d_8x8[c];
const int v = qcoeff_ptr[rc];
v = qcoeff_ptr[rc];
assert(-DCT_MAX_VALUE <= v && v < (DCT_MAX_VALUE));
@ -307,9 +311,6 @@ static void tokenize1st_order_b_8x8
*a = *l = pt;
}
static void tokenize1st_order_b
(
MACROBLOCKD *xd,
@ -347,7 +348,6 @@ static void tokenize1st_order_b
qcoeff_ptr = b->qcoeff;
a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
c = type ? 0 : 1;
@ -438,7 +438,6 @@ static void tokenize1st_order_b
pt = (c != 0); /* 0 <-> all coeff data is zero */
*a = *l = pt;
}
}
@ -505,6 +504,9 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
int has_y2_block;
int b;
int tx_type = x->mode_info_context->mbmi.txfm_size;
#if CONFIG_NEWENTROPY
int mb_skip_context = get_pred_context(&cpi->common, x, PRED_MBSKIP);
#endif
// If the MB is going to be skipped because of a segment level flag
// exclude this from the skip count stats used to calculate the
@ -531,7 +533,11 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
if (x->mode_info_context->mbmi.mb_skip_coeff)
{
#if CONFIG_NEWENTROPY
cpi->skip_true_count[mb_skip_context] += skip_inc;
#else
cpi->skip_true_count += skip_inc;
#endif
if (!cpi->common.mb_no_coeff_skip)
{
@ -548,7 +554,11 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
return;
}
#if CONFIG_NEWENTROPY
cpi->skip_false_count[mb_skip_context] += skip_inc;
#else
cpi->skip_false_count += skip_inc;
#endif
plane_type = 3;
if(has_y2_block)
@ -647,7 +657,7 @@ void print_context_counters()
do
{
const _int64 x = context_counters [type] [band] [pt] [t];
const INT64 x = context_counters [type] [band] [pt] [t];
const int y = (int) x;
assert(x == (INT64) y); /* no overflow handling yet */
@ -695,10 +705,10 @@ void print_context_counters()
do
{
const _int64 x = context_counters [type] [band] [pt] [t];
const INT64 x = context_counters [type] [band] [pt] [t];
const int y = (int) x;
assert(x == (_int64) y); /* no overflow handling yet */
assert(x == (INT64) y); /* no overflow handling yet */
fprintf(f, "%s %d", Comma(t), y);
}
@ -720,6 +730,7 @@ void print_context_counters()
fprintf(f, "\n};\n");
fclose(f);
}
#endif
@ -751,10 +762,10 @@ static __inline void stuff2nd_order_b_8x8
t->context_tree = cpi->common.fc.coef_probs_8x8 [1] [0] [pt];
//t->section = 11;
t->skip_eob_node = 0;
++cpi->coef_counts_8x8 [1] [0] [pt] [DCT_EOB_TOKEN];
++t;
*tp = t;
++cpi->coef_counts_8x8 [1] [0] [pt] [DCT_EOB_TOKEN];
pt = 0;
*a = *l = pt;
@ -782,9 +793,9 @@ static __inline void stuff1st_order_b_8x8
t->context_tree = cpi->common.fc.coef_probs_8x8 [0] [1] [pt];
//t->section = 8;
t->skip_eob_node = 0;
++cpi->coef_counts_8x8 [0] [1] [pt] [DCT_EOB_TOKEN];
++t;
*tp = t;
++cpi->coef_counts_8x8 [0] [1] [pt] [DCT_EOB_TOKEN];
pt = 0; /* 0 <-> all coeff data is zero */
*a = *l = pt;
@ -814,9 +825,9 @@ void stuff1st_order_buv_8x8
t->context_tree = cpi->common.fc.coef_probs_8x8 [2] [0] [pt];
//t->section = 13;
t->skip_eob_node = 0;
++cpi->coef_counts_8x8[2] [0] [pt] [DCT_EOB_TOKEN];
++t;
*tp = t;
++cpi->coef_counts_8x8[2] [0] [pt] [DCT_EOB_TOKEN];
pt = 0; /* 0 <-> all coeff data is zero */
*a = *l = pt;
@ -871,10 +882,10 @@ static __inline void stuff2nd_order_b
t->Token = DCT_EOB_TOKEN;
t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt];
t->skip_eob_node = 0;
++cpi->coef_counts [1] [0] [pt] [DCT_EOB_TOKEN];
++t;
*tp = t;
++cpi->coef_counts [1] [0] [pt] [DCT_EOB_TOKEN];
pt = 0;
*a = *l = pt;
@ -895,9 +906,9 @@ static __inline void stuff1st_order_b
t->Token = DCT_EOB_TOKEN;
t->context_tree = cpi->common.fc.coef_probs [0] [1] [pt];
t->skip_eob_node = 0;
++cpi->coef_counts [0] [1] [pt] [DCT_EOB_TOKEN];
++t;
*tp = t;
++cpi->coef_counts [0] [1] [pt] [DCT_EOB_TOKEN];
pt = 0; /* 0 <-> all coeff data is zero */
*a = *l = pt;
@ -918,9 +929,9 @@ void stuff1st_order_buv
t->Token = DCT_EOB_TOKEN;
t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt];
t->skip_eob_node = 0;
++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN];
++t;
*tp = t;
++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN];
pt = 0; /* 0 <-> all coeff data is zero */
*a = *l = pt;
@ -963,5 +974,4 @@ void vp8_fix_contexts(MACROBLOCKD *x)
vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
}
}

View File

@ -44,8 +44,29 @@ extern int mb_is_skippable_8x8(MACROBLOCKD *x);
void init_context_counters();
void print_context_counters();
extern _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
extern _int64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
extern INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
extern INT64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
#if CONFIG_NEWENTROPY
void init_nzc_counters();
void print_nzc_counters();
extern INT64 nzc4x4y_counters[MAX_NZC_CONTEXTS][NZC4X4_TOKENS];
extern INT64 nzc4x4y2_counters[MAX_NZC_CONTEXTS][NZC4X4_TOKENS];
extern INT64 nzc4x4uv_counters[MAX_NZC_CONTEXTS][NZC4X4_TOKENS];
extern INT64 nzc8x8y_counters[MAX_NZC_CONTEXTS][NZC8X8_TOKENS];
extern INT64 nzc8x8uv_counters[MAX_NZC_CONTEXTS][NZC8X8_TOKENS];
extern INT64 nzc2x2y2_counters[MAX_NZC_CONTEXTS][NZC2X2_TOKENS];
void init_nzb_counters();
void print_nzb_counters();
extern INT64 nzby_counters[MAX_NZB_CONTEXTS][NZBY_TOKENS];
extern INT64 nzbuv_counters[MAX_NZB_CONTEXTS][NZBUV_TOKENS];
extern INT64 nzby2_counters[MAX_NZB_CONTEXTS][2];
void init_nzb2_counters();
void print_nzb2_counters();
extern INT64 nzb2y_counters[MAX_NZB_CONTEXTS][2];
extern INT64 nzb2uv_counters[MAX_NZB_CONTEXTS][2];
extern INT64 nzb2y2_counters[MAX_NZB_CONTEXTS][2];
#endif
#endif
extern const int *vp8_dct_value_cost_ptr;
/* TODO: The Token field should be broken out into a separate char array to

View File

@ -42,4 +42,3 @@ void vp8_cost_tokens_skip(int *c, const vp8_prob *p, vp8_tree t)
{
cost(c, t, p, 2, 0);
}