]> granicus.if.org Git - libvpx/commitdiff
Generalize and increase frame coding contexts
authorJohn Koleszar <jkoleszar@google.com>
Tue, 15 Jan 2013 23:57:11 +0000 (15:57 -0800)
committerJohn Koleszar <jkoleszar@google.com>
Wed, 16 Jan 2013 22:07:27 +0000 (14:07 -0800)
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

vp9/common/vp9_onyxc_int.h
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_ratectrl.c

index 33ac3f236470eb70f68bcb0c85b1b1e1e3242a9d..46a9ff781ff799f46eb0b1f6899e82b3c4b6e2b9 100644 (file)
@@ -40,6 +40,9 @@ void vp9_initialize_common(void);
 #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 @@ typedef struct VP9Common {
 
   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];
index 9e77d202ef9a6663a85d5d5f8be01e412a72e2f7..ca7b31f715986411f61eccbb4974346f9f2985d1 100644 (file)
@@ -1255,6 +1255,7 @@ static void init_frame(VP9D_COMP *pbi) {
   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,8 +1288,9 @@ static void init_frame(VP9D_COMP *pbi) {
     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));
@@ -1636,13 +1638,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
     /* 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 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
   }
 
   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 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
   }
 
   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
index af8fa495f830fcc37c37865952e1910d41867045..c02ae1b650787cc3f2c0b29e5627fdeda14cd14e 100644 (file)
@@ -1820,6 +1820,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
   }
 
   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)
index 2b9b662a42d186e09c82421051548048a342471d..0f087df1e24d84c32ffad53f13af9326a42e9fe7 100644 (file)
@@ -3939,10 +3939,8 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
   }
 
   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
index 0acd6513d70a6ff5e3630fb2212e0b3c1bfd6242..b5e5fec2fa4aa9125d9aaf3aa916a967792b0557 100644 (file)
@@ -241,6 +241,8 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
 
 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,8 +264,10 @@ void vp9_setup_key_frame(VP9_COMP *cpi) {
   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));
@@ -285,15 +289,15 @@ void vp9_setup_key_frame(VP9_COMP *cpi) {
 }
 
 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));
 }