diff options
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/bitstream.c | 61 | ||||
-rw-r--r-- | vp9/encoder/encodeframe.c | 1 | ||||
-rw-r--r-- | vp9/encoder/onyx_int.h | 7 | ||||
-rw-r--r-- | vp9/encoder/ratectrl.c | 4 |
4 files changed, 63 insertions, 10 deletions
diff --git a/vp9/encoder/bitstream.c b/vp9/encoder/bitstream.c index ccce910c7..6f2771adc 100644 --- a/vp9/encoder/bitstream.c +++ b/vp9/encoder/bitstream.c @@ -255,6 +255,42 @@ static void update_refpred_stats(VP9_COMP *cpi) { } } +// This function is called to update the mode probability context used to encode +// inter modes. It assumes the branch counts table has already been populated +// prior to the actual packing of the bitstream (in rd stage or dummy pack) +// +// The branch counts table is re-populated during the actual pack stage and in +// the decoder to facilitate backwards update of the context. +static update_mode_probs(VP9_COMMON *cm, + int mode_context[INTER_MODE_CONTEXTS][4]) { + int i, j; + int (*mv_ref_ct)[4][2]; + + vpx_memcpy(mode_context, cm->fc.vp9_mode_contexts, + sizeof(cm->fc.vp9_mode_contexts)); + + mv_ref_ct = cm->fc.mv_ref_ct; + + for (i = 0; i < INTER_MODE_CONTEXTS; i++) { + for (j = 0; j < 4; j++) { + int new_prob, count, old_cost, new_cost; + + // Work out cost of coding branches with the old and optimal probability + old_cost = cost_branch256(mv_ref_ct[i][j], mode_context[i][j]); + count = mv_ref_ct[i][j][0] + mv_ref_ct[i][j][1]; + new_prob = count > 0 ? (255 * mv_ref_ct[i][j][0]) / count : 128; + new_prob = (new_prob > 0) ? new_prob : 1; + new_cost = cost_branch256(mv_ref_ct[i][j], new_prob); + + // If cost saving is >= 14 bits then update the mode probability. + // This is the approximate net cost of updating one probability given + // that the no update case ismuch more common than the update case. + if (new_cost <= (old_cost - (14 << 8))) { + mode_context[i][j] = new_prob; + } + } + } +} static void write_ymode(vp9_writer *bc, int m, const vp9_prob *p) { write_token(bc, vp9_ymode_tree, p, vp9_ymode_encodings + m); } @@ -2076,6 +2112,30 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, active_section = 7; #endif + // If appropriate update the inter mode probability context and code the + // changes in the bitstream. + if ((pc->frame_type != KEY_FRAME)) { + int i, j; + int new_context[INTER_MODE_CONTEXTS][4]; + update_mode_probs(pc, new_context); + + for (i = 0; i < INTER_MODE_CONTEXTS; i++) { + for (j = 0; j < 4; j++) { + if (new_context[i][j] != pc->fc.vp9_mode_contexts[i][j]) { + vp9_write(&header_bc, 1, 252); + vp9_write_literal(&header_bc, new_context[i][j], 8); + + // Only update the persistent copy if this is the "real pack" + if (!cpi->dummy_packing) { + pc->fc.vp9_mode_contexts[i][j] = new_context[i][j]; + } + } else { + vp9_write(&header_bc, 0, 252); + } + } + } + } + vp9_clear_system_state(); // __asm emms; vp9_copy(cpi->common.fc.pre_coef_probs, cpi->common.fc.coef_probs); @@ -2097,7 +2157,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, vp9_zero(cpi->sub_mv_ref_count); vp9_zero(cpi->mbsplit_count); vp9_zero(cpi->common.fc.mv_ref_ct) - vp9_zero(cpi->common.fc.mv_ref_ct_a) update_coef_probs(cpi, &header_bc); diff --git a/vp9/encoder/encodeframe.c b/vp9/encoder/encodeframe.c index 094dc5bab..7ac0bd331 100644 --- a/vp9/encoder/encodeframe.c +++ b/vp9/encoder/encodeframe.c @@ -1399,7 +1399,6 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { vp9_zero(cpi->sub_mv_ref_count) vp9_zero(cpi->mbsplit_count) vp9_zero(cpi->common.fc.mv_ref_ct) - vp9_zero(cpi->common.fc.mv_ref_ct_a) #if CONFIG_SUPERBLOCKS vp9_zero(cpi->sb_ymode_count) cpi->sb_count = 0; diff --git a/vp9/encoder/onyx_int.h b/vp9/encoder/onyx_int.h index e1ddd45fb..1177451e0 100644 --- a/vp9/encoder/onyx_int.h +++ b/vp9/encoder/onyx_int.h @@ -123,10 +123,9 @@ typedef struct { vp9_prob interintra_prob; #endif - int mv_ref_ct[6][4][2]; - int mode_context[6][4]; - int mv_ref_ct_a[6][4][2]; - int mode_context_a[6][4]; + int mv_ref_ct[INTER_MODE_CONTEXTS][4][2]; + int mode_context[INTER_MODE_CONTEXTS][4]; + int mode_context_a[INTER_MODE_CONTEXTS][4]; } CODING_CONTEXT; diff --git a/vp9/encoder/ratectrl.c b/vp9/encoder/ratectrl.c index 097a54d5a..af93d8b42 100644 --- a/vp9/encoder/ratectrl.c +++ b/vp9/encoder/ratectrl.c @@ -135,9 +135,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) { vp9_copy(cc->nmvcosts, cpi->mb.nmvcosts); vp9_copy(cc->nmvcosts_hp, cpi->mb.nmvcosts_hp); - vp9_copy(cc->mv_ref_ct, cm->fc.mv_ref_ct); vp9_copy(cc->mode_context, cm->fc.mode_context); - vp9_copy(cc->mv_ref_ct_a, cm->fc.mv_ref_ct_a); vp9_copy(cc->mode_context_a, cm->fc.mode_context_a); vp9_copy(cc->ymode_prob, cm->fc.ymode_prob); @@ -193,9 +191,7 @@ void vp9_restore_coding_context(VP9_COMP *cpi) { vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts); vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp); - vp9_copy(cm->fc.mv_ref_ct, cc->mv_ref_ct); vp9_copy(cm->fc.mode_context, cc->mode_context); - vp9_copy(cm->fc.mv_ref_ct_a, cc->mv_ref_ct_a); vp9_copy(cm->fc.mode_context_a, cc->mode_context_a); vp9_copy(cm->fc.ymode_prob, cc->ymode_prob); |