]> granicus.if.org Git - libvpx/commitdiff
New b-intra mode where direction is contextual
authorDeb Mukherjee <debargha@google.com>
Tue, 9 Oct 2012 20:19:15 +0000 (13:19 -0700)
committerDeb Mukherjee <debargha@google.com>
Sat, 10 Nov 2012 15:12:30 +0000 (07:12 -0800)
Preliminary patch on a new 4x4 intra mode B_CONTEXT_PRED where the
dominant direction from the context is used to encode. Various decoder
changes are needed to support decoding of B_CONTEXT_PRED in conjunction
with hybrid transforms since the scan order and tokenization depends on
the actual direction of prediction obtained from the context. Currently
the traditional directional modes are used in conjunction with the
B_CONTEXT_PRED, which also seems to provide the best results.

The gains are small - in the 0.1% range.

Change-Id: I5a7ea80b5218f42a9c0dfb42d3f79a68c7f0cdc2

23 files changed:
configure
vp9/common/blockd.h
vp9/common/entropymode.c
vp9/common/entropymode.h
vp9/common/findnearmv.c
vp9/common/modecontext.c
vp9/common/onyxc_int.h
vp9/common/reconintra.c
vp9/common/reconintra.h
vp9/common/reconintra4x4.c
vp9/decoder/decodemv.c
vp9/decoder/decodframe.c
vp9/decoder/detokenize.c
vp9/decoder/detokenize.h
vp9/encoder/bitstream.c
vp9/encoder/block.h
vp9/encoder/encodeframe.c
vp9/encoder/encodeintra.c
vp9/encoder/modecosts.c
vp9/encoder/onyx_if.c
vp9/encoder/onyx_int.h
vp9/encoder/ratectrl.c
vp9/encoder/rdopt.c

index d52052504fc627d45e0c19580ea0a3a16503efbe..c1ee96dda6063736ede6dfe9f7e9fe66812e53b4 100755 (executable)
--- a/configure
+++ b/configure
@@ -245,6 +245,7 @@ EXPERIMENT_LIST="
     subpelrefmv
     new_mvref
     implicit_segmentation
+    newbintramodes
 "
 CONFIG_LIST="
     external_build
index 9d5eedc58fad46b9088ef55405b88b5d6e855671..86233548367e5f2c5df4114d3f5df4288f70e380 100644 (file)
@@ -149,8 +149,8 @@ typedef enum {
   B_DC_PRED,          /* average of above and left pixels */
   B_TM_PRED,
 
-  B_VE_PRED,           /* vertical prediction */
-  B_HE_PRED,           /* horizontal prediction */
+  B_VE_PRED,          /* vertical prediction */
+  B_HE_PRED,          /* horizontal prediction */
 
   B_LD_PRED,
   B_RD_PRED,
@@ -159,6 +159,9 @@ typedef enum {
   B_VL_PRED,
   B_HD_PRED,
   B_HU_PRED,
+#if CONFIG_NEWBINTRAMODES
+  B_CONTEXT_PRED,
+#endif
 
   LEFT4X4,
   ABOVE4X4,
@@ -168,9 +171,19 @@ typedef enum {
   B_MODE_COUNT
 } B_PREDICTION_MODE;
 
-#define VP9_BINTRAMODES (B_HU_PRED + 1)  /* 10 */
+#define VP9_BINTRAMODES (LEFT4X4)
 #define VP9_SUBMVREFS (1 + NEW4X4 - LEFT4X4)
 
+#if CONFIG_NEWBINTRAMODES
+/* The number of B_PRED intra modes that are replaced by B_CONTEXT_PRED */
+#define CONTEXT_PRED_REPLACEMENTS  0
+#define VP9_KF_BINTRAMODES (VP9_BINTRAMODES - 1)
+#define VP9_NKF_BINTRAMODES  (VP9_BINTRAMODES - CONTEXT_PRED_REPLACEMENTS)
+#else
+#define VP9_KF_BINTRAMODES (VP9_BINTRAMODES)   /* 10 */
+#define VP9_NKF_BINTRAMODES (VP9_BINTRAMODES)  /* 10 */
+#endif
+
 typedef enum {
   PARTITIONING_16X8 = 0,
   PARTITIONING_8X16,
@@ -187,9 +200,11 @@ union b_mode_info {
   struct {
     B_PREDICTION_MODE first;
     TX_TYPE           tx_type;
-
 #if CONFIG_COMP_INTRA_PRED
     B_PREDICTION_MODE second;
+#endif
+#if CONFIG_NEWBINTRAMODES
+    B_PREDICTION_MODE context;
 #endif
   } as_mode;
   struct {
@@ -443,6 +458,12 @@ static TX_TYPE txfm_map(B_PREDICTION_MODE bmode) {
       tx_type = DCT_ADST;
       break;
 
+#if CONFIG_NEWBINTRAMODES
+    case B_CONTEXT_PRED:
+      assert(0);
+      break;
+#endif
+
     default :
       tx_type = DCT_DCT;
       break;
@@ -454,7 +475,11 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, const BLOCKD *b) {
   TX_TYPE tx_type = DCT_DCT;
   if (xd->mode_info_context->mbmi.mode == B_PRED &&
       xd->q_index < ACTIVE_HT) {
-    tx_type = txfm_map(b->bmi.as_mode.first);
+    tx_type = txfm_map(
+#if CONFIG_NEWBINTRAMODES
+        b->bmi.as_mode.first == B_CONTEXT_PRED ? b->bmi.as_mode.context :
+#endif
+        b->bmi.as_mode.first);
   }
   return tx_type;
 }
index 5b265787cb071734898af65761a759c57b74e5bb..37d09db9e6c665ef95446e90de297ec1c148a0e7 100644 (file)
@@ -68,9 +68,22 @@ static const unsigned int kf_uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
   { 122, 41, 35, 20, 20, 20, 20, 20, 20, 18}, /* BPRED */
 };
 
-static const unsigned int bmode_cts[VP9_BINTRAMODES] = {
+static const unsigned int bmode_cts[VP9_NKF_BINTRAMODES] = {
+#if CONFIG_NEWBINTRAMODES
+#if CONTEXT_PRED_REPLACEMENTS == 6
+  /* DC    TM     VE     HE   CONTEXT */
+  43891, 17694, 10036, 3920, 20000
+#elif CONTEXT_PRED_REPLACEMENTS == 4
+  /* DC    TM     VE     HE   LD    RD   CONTEXT */
+  43891, 17694, 10036, 3920, 3363, 2546, 14000
+#elif CONTEXT_PRED_REPLACEMENTS == 0
+  /* DC    TM     VE     HE   LD    RD   VR    VL    HD    HU   CONTEXT */
+  43891, 17694, 10036, 3920, 3363, 2546, 5119, 3221, 2471, 1723, 50000
+#endif
+#else
   /* DC    TM     VE     HE   LD    RD    VR    VL    HD    HU */
   43891, 17694, 10036, 3920, 3363, 2546, 5119, 3221, 2471, 1723
+#endif
 };
 
 typedef enum {
@@ -141,17 +154,55 @@ const vp9_prob vp9_mbsplit_probs [VP9_NUMMBSPLITS - 1] = { 110, 111, 150};
 
 /* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
 
-const vp9_tree_index vp9_bmode_tree[VP9_BINTRAMODES * 2 - 2] = /* INTRAMODECONTEXTNODE value */
-{
-  -B_DC_PRED, 2,                             /* 0 = DC_NODE */
-  -B_TM_PRED, 4,                            /* 1 = TM_NODE */
-  -B_VE_PRED, 6,                           /* 2 = VE_NODE */
-  8, 12,                                  /* 3 = COM_NODE */
-  -B_HE_PRED, 10,                        /* 4 = HE_NODE */
-  -B_RD_PRED, -B_VR_PRED,               /* 5 = RD_NODE */
-  -B_LD_PRED, 14,                        /* 6 = LD_NODE */
-  -B_VL_PRED, 16,                      /* 7 = VL_NODE */
-  -B_HD_PRED, -B_HU_PRED             /* 8 = HD_NODE */
+const vp9_tree_index vp9_kf_bmode_tree[VP9_KF_BINTRAMODES * 2 - 2] = {
+  -B_DC_PRED, 2,                      /* 0 = DC_NODE */
+  -B_TM_PRED, 4,                      /* 1 = TM_NODE */
+  -B_VE_PRED, 6,                      /* 2 = VE_NODE */
+  8, 12,                              /* 3 = COM_NODE */
+  -B_HE_PRED, 10,                     /* 4 = HE_NODE */
+  -B_RD_PRED, -B_VR_PRED,             /* 5 = RD_NODE */
+  -B_LD_PRED, 14,                     /* 6 = LD_NODE */
+  -B_VL_PRED, 16,                     /* 7 = VL_NODE */
+  -B_HD_PRED, -B_HU_PRED              /* 8 = HD_NODE */
+};
+
+const vp9_tree_index vp9_bmode_tree[VP9_NKF_BINTRAMODES * 2 - 2] = {
+#if CONFIG_NEWBINTRAMODES
+#if CONTEXT_PRED_REPLACEMENTS == 6
+  -B_DC_PRED, 2,
+  -B_TM_PRED, 4,
+  6, -(B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS),
+  -B_VE_PRED, -B_HE_PRED
+#elif CONTEXT_PRED_REPLACEMENTS == 4
+  -B_DC_PRED, 2,
+  -B_TM_PRED, 4,
+  6, 8,
+  -B_VE_PRED, -B_HE_PRED,
+  10, -(B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS),
+  -B_RD_PRED, -B_LD_PRED,
+#elif CONTEXT_PRED_REPLACEMENTS == 0
+  -B_DC_PRED, 2,                      /* 0 = DC_NODE */
+  -B_TM_PRED, 4,                      /* 1 = TM_NODE */
+  -B_VE_PRED, 6,                      /* 2 = VE_NODE */
+  8, 12,                              /* 3 = COM_NODE */
+  -B_HE_PRED, 10,                     /* 4 = HE_NODE */
+  -B_RD_PRED, -B_VR_PRED,             /* 5 = RD_NODE */
+  -B_LD_PRED, 14,                     /* 6 = LD_NODE */
+  -B_VL_PRED, 16,                     /* 7 = VL_NODE */
+  -B_HD_PRED, 18,
+  -B_HU_PRED, -B_CONTEXT_PRED
+#endif
+#else
+  -B_DC_PRED, 2,                      /* 0 = DC_NODE */
+  -B_TM_PRED, 4,                      /* 1 = TM_NODE */
+  -B_VE_PRED, 6,                      /* 2 = VE_NODE */
+  8, 12,                              /* 3 = COM_NODE */
+  -B_HE_PRED, 10,                     /* 4 = HE_NODE */
+  -B_RD_PRED, -B_VR_PRED,             /* 5 = RD_NODE */
+  -B_LD_PRED, 14,                     /* 6 = LD_NODE */
+  -B_VL_PRED, 16,                     /* 7 = VL_NODE */
+  -B_HD_PRED, -B_HU_PRED              /* 8 = HD_NODE */
+#endif
 };
 
 /* Again, these trees use the same probability indices as their
@@ -235,21 +286,22 @@ const vp9_tree_index vp9_sub_mv_ref_tree[6] = {
   -ZERO4X4, -NEW4X4
 };
 
-struct vp9_token_struct vp9_bmode_encodings   [VP9_BINTRAMODES];
-struct vp9_token_struct vp9_ymode_encodings   [VP9_YMODES];
+struct vp9_token_struct vp9_bmode_encodings[VP9_NKF_BINTRAMODES];
+struct vp9_token_struct vp9_kf_bmode_encodings[VP9_KF_BINTRAMODES];
+struct vp9_token_struct vp9_ymode_encodings[VP9_YMODES];
 #if CONFIG_SUPERBLOCKS
 struct vp9_token_struct vp9_sb_kf_ymode_encodings [VP9_I32X32_MODES];
 #endif
-struct vp9_token_struct vp9_kf_ymode_encodings [VP9_YMODES];
-struct vp9_token_struct vp9_uv_mode_encodings  [VP9_UV_MODES];
-struct vp9_token_struct vp9_i8x8_mode_encodings  [VP9_I8X8_MODES];
-struct vp9_token_struct vp9_mbsplit_encodings [VP9_NUMMBSPLITS];
+struct vp9_token_struct vp9_kf_ymode_encodings[VP9_YMODES];
+struct vp9_token_struct vp9_uv_mode_encodings[VP9_UV_MODES];
+struct vp9_token_struct vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
+struct vp9_token_struct vp9_mbsplit_encodings[VP9_NUMMBSPLITS];
 
-struct vp9_token_struct vp9_mv_ref_encoding_array    [VP9_MVREFS];
+struct vp9_token_struct vp9_mv_ref_encoding_array[VP9_MVREFS];
 #if CONFIG_SUPERBLOCKS
-struct vp9_token_struct vp9_sb_mv_ref_encoding_array  [VP9_MVREFS];
+struct vp9_token_struct vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
 #endif
-struct vp9_token_struct vp9_sub_mv_ref_encoding_array [VP9_SUBMVREFS];
+struct vp9_token_struct vp9_sub_mv_ref_encoding_array[VP9_SUBMVREFS];
 
 void vp9_init_mbmode_probs(VP9_COMMON *x) {
   unsigned int bct [VP9_YMODES] [2];      /* num Ymodes > num UV modes */
@@ -297,28 +349,36 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
 
 
 static void intra_bmode_probs_from_distribution(
-  vp9_prob p [VP9_BINTRAMODES - 1],
-  unsigned int branch_ct [VP9_BINTRAMODES - 1] [2],
-  const unsigned int events [VP9_BINTRAMODES]) {
-  vp9_tree_probs_from_distribution(VP9_BINTRAMODES, vp9_bmode_encodings,
-                                   vp9_bmode_tree, p, branch_ct,
-                                   events, 256, 1);
+  vp9_prob p[VP9_NKF_BINTRAMODES - 1],
+  unsigned int branch_ct[VP9_NKF_BINTRAMODES - 1][2],
+  const unsigned int events[VP9_NKF_BINTRAMODES]) {
+  vp9_tree_probs_from_distribution(VP9_NKF_BINTRAMODES, vp9_bmode_encodings,
+    vp9_bmode_tree, p, branch_ct, events, 256, 1);
 }
 
-void vp9_default_bmode_probs(vp9_prob p [VP9_BINTRAMODES - 1]) {
-  unsigned int branch_ct [VP9_BINTRAMODES - 1] [2];
+void vp9_default_bmode_probs(vp9_prob p[VP9_NKF_BINTRAMODES - 1]) {
+  unsigned int branch_ct[VP9_NKF_BINTRAMODES - 1][2];
   intra_bmode_probs_from_distribution(p, branch_ct, bmode_cts);
 }
 
-void vp9_kf_default_bmode_probs(vp9_prob p[VP9_BINTRAMODES][VP9_BINTRAMODES]
-                                          [VP9_BINTRAMODES - 1]) {
-  unsigned int branch_ct[VP9_BINTRAMODES - 1][2];
+static void intra_kf_bmode_probs_from_distribution(
+  vp9_prob p[VP9_KF_BINTRAMODES - 1],
+  unsigned int branch_ct[VP9_KF_BINTRAMODES - 1][2],
+  const unsigned int events[VP9_KF_BINTRAMODES]) {
+  vp9_tree_probs_from_distribution(VP9_KF_BINTRAMODES, vp9_kf_bmode_encodings,
+    vp9_kf_bmode_tree, p, branch_ct, events, 256, 1);
+}
+
+void vp9_kf_default_bmode_probs(vp9_prob p[VP9_KF_BINTRAMODES]
+                                          [VP9_KF_BINTRAMODES]
+                                          [VP9_KF_BINTRAMODES - 1]) {
+  unsigned int branch_ct[VP9_KF_BINTRAMODES - 1][2];
   int i, j;
 
-  for (i = 0; i < VP9_BINTRAMODES; i++) {
-    for (j = 0; j < VP9_BINTRAMODES; j++) {
-      intra_bmode_probs_from_distribution(
-        p[i][j], branch_ct, vp9_kf_default_bmode_counts[i][j]);
+  for (i = 0; i < VP9_KF_BINTRAMODES; ++i) {
+    for (j = 0; j < VP9_KF_BINTRAMODES; ++j) {
+      intra_kf_bmode_probs_from_distribution(
+          p[i][j], branch_ct, vp9_kf_default_bmode_counts[i][j]);
     }
   }
 }
@@ -353,6 +413,7 @@ const int vp9_switchable_interp_map[SWITCHABLE+1] = {-1, -1, 0, 1, -1}; //8, 8s
 #endif
 
 void vp9_entropy_mode_init() {
+  vp9_tokens_from_tree(vp9_kf_bmode_encodings,   vp9_kf_bmode_tree);
   vp9_tokens_from_tree(vp9_bmode_encodings,   vp9_bmode_tree);
   vp9_tokens_from_tree(vp9_ymode_encodings,   vp9_ymode_tree);
   vp9_tokens_from_tree(vp9_kf_ymode_encodings, vp9_kf_ymode_tree);
@@ -444,7 +505,7 @@ void vp9_update_mode_context(VP9_COMMON *pc) {
         this_prob = count > 0 ? 256 * mv_ref_ct[j][i][0] / count : 128;
         count = count > MVREF_COUNT_SAT ? MVREF_COUNT_SAT : count;
         factor = (MVREF_MAX_UPDATE_FACTOR * count / MVREF_COUNT_SAT);
-        this_prob = (pc->fc.vp8_mode_contexts[j][i] * (256 - factor) +
+        this_prob = (pc->fc.vp9_mode_contexts[j][i] * (256 - factor) +
                      this_prob * factor + 128) >> 8;
         this_prob = this_prob ? (this_prob < 255 ? this_prob : 255) : 1;
         mode_context[j][i] = this_prob;
@@ -482,7 +543,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
   unsigned int branch_ct[32][2];
   vp9_prob ymode_probs[VP9_YMODES - 1];
   vp9_prob uvmode_probs[VP9_UV_MODES - 1];
-  vp9_prob bmode_probs[VP9_BINTRAMODES - 1];
+  vp9_prob bmode_probs[VP9_NKF_BINTRAMODES - 1];
   vp9_prob i8x8_mode_probs[VP9_I8X8_MODES - 1];
   vp9_prob sub_mv_ref_probs[VP9_SUBMVREFS - 1];
   vp9_prob mbsplit_probs[VP9_NUMMBSPLITS - 1];
@@ -500,8 +561,9 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
   }
   printf("};\n");
   printf("static const unsigned int\nbmode_counts"
-         "[VP9_BINTRAMODES] = {\n");
-  for (t = 0; t < VP9_BINTRAMODES; ++t) printf("%d, ", cm->fc.bmode_counts[t]);
+         "[VP9_NKF_BINTRAMODES] = {\n");
+  for (t = 0; t < VP9_NKF_BINTRAMODES; ++t)
+    printf("%d, ", cm->fc.bmode_counts[t]);
   printf("};\n");
   printf("static const unsigned int\ni8x8_mode_counts"
          "[VP9_I8X8_MODES] = {\n");
@@ -551,10 +613,10 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
       else cm->fc.uv_mode_prob[i][t] = prob;
     }
   }
-  vp9_tree_probs_from_distribution(VP9_BINTRAMODES, vp9_bmode_encodings,
+  vp9_tree_probs_from_distribution(VP9_NKF_BINTRAMODES, vp9_bmode_encodings,
                                    vp9_bmode_tree, bmode_probs, branch_ct,
                                    cm->fc.bmode_counts, 256, 1);
-  for (t = 0; t < VP9_BINTRAMODES - 1; ++t) {
+  for (t = 0; t < VP9_NKF_BINTRAMODES - 1; ++t) {
     int prob;
     count = branch_ct[t][0] + branch_ct[t][1];
     count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
index b55e3b0a6b5534e9df868dc767b5318c7c9517e1..02975918e5d25774b7ff889bfee75cd2afb3ed5b 100644 (file)
@@ -17,6 +17,9 @@
 
 #define SUBMVREF_COUNT 5
 #define VP9_NUMMBSPLITS 4
+#if CONFIG_COMP_INTRA_PRED
+#define DEFAULT_COMP_INTRA_PROB  32
+#endif
 
 typedef const int vp9_mbsplit[16];
 
@@ -32,11 +35,12 @@ extern const vp9_prob vp9_sub_mv_ref_prob[VP9_SUBMVREFS - 1];
 
 extern const vp9_prob vp9_sub_mv_ref_prob2[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
 
-extern const unsigned int vp9_kf_default_bmode_counts[VP9_BINTRAMODES]
-                                                     [VP9_BINTRAMODES]
-                                                     [VP9_BINTRAMODES];
+extern const unsigned int vp9_kf_default_bmode_counts[VP9_KF_BINTRAMODES]
+                                                     [VP9_KF_BINTRAMODES]
+                                                     [VP9_KF_BINTRAMODES];
 
 extern const vp9_tree_index vp9_bmode_tree[];
+extern const vp9_tree_index vp9_kf_bmode_tree[];
 
 extern const vp9_tree_index  vp9_ymode_tree[];
 extern const vp9_tree_index  vp9_kf_ymode_tree[];
@@ -48,7 +52,8 @@ extern const vp9_tree_index  vp9_mv_ref_tree[];
 extern const vp9_tree_index  vp9_sb_mv_ref_tree[];
 extern const vp9_tree_index  vp9_sub_mv_ref_tree[];
 
-extern struct vp9_token_struct vp9_bmode_encodings[VP9_BINTRAMODES];
+extern struct vp9_token_struct vp9_bmode_encodings[VP9_NKF_BINTRAMODES];
+extern struct vp9_token_struct vp9_kf_bmode_encodings[VP9_KF_BINTRAMODES];
 extern struct vp9_token_struct vp9_ymode_encodings[VP9_YMODES];
 extern struct vp9_token_struct vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES];
 extern struct vp9_token_struct vp9_kf_ymode_encodings[VP9_YMODES];
@@ -76,10 +81,11 @@ extern void vp9_accum_mv_refs(struct VP9Common *pc,
                               MB_PREDICTION_MODE m,
                               const int ct[4]);
 
-void vp9_default_bmode_probs(vp9_prob dest[VP9_BINTRAMODES - 1]);
+void vp9_default_bmode_probs(vp9_prob dest[VP9_NKF_BINTRAMODES - 1]);
 
-void vp9_kf_default_bmode_probs(vp9_prob dest[VP9_BINTRAMODES][VP9_BINTRAMODES]
-                                             [VP9_BINTRAMODES - 1]);
+void vp9_kf_default_bmode_probs(vp9_prob dest[VP9_KF_BINTRAMODES]
+                                             [VP9_KF_BINTRAMODES]
+                                             [VP9_KF_BINTRAMODES - 1]);
 
 void vp9_adapt_mode_probs(struct VP9Common *);
 
index 4f3d15a82b6174fee370a6bbb1519af64b04854c..84a377e75ddbf6d93771a83bc9894128e2bca05f 100644 (file)
@@ -159,12 +159,12 @@ void vp9_find_near_mvs
 }
 
 vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
-                           vp9_prob p[VP9_MVREFS - 1], const int near_mv_ref_ct[4]
-                          ) {
-  p[0] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[0]] [0];
-  p[1] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[1]] [1];
-  p[2] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[2]] [2];
-  p[3] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[3]] [3];
+                           vp9_prob p[VP9_MVREFS - 1],
+                           const int near_mv_ref_ct[4]) {
+  p[0] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[0]][0];
+  p[1] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[1]][1];
+  p[2] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[2]][2];
+  p[3] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[3]][3];
   return p;
 }
 
index 37796d80fe0607323c43e6b80653b1fc1bd4b312..52249860928f3ad81370d8afcd3c7a25e497a691 100644 (file)
@@ -11,7 +11,9 @@
 
 #include "entropymode.h"
 
-const unsigned int vp9_kf_default_bmode_counts[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES] = {
+const unsigned int vp9_kf_default_bmode_counts[VP9_KF_BINTRAMODES]
+                                              [VP9_KF_BINTRAMODES]
+                                              [VP9_KF_BINTRAMODES] = {
   {
     /*Above Mode :  0*/
     { 43438,   2195,    470,    316,    615,    171,    217,    412,    124,    160, }, /* left_mode 0 */
index c85c7ef496d83c6700de7e210de86957f6429644..de814705bfe4384bea074d4569df6e4557cabc37 100644 (file)
@@ -44,12 +44,12 @@ void vp9_initialize_common(void);
 #define COMP_PRED_CONTEXTS   2
 
 typedef struct frame_contexts {
-  vp9_prob bmode_prob [VP9_BINTRAMODES - 1];
-  vp9_prob ymode_prob [VP9_YMODES - 1]; /* interframe intra mode probs */
-  vp9_prob uv_mode_prob [VP9_YMODES][VP9_UV_MODES - 1];
-  vp9_prob i8x8_mode_prob [VP9_I8X8_MODES - 1];
-  vp9_prob sub_mv_ref_prob [SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
-  vp9_prob mbsplit_prob [VP9_NUMMBSPLITS - 1];
+  vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
+  vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
+  vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+  vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
+  vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+  vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
   vp9_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
   vp9_prob hybrid_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
   vp9_prob coef_probs_8x8 [BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
@@ -59,18 +59,18 @@ typedef struct frame_contexts {
 
   nmv_context nmvc;
   nmv_context pre_nmvc;
-  vp9_prob pre_bmode_prob [VP9_BINTRAMODES - 1];
-  vp9_prob pre_ymode_prob [VP9_YMODES - 1]; /* interframe intra mode probs */
-  vp9_prob pre_uv_mode_prob [VP9_YMODES][VP9_UV_MODES - 1];
-  vp9_prob pre_i8x8_mode_prob [VP9_I8X8_MODES - 1];
-  vp9_prob pre_sub_mv_ref_prob [SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
-  vp9_prob pre_mbsplit_prob [VP9_NUMMBSPLITS - 1];
-  unsigned int bmode_counts [VP9_BINTRAMODES];
-  unsigned int ymode_counts [VP9_YMODES];   /* interframe intra mode probs */
-  unsigned int uv_mode_counts [VP9_YMODES][VP9_UV_MODES];
-  unsigned int i8x8_mode_counts [VP9_I8X8_MODES];   /* interframe intra mode probs */
-  unsigned int sub_mv_ref_counts [SUBMVREF_COUNT][VP9_SUBMVREFS];
-  unsigned int mbsplit_counts [VP9_NUMMBSPLITS];
+  vp9_prob pre_bmode_prob[VP9_NKF_BINTRAMODES - 1];
+  vp9_prob pre_ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
+  vp9_prob pre_uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+  vp9_prob pre_i8x8_mode_prob[VP9_I8X8_MODES - 1];
+  vp9_prob pre_sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+  vp9_prob pre_mbsplit_prob[VP9_NUMMBSPLITS - 1];
+  unsigned int bmode_counts[VP9_NKF_BINTRAMODES];
+  unsigned int ymode_counts[VP9_YMODES];   /* interframe intra mode probs */
+  unsigned int uv_mode_counts[VP9_YMODES][VP9_UV_MODES];
+  unsigned int i8x8_mode_counts[VP9_I8X8_MODES];   /* interframe intra probs */
+  unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS];
+  unsigned int mbsplit_counts[VP9_NUMMBSPLITS];
 
   vp9_prob pre_coef_probs [BLOCK_TYPES] [COEF_BANDS]
       [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
@@ -108,7 +108,7 @@ typedef struct frame_contexts {
 
   int mode_context[6][4];
   int mode_context_a[6][4];
-  int vp8_mode_contexts[6][4];
+  int vp9_mode_contexts[6][4];
   int mv_ref_ct[6][4][2];
   int mv_ref_ct_a[6][4][2];
 } FRAME_CONTEXT;
@@ -241,7 +241,9 @@ typedef struct VP9Common {
 
   /* keyframe block modes are predicted by their above, left neighbors */
 
-  vp9_prob kf_bmode_prob [VP9_BINTRAMODES] [VP9_BINTRAMODES] [VP9_BINTRAMODES - 1];
+  vp9_prob kf_bmode_prob[VP9_KF_BINTRAMODES]
+                        [VP9_KF_BINTRAMODES]
+                        [VP9_KF_BINTRAMODES - 1];
   vp9_prob kf_ymode_prob[8][VP9_YMODES - 1]; /* keyframe "" */
 #if CONFIG_SUPERBLOCKS
   vp9_prob sb_kf_ymode_prob[8][VP9_I32X32_MODES - 1];
index 97f782c52d4bff53c3ddf2c36ae35e3b806d486a..c9b8bd0523a4b76d142b3f3fc8babc09fc285525 100644 (file)
@@ -196,9 +196,50 @@ static void d153_predictor(uint8_t *ypred_ptr, int y_stride, int n,
   }
 }
 
+static void corner_predictor(unsigned char *ypred_ptr, int y_stride, int n,
+                             unsigned char *yabove_row,
+                             unsigned char *yleft_col) {
+  int h[32], v[32], mh, mv, maxgradh, maxgradv, x, y, nx, ny;
+  int i, j;
+  int top_left = yabove_row[-1];
+  mh = mv = 0;
+  maxgradh = yabove_row[1] - top_left;
+  maxgradv = yleft_col[1] - top_left;
+  for (i = 2; i < n; ++i) {
+    int gh = yabove_row[i] - yabove_row[i - 2];
+    int gv = yleft_col[i] - yleft_col[i - 2];
+    if (gh > maxgradh) {
+      maxgradh = gh;
+      mh = i - 1;
+    }
+    if (gv > maxgradv) {
+      maxgradv = gv;
+      mv = i - 1;
+    }
+  }
+  nx = mh + mv + 3;
+  ny = 2 * n + 1 - nx;
+
+  x = top_left;
+  for (i = 0; i <= mh; ++i) x += yabove_row[i];
+  for (i = 0; i <= mv; ++i) x += yleft_col[i];
+  x += (nx >> 1);
+  x /= nx;
+  y = 0;
+  for (i = mh + 1; i < n; ++i) y += yabove_row[i];
+  for (i = mv + 1; i < n; ++i) y += yleft_col[i];
+  y += (ny >> 1);
+  y /= ny;
+
+  for (i = 0; i < n; ++i) {
+    for (j = 0; j < n; ++j)
+      ypred_ptr[j] = (i <= mh && j <= mv ? x : y);
+    ypred_ptr += y_stride;
+  }
+}
+
 void vp9_recon_intra_mbuv(MACROBLOCKD *xd) {
   int i;
-
   for (i = 16; i < 24; i += 2) {
     BLOCKD *b = &xd->block[i];
     vp9_recon2b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
index 7bc66707c5a7a25c33371f3a96811a02fe2f495a..35a839db3813179565ac655fed01169a8858f3a8 100644 (file)
@@ -14,5 +14,8 @@
 #include "blockd.h"
 
 extern void vp9_recon_intra_mbuv(MACROBLOCKD *xd);
+extern B_PREDICTION_MODE vp9_find_dominant_direction(unsigned char *ptr,
+                                                     int stride, int n);
+extern B_PREDICTION_MODE vp9_find_bpred_context(BLOCKD *x);
 
 #endif  // __INC_RECONINTRA_H
index d2b457c588f09e09b785817bf64a5fbe1618cdd0..7af613d33a0f8b07fc9a1505a97ae725298ec644 100644 (file)
 #include "reconintra.h"
 #include "vpx_rtcd.h"
 
-void vp9_intra4x4_predict_c(BLOCKD *x, int b_mode,
-                            unsigned char *predictor) {
+#if CONFIG_NEWBINTRAMODES
+static int find_grad_measure(unsigned char *x, int stride, int n, int t,
+                             int dx, int dy) {
+  int i, j;
+  int count = 0, gsum = 0, gdiv;
+  /* TODO: Make this code more efficient by breaking up into two loops */
+  for (i = -t; i < n; ++i)
+    for (j = -t; j < n; ++j) {
+      int g;
+      if (i >= 0 && j >= 0) continue;
+      if (i + dy >= 0 && j + dx >= 0) continue;
+      if (i + dy < -t || i + dy >= n || j + dx < -t || j + dx >= n) continue;
+      g = abs(x[(i + dy) * stride + j + dx] - x[i * stride + j]);
+      gsum += g * g;
+      count++;
+    }
+  gdiv = (dx * dx + dy * dy) * count;
+  return ((gsum << 8) + (gdiv >> 1)) / gdiv;
+}
+
+#if CONTEXT_PRED_REPLACEMENTS == 6
+B_PREDICTION_MODE vp9_find_dominant_direction(
+    unsigned char *ptr, int stride, int n) {
+  int g[8], i, imin, imax;
+  g[1] = find_grad_measure(ptr, stride, n, 4,  2, 1);
+  g[2] = find_grad_measure(ptr, stride, n, 4,  1, 1);
+  g[3] = find_grad_measure(ptr, stride, n, 4,  1, 2);
+  g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2);
+  g[6] = find_grad_measure(ptr, stride, n, 4, -1, 1);
+  g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1);
+  imin = 1;
+  for (i = 2; i < 8; i += 1 + (i == 3))
+    imin = (g[i] < g[imin] ? i : imin);
+  imax = 1;
+  for (i = 2; i < 8; i += 1 + (i == 3))
+    imax = (g[i] > g[imax] ? i : imax);
+  /*
+  printf("%d %d %d %d %d %d = %d %d\n",
+         g[1], g[2], g[3], g[5], g[6], g[7], imin, imax);
+         */
+  switch (imin) {
+    case 1:
+      return B_HD_PRED;
+    case 2:
+      return B_RD_PRED;
+    case 3:
+      return B_VR_PRED;
+    case 5:
+      return B_VL_PRED;
+    case 6:
+      return B_LD_PRED;
+    case 7:
+      return B_HU_PRED;
+    default:
+      assert(0);
+  }
+}
+#elif CONTEXT_PRED_REPLACEMENTS == 4
+B_PREDICTION_MODE vp9_find_dominant_direction(
+    unsigned char *ptr, int stride, int n) {
+  int g[8], i, imin, imax;
+  g[1] = find_grad_measure(ptr, stride, n, 4,  2, 1);
+  g[3] = find_grad_measure(ptr, stride, n, 4,  1, 2);
+  g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2);
+  g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1);
+  imin = 1;
+  for (i = 3; i < 8; i+=2)
+    imin = (g[i] < g[imin] ? i : imin);
+  imax = 1;
+  for (i = 3; i < 8; i+=2)
+    imax = (g[i] > g[imax] ? i : imax);
+  /*
+  printf("%d %d %d %d = %d %d\n",
+         g[1], g[3], g[5], g[7], imin, imax);
+         */
+  switch (imin) {
+    case 1:
+      return B_HD_PRED;
+    case 3:
+      return B_VR_PRED;
+    case 5:
+      return B_VL_PRED;
+    case 7:
+      return B_HU_PRED;
+    default:
+      assert(0);
+  }
+}
+#elif CONTEXT_PRED_REPLACEMENTS == 0
+B_PREDICTION_MODE vp9_find_dominant_direction(
+    unsigned char *ptr, int stride, int n) {
+  int g[8], i, imin, imin2, imax;
+  g[0] = find_grad_measure(ptr, stride, n, 4,  1, 0);
+  g[1] = find_grad_measure(ptr, stride, n, 4,  2, 1);
+  g[2] = find_grad_measure(ptr, stride, n, 4,  1, 1);
+  g[3] = find_grad_measure(ptr, stride, n, 4,  1, 2);
+  g[4] = find_grad_measure(ptr, stride, n, 4,  0, 1);
+  g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2);
+  g[6] = find_grad_measure(ptr, stride, n, 4, -1, 1);
+  g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1);
+  imax = 0;
+  for (i = 1; i < 8; i++)
+    imax = (g[i] > g[imax] ? i : imax);
+  imin = 0;
+  for (i = 1; i < 8; i++)
+    imin = (g[i] < g[imin] ? i : imin);
+
+  switch (imin) {
+    case 0:
+      return B_HE_PRED;
+    case 1:
+      return B_HD_PRED;
+    case 2:
+      return B_RD_PRED;
+    case 3:
+      return B_VR_PRED;
+    case 4:
+      return B_VE_PRED;
+    case 5:
+      return B_VL_PRED;
+    case 6:
+      return B_LD_PRED;
+    case 7:
+      return B_HU_PRED;
+    default:
+      assert(0);
+  }
+}
+#endif
+
+B_PREDICTION_MODE vp9_find_bpred_context(BLOCKD *x) {
+  unsigned char *ptr = *(x->base_dst) + x->dst;
+  int stride = x->dst_stride;
+  return vp9_find_dominant_direction(ptr, stride, 4);
+}
+#endif
+
+void vp9_intra4x4_predict(BLOCKD *x,
+                          int b_mode,
+                          unsigned char *predictor) {
   int i, r, c;
 
   unsigned char *Above = *(x->base_dst) + x->dst - x->dst_stride;
@@ -27,6 +165,11 @@ void vp9_intra4x4_predict_c(BLOCKD *x, int b_mode,
   Left[2] = (*(x->base_dst))[x->dst - 1 + 2 * x->dst_stride];
   Left[3] = (*(x->base_dst))[x->dst - 1 + 3 * x->dst_stride];
 
+#if CONFIG_NEWBINTRAMODES
+  if (b_mode == B_CONTEXT_PRED)
+    b_mode = x->bmi.as_mode.context;
+#endif
+
   switch (b_mode) {
     case B_DC_PRED: {
       int expected_dc = 0;
@@ -270,7 +413,15 @@ void vp9_intra4x4_predict_c(BLOCKD *x, int b_mode,
     }
     break;
 
-
+#if CONFIG_NEWBINTRAMODES
+    case B_CONTEXT_PRED:
+    break;
+    /*
+    case B_CORNER_PRED:
+    corner_predictor(predictor, 16, 4, Above, Left);
+    break;
+    */
+#endif
   }
 }
 
index a22df8f3c38b1ba96c0742b384db223b83c36b7b..7d4d6a7c2c4d02fb60315dfcba1719f716d98d5f 100644 (file)
@@ -29,7 +29,17 @@ int dec_mvcount = 0;
 #endif
 
 static int read_bmode(vp9_reader *bc, const vp9_prob *p) {
-  return treed_read(bc, vp9_bmode_tree, p);
+  B_PREDICTION_MODE m = treed_read(bc, vp9_bmode_tree, p);
+#if CONFIG_NEWBINTRAMODES
+  if (m == B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS)
+    m = B_CONTEXT_PRED;
+  assert(m < B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS || m == B_CONTEXT_PRED);
+#endif
+  return m;
+}
+
+static int read_kf_bmode(vp9_reader *bc, const vp9_prob *p) {
+  return treed_read(bc, vp9_kf_bmode_tree, p);
 }
 
 static int read_ymode(vp9_reader *bc, const vp9_prob *p) {
@@ -142,19 +152,19 @@ static void kfread_modes(VP9D_COMP *pbi,
   if ((m->mbmi.mode = y_mode) == B_PRED) {
     int i = 0;
 #if CONFIG_COMP_INTRA_PRED
-    int use_comp_pred = vp9_read(bc, 128);
+    int use_comp_pred = vp9_read(bc, DEFAULT_COMP_INTRA_PROB);
 #endif
     do {
       const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
       const B_PREDICTION_MODE L = left_block_mode(m, i);
 
       m->bmi[i].as_mode.first =
-        (B_PREDICTION_MODE) read_bmode(
+        (B_PREDICTION_MODE) read_kf_bmode(
           bc, pbi->common.kf_bmode_prob [A] [L]);
 #if CONFIG_COMP_INTRA_PRED
       if (use_comp_pred) {
         m->bmi[i].as_mode.second =
-          (B_PREDICTION_MODE) read_bmode(
+          (B_PREDICTION_MODE) read_kf_bmode(
             bc, pbi->common.kf_bmode_prob [A] [L]);
       } else {
         m->bmi[i].as_mode.second = (B_PREDICTION_MODE)(B_DC_PRED - 1);
@@ -1075,19 +1085,16 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
     if (mbmi->mode == B_PRED) {
       int j = 0;
 #if CONFIG_COMP_INTRA_PRED
-      int use_comp_pred = vp9_read(bc, 128);
+      int use_comp_pred = vp9_read(bc, DEFAULT_COMP_INTRA_PROB);
 #endif
       do {
-        mi->bmi[j].as_mode.first = (B_PREDICTION_MODE)read_bmode(bc, pbi->common.fc.bmode_prob);
-        /*
-        {
-          int p;
-          for (p = 0; p < VP9_BINTRAMODES - 1; ++p)
-            printf(" %d", pbi->common.fc.bmode_prob[p]);
-          printf("\nbmode[%d][%d]: %d\n", pbi->common.current_video_frame, j, mi->bmi[j].as_mode.first);
-        }
-        */
-        pbi->common.fc.bmode_counts[mi->bmi[j].as_mode.first]++;
+        int m;
+        m = mi->bmi[j].as_mode.first = (B_PREDICTION_MODE)
+            read_bmode(bc, pbi->common.fc.bmode_prob);
+#if CONFIG_NEWBINTRAMODES
+        if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS;
+#endif
+        pbi->common.fc.bmode_counts[m]++;
 #if CONFIG_COMP_INTRA_PRED
         if (use_comp_pred) {
           mi->bmi[j].as_mode.second = (B_PREDICTION_MODE)read_bmode(bc, pbi->common.fc.bmode_prob);
index 72dcb5a81053bc75f670a0aac74c4b6205009fa6..ebbf1669a8db2a60976afe1947171a8e7fc0b18c 100644 (file)
@@ -376,7 +376,7 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
       eobtotal = vp9_decode_mb_tokens_16x16(pbi, xd, bc);
     } else if (tx_size == TX_8X8) {
       eobtotal = vp9_decode_mb_tokens_8x8(pbi, xd, bc);
-    } else {
+    } else if (mode != B_PRED) {
       eobtotal = vp9_decode_mb_tokens(pbi, xd, bc);
     }
   }
@@ -404,7 +404,9 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
   /* do prediction */
   if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
     if (mode != I8X8_PRED) {
-      vp9_build_intra_predictors_mbuv(xd);
+      if (mode != B_PRED) {
+        vp9_build_intra_predictors_mbuv(xd);
+      }
       if (mode != B_PRED) {
         vp9_build_intra_predictors_mby(xd);
       }
@@ -461,10 +463,20 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
     }
   } else if (mode == B_PRED) {
     for (i = 0; i < 16; i++) {
+      int b_mode;
+#if CONFIG_COMP_INTRA_PRED
+      int b_mode2;
+#endif
       BLOCKD *b = &xd->block[i];
-      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
+      b_mode = xd->mode_info_context->bmi[i].as_mode.first;
+#if CONFIG_NEWBINTRAMODES
+      xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
+          vp9_find_bpred_context(b);
+#endif
+      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
+        eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
 #if CONFIG_COMP_INTRA_PRED
-      int b_mode2 = xd->mode_info_context->bmi[i].as_mode.second;
+      b_mode2 = xd->mode_info_context->bmi[i].as_mode.second;
 
       if (b_mode2 == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
 #endif
@@ -485,6 +497,14 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
                                *(b->base_dst) + b->dst, 16, b->dst_stride);
       }
     }
+    if (!xd->mode_info_context->mbmi.mb_skip_coeff) {
+      for (i = 16; i < 24; ++i)
+        eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_UV, i);
+    }
+    vp9_build_intra_predictors_mbuv(xd);
+    pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
+                           xd->predictor + 16 * 16, xd->dst.u_buffer,
+                           xd->dst.v_buffer, xd->dst.uv_stride, xd->eobs + 16);
   } else if (mode == SPLITMV) {
     if (tx_size == TX_8X8) {
       vp9_dequant_idct_add_y_block_8x8(xd->qcoeff, xd->block[0].dequant,
@@ -492,8 +512,8 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
                                          xd->dst.y_stride, xd->eobs, xd);
     } else {
       pbi->idct_add_y_block(xd->qcoeff, xd->block[0].dequant,
-                                       xd->predictor, xd->dst.y_buffer,
-                                       xd->dst.y_stride, xd->eobs);
+                            xd->predictor, xd->dst.y_buffer,
+                            xd->dst.y_stride, xd->eobs);
     }
   } else {
     BLOCKD *b = &xd->block[24];
@@ -556,7 +576,8 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
         (xd->qcoeff + 16 * 16, xd->block[16].dequant,
          xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
          xd->dst.uv_stride, xd->eobs + 16, xd);
-  else if (xd->mode_info_context->mbmi.mode != I8X8_PRED)
+  else if (xd->mode_info_context->mbmi.mode != I8X8_PRED &&
+           xd->mode_info_context->mbmi.mode != B_PRED)
     pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
          xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
          xd->dst.uv_stride, xd->eobs + 16);
@@ -833,7 +854,7 @@ static void init_frame(VP9D_COMP *pbi) {
     vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
     vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
 
-    vpx_memcpy(pbi->common.fc.vp8_mode_contexts,
+    vpx_memcpy(pbi->common.fc.vp9_mode_contexts,
                pbi->common.fc.mode_context,
                sizeof(pbi->common.fc.mode_context));
     vpx_memset(pc->prev_mip, 0,
@@ -1220,14 +1241,14 @@ int vp9_decode_frame(VP9D_COMP *pbi) {
 
     if (pc->refresh_alt_ref_frame) {
       vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
-      vpx_memcpy(pc->fc.vp8_mode_contexts,
+      vpx_memcpy(pc->fc.vp9_mode_contexts,
                  pc->fc.mode_context_a,
-                 sizeof(pc->fc.vp8_mode_contexts));
+                 sizeof(pc->fc.vp9_mode_contexts));
     } else {
       vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
-      vpx_memcpy(pc->fc.vp8_mode_contexts,
+      vpx_memcpy(pc->fc.vp9_mode_contexts,
                  pc->fc.mode_context,
-                 sizeof(pc->fc.vp8_mode_contexts));
+                 sizeof(pc->fc.vp9_mode_contexts));
     }
 
     /* Buffer to buffer copy flags. */
index 68f2c283a76901c5d3444960b07675b61351bfae..54baa0c951053f370fc591d944a2dc1473506254 100644 (file)
@@ -572,36 +572,58 @@ int vp9_decode_mb_tokens_8x8(VP9D_COMP* const pbi,
   return eobtotal;
 }
 
-
-int vp9_decode_mb_tokens(VP9D_COMP* const dx,
-                         MACROBLOCKD* const xd,
-                         BOOL_DECODER* const bc) {
+int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
+                         BOOL_DECODER* const bc, int type, int i) {
   ENTROPY_CONTEXT *const A = (ENTROPY_CONTEXT *)xd->above_context;
   ENTROPY_CONTEXT *const L = (ENTROPY_CONTEXT *)xd->left_context;
-
-  unsigned short *const eobs = xd->eobs;
-  const int *scan = vp9_default_zig_zag1d;
-  PLANE_TYPE type;
-  int c, i, eobtotal = 0, seg_eob = 16;
+  ENTROPY_CONTEXT *const a = A + vp9_block2above[i];
+  ENTROPY_CONTEXT *const l = L + vp9_block2left[i];
   INT16 *qcoeff_ptr = &xd->qcoeff[0];
-
+  const int *scan = vp9_default_zig_zag1d;
+  unsigned short *const eobs = xd->eobs;
+  int c, seg_eob = 16;
+  TX_TYPE tx_type = DCT_DCT;
   int segment_id = xd->mode_info_context->mbmi.segment_id;
   if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB))
     seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB);
 
+  if (i == 24)
+    type = PLANE_TYPE_Y2;
+  else if (i >= 16)
+    type = PLANE_TYPE_UV;
+
+  if (type == PLANE_TYPE_Y_WITH_DC)
+    tx_type = get_tx_type(xd, &xd->block[i]);
+  switch (tx_type) {
+    case ADST_DCT :
+      scan = vp9_row_scan;
+      break;
+
+    case DCT_ADST :
+      scan = vp9_col_scan;
+      break;
+
+    default :
+      scan = vp9_default_zig_zag1d;
+      break;
+  }
+  c = decode_coefs(dx, xd, bc, a, l, type,
+                   tx_type,
+                   seg_eob, qcoeff_ptr + i * 16,
+                   i, scan, TX_4X4, coef_bands_x);
+  a[0] = l[0] = ((eobs[i] = c) != !type);
+  return c;
+}
+
+int vp9_decode_mb_tokens(VP9D_COMP *dx, MACROBLOCKD *xd,
+                         BOOL_DECODER* const bc) {
+  int i, type, eobtotal = 0;
+
   if (xd->mode_info_context->mbmi.mode != B_PRED &&
       xd->mode_info_context->mbmi.mode != I8X8_PRED &&
       xd->mode_info_context->mbmi.mode != SPLITMV) {
-    ENTROPY_CONTEXT *const a = A + vp9_block2above[24];
-    ENTROPY_CONTEXT *const l = L + vp9_block2left[24];
-    type = PLANE_TYPE_Y2;
 
-    c = decode_coefs(dx, xd, bc, a, l, type,
-                     DCT_DCT,
-                     seg_eob, qcoeff_ptr + 24 * 16, 24,
-                     scan, TX_4X4, coef_bands_x);
-    a[0] = l[0] = ((eobs[24] = c) != !type);
-    eobtotal += c - 16;
+    eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y2, 24) - 16;
 
     type = PLANE_TYPE_Y_NO_DC;
   } else {
@@ -609,35 +631,7 @@ int vp9_decode_mb_tokens(VP9D_COMP* const dx,
   }
 
   for (i = 0; i < 24; ++i) {
-    ENTROPY_CONTEXT *const a = A + vp9_block2above[i];
-    ENTROPY_CONTEXT *const l = L + vp9_block2left[i];
-    TX_TYPE tx_type = DCT_DCT;
-    if (i == 16)
-      type = PLANE_TYPE_UV;
-
-    tx_type = get_tx_type(xd, &xd->block[i]);
-    switch(tx_type) {
-      case ADST_DCT :
-        scan = vp9_row_scan;
-        break;
-
-      case DCT_ADST :
-        scan = vp9_col_scan;
-        break;
-
-      default :
-        scan = vp9_default_zig_zag1d;
-        break;
-    }
-
-    c = decode_coefs(dx, xd, bc, a, l, type, tx_type,
-                     seg_eob, qcoeff_ptr,
-                     i, scan, TX_4X4, coef_bands_x);
-    a[0] = l[0] = ((eobs[i] = c) != !type);
-
-    eobtotal += c;
-    qcoeff_ptr += 16;
+    eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, type, i);
   }
-
   return eobtotal;
 }
index aa36402c16897ea108966e8b3e647b822983d124..674850382b29de6a987774c6b81242926ae3faa9 100644 (file)
@@ -21,5 +21,7 @@ int vp9_decode_mb_tokens_8x8(VP9D_COMP* const, MACROBLOCKD* const,
                              BOOL_DECODER* const);
 int vp9_decode_mb_tokens_16x16(VP9D_COMP* const, MACROBLOCKD* const,
                                BOOL_DECODER* const);
+int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd, BOOL_DECODER* const bc,
+                         int type, int i);
 
 #endif /* DETOKENIZE_H */
index 47958bf09a8a4d1f7f39eff882e2f6ebb2596cb4..a80532e48b0c53538f02a8bd83a9383fed5f37fb 100644 (file)
@@ -36,7 +36,9 @@ unsigned __int64 Sectionbits[500];
 #endif
 
 #ifdef ENTROPY_STATS
-int intra_mode_stats [VP9_BINTRAMODES] [VP9_BINTRAMODES] [VP9_BINTRAMODES];
+int intra_mode_stats[VP9_KF_BINTRAMODES]
+                    [VP9_KF_BINTRAMODES]
+                    [VP9_KF_BINTRAMODES];
 unsigned int tree_update_hist [BLOCK_TYPES]
                               [COEF_BANDS]
                               [PREV_COEF_CONTEXTS]
@@ -341,11 +343,20 @@ static void write_uv_mode(vp9_writer *bc, int m, const vp9_prob *p) {
 
 
 static void write_bmode(vp9_writer *bc, int m, const vp9_prob *p) {
+#if CONFIG_NEWBINTRAMODES
+  assert(m < B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS || m == B_CONTEXT_PRED);
+  if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS;
+#endif
   write_token(bc, vp9_bmode_tree, p, vp9_bmode_encodings + m);
 }
 
+static void write_kf_bmode(vp9_writer *bc, int m, const vp9_prob *p) {
+  write_token(bc, vp9_kf_bmode_tree, p, vp9_kf_bmode_encodings + m);
+}
+
 static void write_split(vp9_writer *bc, int x, const vp9_prob *p) {
-  write_token(bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x);
+  write_token(
+    bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x);
 }
 
 static int prob_update_savings(const unsigned int *ct,
@@ -1005,7 +1016,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
             int uses_second =
               m->bmi[0].as_mode.second !=
               (B_PREDICTION_MODE)(B_DC_PRED - 1);
-            vp9_write(bc, uses_second, 128);
+            vp9_write(bc, uses_second, DEFAULT_COMP_INTRA_PROB);
 #endif
             do {
 #if CONFIG_COMP_INTRA_PRED
@@ -1013,14 +1024,6 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
 #endif
               write_bmode(bc, m->bmi[j].as_mode.first,
                           pc->fc.bmode_prob);
-              /*
-              if (!cpi->dummy_packing) {
-                int p;
-                for (p = 0; p < VP9_BINTRAMODES - 1; ++p)
-                  printf(" %d", pc->fc.bmode_prob[p]);
-                printf("\nbmode[%d][%d]: %d\n", pc->current_video_frame, j, m->bmi[j].as_mode.first);
-              }
-              */
 #if CONFIG_COMP_INTRA_PRED
               if (uses_second) {
                 write_bmode(bc, mode2, pc->fc.bmode_prob);
@@ -1344,7 +1347,7 @@ static void write_mb_modes_kf(const VP9_COMMON  *c,
     int uses_second =
       m->bmi[0].as_mode.second !=
       (B_PREDICTION_MODE)(B_DC_PRED - 1);
-    vp9_write(bc, uses_second, 128);
+    vp9_write(bc, uses_second, DEFAULT_COMP_INTRA_PROB);
 #endif
     do {
       const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
@@ -1358,11 +1361,14 @@ static void write_mb_modes_kf(const VP9_COMMON  *c,
       ++intra_mode_stats [A] [L] [bm];
 #endif
 
-      write_bmode(bc, bm, c->kf_bmode_prob [A] [L]);
-      // printf("    mode: %d\n", bm);
+      write_kf_bmode(bc, bm, c->kf_bmode_prob[A][L]);
+#if 0  // CONFIG_NEWBINTRAMODES
+      if (!cpi->dummy_packing)
+        printf("%d: %d %d\n", i, bm, m->bmi[i].as_mode.context);
+#endif
 #if CONFIG_COMP_INTRA_PRED
       if (uses_second) {
-        write_bmode(bc, bm2, c->kf_bmode_prob [A] [L]);
+        write_kf_bmode(bc, bm2, c->kf_bmode_prob[A][L]);
       }
 #endif
     } while (++i < 16);
index 3f2910dbbc07bbb94a9be85586ca248e60f57f12..7c0099368806010e2637074e8693b5968b05c284 100644 (file)
@@ -129,7 +129,7 @@ typedef struct macroblock {
 
   int mbmode_cost[2][MB_MODE_COUNT];
   int intra_uv_mode_cost[2][MB_MODE_COUNT];
-  int bmode_costs[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES];
+  int bmode_costs[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES];
   int i8x8_mode_costs[MB_MODE_COUNT];
   int inter_bmode_costs[B_MODE_COUNT];
   int switchable_interp_costs[VP9_SWITCHABLE_FILTERS + 1]
index 21def264f2dac25def04bbcd891201ef723f7b30..12e517a36bc87987621c2003e595dd7a00c1f3f3 100644 (file)
@@ -1778,7 +1778,11 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
   if (m == B_PRED) {
     int b = 0;
     do {
-      ++ cpi->bmode_count[xd->block[b].bmi.as_mode.first];
+      int m = xd->block[b].bmi.as_mode.first;
+#if CONFIG_NEWBINTRAMODES
+      if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS;
+#endif
+      ++cpi->bmode_count[m];
     } while (++b < 16);
   }
 }
index 32aa5bde4752ebcf457c47d1dee6390da9678225..365784c4ff53c0a0410a6a9be057720f1b7ec422 100644 (file)
@@ -57,6 +57,10 @@ void vp9_encode_intra4x4block(const VP9_ENCODER_RTCD *rtcd,
   BLOCK *be = &x->block[ib];
   TX_TYPE tx_type;
 
+#if CONFIG_NEWBINTRAMODES
+  b->bmi.as_mode.context = vp9_find_bpred_context(b);
+#endif
+
 #if CONFIG_COMP_INTRA_PRED
   if (b->bmi.as_mode.second == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
 #endif
index 2224f54305e15cda84d94838dd6d68783f375b24..f7c38eacd7bdc90618839ba4c253e3d53fceda2e 100644 (file)
 void vp9_init_mode_costs(VP9_COMP *c) {
   VP9_COMMON *x = &c->common;
   const vp9_tree_p T = vp9_bmode_tree;
+  const vp9_tree_p KT = vp9_kf_bmode_tree;
   int i, j;
 
-  for (i = 0; i < VP9_BINTRAMODES; i++) {
-    for (j = 0; j < VP9_BINTRAMODES; j++) {
+  for (i = 0; i < VP9_KF_BINTRAMODES; i++) {
+    for (j = 0; j < VP9_KF_BINTRAMODES; j++) {
       vp9_cost_tokens((int *)c->mb.bmode_costs[i][j],
-                      x->kf_bmode_prob[i][j], T);
+                      x->kf_bmode_prob[i][j], KT);
     }
   }
 
index 88ec5ecf28eced2be34ba87fe413fc85bc02cad9..50ead37b0019a1e40cfe79ab80b1e8a6199471a3 100644 (file)
@@ -122,7 +122,9 @@ extern int skip_false_count;
 
 
 #ifdef ENTROPY_STATS
-extern int intra_mode_stats[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES];
+extern int intra_mode_stats[VP9_KF_BINTRAMODES]
+                           [VP9_KF_BINTRAMODES]
+                           [VP9_KF_BINTRAMODES];
 #endif
 
 #ifdef NMV_STATS
@@ -2126,7 +2128,7 @@ void vp9_remove_compressor(VP9_PTR *ptr) {
         int i;
 
         fprintf(f, "B: ");
-        for (i = 0; i < VP9_BINTRAMODES; i++)
+        for (i = 0; i < VP9_NKF_BINTRAMODES; i++)
           fprintf(f, "%8d, ", b_modes[i]);
 
         fprintf(f, "\n");
@@ -2165,17 +2167,18 @@ void vp9_remove_compressor(VP9_PTR *ptr) {
 
       fprintf(fmode, "\n#include \"entropymode.h\"\n\n");
       fprintf(fmode, "const unsigned int vp9_kf_default_bmode_counts ");
-      fprintf(fmode, "[VP9_BINTRAMODES] [VP9_BINTRAMODES] [VP9_BINTRAMODES] =\n{\n");
+      fprintf(fmode, "[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES]"
+                     "[VP9_KF_BINTRAMODES] =\n{\n");
 
-      for (i = 0; i < 10; i++) {
+      for (i = 0; i < VP8_KF_BINTRAMODES; i++) {
 
         fprintf(fmode, "    { // Above Mode :  %d\n", i);
 
-        for (j = 0; j < 10; j++) {
+        for (j = 0; j < VP8_KF_BINTRAMODES; j++) {
 
           fprintf(fmode, "        {");
 
-          for (k = 0; k < VP9_BINTRAMODES; k++) {
+          for (k = 0; k < VP9_KF_BINTRAMODES; k++) {
             if (!intra_mode_stats[i][j][k])
               fprintf(fmode, " %5d, ", 1);
             else
index 5406e9029b243b1d4b11de36edcee24dd70a84de..2a9fd68b16f02f05bfc6331f07c732f632a82d96 100644 (file)
@@ -102,12 +102,12 @@ typedef struct {
   vp9_prob hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]
       [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
 
-  vp9_prob ymode_prob [VP9_YMODES - 1]; /* interframe intra mode probs */
-  vp9_prob uv_mode_prob [VP9_YMODES][VP9_UV_MODES - 1];
-  vp9_prob bmode_prob [VP9_BINTRAMODES - 1];
-  vp9_prob i8x8_mode_prob [VP9_I8X8_MODES - 1];
-  vp9_prob sub_mv_ref_prob [SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
-  vp9_prob mbsplit_prob [VP9_NUMMBSPLITS - 1];
+  vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
+  vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+  vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
+  vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
+  vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+  vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
 
   vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
                                  [VP9_SWITCHABLE_FILTERS - 1];
@@ -533,12 +533,11 @@ typedef struct VP9_COMP {
   int sb_count;
   int sb_ymode_count [VP9_I32X32_MODES];
 #endif
-  int ymode_count [VP9_YMODES];        /* intra MB type cts this frame */
-  int bmode_count [VP9_BINTRAMODES];
-  int i8x8_mode_count [VP9_I8X8_MODES];
-  int sub_mv_ref_count [SUBMVREF_COUNT][VP9_SUBMVREFS];
-  int mbsplit_count [VP9_NUMMBSPLITS];
-  // int uv_mode_count[VP9_UV_MODES];       /* intra MB type cts this frame */
+  int ymode_count[VP9_YMODES];        /* intra MB type cts this frame */
+  int bmode_count[VP9_NKF_BINTRAMODES];
+  int i8x8_mode_count[VP9_I8X8_MODES];
+  int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS];
+  int mbsplit_count[VP9_NUMMBSPLITS];
   int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES];
 
   nmv_context_counts NMVcount;
index 2838e26f0f1a02f3984006af1cc8455b313b9652..b499f1df087d0196b380a88a2781c445cc65d832 100644 (file)
@@ -271,16 +271,16 @@ void vp9_setup_inter_frame(VP9_COMP *cpi) {
     vpx_memcpy(&cpi->common.fc,
                &cpi->common.lfc_a,
                sizeof(cpi->common.fc));
-    vpx_memcpy(cpi->common.fc.vp8_mode_contexts,
+    vpx_memcpy(cpi->common.fc.vp9_mode_contexts,
                cpi->common.fc.mode_context_a,
-               sizeof(cpi->common.fc.vp8_mode_contexts));
+               sizeof(cpi->common.fc.vp9_mode_contexts));
   } else {
     vpx_memcpy(&cpi->common.fc,
                &cpi->common.lfc,
                sizeof(cpi->common.fc));
-    vpx_memcpy(cpi->common.fc.vp8_mode_contexts,
+    vpx_memcpy(cpi->common.fc.vp9_mode_contexts,
                cpi->common.fc.mode_context,
-               sizeof(cpi->common.fc.vp8_mode_contexts));
+               sizeof(cpi->common.fc.vp9_mode_contexts));
   }
 }
 
index 65467f7c81e0b532f8854e246cd2e42d74f1e248..4637db0330a4644cc10d165f5ceac0bcecd9b63f 100644 (file)
@@ -1005,7 +1005,10 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, BLOCK *be,
   DECLARE_ALIGNED_ARRAY(16, unsigned char,  best_predictor, 16 * 4);
   DECLARE_ALIGNED_ARRAY(16, short, best_dqcoeff, 16);
 
-  for (mode = B_DC_PRED; mode <= B_HU_PRED; mode++) {
+#if CONFIG_NEWBINTRAMODES
+  b->bmi.as_mode.context = vp9_find_bpred_context(b);
+#endif
+  for (mode = B_DC_PRED; mode < LEFT4X4; mode++) {
 #if CONFIG_COMP_INTRA_PRED
     for (mode2 = (allow_comp ? 0 : (B_DC_PRED - 1));
                    mode2 != (allow_comp ? (mode + 1) : 0); mode2++) {
@@ -1013,8 +1016,31 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, BLOCK *be,
       int64_t this_rd;
       int ratey;
 
+#if CONFIG_NEWBINTRAMODES
+      if (xd->frame_type == KEY_FRAME) {
+        if (mode == B_CONTEXT_PRED) continue;
+#if CONFIG_COMP_INTRA_PRED
+        if (mode2 == B_CONTEXT_PRED) continue;
+#endif
+      } else {
+        if (mode >= B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS &&
+            mode < B_CONTEXT_PRED)
+          continue;
+#if CONFIG_COMP_INTRA_PRED
+        if (mode2 >= B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS &&
+            mode2 < B_CONTEXT_PRED)
+          continue;
+#endif
+      }
+#endif
+
       b->bmi.as_mode.first = mode;
+#if CONFIG_NEWBINTRAMODES
+      rate = bmode_costs[
+          mode == B_CONTEXT_PRED ? mode - CONTEXT_PRED_REPLACEMENTS : mode];
+#else
       rate = bmode_costs[mode];
+#endif
 
 #if CONFIG_COMP_INTRA_PRED
       if (mode2 == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
@@ -1023,7 +1049,13 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, BLOCK *be,
 #if CONFIG_COMP_INTRA_PRED
       } else {
         vp9_comp_intra4x4_predict(b, mode, mode2, b->predictor);
+#if CONFIG_NEWBINTRAMODES
+        rate += bmode_costs[
+            mode2 == B_CONTEXT_PRED ?
+            mode2 - CONTEXT_PRED_REPLACEMENTS : mode2];
+#else
         rate += bmode_costs[mode2];
+#endif
       }
 #endif
       vp9_subtract_b(be, b, 16);
@@ -1131,6 +1163,9 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb, int *Rat
 
       bmode_costs  = mb->bmode_costs[A][L];
     }
+#if CONFIG_NEWBINTRAMODES
+    mic->bmi[i].as_mode.context = vp9_find_bpred_context(xd->block + i);
+#endif
 
     total_rd += rd_pick_intra4x4block(
                   cpi, mb, mb->block + i, xd->block + i, &best_mode,
@@ -1149,6 +1184,10 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb, int *Rat
     mic->bmi[i].as_mode.second = best_second_mode;
 #endif
 
+#if 0  // CONFIG_NEWBINTRAMODES
+    printf("%d %d\n", mic->bmi[i].as_mode.first, mic->bmi[i].as_mode.context);
+#endif
+
     if (total_rd >= best_rd)
       break;
   }
@@ -1970,7 +2009,12 @@ static int labels2mode(
           m = LEFT4X4;
       }
 
-      cost = x->inter_bmode_costs[ m];
+#if CONFIG_NEWBINTRAMODES
+      cost = x->inter_bmode_costs[
+          m == B_CONTEXT_PRED ? m - CONTEXT_PRED_REPLACEMENTS : m];
+#else
+      cost = x->inter_bmode_costs[m];
+#endif
     }
 
     d->bmi.as_mv.first.as_int = this_mv->as_int;