From 869a39ba60379b031573ed5ba1911088d353a3c1 Mon Sep 17 00:00:00 2001 From: Deb Mukherjee Date: Fri, 7 Jun 2013 13:24:14 -0700 Subject: [PATCH] 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 --- vp9/common/vp9_entropymode.c | 13 ++++- vp9/common/vp9_onyxc_int.h | 6 ++- vp9/common/vp9_pred_common.c | 2 +- vp9/decoder/vp9_decodemv.c | 21 ++++++-- vp9/decoder/vp9_decodframe.c | 2 + vp9/encoder/vp9_bitstream.c | 18 ++++--- vp9/encoder/vp9_bitstream.h | 2 +- vp9/encoder/vp9_encodeframe.c | 6 +-- vp9/encoder/vp9_onyx_if.c | 95 ++--------------------------------- vp9/encoder/vp9_onyx_int.h | 5 +- vp9/encoder/vp9_ratectrl.c | 2 + vp9/encoder/vp9_tokenize.c | 4 +- 12 files changed, 56 insertions(+), 120 deletions(-) diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index bf57e7ecc..a70d1a5d4 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c @@ -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) { diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index dedda2069..4cb60f196 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -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 */ diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c index 73c7278b0..f5ea9a48a 100644 --- a/vp9/common/vp9_pred_common.c +++ b/vp9/common/vp9_pred_common.c @@ -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: diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 82ea7dc96..8ecf4c983 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -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); } diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index deb39561d..989fbc0c0 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -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) { diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 2070432b2..0e298e016 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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 diff --git a/vp9/encoder/vp9_bitstream.h b/vp9/encoder/vp9_bitstream.h index f7a8ece64..b3dbee1a7 100644 --- a/vp9/encoder/vp9_bitstream.h +++ b/vp9/encoder/vp9_bitstream.h @@ -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_ diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index d7810dd66..72c530a18 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -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); } diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 65efb548c..13ed345f0 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -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 { diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index b8a60d2f2..259fd277b 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -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; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 60ca355c5..7a5d23a77 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -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) { diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c index cb05219dd..0a290e124 100644 --- a/vp9/encoder/vp9_tokenize.c +++ b/vp9/encoder/vp9_tokenize.c @@ -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); -- 2.40.0