shithub: libvpx

Download patch

ref: 4b65837bc6d7d341e7c4be078d5a26e0bb717eeb
parent: da832a80e435a6656b15f889bf81df8be22d34a7
author: John Koleszar <jkoleszar@google.com>
date: Tue Jan 15 10:57:11 EST 2013

Generalize and increase frame coding contexts

Previously there were two frame coding contexts tracked, one for normal
frames and one for alt-ref frames. Generalize this by signalling the
context to use in the bitstream, rather than tieing it to the alt ref
refresh bit. Also increase the number of contexts available to 4, which
may be useful for temporal scalability.

Change-Id: I7b66daaddd55c535c20cd16713541fab182b1662

--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -40,6 +40,9 @@
 #define NUM_REF_FRAMES 3
 #define NUM_YV12_BUFFERS (NUM_REF_FRAMES + 1)
 
+#define NUM_FRAME_CONTEXTS_LG2 2
+#define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LG2)
+
 #define COMP_PRED_CONTEXTS   2
 
 typedef struct frame_contexts {
@@ -245,9 +248,9 @@
 
   vp9_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
 
-  FRAME_CONTEXT lfc_a; /* last alt ref entropy */
-  FRAME_CONTEXT lfc; /* last frame entropy */
   FRAME_CONTEXT fc;  /* this frame entropy */
+  FRAME_CONTEXT frame_contexts[NUM_FRAME_CONTEXTS];
+  unsigned int  frame_context_idx; /* Context to use/update */
 
   unsigned int current_video_frame;
   int near_boffset[3];
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1255,6 +1255,7 @@
   MACROBLOCKD *const xd  = &pbi->mb;
 
   if (pc->frame_type == KEY_FRAME) {
+    int i;
 
     if (pc->last_frame_seg_map)
       vpx_memset(pc->last_frame_seg_map, 0, (pc->mb_rows * pc->mb_cols));
@@ -1287,9 +1288,10 @@
     pc->ref_frame_sign_bias[ALTREF_FRAME] = 0;
 
     vp9_init_mode_contexts(&pbi->common);
-    vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
-    vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
 
+    for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
+      vpx_memcpy(&pc->frame_contexts[i], &pc->fc, sizeof(pc->fc));
+
     vpx_memset(pc->prev_mip, 0,
                (pc->mb_cols + 1) * (pc->mb_rows + 1)* sizeof(MODE_INFO));
     vpx_memset(pc->mip, 0,
@@ -1636,13 +1638,6 @@
     /* Should the GF or ARF be updated from the current frame */
     pbi->refresh_frame_flags = vp9_read_literal(&header_bc, NUM_REF_FRAMES);
 
-    /* TODO(jkoleszar): What's the right thing to do here with more refs? */
-    if (pbi->refresh_frame_flags & 0x4) {
-      vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
-    } else {
-      vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
-    }
-
     pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp9_read_bit(&header_bc);
     pc->ref_frame_sign_bias[ALTREF_FRAME] = vp9_read_bit(&header_bc);
 
@@ -1662,9 +1657,9 @@
   }
 
   pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
-  if (pc->refresh_entropy_probs == 0) {
-    vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
-  }
+  pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
+  vpx_memcpy(&pc->fc, &pc->frame_contexts[pc->frame_context_idx],
+             sizeof(pc->fc));
 
   // Read inter mode probability context updates
   if (pc->frame_type != KEY_FRAME) {
@@ -1820,11 +1815,8 @@
   }
 
   if (pc->refresh_entropy_probs) {
-    /* TODO(jkoleszar): What's the right thing to do here with more refs? */
-    if (pbi->refresh_frame_flags & 0x4)
-      vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
-    else
-      vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
+    vpx_memcpy(&pc->frame_contexts[pc->frame_context_idx], &pc->fc,
+               sizeof(pc->fc));
   }
 
 #ifdef PACKET_TESTING
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1820,6 +1820,8 @@
   }
 
   vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
+  vp9_write_literal(&header_bc, pc->frame_context_idx,
+                    NUM_FRAME_CONTEXTS_LG2);
 
 #ifdef ENTROPY_STATS
   if (pc->frame_type == INTER_FRAME)
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -3939,10 +3939,8 @@
   }
 
   if (cm->refresh_entropy_probs) {
-    if (cpi->refresh_alt_ref_frame)
-      vpx_memcpy(&cm->lfc_a, &cm->fc, sizeof(cm->fc));
-    else
-      vpx_memcpy(&cm->lfc, &cm->fc, sizeof(cm->fc));
+    vpx_memcpy(&cm->frame_contexts[cm->frame_context_idx], &cm->fc,
+               sizeof(cm->fc));
   }
 
   // if its a dropped frame honor the requests on subsequent frames
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -241,6 +241,8 @@
 
 void vp9_setup_key_frame(VP9_COMP *cpi) {
   VP9_COMMON *cm = &cpi->common;
+  int i;
+
   // Setup for Key frame:
   vp9_default_coef_probs(& cpi->common);
   vp9_kf_default_bmode_probs(cpi->common.kf_bmode_prob);
@@ -262,9 +264,11 @@
   cpi->refresh_alt_ref_frame = TRUE;
 
   vp9_init_mode_contexts(&cpi->common);
-  vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
-  vpx_memcpy(&cpi->common.lfc_a, &cpi->common.fc, sizeof(cpi->common.fc));
 
+  for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
+    vpx_memcpy(&cpi->common.frame_contexts[i], &cpi->common.fc,
+               sizeof(cpi->common.fc));
+
   vpx_memset(cm->prev_mip, 0,
     (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
   vpx_memset(cm->mip, 0,
@@ -285,15 +289,15 @@
 }
 
 void vp9_setup_inter_frame(VP9_COMP *cpi) {
-  if (cpi->refresh_alt_ref_frame) {
-    vpx_memcpy(&cpi->common.fc,
-               &cpi->common.lfc_a,
-               sizeof(cpi->common.fc));
-  } else {
-    vpx_memcpy(&cpi->common.fc,
-               &cpi->common.lfc,
-               sizeof(cpi->common.fc));
-  }
+  /* Choose which entropy context to use. Currently there are only two
+   * contexts used, one for normal frames and one for alt ref frames.
+   */
+  cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
+
+  assert(cpi->common.frame_context_idx < NUM_FRAME_CONTEXTS);
+  vpx_memcpy(&cpi->common.fc,
+             &cpi->common.frame_contexts[cpi->common.frame_context_idx],
+             sizeof(cpi->common.fc));
 }