]> granicus.if.org Git - libvpx/commitdiff
Use balanced model for intra prediction mode coding sandbox/jingning@google.com/experimental
authorJingning Han <jingning@google.com>
Sat, 20 Jun 2015 00:31:34 +0000 (17:31 -0700)
committerJingning Han <jingning@google.com>
Tue, 23 Jun 2015 23:42:56 +0000 (16:42 -0700)
This commit replaces the previous table based intra mode model
coding with a more balanced entropy coding system. It reduces the
decoder lookup table size by 1K bytes. The key frame compression
performance is about even on average. There are a few points where
the compression performance is improved by over 5%. Most test
points are fairly close to the lookup table approach.

Change-Id: I47154276c0a6a22ae87de8845bc2d494681b95f6

vp9/common/vp9_entropymode.c
vp9/common/vp9_entropymode.h
vp9/decoder/vp9_decodeframe.c
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_rd.c
vp9/encoder/vp9_rdopt.c

index 15185e8a2292d1aa08fa24877c663ae43c615539..167a165436cd643187ec424b4e8fba7ea5eda65a 100644 (file)
 #include "vp9/common/vp9_onyxc_int.h"
 #include "vp9/common/vp9_seg_common.h"
 
-const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
-  {  // above = dc
-    { 137,  30,  42, 148, 151, 207,  70,  52,  91 },  // left = dc
-    {  92,  45, 102, 136, 116, 180,  74,  90, 100 },  // left = v
-    {  73,  32,  19, 187, 222, 215,  46,  34, 100 },  // left = h
-    {  91,  30,  32, 116, 121, 186,  93,  86,  94 },  // left = d45
-    {  72,  35,  36, 149,  68, 206,  68,  63, 105 },  // left = d135
-    {  73,  31,  28, 138,  57, 124,  55, 122, 151 },  // left = d117
-    {  67,  23,  21, 140, 126, 197,  40,  37, 171 },  // left = d153
-    {  86,  27,  28, 128, 154, 212,  45,  43,  53 },  // left = d207
-    {  74,  32,  27, 107,  86, 160,  63, 134, 102 },  // left = d63
-    {  59,  67,  44, 140, 161, 202,  78,  67, 119 }   // left = tm
-  }, {  // above = v
-    {  63,  36, 126, 146, 123, 158,  60,  90,  96 },  // left = dc
-    {  43,  46, 168, 134, 107, 128,  69, 142,  92 },  // left = v
-    {  44,  29,  68, 159, 201, 177,  50,  57,  77 },  // left = h
-    {  58,  38,  76, 114,  97, 172,  78, 133,  92 },  // left = d45
-    {  46,  41,  76, 140,  63, 184,  69, 112,  57 },  // left = d135
-    {  38,  32,  85, 140,  46, 112,  54, 151, 133 },  // left = d117
-    {  39,  27,  61, 131, 110, 175,  44,  75, 136 },  // left = d153
-    {  52,  30,  74, 113, 130, 175,  51,  64,  58 },  // left = d207
-    {  47,  35,  80, 100,  74, 143,  64, 163,  74 },  // left = d63
-    {  36,  61, 116, 114, 128, 162,  80, 125,  82 }   // left = tm
-  }, {  // above = h
-    {  82,  26,  26, 171, 208, 204,  44,  32, 105 },  // left = dc
-    {  55,  44,  68, 166, 179, 192,  57,  57, 108 },  // left = v
-    {  42,  26,  11, 199, 241, 228,  23,  15,  85 },  // left = h
-    {  68,  42,  19, 131, 160, 199,  55,  52,  83 },  // left = d45
-    {  58,  50,  25, 139, 115, 232,  39,  52, 118 },  // left = d135
-    {  50,  35,  33, 153, 104, 162,  64,  59, 131 },  // left = d117
-    {  44,  24,  16, 150, 177, 202,  33,  19, 156 },  // left = d153
-    {  55,  27,  12, 153, 203, 218,  26,  27,  49 },  // left = d207
-    {  53,  49,  21, 110, 116, 168,  59,  80,  76 },  // left = d63
-    {  38,  72,  19, 168, 203, 212,  50,  50, 107 }   // left = tm
-  }, {  // above = d45
-    { 103,  26,  36, 129, 132, 201,  83,  80,  93 },  // left = dc
-    {  59,  38,  83, 112, 103, 162,  98, 136,  90 },  // left = v
-    {  62,  30,  23, 158, 200, 207,  59,  57,  50 },  // left = h
-    {  67,  30,  29,  84,  86, 191, 102,  91,  59 },  // left = d45
-    {  60,  32,  33, 112,  71, 220,  64,  89, 104 },  // left = d135
-    {  53,  26,  34, 130,  56, 149,  84, 120, 103 },  // left = d117
-    {  53,  21,  23, 133, 109, 210,  56,  77, 172 },  // left = d153
-    {  77,  19,  29, 112, 142, 228,  55,  66,  36 },  // left = d207
-    {  61,  29,  29,  93,  97, 165,  83, 175, 162 },  // left = d63
-    {  47,  47,  43, 114, 137, 181, 100,  99,  95 }   // left = tm
-  }, {  // above = d135
-    {  69,  23,  29, 128,  83, 199,  46,  44, 101 },  // left = dc
-    {  53,  40,  55, 139,  69, 183,  61,  80, 110 },  // left = v
-    {  40,  29,  19, 161, 180, 207,  43,  24,  91 },  // left = h
-    {  60,  34,  19, 105,  61, 198,  53,  64,  89 },  // left = d45
-    {  52,  31,  22, 158,  40, 209,  58,  62,  89 },  // left = d135
-    {  44,  31,  29, 147,  46, 158,  56, 102, 198 },  // left = d117
-    {  35,  19,  12, 135,  87, 209,  41,  45, 167 },  // left = d153
-    {  55,  25,  21, 118,  95, 215,  38,  39,  66 },  // left = d207
-    {  51,  38,  25, 113,  58, 164,  70,  93,  97 },  // left = d63
-    {  47,  54,  34, 146, 108, 203,  72, 103, 151 }   // left = tm
-  }, {  // above = d117
-    {  64,  19,  37, 156,  66, 138,  49,  95, 133 },  // left = dc
-    {  46,  27,  80, 150,  55, 124,  55, 121, 135 },  // left = v
-    {  36,  23,  27, 165, 149, 166,  54,  64, 118 },  // left = h
-    {  53,  21,  36, 131,  63, 163,  60, 109,  81 },  // left = d45
-    {  40,  26,  35, 154,  40, 185,  51,  97, 123 },  // left = d135
-    {  35,  19,  34, 179,  19,  97,  48, 129, 124 },  // left = d117
-    {  36,  20,  26, 136,  62, 164,  33,  77, 154 },  // left = d153
-    {  45,  18,  32, 130,  90, 157,  40,  79,  91 },  // left = d207
-    {  45,  26,  28, 129,  45, 129,  49, 147, 123 },  // left = d63
-    {  38,  44,  51, 136,  74, 162,  57,  97, 121 }   // left = tm
-  }, {  // above = d153
-    {  75,  17,  22, 136, 138, 185,  32,  34, 166 },  // left = dc
-    {  56,  39,  58, 133, 117, 173,  48,  53, 187 },  // left = v
-    {  35,  21,  12, 161, 212, 207,  20,  23, 145 },  // left = h
-    {  56,  29,  19, 117, 109, 181,  55,  68, 112 },  // left = d45
-    {  47,  29,  17, 153,  64, 220,  59,  51, 114 },  // left = d135
-    {  46,  16,  24, 136,  76, 147,  41,  64, 172 },  // left = d117
-    {  34,  17,  11, 108, 152, 187,  13,  15, 209 },  // left = d153
-    {  51,  24,  14, 115, 133, 209,  32,  26, 104 },  // left = d207
-    {  55,  30,  18, 122,  79, 179,  44,  88, 116 },  // left = d63
-    {  37,  49,  25, 129, 168, 164,  41,  54, 148 }   // left = tm
-  }, {  // above = d207
-    {  82,  22,  32, 127, 143, 213,  39,  41,  70 },  // left = dc
-    {  62,  44,  61, 123, 105, 189,  48,  57,  64 },  // left = v
-    {  47,  25,  17, 175, 222, 220,  24,  30,  86 },  // left = h
-    {  68,  36,  17, 106, 102, 206,  59,  74,  74 },  // left = d45
-    {  57,  39,  23, 151,  68, 216,  55,  63,  58 },  // left = d135
-    {  49,  30,  35, 141,  70, 168,  82,  40, 115 },  // left = d117
-    {  51,  25,  15, 136, 129, 202,  38,  35, 139 },  // left = d153
-    {  68,  26,  16, 111, 141, 215,  29,  28,  28 },  // left = d207
-    {  59,  39,  19, 114,  75, 180,  77, 104,  42 },  // left = d63
-    {  40,  61,  26, 126, 152, 206,  61,  59,  93 }   // left = tm
-  }, {  // above = d63
-    {  78,  23,  39, 111, 117, 170,  74, 124,  94 },  // left = dc
-    {  48,  34,  86, 101,  92, 146,  78, 179, 134 },  // left = v
-    {  47,  22,  24, 138, 187, 178,  68,  69,  59 },  // left = h
-    {  56,  25,  33, 105, 112, 187,  95, 177, 129 },  // left = d45
-    {  48,  31,  27, 114,  63, 183,  82, 116,  56 },  // left = d135
-    {  43,  28,  37, 121,  63, 123,  61, 192, 169 },  // left = d117
-    {  42,  17,  24, 109,  97, 177,  56,  76, 122 },  // left = d153
-    {  58,  18,  28, 105, 139, 182,  70,  92,  63 },  // left = d207
-    {  46,  23,  32,  74,  86, 150,  67, 183,  88 },  // left = d63
-    {  36,  38,  48,  92, 122, 165,  88, 137,  91 }   // left = tm
-  }, {  // above = tm
-    {  65,  70,  60, 155, 159, 199,  61,  60,  81 },  // left = dc
-    {  44,  78, 115, 132, 119, 173,  71, 112,  93 },  // left = v
-    {  39,  38,  21, 184, 227, 206,  42,  32,  64 },  // left = h
-    {  58,  47,  36, 124, 137, 193,  80,  82,  78 },  // left = d45
-    {  49,  50,  35, 144,  95, 205,  63,  78,  59 },  // left = d135
-    {  41,  53,  52, 148,  71, 142,  65, 128,  51 },  // left = d117
-    {  40,  36,  28, 143, 143, 202,  40,  55, 137 },  // left = d153
-    {  52,  34,  29, 129, 183, 227,  42,  35,  43 },  // left = d207
-    {  42,  44,  44, 104, 105, 164,  64, 130,  80 },  // left = d63
-    {  43,  81,  53, 140, 169, 204,  68,  84,  72 }   // left = tm
-  }
+const vp9_prob vp9_intra_mode_prob[INTRA_MODES] = {
+    227, 223, 219, 213, 204, 191, 170, 127
+};
+
+const vp9_prob vp9_intra_predictor_prob[3] = {
+    170, 192, 170
 };
 
 const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = {
@@ -329,6 +223,7 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
   vp9_copy(fc->single_ref_prob, default_single_ref_p);
   fc->tx_probs = default_tx_probs;
   vp9_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
+  vp9_copy(fc->intra_predictor_prob, vp9_intra_predictor_prob);
   vp9_copy(fc->skip_probs, default_skip_probs);
   vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
 }
index 8db3de9f28a6314b2250cb40aa25e289ae403b76..68c89ebd26c1655a7a70ed464f9db64ba296ddf6 100644 (file)
@@ -50,6 +50,7 @@ typedef struct frame_contexts {
   vp9_prob comp_ref_prob[REF_CONTEXTS];
   struct tx_probs tx_probs;
   vp9_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
+  vp9_prob intra_predictor_prob[3];
   vp9_prob skip_probs[SKIP_CONTEXTS];
   nmv_context nmvc;
   int initialized;
@@ -72,12 +73,12 @@ typedef struct FRAME_COUNTS {
   struct tx_counts tx;
   unsigned int skip[SKIP_CONTEXTS][2];
   unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
+  unsigned int intra_predictor[2][2];
   nmv_context_counts mv;
 } FRAME_COUNTS;
 
+extern const vp9_prob vp9_intra_mode_prob[INTRA_MODES];
 extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
-extern const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES]
-                                        [INTRA_MODES - 1];
 extern const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS]
                                             [PARTITION_TYPES - 1];
 extern const vp9_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
@@ -99,15 +100,6 @@ void tx_counts_to_branch_counts_16x16(const unsigned int *tx_count_16x16p,
 void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
                                     unsigned int (*ct_8x8p)[2]);
 
-static INLINE const vp9_prob *get_y_mode_probs(const MODE_INFO *mi,
-                                               const MODE_INFO *above_mi,
-                                               const MODE_INFO *left_mi,
-                                               int block) {
-  const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
-  const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
-  return vp9_kf_y_mode_prob[above][left];
-}
-
 #ifdef __cplusplus
 }  // extern "C"
 #endif
index 16e30d99f48a705f0ef8783432296ce76539f406..d6546e6f2bdf9b387ecbafc5cae40d1a17188b24 100644 (file)
@@ -1598,6 +1598,9 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
   for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
     vp9_diff_update_prob(&r, &fc->txfm_partition_prob[k]);
 
+  for (k = 0; k < 3; ++k)
+    vp9_diff_update_prob(&r, &fc->intra_predictor_prob[k]);
+
   for (k = 0; k < SKIP_CONTEXTS; ++k)
     vp9_diff_update_prob(&r, &fc->skip_probs[k]);
 
index 0ea7337e3536678c42ff036f74d7a6d50239536c..a6fdd79482a0f82aa6855426fea1e4a9b65db73d 100644 (file)
 #include "vp9/decoder/vp9_decodeframe.h"
 #include "vp9/decoder/vp9_reader.h"
 
+static PREDICTION_MODE read_intra_mode_exp(const VP9_COMMON *cm,
+                                           vp9_reader *r, const MODE_INFO *mi,
+                                           const MODE_INFO *above_mi,
+                                           const MODE_INFO *left_mi,
+                                           int block) {
+  const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
+  const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
+  PREDICTION_MODE i;
+  int count = 0;
+
+  if (above == left) {
+    if (vp9_read(r, cm->fc->intra_predictor_prob[0]))
+      return above;
+    for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+      if (i == above)
+        continue;
+      if (vp9_read(r, vp9_intra_mode_prob[count]))
+        return i;
+      ++count;
+      if (count == INTRA_MODES - 2)
+        return (i + 1) == above ? (i + 2) : (i + 1);
+    }
+    return (INTRA_MODES - 1);
+  } else {
+    if (vp9_read(r, cm->fc->intra_predictor_prob[1]))
+      return above;
+    if (vp9_read(r, cm->fc->intra_predictor_prob[2]))
+      return left;
+
+    for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+      if (i == above || i == left)
+        continue;
+      if (vp9_read(r, vp9_intra_mode_prob[count + 1]))
+        return i;
+      ++count;
+      if (count == INTRA_MODES - 3)
+        break;
+    }
+    for (++i; i <= INTRA_MODES - 1; ++i)
+      if (i != above && i != left)
+        return i;
+    return (INTRA_MODES - 1);
+  }
+}
+
 static PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
   return (PREDICTION_MODE)vp9_read_tree(r, vp9_intra_mode_tree, p);
 }
@@ -264,24 +309,24 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
     case BLOCK_4X4:
       for (i = 0; i < 4; ++i)
         mi->bmi[i].as_mode =
-            read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i));
+            read_intra_mode_exp(cm, r, mi, above_mi, left_mi, i);
       mbmi->mode = mi->bmi[3].as_mode;
       break;
     case BLOCK_4X8:
       mi->bmi[0].as_mode = mi->bmi[2].as_mode =
-          read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
+          read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
       mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
-          read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1));
+          read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 1);
       break;
     case BLOCK_8X4:
       mi->bmi[0].as_mode = mi->bmi[1].as_mode =
-          read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
+          read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
       mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
-          read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2));
+          read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 2);
       break;
     default:
-      mbmi->mode = read_intra_mode(r,
-                                   get_y_mode_probs(mi, above_mi, left_mi, 0));
+      mbmi->mode =
+          read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
   }
 
   mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
index e7477476896c102da00b429ebfa28a77c05b280e..1a91a41f7cfe1e57e97d251e56e2e4cdaca702c1 100644 (file)
@@ -44,6 +44,53 @@ static const struct vp9_token partition_encodings[PARTITION_TYPES] =
 static const struct vp9_token inter_mode_encodings[INTER_MODES] =
   {{2, 2}, {6, 3}, {0, 1}, {7, 3}};
 
+static void write_intra_mode_exp(const VP9_COMMON *cm,
+                                 vp9_writer *w, const MODE_INFO *mi,
+                                 const MODE_INFO *above_mi,
+                                 const MODE_INFO *left_mi, int block,
+                                 PREDICTION_MODE mode) {
+  const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
+  const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
+  PREDICTION_MODE i;
+  int count = 0;
+
+  if (above == left) {
+    vp9_write(w, mode == above, cm->fc->intra_predictor_prob[0]);
+    if (mode == above)
+      return;
+
+    for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+      if (i == above)
+        continue;
+      vp9_write(w, i == mode, vp9_intra_mode_prob[count]);
+      ++count;
+      if (i == mode)
+        return;
+      if (count == INTRA_MODES - 2)
+        return;
+    }
+  } else {
+    // above and left reference modes differ
+    vp9_write(w, mode == above, cm->fc->intra_predictor_prob[1]);
+    if (mode == above)
+      return;
+    vp9_write(w, mode == left, cm->fc->intra_predictor_prob[2]);
+    if (mode == left)
+      return;
+
+    for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+      if (i == above || i == left)
+        continue;
+      vp9_write(w, i == mode, vp9_intra_mode_prob[count + 1]);
+      ++count;
+      if (i == mode)
+        return;
+      if (count == INTRA_MODES - 3)
+        return;
+    }
+  }
+}
+
 static void write_intra_mode(vp9_writer *w, PREDICTION_MODE mode,
                              const vp9_prob *probs) {
   vp9_write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]);
@@ -145,6 +192,14 @@ static void update_txfm_partition_probs(VP9_COMMON *cm, vp9_writer *w,
                               counts->txfm_partition[k]);
 }
 
+static void update_intra_predictor_probs(VP9_COMMON *cm, vp9_writer *w,
+                                         FRAME_COUNTS *counts) {
+  int k;
+  for (k = 0; k < 3; ++k)
+    vp9_cond_prob_diff_update(w, &cm->fc->intra_predictor_prob[k],
+                              counts->intra_predictor[k]);
+}
+
 static int write_skip(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                       int segment_id, const MODE_INFO *mi, vp9_writer *w) {
   if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
@@ -449,7 +504,7 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
     write_selected_tx_size(cm, xd, w);
 
   if (bsize >= BLOCK_8X8) {
-    write_intra_mode(w, mbmi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0));
+    write_intra_mode_exp(cm, w, mi, above_mi, left_mi, 0, mbmi->mode);
   } else {
     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -458,8 +513,8 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
     for (idy = 0; idy < 2; idy += num_4x4_h) {
       for (idx = 0; idx < 2; idx += num_4x4_w) {
         const int block = idy * 2 + idx;
-        write_intra_mode(w, mi->bmi[block].as_mode,
-                         get_y_mode_probs(mi, above_mi, left_mi, block));
+        write_intra_mode_exp(cm, w, mi, above_mi, left_mi, block,
+                             mi->bmi[block].as_mode);
       }
     }
   }
@@ -1258,6 +1313,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
 
   update_coef_probs(cpi, &header_bc);
   update_txfm_partition_probs(cm, &header_bc, counts);
+  update_intra_predictor_probs(cm, &header_bc, counts);
   update_skip_probs(cm, &header_bc, counts);
 
   if (!frame_is_intra_only(cm)) {
index 4b13aa3742af17f5908d26110994d7f68bebc04a..b469a8e6d22f9368533ac0777a29d36c48757025 100644 (file)
@@ -4211,6 +4211,45 @@ static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
           if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
             mi_8x8[mis * y + x].src_mi->mbmi.tx_size = tx_size;
     }
+
+    if (!is_inter_block(mbmi)) {
+      // TODO(jingning): refactor this code for speed improvement.
+      const MODE_INFO *above_mi = xd->mi[-cm->mi_stride].src_mi;
+      const MODE_INFO *left_mi  = xd->left_available ? xd->mi[-1].src_mi : NULL;
+      if (bsize >= BLOCK_8X8) {
+        int idx, idy;
+        const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
+        const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
+        for (idy = 0; idy < 2; idy += num_4x4_h) {
+          for (idx = 0; idx < 2; idx += num_4x4_w) {
+            const int block = idy * 2 + idx;
+            const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi,
+                                                               block);
+            const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi,
+                                                             block);
+            if (above == left) {
+              ++td->counts->intra_predictor[0][mi->bmi[block].as_mode == above];
+            } else {
+              ++td->counts->intra_predictor[1][mi->bmi[block].as_mode == above];
+              if (mbmi->mode != above)
+                ++td->counts->intra_predictor[1]
+                                             [mi->bmi[block].as_mode == left];
+            }
+          }
+        }
+      } else {
+        const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, 0);
+        const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, 0);
+        if (above == left) {
+          ++td->counts->intra_predictor[0][mbmi->mode == above];
+        } else {
+          ++td->counts->intra_predictor[1][mbmi->mode == above];
+          if (mbmi->mode != above)
+            ++td->counts->intra_predictor[1][mbmi->mode == left];
+        }
+      }
+    }
+
     ++td->counts->tx.tx_totals[mbmi->tx_size];
     ++td->counts->tx.tx_totals[get_uv_tx_size(mbmi, &xd->plane[1])];
   }
index b69fcfc26a4b51d8cec1b0612fa19a2b51611ebf..ccdac6617c63a771bbe4366c4ab8d271388324df 100644 (file)
@@ -940,12 +940,11 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
       MIN(max_txsize_lookup[bsize],
           tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
   MODE_INFO *const mic = xd->mi[0].src_mi;
-  int *bmode_costs;
+  int bmode_costs;
   const MODE_INFO *above_mi = xd->mi[-xd->mi_stride].src_mi;
   const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL;
   const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
   const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
-  bmode_costs = cpi->y_mode_costs[A][L];
 
   (void) ctx;
   vp9_rd_cost_reset(&best_rdc);
@@ -963,11 +962,17 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
     args.rate = 0;
     args.dist = 0;
     mbmi->tx_size = intra_tx_size;
+
+    if (A == L)
+      bmode_costs = (this_mode == A) ? 406 : 961;
+    else  // (A != L)
+      bmode_costs = (this_mode == A) || (this_mode == L) ? 512 : 1024;
+
     vp9_foreach_transformed_block_in_plane(xd, bsize, 0,
                                            estimate_block_intra, &args);
     this_rdc.rate = args.rate;
     this_rdc.dist = args.dist;
-    this_rdc.rate += bmode_costs[this_mode];
+    this_rdc.rate += bmode_costs;
     this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
                              this_rdc.rate, this_rdc.dist);
 
index bbf70ead523307756ff453d01ac26e1e1b95921f..217626c2e5b4ee7df5999ea29610ebb8a5048d99 100644 (file)
@@ -66,12 +66,7 @@ static const uint8_t rd_thresh_block_size_factor[BLOCK_SIZES] = {
 
 static void fill_mode_costs(VP9_COMP *cpi) {
   const FRAME_CONTEXT *const fc = cpi->common.fc;
-  int i, j;
-
-  for (i = 0; i < INTRA_MODES; ++i)
-    for (j = 0; j < INTRA_MODES; ++j)
-      vp9_cost_tokens(cpi->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
-                      vp9_intra_mode_tree);
+  int i;
 
   vp9_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
   vp9_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME],
index 912a92a6b338ed6a4e9a5d5fb0bdbf975dbff22f..8869d8407782296b1d383d15aa8103a8a3a35910 100644 (file)
@@ -777,8 +777,8 @@ static int conditional_skipintra(PREDICTION_MODE mode,
 
 static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
                                      PREDICTION_MODE *best_mode,
-                                     const int *bmode_costs,
                                      ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
+                                     PREDICTION_MODE A, PREDICTION_MODE L,
                                      int *bestrate, int *bestratey,
                                      int64_t *bestdistortion,
                                      BLOCK_SIZE bsize, int64_t rd_thresh) {
@@ -817,7 +817,12 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
       int64_t this_rd;
       int ratey = 0;
       int64_t distortion = 0;
-      int rate = bmode_costs[mode];
+      int rate;
+
+      if (A == L)
+        rate = (mode == A) ? 256 : 1064;
+      else  // (A != L)
+        rate = (mode == A) || (mode == L) ? 404 : 1169;
 
       if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
         continue;
@@ -918,7 +923,12 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
     int64_t this_rd;
     int ratey = 0;
     int64_t distortion = 0;
-    int rate = bmode_costs[mode];
+    int rate;
+
+    if (A == L)
+      rate = (mode == A) ? 406 : 961;
+    else  // (A != L)
+      rate = (mode == A) || (mode == L) ? 512 : 1024;
 
     if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
       continue;
@@ -1026,7 +1036,8 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
   int tot_rate_y = 0;
   int64_t total_rd = 0;
   ENTROPY_CONTEXT t_above[4], t_left[4];
-  const int *bmode_costs = cpi->mbmode_cost;
+  PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
+  PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
 
   vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
   vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
@@ -1039,14 +1050,13 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
       int64_t d = INT64_MAX, this_rd = INT64_MAX;
       i = idy * 2 + idx;
       if (cpi->common.frame_type == KEY_FRAME) {
-        const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, i);
-        const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, i);
-
-        bmode_costs  = cpi->y_mode_costs[A][L];
+        A = vp9_above_block_mode(mic, above_mi, i);
+        L = vp9_left_block_mode(mic, left_mi, i);
       }
 
-      this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs,
-                                      t_above + idx, t_left + idy, &r, &ry, &d,
+      this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode,
+                                      t_above + idx, t_left + idy,
+                                      A, L, &r, &ry, &d,
                                       bsize, best_rd - total_rd);
       if (this_rd >= best_rd - total_rd)
         return INT64_MAX;
@@ -1090,12 +1100,11 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
   int64_t this_distortion, this_rd;
   TX_SIZE best_tx = TX_4X4;
   int i;
-  int *bmode_costs;
+  int bmode_costs;
   const MODE_INFO *above_mi = xd->above_mi;
   const MODE_INFO *left_mi = xd->left_mi;
   const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
   const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
-  bmode_costs = cpi->y_mode_costs[A][L];
 
   if (cpi->sf.tx_size_search_method == USE_FULL_RD)
     for (i = 0; i < TX_MODES; i++)
@@ -1106,6 +1115,11 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
   for (mode = DC_PRED; mode <= TM_PRED; mode++) {
     int64_t local_tx_cache[TX_MODES];
 
+    if (A == L)
+      bmode_costs = (mode == A) ? 406 : 961;
+    else  // (A != L)
+      bmode_costs = (mode == A) || (mode == L) ? 512 : 1024;
+
     if (cpi->sf.use_nonrd_pick_mode) {
       // These speed features are turned on in hybrid non-RD and RD mode
       // for key frame coding in the context of real-time setting.
@@ -1123,7 +1137,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
     if (this_rate_tokenonly == INT_MAX)
       continue;
 
-    this_rate = this_rate_tokenonly + bmode_costs[mode];
+    this_rate = this_rate_tokenonly + bmode_costs;
     this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
 
     if (this_rd < best_rd) {
@@ -3782,6 +3796,13 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
     if (ref_frame == INTRA_FRAME) {
       TX_SIZE uv_tx;
       struct macroblockd_plane *const pd = &xd->plane[1];
+      MODE_INFO *const mic = xd->mi[0].src_mi;
+      const MODE_INFO *above_mi = xd->above_mi;
+      const MODE_INFO *left_mi = xd->left_mi;
+
+      const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
+      const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
+      int intra_mode_cost;
       vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
       super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
                       NULL, bsize, tx_cache, best_rd);
@@ -3796,12 +3817,17 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
                              &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
       }
 
+      if (A == L)
+        intra_mode_cost = (this_mode == A) ? 256 : 1064;
+      else  // (A != L)
+        intra_mode_cost = (this_mode == A) || (this_mode == L) ? 404 : 1169;
+
       rate_uv = rate_uv_tokenonly[uv_tx];
       distortion_uv = dist_uv[uv_tx];
       skippable = skippable && skip_uv[uv_tx];
       mbmi->uv_mode = mode_uv[uv_tx];
 
-      rate2 = rate_y + cpi->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
+      rate2 = rate_y + intra_mode_cost + rate_uv_intra[uv_tx];
       if (this_mode != DC_PRED && this_mode != TM_PRED)
         rate2 += intra_cost_penalty;
       distortion2 = distortion_y + distortion_uv;