summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/bitstream.c61
-rw-r--r--vp9/encoder/encodeframe.c1
-rw-r--r--vp9/encoder/onyx_int.h7
-rw-r--r--vp9/encoder/ratectrl.c4
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);