]> granicus.if.org Git - libvpx/commitdiff
Added MACRO for reference frame encoding
authorZoe Liu <zoeliu@google.com>
Fri, 11 Sep 2015 21:57:31 +0000 (14:57 -0700)
committerZoe Liu <zoeliu@google.com>
Fri, 11 Sep 2015 21:57:31 +0000 (14:57 -0700)
This CL introduces a few macros plus code cleaning on the encoding of
the reference frames. Coding performance remains unchanged.

For the encoding of either the compound reference or the single reference
case, since each bit has different contexts, the tree structure may not
be applied to treat the combined bits as one symbol. It is possible we may
explore the sharing of the same context for all the bits to introduce
the use of tree structure for the next step.

Change-Id: I6916ae53c66be1a0b23e6273811c0139515484df

vp9/common/vp9_blockd.h
vp9/common/vp9_entropymode.c
vp9/common/vp9_entropymode.h
vp9/common/vp9_pred_common.h
vp9/decoder/vp9_decodeframe.c
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c

index 9d2d3b0ad9c39d9ed004f7ef09b600c7c1888f89..82403dad2c2c077a617e855e165af7eb0630b2ff 100644 (file)
@@ -66,6 +66,14 @@ extern "C" {
 #define COMP_INTER_CONTEXTS 5
 #define REF_CONTEXTS 5
 
+#if CONFIG_MULTI_REF
+#define SINGLE_REFS 4
+#define COMP_REFS 3
+#else
+#define SINGLE_REFS 3
+#define COMP_REFS 2
+#endif  // CONFIG_MULTI_REF
+
 typedef enum {
   PLANE_TYPE_Y  = 0,
   PLANE_TYPE_UV = 1,
index 6cb0951f7c17ff9f7b7574f47276c57b49a8dff2..3f46412db3882647b7def7b99a1f8c6669a6dec7 100644 (file)
@@ -415,36 +415,60 @@ static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
   239, 183, 119,  96,  41
 };
 
+static const vp9_prob default_single_ref_probs[REF_CONTEXTS][SINGLE_REFS - 1] =
+{
 #if CONFIG_MULTI_REF
-// TODO(zoeliu): To adjust the initial prob values.
-static const vp9_prob default_comp_ref_p[REF_CONTEXTS][2] = {
-  {  33,  16 },
-  {  77,  74 },
-  { 142, 142 },
-  { 172, 170 },
-  { 238, 247 }
-};
-
-static const vp9_prob default_single_ref_p[REF_CONTEXTS][3] = {
+  // TODO(zoeliu): To adjust the initial prob values.
   {  33,  16,  16 },
   {  77,  74,  74 },
   { 142, 142, 142 },
   { 172, 170, 170 },
   { 238, 247, 247 }
-};
 #else
-static const vp9_prob default_comp_ref_p[REF_CONTEXTS] = {
-  50, 126, 123, 221, 226
+  {  33,  16 },
+  {  77,  74 },
+  { 142, 142 },
+  { 172, 170 },
+  { 238, 247 }
+#endif  // CONFIG_MULTI_REF
 };
 
-static const vp9_prob default_single_ref_p[REF_CONTEXTS][2] = {
+static const vp9_prob default_comp_ref_probs[REF_CONTEXTS][COMP_REFS - 1] = {
+#if CONFIG_MULTI_REF
+  // TODO(zoeliu): To adjust the initial prob values.
   {  33,  16 },
   {  77,  74 },
   { 142, 142 },
   { 172, 170 },
   { 238, 247 }
+#else
+  { 50 }, { 126 }, { 123 }, { 221 }, { 226 }
+#endif  // CONFIG_MULTI_REF
 };
+
+/*
+// TODO(zoeliu): Tree structure may be introduced when all bits of the encoding
+// of either the compound or the single references share the same contexts.
+const vp9_tree_index vp9_comp_ref_tree[TREE_SIZE(COMP_REFS)] = {
+#if CONFIG_MULTI_REF
+  -REF_OFFSET(GOLDEN_FRAME), 2,
+  -REF_OFFSET(LAST_FRAME), -REF_OFFSET(LAST2_FRAME)
+#else
+  -REF_OFFSET(GOLDEN_FRAME), -REF_OFFSET(LAST_FRAME)
 #endif  // CONFIG_MULTI_REF
+};
+
+const vp9_tree_index vp9_single_ref_tree[TREE_SIZE(SINGLE_REFS)] = {
+#if CONFIG_MULTI_REF
+  2, 4,
+  -REF_OFFSET(ALTREF_FRAME), -REF_OFFSET(GOLDEN_FRAME),
+  -REF_OFFSET(LAST2_FRAME), -REF_OFFSET(LAST_FRAME)
+#else
+  2, -REF_OFFSET(LAST_FRAME),
+  -REF_OFFSET(ALTREF_FRAME), -REF_OFFSET(GOLDEN_FRAME)
+#endif  // CONFIG_MULTI_REF
+};
+*/
 
 static const struct tx_probs default_tx_probs = {
 #if CONFIG_TX64X64
@@ -1000,8 +1024,8 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
   vp9_copy(fc->partition_prob, default_partition_probs);
   vp9_copy(fc->intra_inter_prob, default_intra_inter_p);
   vp9_copy(fc->comp_inter_prob, default_comp_inter_p);
-  vp9_copy(fc->comp_ref_prob, default_comp_ref_p);
-  vp9_copy(fc->single_ref_prob, default_single_ref_p);
+  vp9_copy(fc->single_ref_probs, default_single_ref_probs);
+  vp9_copy(fc->comp_ref_probs, default_comp_ref_probs);
   fc->tx_probs = default_tx_probs;
   vp9_copy(fc->skip_probs, default_skip_probs);
   vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
@@ -1083,25 +1107,19 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
   for (i = 0; i < COMP_INTER_CONTEXTS; i++)
     fc->comp_inter_prob[i] = adapt_prob(pre_fc->comp_inter_prob[i],
                                         counts->comp_inter[i]);
+
   for (i = 0; i < REF_CONTEXTS; i++) {
-#if CONFIG_MULTI_REF
-    for (j = 0; j < 2; j++)
-      fc->comp_ref_prob[i][j] = adapt_prob(pre_fc->comp_ref_prob[i][j],
-                                           counts->comp_ref[i][j]);
-#else
-    fc->comp_ref_prob[i] = adapt_prob(pre_fc->comp_ref_prob[i],
-                                      counts->comp_ref[i]);
-#endif  // CONFIG_MULTI_REF
+    for (j = 0; j < (SINGLE_REFS - 1); j++) {
+      fc->single_ref_probs[i][j] = adapt_prob(pre_fc->single_ref_probs[i][j],
+                                              counts->single_ref[i][j]);
+    }
   }
 
   for (i = 0; i < REF_CONTEXTS; i++) {
-#if CONFIG_MULTI_REF
-    for (j = 0; j < 3; j++)
-#else
-    for (j = 0; j < 2; j++)
-#endif  // CONFIG_MULTI_REF
-      fc->single_ref_prob[i][j] = adapt_prob(pre_fc->single_ref_prob[i][j],
-                                             counts->single_ref[i][j]);
+    for (j = 0; j < (COMP_REFS - 1); j++) {
+      fc->comp_ref_probs[i][j] = adapt_prob(pre_fc->comp_ref_probs[i][j],
+                                            counts->comp_ref[i][j]);
+    }
   }
 
   for (i = 0; i < INTER_MODE_CONTEXTS; i++)
index a7963925c2ccb4c13a783af399991261f52a21d7..d8e5f4cae3ff5fa48ab27ae2eda718df145fd72f 100644 (file)
@@ -74,13 +74,8 @@ typedef struct frame_contexts {
 #endif  // CONFIG_NEW_INTER
   vp9_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
   vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS];
-#if CONFIG_MULTI_REF
-  vp9_prob single_ref_prob[REF_CONTEXTS][3];
-  vp9_prob comp_ref_prob[REF_CONTEXTS][2];
-#else
-  vp9_prob single_ref_prob[REF_CONTEXTS][2];
-  vp9_prob comp_ref_prob[REF_CONTEXTS];
-#endif  // CONFIG_MULTI_REF
+  vp9_prob single_ref_probs[REF_CONTEXTS][SINGLE_REFS - 1];
+  vp9_prob comp_ref_probs[REF_CONTEXTS][COMP_REFS - 1];
   struct tx_probs tx_probs;
   vp9_prob skip_probs[SKIP_CONTEXTS];
   nmv_context nmvc;
@@ -159,13 +154,8 @@ typedef struct {
 #endif  // CONFIG_NEW_INTER
   unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
   unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
-#if CONFIG_MULTI_REF
-  unsigned int single_ref[REF_CONTEXTS][3][2];
-  unsigned int comp_ref[REF_CONTEXTS][2][2];
-#else
-  unsigned int single_ref[REF_CONTEXTS][2][2];
-  unsigned int comp_ref[REF_CONTEXTS][2];
-#endif  // CONFIG_MULTI_REF
+  unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
+  unsigned int comp_ref[REF_CONTEXTS][COMP_REFS-1][2];
   struct tx_counts tx;
   unsigned int skip[SKIP_CONTEXTS][2];
   nmv_context_counts mv;
index 8c16f744e8fe256224f6081f3aaff725a24b7027..b91c4f9f1d908dff1834a381a0a21e2c73799a68 100644 (file)
@@ -127,11 +127,7 @@ int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
 static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p(const VP9_COMMON *cm,
                                                     const MACROBLOCKD *xd) {
   const int pred_context = vp9_get_pred_context_comp_ref_p(cm, xd);
-#if CONFIG_MULTI_REF
-  return cm->fc.comp_ref_prob[pred_context][0];
-#else
-  return cm->fc.comp_ref_prob[pred_context];
-#endif  // CONFIG_MULTI_REF
+  return cm->fc.comp_ref_probs[pred_context][0];
 }
 
 #if CONFIG_MULTI_REF
@@ -141,7 +137,7 @@ int vp9_get_pred_context_comp_ref_p1(const VP9_COMMON *cm,
 static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p1(const VP9_COMMON *cm,
                                                      const MACROBLOCKD *xd) {
   const int pred_context = vp9_get_pred_context_comp_ref_p1(cm, xd);
-  return cm->fc.comp_ref_prob[pred_context][1];
+  return cm->fc.comp_ref_probs[pred_context][1];
 }
 #endif  // CONFIG_MULTI_REF
 
@@ -149,14 +145,14 @@ int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
 
 static INLINE vp9_prob vp9_get_pred_prob_single_ref_p1(const VP9_COMMON *cm,
                                                        const MACROBLOCKD *xd) {
-  return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p1(xd)][0];
+  return cm->fc.single_ref_probs[vp9_get_pred_context_single_ref_p1(xd)][0];
 }
 
 int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
 
 static INLINE vp9_prob vp9_get_pred_prob_single_ref_p2(const VP9_COMMON *cm,
                                                        const MACROBLOCKD *xd) {
-  return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p2(xd)][1];
+  return cm->fc.single_ref_probs[vp9_get_pred_context_single_ref_p2(xd)][1];
 }
 
 #if CONFIG_MULTI_REF
@@ -164,7 +160,7 @@ int vp9_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
 
 static INLINE vp9_prob vp9_get_pred_prob_single_ref_p3(const VP9_COMMON *cm,
                                                        const MACROBLOCKD *xd) {
-  return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p3(xd)][2];
+  return cm->fc.single_ref_probs[vp9_get_pred_context_single_ref_p3(xd)][2];
 }
 #endif  // CONFIG_MULTI_REF
 
index 606ee4d77e7065ee895862576d9477cf94a1bfa6..65b8c563ce5e9a4488b13ccfa53472712b713f4d 100644 (file)
@@ -164,7 +164,7 @@ static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm,
 
 static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
   FRAME_CONTEXT *const fc = &cm->fc;
-  int i;
+  int i, j;
 
   if (cm->reference_mode == REFERENCE_MODE_SELECT)
     for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
@@ -172,21 +172,16 @@ static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
 
   if (cm->reference_mode != COMPOUND_REFERENCE)
     for (i = 0; i < REF_CONTEXTS; ++i) {
-      vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]);
-      vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]);
-#if CONFIG_MULTI_REF
-      vp9_diff_update_prob(r, &fc->single_ref_prob[i][2]);
-#endif  // CONFIG_MULTI_REF
+      for (j = 0; j < (SINGLE_REFS - 1); ++j) {
+        vp9_diff_update_prob(r, &fc->single_ref_probs[i][j]);
+      }
     }
 
   if (cm->reference_mode != SINGLE_REFERENCE)
     for (i = 0; i < REF_CONTEXTS; ++i) {
-#if CONFIG_MULTI_REF
-      vp9_diff_update_prob(r, &fc->comp_ref_prob[i][0]);
-      vp9_diff_update_prob(r, &fc->comp_ref_prob[i][1]);
-#else
-      vp9_diff_update_prob(r, &fc->comp_ref_prob[i]);
-#endif  // CONFIG_MULTI_REF
+      for (j = 0; j < (COMP_REFS - 1); ++j) {
+        vp9_diff_update_prob(r, &fc->comp_ref_probs[i][j]);
+      }
     }
 }
 
index 442aca5cfa64602f767a1a0842a2cad3ed96c202..1a77f77c2694a8ac20f2a76e843d4a0ca4381f21 100644 (file)
@@ -767,25 +767,17 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
     if (mode == COMPOUND_REFERENCE) {
       const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
       const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
-#if CONFIG_MULTI_REF
-      const int bit = vp9_read(r, fc->comp_ref_prob[ctx][0]);
-#else
-      const int bit = vp9_read(r, fc->comp_ref_prob[ctx]);
-#endif  // CONFIG_MULTI_REF
+      const int bit = vp9_read(r, fc->comp_ref_probs[ctx][0]);
 
       if (!cm->frame_parallel_decoding_mode)
-#if CONFIG_MULTI_REF
         ++counts->comp_ref[ctx][0][bit];
-#else
-        ++counts->comp_ref[ctx][bit];
-#endif  // CONFIG_MULTI_REF
 
       ref_frame[idx] = cm->comp_fixed_ref;
 
 #if CONFIG_MULTI_REF
       if (!bit) {
         const int ctx1 = vp9_get_pred_context_comp_ref_p1(cm, xd);
-        const int bit1 = vp9_read(r, fc->comp_ref_prob[ctx1][1]);
+        const int bit1 = vp9_read(r, fc->comp_ref_probs[ctx1][1]);
 
         if (!cm->frame_parallel_decoding_mode)
           ++counts->comp_ref[ctx1][1][bit1];
@@ -800,30 +792,30 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
     } else if (mode == SINGLE_REFERENCE) {
 #if CONFIG_MULTI_REF
       const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
-      const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
+      const int bit0 = vp9_read(r, fc->single_ref_probs[ctx0][0]);
       if (!cm->frame_parallel_decoding_mode)
         ++counts->single_ref[ctx0][0][bit0];
       if (bit0) {
         const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
-        const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
+        const int bit1 = vp9_read(r, fc->single_ref_probs[ctx1][1]);
         if (!cm->frame_parallel_decoding_mode)
           ++counts->single_ref[ctx1][1][bit1];
         ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
       } else {
         const int ctx2 = vp9_get_pred_context_single_ref_p3(xd);
-        const int bit2 = vp9_read(r, fc->single_ref_prob[ctx2][2]);
+        const int bit2 = vp9_read(r, fc->single_ref_probs[ctx2][2]);
         if (!cm->frame_parallel_decoding_mode)
           ++counts->single_ref[ctx2][2][bit2];
         ref_frame[0] = bit2 ? LAST2_FRAME : LAST_FRAME;
       }
 #else
       const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
-      const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
+      const int bit0 = vp9_read(r, fc->single_ref_probs[ctx0][0]);
       if (!cm->frame_parallel_decoding_mode)
         ++counts->single_ref[ctx0][0][bit0];
       if (bit0) {
         const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
-        const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
+        const int bit1 = vp9_read(r, fc->single_ref_probs[ctx1][1]);
         if (!cm->frame_parallel_decoding_mode)
           ++counts->single_ref[ctx1][1][bit1];
         ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
index 6b5d907eca76e2d454f623c3d6a28b75a12c56df..d0e900fafc520da96b55f165ad0b60c93e88aaa8 100644 (file)
@@ -2516,7 +2516,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
 #endif  // CONFIG_SR_MODE
 
   if (!frame_is_intra_only(cm)) {
-    int i;
+    int i, j;
     for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
       prob_diff_update(vp9_inter_mode_tree, cm->fc.inter_mode_probs[i],
                        cm->counts.inter_mode[i], INTER_MODES, &header_bc);
@@ -2551,28 +2551,19 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
 
     if (cm->reference_mode != COMPOUND_REFERENCE) {
       for (i = 0; i < REF_CONTEXTS; i++) {
-        vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
-                                  cm->counts.single_ref[i][0]);
-        vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
-                                  cm->counts.single_ref[i][1]);
-#if CONFIG_MULTI_REF
-        vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][2],
-                                  cm->counts.single_ref[i][2]);
-#endif  // CONFIG_MULTI_REF
+        for (j = 0; j < (SINGLE_REFS - 1); j++) {
+          vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_probs[i][j],
+                                    cm->counts.single_ref[i][j]);
+        }
       }
     }
 
     if (cm->reference_mode != SINGLE_REFERENCE) {
       for (i = 0; i < REF_CONTEXTS; i++) {
-#if CONFIG_MULTI_REF
-        vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][0],
-                                  cm->counts.comp_ref[i][0]);
-        vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][1],
-                                  cm->counts.comp_ref[i][1]);
-#else
-        vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
-                                  cm->counts.comp_ref[i]);
-#endif  // CONFIG_MULTI_REF
+        for (j = 0; j < (COMP_REFS - 1); j++) {
+          vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_probs[i][j],
+                                    cm->counts.comp_ref[i][j]);
+        }
       }
     }
 
index 72cc139f0bc978fb982675fa72673c32af29c7a2..0f801a3703243206aea962815e0713ed8878cc3e 100644 (file)
@@ -1522,16 +1522,13 @@ static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) {
                             [has_second_ref(mbmi)]++;
 
         if (has_second_ref(mbmi)) {
-#if CONFIG_MULTI_REF
           counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)][0]
                           [ref0 == GOLDEN_FRAME]++;
+#if CONFIG_MULTI_REF
           if (ref0 != GOLDEN_FRAME) {
             counts->comp_ref[vp9_get_pred_context_comp_ref_p1(cm, xd)][1]
                             [ref0 == LAST_FRAME]++;
           }
-#else
-          counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
-                          [ref0 == GOLDEN_FRAME]++;
 #endif  // CONFIG_MULTI_REF
         } else {
 #if CONFIG_MULTI_REF