Cleans up mbskip encoding

Refactors mbskip coding to be compatible with coding of the rest of
the symbols. Adds forward/backward adaptation and removes a lot of
the legacy code.

Results:
fast50: +1.6%
derfraw300: +0.317%

Change-Id: I395a2976d15af044d3b8ded5acfa45f6f065f980
This commit is contained in:
Deb Mukherjee 2013-06-07 13:24:14 -07:00
parent 36f02bf3c1
commit 869a39ba60
12 changed files with 56 additions and 120 deletions

View File

@ -197,6 +197,10 @@ const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS] = {
};
#endif
const vp9_prob vp9_default_mbskip_probs[MBSKIP_CONTEXTS] = {
192, 128, 64
};
void vp9_init_mbmode_probs(VP9_COMMON *x) {
vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs,
sizeof(default_if_uv_probs));
@ -221,6 +225,8 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
sizeof(default_single_ref_p));
vpx_memcpy(x->fc.tx_probs, vp9_default_tx_probs,
sizeof(vp9_default_tx_probs));
vpx_memcpy(x->fc.mbskip_probs, vp9_default_mbskip_probs,
sizeof(vp9_default_mbskip_probs));
}
#if VP9_SWITCHABLE_FILTERS == 3
@ -321,7 +327,7 @@ void vp9_adapt_mode_context(VP9_COMMON *pc) {
#define MODE_COUNT_SAT 20
#define MODE_MAX_UPDATE_FACTOR 144
static int update_mode_ct(int pre_prob, int prob,
static int update_mode_ct(vp9_prob pre_prob, vp9_prob prob,
unsigned int branch_ct[2]) {
int factor, count = branch_ct[0] + branch_ct[1];
count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
@ -344,7 +350,7 @@ static void update_mode_probs(int n_modes,
dst_probs[t] = update_mode_ct(pre_probs[t], probs[t], branch_ct[t]);
}
static int update_mode_ct2(int pre_prob, unsigned int branch_ct[2]) {
static int update_mode_ct2(vp9_prob pre_prob, unsigned int branch_ct[2]) {
return update_mode_ct(pre_prob, get_binary_prob(branch_ct[0],
branch_ct[1]), branch_ct);
}
@ -438,6 +444,9 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
cm->fc.tx_probs[i] = weighted_prob(cm->fc.pre_tx_probs[i], prob, factor);
}
}
for (i = 0; i < MBSKIP_CONTEXTS; ++i)
fc->mbskip_probs[i] = update_mode_ct2(fc->pre_mbskip_probs[i],
fc->mbskip_count[i]);
}
static void set_default_lf_deltas(MACROBLOCKD *xd) {

View File

@ -94,6 +94,10 @@ typedef struct frame_contexts {
unsigned int tx_count_32x32p[TX_SIZE_MAX_SB];
unsigned int tx_count_16x16p[TX_SIZE_MAX_SB - 1];
unsigned int tx_count_8x8p[TX_SIZE_MAX_SB - 2];
vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
vp9_prob pre_mbskip_probs[MBSKIP_CONTEXTS];
unsigned int mbskip_count[MBSKIP_CONTEXTS][2];
} FRAME_CONTEXT;
typedef enum {
@ -244,8 +248,6 @@ typedef struct VP9Common {
MV_REFERENCE_FRAME comp_var_ref[2];
COMPPREDMODE_TYPE comp_pred_mode;
vp9_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
FRAME_CONTEXT fc; /* this frame entropy */
FRAME_CONTEXT frame_contexts[NUM_FRAME_CONTEXTS];
unsigned int frame_context_idx; /* Context to use/update */

View File

@ -368,7 +368,7 @@ vp9_prob vp9_get_pred_prob(const VP9_COMMON *const cm,
case PRED_SEG_ID:
return cm->segment_pred_probs[pred_context];
case PRED_MBSKIP:
return cm->mbskip_pred_probs[pred_context];
return cm->fc.mbskip_probs[pred_context];
case PRED_INTRA_INTER:
return cm->fc.intra_inter_prob[pred_context];
case PRED_COMP_INTER_INTER:

View File

@ -99,8 +99,11 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
m->mbmi.mb_skip_coeff = vp9_segfeature_active(xd, m->mbmi.segment_id,
SEG_LVL_SKIP);
if (!m->mbmi.mb_skip_coeff)
if (!m->mbmi.mb_skip_coeff) {
m->mbmi.mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
[m->mbmi.mb_skip_coeff]++;
}
if (cm->txfm_mode == TX_MODE_SELECT &&
m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
@ -521,8 +524,11 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id,
SEG_LVL_SKIP);
if (!mbmi->mb_skip_coeff)
if (!mbmi->mb_skip_coeff) {
mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
[mbmi->mb_skip_coeff]++;
}
// Read the reference frame
if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_REF_FRAME)) {
@ -788,9 +794,14 @@ void vp9_decode_mode_mvs_init(VP9D_COMP* const pbi, vp9_reader *r) {
int k;
// TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
for (k = 0; k < MBSKIP_CONTEXTS; ++k)
cm->mbskip_pred_probs[k] = vp9_read_prob(r);
// vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
cm->fc.mbskip_probs[k] =
vp9_read_prob_diff_update(r, cm->fc.mbskip_probs[k]);
}
// cm->fc.mbskip_probs[k] = vp9_read_prob(r);
}
mb_mode_mv_init(pbi, r);
}

View File

@ -794,6 +794,7 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob);
vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs);
vp9_copy(fc->pre_tx_probs, fc->tx_probs);
vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs);
vp9_zero(fc->coef_counts);
vp9_zero(fc->eob_branch_counts);
@ -810,6 +811,7 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
vp9_zero(fc->tx_count_8x8p);
vp9_zero(fc->tx_count_16x16p);
vp9_zero(fc->tx_count_32x32p);
vp9_zero(fc->mbskip_count);
}
static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) {

View File

@ -334,13 +334,18 @@ static void update_mbintra_mode_probs(VP9_COMP* const cpi,
(unsigned int *)cpi->y_mode_count[j]);
}
void vp9_update_skip_probs(VP9_COMP *cpi) {
void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *bc) {
VP9_COMMON *const pc = &cpi->common;
int k;
for (k = 0; k < MBSKIP_CONTEXTS; ++k)
pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
cpi->skip_true_count[k]);
for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
vp9_cond_prob_diff_update(bc, &pc->fc.mbskip_probs[k],
VP9_DEF_UPDATE_PROB, pc->fc.mbskip_count[k]);
/*
pc->fc.mbskip_probs[k] = get_binary_prob(pc->fc.mbskip_count[k][0],
pc->fc.mbskip_count[k][1]);
*/
}
}
static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) {
@ -1471,6 +1476,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
vp9_copy(pc->fc.pre_comp_ref_prob, pc->fc.comp_ref_prob);
vp9_copy(pc->fc.pre_single_ref_prob, pc->fc.single_ref_prob);
vp9_copy(pc->fc.pre_tx_probs, pc->fc.tx_probs);
vp9_copy(pc->fc.pre_mbskip_probs, pc->fc.mbskip_probs);
if (xd->lossless) {
pc->txfm_mode = ONLY_4X4;
@ -1484,9 +1490,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
active_section = 2;
#endif
vp9_update_skip_probs(cpi);
for (i = 0; i < MBSKIP_CONTEXTS; ++i)
vp9_write_prob(&header_bc, pc->mbskip_pred_probs[i]);
vp9_update_skip_probs(cpi, &header_bc);
if (pc->frame_type != KEY_FRAME) {
#ifdef ENTROPY_STATS

View File

@ -12,6 +12,6 @@
#ifndef VP9_ENCODER_VP9_BITSTREAM_H_
#define VP9_ENCODER_VP9_BITSTREAM_H_
void vp9_update_skip_probs(VP9_COMP *cpi);
void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *bc);
#endif // VP9_ENCODER_VP9_BITSTREAM_H_

View File

@ -1464,6 +1464,7 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
vp9_zero(cm->fc.tx_count_32x32p);
vp9_zero(cm->fc.tx_count_16x16p);
vp9_zero(cm->fc.tx_count_8x8p);
vp9_zero(cm->fc.mbskip_count);
// Note: this memset assumes above_context[0], [1] and [2]
// are allocated as part of the same buffer.
@ -1518,9 +1519,6 @@ static void encode_frame_internal(VP9_COMP *cpi) {
// Reset frame count of inter 0,0 motion vector usage.
cpi->inter_zz_count = 0;
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;
vp9_zero(cm->fc.switchable_interp_count);
vp9_zero(cpi->best_switchable_interp_count);
@ -2041,7 +2039,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
mbmi->mb_skip_coeff = 1;
if (output_enabled)
cpi->skip_true_count[mb_skip_context]++;
cm->fc.mbskip_count[mb_skip_context][1]++;
vp9_reset_sb_tokens_context(xd,
(bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize);
}

View File

@ -96,11 +96,6 @@ FILE *kf_list;
FILE *keyfile;
#endif
#if 0
extern int skip_true_count;
extern int skip_false_count;
#endif
#ifdef ENTROPY_STATS
extern int intra_mode_stats[VP9_INTRA_MODES]
@ -123,8 +118,6 @@ extern unsigned __int64 Sectionbits[500];
extern void vp9_init_quantizer(VP9_COMP *cpi);
static int base_skip_false_prob[QINDEX_RANGE][3];
// Tables relating active max Q to active min Q
static int kf_low_motion_minq[QINDEX_RANGE];
static int kf_high_motion_minq[QINDEX_RANGE];
@ -201,49 +194,6 @@ static void set_mvcost(MACROBLOCK *mb) {
mb->mvsadcost = mb->nmvsadcost;
}
}
static void init_base_skip_probs(void) {
int i;
for (i = 0; i < QINDEX_RANGE; i++) {
const double q = vp9_convert_qindex_to_q(i);
// Exponential decay caluclation of baseline skip prob with clamping
// Based on crude best fit of old table.
const int t = (int)(564.25 * pow(2.71828, (-0.012 * q)));
base_skip_false_prob[i][1] = clip_prob(t);
base_skip_false_prob[i][2] = clip_prob(t * 3 / 4);
base_skip_false_prob[i][0] = clip_prob(t * 5 / 4);
}
}
static void update_base_skip_probs(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
int k;
if (cm->frame_type != KEY_FRAME) {
vp9_update_skip_probs(cpi);
if (cpi->refresh_alt_ref_frame) {
for (k = 0; k < MBSKIP_CONTEXTS; ++k)
cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
cpi->last_skip_probs_q[2] = cm->base_qindex;
} else if (cpi->refresh_golden_frame) {
for (k = 0; k < MBSKIP_CONTEXTS; ++k)
cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
cpi->last_skip_probs_q[1] = cm->base_qindex;
} else {
for (k = 0; k < MBSKIP_CONTEXTS; ++k)
cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
cpi->last_skip_probs_q[0] = cm->base_qindex;
// update the baseline table for the current q
for (k = 0; k < MBSKIP_CONTEXTS; ++k)
cpi->base_skip_false_prob[cm->base_qindex][k] =
cm->mbskip_pred_probs[k];
}
}
}
void vp9_initialize_enc() {
static int init_done = 0;
@ -254,7 +204,7 @@ void vp9_initialize_enc() {
vp9_init_quant_tables();
vp9_init_me_luts();
init_minq_luts();
init_base_skip_probs();
// init_base_skip_probs();
init_done = 1;
}
}
@ -1288,7 +1238,6 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
init_config((VP9_PTR)cpi, oxcf);
memcpy(cpi->base_skip_false_prob, base_skip_false_prob, sizeof(base_skip_false_prob));
cpi->common.current_video_frame = 0;
cpi->kf_overspend_bits = 0;
cpi->kf_bitrate_adjustment = 0;
@ -2741,44 +2690,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_set_quantizer(cpi, q);
if (loop_count == 0) {
int k;
// setup skip prob for costing in mode/mv decision
for (k = 0; k < MBSKIP_CONTEXTS; k++)
cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[q][k];
if (cm->frame_type != KEY_FRAME) {
if (cpi->refresh_alt_ref_frame) {
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->refresh_golden_frame) {
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 {
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];
}
}
// as this is for cost estimate, let's make sure it does not
// get extreme either way
{
int k;
for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
cm->mbskip_pred_probs[k] = clamp(cm->mbskip_pred_probs[k],
5, 250);
if (cpi->is_src_frame_alt_ref)
cm->mbskip_pred_probs[k] = 1;
}
}
}
// Set up entropy depending on frame type.
if (cm->frame_type == KEY_FRAME) {
@ -2804,7 +2715,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Update the skip mb flag probabilities based on the distribution
// seen in the last encoder iteration.
update_base_skip_probs(cpi);
// update_base_skip_probs(cpi);
vp9_clear_system_state(); // __asm emms;
@ -3170,7 +3081,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Update the skip mb flag probabilities based on the distribution seen
// in this frame.
update_base_skip_probs(cpi);
// update_base_skip_probs(cpi);
#if 0 && CONFIG_INTERNAL_STATS
{

View File

@ -90,6 +90,7 @@ typedef struct {
vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
vp9_prob tx_probs[TX_SIZE_PROBS];
vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
} CODING_CONTEXT;
typedef struct {
@ -459,8 +460,6 @@ typedef struct VP9_COMP {
int inter_zz_count;
int gf_bad_count;
int gf_update_recommended;
int skip_true_count[3];
int skip_false_count[3];
unsigned char *segmentation_map;
@ -480,8 +479,6 @@ typedef struct VP9_COMP {
uint64_t time_pick_lpf;
uint64_t time_encode_mb_row;
int base_skip_false_prob[QINDEX_RANGE][3];
struct twopass_rc {
unsigned int section_intra_rating;
unsigned int next_iiratio;

View File

@ -144,6 +144,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
vp9_copy(cc->coef_probs, cm->fc.coef_probs);
vp9_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob);
vp9_copy(cc->tx_probs, cm->fc.tx_probs);
vp9_copy(cc->mbskip_probs, cm->fc.mbskip_probs);
}
void vp9_restore_coding_context(VP9_COMP *cpi) {
@ -182,6 +183,7 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
vp9_copy(cm->fc.coef_probs, cc->coef_probs);
vp9_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob);
vp9_copy(cm->fc.tx_probs, cc->tx_probs);
vp9_copy(cm->fc.mbskip_probs, cc->mbskip_probs);
}
void vp9_setup_key_frame(VP9_COMP *cpi) {

View File

@ -294,7 +294,7 @@ void vp9_tokenize_sb(VP9_COMP *cpi,
if (mbmi->mb_skip_coeff) {
if (!dry_run)
cpi->skip_true_count[mb_skip_context] += skip_inc;
cm->fc.mbskip_count[mb_skip_context][1] += skip_inc;
vp9_reset_sb_tokens_context(xd, bsize);
if (dry_run)
*t = t_backup;
@ -302,7 +302,7 @@ void vp9_tokenize_sb(VP9_COMP *cpi,
}
if (!dry_run)
cpi->skip_false_count[mb_skip_context] += skip_inc;
cm->fc.mbskip_count[mb_skip_context][0] += skip_inc;
foreach_transformed_block(xd, bsize, tokenize_b, &arg);