summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2012-11-16 16:31:32 +0000
committerPaul Wilkins <paulwilkins@google.com>2012-11-16 16:58:00 +0000
commita57dbd957b44a5b72bd404a3b006aaf5a5eb4bc0 (patch)
tree903f8d1bc8424cb02684cfd31ab8fa1f8c97ba18 /vp9/encoder
parent6bca6decbf3cce47f77ccb0bf6a5cc293ce6a186 (diff)
downloadlibvpx-a57dbd957b44a5b72bd404a3b006aaf5a5eb4bc0.tar
libvpx-a57dbd957b44a5b72bd404a3b006aaf5a5eb4bc0.tar.gz
libvpx-a57dbd957b44a5b72bd404a3b006aaf5a5eb4bc0.tar.bz2
libvpx-a57dbd957b44a5b72bd404a3b006aaf5a5eb4bc0.zip
Further experimentation with the mode context
Experiments with a larger set of contexts and some clean up to replace magic numbers regarding the number of contexts. The starting values and rate of backwards adaption are still suspect and based on a small set of tests. Added forwards adjustment of probabilities. The net result of adding the new context and forward update is small compared to the old context from the legacy find_near function. (down a little on derf but up by a similar amount for HD) HOWEVER.... with the new context and forward update the impact of disabling the reverse update (which may be necessary in some use cases to facilitate parallel decoding) is hugely reduced. For the old context without forward update, the impact of turning off reverse update (Experiment was with SB off) was Derf - 0.9, Yt -1.89, ythd -2.75 and sthd -8.35. The impact was mainly at low data rates. With the new context and forward update enabled the impact for all the test sets was no more than 0.5-1% (again most at the low end). Change-Id: Ic751b414c8ce7f7f3ebc6f19a741d774d2b4b556
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);