]> granicus.if.org Git - libvpx/commitdiff
Palette experiment: adaptly update probs
authorhui su <huisu@google.com>
Sat, 7 Mar 2015 02:08:50 +0000 (18:08 -0800)
committerhui su <huisu@google.com>
Wed, 25 Mar 2015 16:12:57 +0000 (09:12 -0700)
Also make changes to transmit palette-enabled flag using
neighbor blocks as context.

on screen_content
--enable-palette                            +7.35%

on derflr
with all other experiments                  +6.05%

Change-Id: Id6c2f726d21913d54a3f86ecfea474a4044c27f6

vp9/common/vp9_blockd.h
vp9/common/vp9_entropymode.c
vp9/common/vp9_entropymode.h
vp9/common/vp9_enums.h
vp9/common/vp9_palette.c
vp9/common/vp9_palette.h
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_rdopt.c

index 463998e36424c8269de9791cbc55c3055543486d..a74bb6525725e8a147b3dff4856350db46bc44a9 100644 (file)
@@ -109,16 +109,6 @@ typedef enum {
 } COPY_MODE;
 #endif  // CONFIG_COPY_MODE
 
-#if CONFIG_PALETTE
-typedef enum {
-  H_SCAN,
-  V_SCAN,
-  SPIRAL_SCAN,
-  ZZ_SCAN,
-  PALETTE_SCAN_ORDERS
-} PALETTE_SCAN_ORDER;
-#endif
-
 static INLINE int is_inter_mode(PREDICTION_MODE mode) {
   return mode >= NEARESTMV && mode <= NEWMV;
 }
index dad007643f3f5805e3c081c962c3e24f3e55de36..05d85fcf17e8b9a92b620877100fd42735301c9a 100644 (file)
@@ -373,6 +373,32 @@ const vp9_tree_index vp9_palette_size_tree[TREE_SIZE(PALETTE_SIZES)] = {
   -SEVEN_COLORS, -EIGHT_COLORS
 };
 
+static const vp9_prob default_palette_size_prob[10][PALETTE_SIZES - 1] = {
+    {  96,  89, 100,  64,  77, 130},
+    {  22,  15,  44,  16,  34,  82},
+    {  30,  19,  57,  18,  38,  86},
+    {  94,  36, 104,  23,  43,  92},
+    { 116,  76, 107,  46,  65, 105},
+    { 112,  82,  94,  40,  70, 112},
+    { 147, 124, 123,  58,  69, 103},
+    { 180, 113, 136,  49,  45, 114},
+    { 107,  70,  87,  49, 154, 156},
+    {  98, 105, 142,  63,  64, 152},
+};
+
+static const vp9_prob default_palette_uv_size_prob[10][PALETTE_SIZES - 1] = {
+    { 160, 196, 228, 213, 175, 230},
+    {  87, 148, 208, 141, 166, 163},
+    {  72, 151, 204, 139, 155, 161},
+    {  78, 135, 171, 104, 120, 173},
+    {  59,  92, 131,  78,  92, 142},
+    {  75, 118, 149,  84,  90, 128},
+    {  89,  87,  92,  66,  66, 128},
+    {  67,  53,  54,  55,  66,  93},
+    { 120, 130,  83, 171,  75, 214},
+    {  72,  55,  66,  68,  79, 107},
+};
+
 const vp9_tree_index vp9_palette_run_length_tree[TREE_SIZE(PALETTE_RUN_LENGTHS)]
                                                  = {
   -ONE_BITS, 2,
@@ -383,19 +409,6 @@ const vp9_tree_index vp9_palette_run_length_tree[TREE_SIZE(PALETTE_RUN_LENGTHS)]
   -SIX_BITS, -MAX_BITS
 };
 
-static const vp9_prob default_palette_size_prob[10][PALETTE_SIZES - 1] = {
-    {  54,  82,  96, 100, 117, 139},
-    {  11,  10,  30,  20,  45,  82},
-    {  11,  10,  30,  20,  45,  82},
-    {  16,  13,  29,   9,  34,  93},
-    { 128,  40,  50,  46,  62,  77},
-    { 128,  40,  50,  46,  62,  77},
-    {  92, 177, 193,  78,  28,  40},
-    { 160,  30, 228,  64, 105, 180},
-    { 160,  30, 228,  64, 105, 180},
-    {  32,  84, 227,  45,  12, 232},
-};
-
 static const vp9_prob
 default_palette_run_length_prob[10][PALETTE_RUN_LENGTHS - 1] = {
     {  10,  91, 148,  95, 121, 254},
@@ -410,19 +423,6 @@ default_palette_run_length_prob[10][PALETTE_RUN_LENGTHS - 1] = {
     {  72,  34,  32,  42,  42, 108},
 };
 
-static const vp9_prob default_palette_uv_size_prob[10][PALETTE_SIZES - 1] = {
-    { 180, 192, 207, 221,  55, 254},
-    { 128, 185, 235, 148, 180, 128},
-    { 128, 185, 235, 148, 180, 128},
-    { 150, 180, 211,  77, 147, 179},
-    { 128,  60, 195,  68, 120, 228},
-    { 128,  60, 195,  68, 120, 228},
-    { 228,  15,  17, 178,  47, 197},
-    { 103, 210, 145, 250, 190, 128},
-    { 103, 210, 145, 250, 190, 128},
-    {   5,  76, 230, 148, 239, 254},
-};
-
 static const vp9_prob
 default_palette_uv_run_length_prob[10][PALETTE_RUN_LENGTHS - 1] = {
     {  81, 107, 112, 254, 128, 128},
@@ -436,6 +436,59 @@ default_palette_uv_run_length_prob[10][PALETTE_RUN_LENGTHS - 1] = {
     {   5,   5,   5,  70,  75,  18},
     {   5,   5,   5,   5, 157,   5},
 };
+
+const vp9_tree_index vp9_palette_scan_order_tree
+[TREE_SIZE(PALETTE_SCAN_ORDERS)] = {
+  -H_SCAN, 2,
+  -V_SCAN, 4,
+  -SPIRAL_SCAN, -ZZ_SCAN,
+};
+
+static const vp9_prob
+default_palette_scan_order_prob[10][PALETTE_SCAN_ORDERS - 1] = {
+    {  95, 152, 184},
+    {  79, 102, 219},
+    { 114, 143, 201},
+    { 121, 133, 178},
+    {  80, 163, 180},
+    { 147, 124, 192},
+    { 140, 202, 142},
+    {  91, 238, 206},
+    { 214, 203, 180},
+    {  85, 223,  29},
+};
+
+static const vp9_prob
+default_palette_uv_scan_order_prob[10][PALETTE_SCAN_ORDERS - 1] = {
+    { 131, 171, 112},
+    {  29, 133, 213},
+    { 159, 147, 196},
+    {  86, 113, 173},
+    {  36, 210, 119},
+    { 148, 156, 160},
+    { 104, 209,  72},
+    {  37, 253, 232},
+    { 198, 240, 153},
+    {  61, 253, 109},
+};
+
+static const vp9_prob default_palette_enabled_prob[10][3] = {
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+    { 240,  180,  100, },
+};
+
+
+static const vp9_prob default_uv_palette_enabled_prob[2] = {
+    253, 229
+};
 #endif  // CONFIG_PALETTE
 
 #if CONFIG_SUPERTX
@@ -570,6 +623,10 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
 #endif  // CONFIG_EXT_TX
 #if CONFIG_PALETTE
   vp9_copy(fc->palette_size_prob, default_palette_size_prob);
+  vp9_copy(fc->palette_enabled_prob, default_palette_enabled_prob);
+  vp9_copy(fc->palette_uv_enabled_prob, default_uv_palette_enabled_prob);
+  vp9_copy(fc->palette_scan_order_prob, default_palette_scan_order_prob);
+  vp9_copy(fc->palette_uv_scan_order_prob, default_palette_uv_scan_order_prob);
   vp9_copy(fc->palette_run_length_prob, default_palette_run_length_prob);
   vp9_copy(fc->palette_uv_size_prob, default_palette_uv_size_prob);
   vp9_copy(fc->palette_uv_run_length_prob, default_palette_uv_run_length_prob);
@@ -768,6 +825,41 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
            counts->wedge_interinter[i]);
   }
 #endif  // CONFIG_WEDGE_PARTITION
+
+#if CONFIG_PALETTE
+  for (i = 0; i < 10; i++) {
+    adapt_probs(vp9_palette_scan_order_tree,
+                pre_fc->palette_scan_order_prob[i],
+                counts->y_palette_scan_order[i],
+                fc->palette_scan_order_prob[i]);
+  }
+  for (i = 0; i < 10; i++) {
+    adapt_probs(vp9_palette_scan_order_tree,
+                pre_fc->palette_uv_scan_order_prob[i],
+                counts->uv_palette_scan_order[i],
+                fc->palette_uv_scan_order_prob[i]);
+  }
+  for (i = 0; i < 10; i++) {
+    adapt_probs(vp9_palette_size_tree, pre_fc->palette_size_prob[i],
+                counts->y_palette_size[i],
+                fc->palette_size_prob[i]);
+  }
+  for (i = 0; i < 10; i++) {
+    adapt_probs(vp9_palette_size_tree, pre_fc->palette_uv_size_prob[i],
+                counts->uv_palette_size[i],
+                fc->palette_uv_size_prob[i]);
+  }
+  for (i = 0; i < 10; i++) {
+    for (j = 0; j < 3; j++)
+      fc->palette_enabled_prob[i][j] =
+          adapt_prob(pre_fc->palette_enabled_prob[i][j],
+                     counts->y_palette_enabled[i][j]);
+  }
+  for (i = 0; i < 2; i++)
+    fc->palette_uv_enabled_prob[i] =
+        adapt_prob(pre_fc->palette_uv_enabled_prob[i],
+                   counts->uv_palette_enabled[i]);
+#endif  // CONFIG_PALETTE
 }
 
 static void set_default_lf_deltas(struct loopfilter *lf) {
index 9c2f3a278c6d22d5fd0256089f0e777b8cad092f..f916135ba2c0e754edbe9bc6a9f3f06e3f10609c 100644 (file)
@@ -67,6 +67,10 @@ typedef struct frame_contexts {
   vp9_prob ext_tx_prob[3][EXT_TX_TYPES - 1];
 #endif  // CONFIG_EXT_TX
 #if CONFIG_PALETTE
+  vp9_prob palette_enabled_prob[10][3];
+  vp9_prob palette_uv_enabled_prob[2];
+  vp9_prob palette_scan_order_prob[10][PALETTE_SCAN_ORDERS - 1];
+  vp9_prob palette_uv_scan_order_prob[10][PALETTE_SCAN_ORDERS - 1];
   vp9_prob palette_size_prob[10][PALETTE_SIZES - 1];
   vp9_prob palette_run_length_prob[10][PALETTE_RUN_LENGTHS - 1];
   vp9_prob palette_uv_size_prob[10][PALETTE_SIZES - 1];
@@ -117,18 +121,18 @@ typedef struct {
   nmv_context_counts mv;
 #if CONFIG_FILTERINTRA
   unsigned int filterintra[TX_SIZES][INTRA_MODES][2];
-#endif
+#endif  // CONFIG_FILTERINTRA
 #if CONFIG_EXT_TX
   unsigned int ext_tx[3][EXT_TX_TYPES];
-#endif
+#endif  // CONFIG_EXT_TX
 #if CONFIG_SUPERTX
   unsigned int supertx[PARTITION_SUPERTX_CONTEXTS][TX_SIZES][2];
   unsigned int supertx_size[BLOCK_SIZES];
-#endif
+#endif  // CONFIG_SUPERTX
 #if CONFIG_TX_SKIP
   unsigned int y_tx_skip[2][2];
   unsigned int uv_tx_skip[2][2];
-#endif
+#endif  // CONFIG_TX_SKIP
 #if CONFIG_COPY_MODE
   unsigned int copy_noref[COPY_MODE_CONTEXTS][BLOCK_SIZES][2];
   unsigned int copy_mode_l2[COPY_MODE_CONTEXTS][2];
@@ -143,6 +147,14 @@ typedef struct {
 #if CONFIG_WEDGE_PARTITION
   unsigned int wedge_interinter[BLOCK_SIZES][2];
 #endif  // CONFIG_WEDGE_PARTITION
+#if CONFIG_PALETTE
+  unsigned int y_palette_enabled[10][3][2];
+  unsigned int uv_palette_enabled[2][2];
+  unsigned int y_palette_scan_order[10][PALETTE_SCAN_ORDERS];
+  unsigned int uv_palette_scan_order[10][PALETTE_SCAN_ORDERS];
+  unsigned int y_palette_size[10][PALETTE_SIZES];
+  unsigned int uv_palette_size[10][PALETTE_SIZES];
+#endif  // CONFIG_PALETTE
 } FRAME_COUNTS;
 
 extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
@@ -161,6 +173,8 @@ extern const vp9_tree_index vp9_ext_tx_tree[TREE_SIZE(EXT_TX_TYPES)];
 #if CONFIG_PALETTE
 extern const vp9_tree_index vp9_palette_size_tree[TREE_SIZE(PALETTE_SIZES)];
 extern const vp9_tree_index
+vp9_palette_scan_order_tree[TREE_SIZE(PALETTE_SCAN_ORDERS)];
+extern const vp9_tree_index
 vp9_palette_run_length_tree[TREE_SIZE(PALETTE_RUN_LENGTHS)];
 #endif
 #if CONFIG_COPY_MODE
index 81f99f37ffc5ec2989b8ea38b01af9ccad59e46a..39a885ee8bcbbbde877216491a4b9cf000c95d9f 100644 (file)
@@ -149,7 +149,15 @@ typedef enum {
   MAX_BITS,
   PALETTE_RUN_LENGTHS
 } PALETTE_RUN_LENGTH;
-#endif
+
+typedef enum {
+  H_SCAN,
+  V_SCAN,
+  SPIRAL_SCAN,
+  ZZ_SCAN,
+  PALETTE_SCAN_ORDERS
+} PALETTE_SCAN_ORDER;
+#endif  // CONFIG_PALETTE
 
 typedef enum {
   VP9_LAST_FLAG = 1 << 0,
index a70e86218fbfe9298909f75f3638b13c33aa0662..b90b45f83424eaafe0b05fa20ebd33dba90c9190 100644 (file)
@@ -424,4 +424,22 @@ void palette_iscan(uint8_t *color_index_map, uint8_t *sequence,
       break;
   }
 }
-#endif
+
+void update_palette_counts(FRAME_COUNTS *counts, MB_MODE_INFO *mbmi,
+                           BLOCK_SIZE bsize, int palette_ctx) {
+  int idx = bsize - BLOCK_8X8;
+
+  counts->y_palette_enabled[idx][palette_ctx][mbmi->palette_enabled[0]]++;
+  counts->uv_palette_enabled[mbmi->palette_enabled[0]]
+                            [mbmi->palette_enabled[1]]++;
+  if (mbmi->palette_enabled[0]) {
+    counts->y_palette_scan_order[idx][mbmi->palette_scan_order[0]]++;
+    counts->y_palette_size[idx][mbmi->palette_size[0] - 2]++;
+  }
+
+  if (mbmi->palette_enabled[1]) {
+    counts->uv_palette_scan_order[idx][mbmi->palette_scan_order[1]]++;
+    counts->uv_palette_size[idx][mbmi->palette_size[1] - 2]++;
+  }
+}
+#endif  // CONFIG_PALETTE
index 5b00ff29df6b320444c955a789894b5524f22e6a..3148a38dd3bed237135c603c43a0064a84d2b3df 100644 (file)
@@ -12,6 +12,7 @@
 #define VP9_COMMON_VP9_PALETTE_H_
 
 #include "vp9/common/vp9_blockd.h"
+#include "vp9/common/vp9_entropymode.h"
 
 #if CONFIG_PALETTE
 int count_colors(const uint8_t *src, int stride, int rows, int cols);
@@ -34,6 +35,8 @@ void palette_scan(uint8_t *color_index_map, uint8_t *sequence,
                   int rows, int cols, PALETTE_SCAN_ORDER ps, int *scan_order);
 void palette_iscan(uint8_t *color_index_map, uint8_t *sequence,
                    int rows, int cols, PALETTE_SCAN_ORDER ps, int *scan_order);
+void update_palette_counts(FRAME_COUNTS *counts, MB_MODE_INFO *mbmi,
+                           BLOCK_SIZE bsize, int palette_ctx);
 #endif
 
 #endif  // VP9_COMMON_VP9_PALETTE_H_
index c5cf2ab4559e53b6828a807dedb4b06df35962f1..cea3769c0f608c49ad022ac7b35cbc2769b9cefa 100644 (file)
@@ -224,8 +224,16 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
   mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
 #if CONFIG_PALETTE
   if (bsize >= BLOCK_8X8 && cm->allow_palette_mode) {
-    mbmi->palette_enabled[0] = vp9_read_bit(r);
-    mbmi->palette_enabled[1] = vp9_read_bit(r);
+    int palette_ctx = 0;
+    if (above_mi)
+      palette_ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+    if (left_mi)
+      palette_ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+    mbmi->palette_enabled[0] =
+        vp9_read(r,
+                 cm->fc.palette_enabled_prob[bsize - BLOCK_8X8][palette_ctx]);
+    mbmi->palette_enabled[1] =
+        vp9_read(r, cm->fc.palette_uv_enabled_prob[mbmi->palette_enabled[0]]);
   } else {
     mbmi->palette_enabled[0] = 0;
     mbmi->palette_enabled[1] = 0;
@@ -260,7 +268,9 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
     mbmi->palette_run_length[0] =
         vp9_read_literal(r, get_bit_depth(palette_max_run(bsize)));
     mbmi->palette_run_length[0] = (mbmi->palette_run_length[0]) << 1;
-    mbmi->palette_scan_order[0] = vp9_read_literal(r, 2);
+    mbmi->palette_scan_order[0] =
+        vp9_read_tree(r, vp9_palette_scan_order_tree,
+                      cm->fc.palette_scan_order_prob[bsize - BLOCK_8X8]);
     m1 = mbmi->palette_indexed_size;
     m2 = mbmi->palette_literal_size;
 
@@ -311,7 +321,6 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
     palette_color_insertion(cm->current_palette_colors,
                             &cm ->current_palette_size,
                             cm->current_palette_count, mbmi);
-
     run_lengh_decoding(mbmi->palette_runs, mbmi->palette_run_length[0],
                        xd->palette_map_buffer);
     palette_iscan(xd->plane[0].color_index_map, xd->palette_map_buffer,
@@ -335,12 +344,14 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
     if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
       mbmi->palette_size[1] =
           vp9_read_tree(r, vp9_palette_size_tree,
-                        cm->fc.palette_uv_size_prob[uv_bsize - BLOCK_4X4]);
+                        cm->fc.palette_uv_size_prob[bsize - BLOCK_8X8]);
       mbmi->palette_size[1] += 2;
       mbmi->palette_run_length[1] =
           vp9_read_literal(r, get_bit_depth(palette_max_run(uv_bsize)));
       mbmi->palette_run_length[1] = (mbmi->palette_run_length[1]) << 1;
-      mbmi->palette_scan_order[1] = vp9_read_literal(r, 2);
+      mbmi->palette_scan_order[1] =
+          vp9_read_tree(r, vp9_palette_scan_order_tree,
+                        cm->fc.palette_uv_scan_order_prob[bsize - BLOCK_8X8]);
     } else {
       mbmi->palette_size[1] = mbmi->palette_size[0];
     }
@@ -357,7 +368,7 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
             vp9_read_literal(r, get_bit_depth(mbmi->palette_size[1]));
         bits = vp9_read_tree(r, vp9_palette_run_length_tree,
                              cm->fc.
-                             palette_uv_run_length_prob[uv_bsize - BLOCK_4X4]);
+                             palette_uv_run_length_prob[bsize - BLOCK_8X8]);
         if (bits == MAX_BITS)
           mbmi->palette_runs[PALETTE_MAX_RUNS + i + 1] = vp9_read_literal(r, d);
         else
@@ -1247,13 +1258,27 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
     if (mbmi->copy_mode == NOREF)
 #endif
       inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
+
 #if CONFIG_PALETTE
     mbmi->palette_enabled[0] = 0;
     mbmi->palette_enabled[1] = 0;
 
     if (!inter_block && mbmi->sb_type >= BLOCK_8X8 && cm->allow_palette_mode) {
-      mbmi->palette_enabled[0] = vp9_read_bit(r);
-      mbmi->palette_enabled[1] = vp9_read_bit(r);
+      const MODE_INFO *above_mi = xd->up_available ?
+          xd->mi[-xd->mi_stride].src_mi : NULL;
+      const MODE_INFO *left_mi = xd->left_available ?
+          xd->mi[-1].src_mi : NULL;
+      int ctx = 0;
+
+      if (above_mi)
+        ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+      if (left_mi)
+        ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+      mbmi->palette_enabled[0] =
+          vp9_read(r,
+                   cm->fc.palette_enabled_prob[mbmi->sb_type - BLOCK_8X8][ctx]);
+      mbmi->palette_enabled[1] =
+          vp9_read(r, cm->fc.palette_uv_enabled_prob[mbmi->palette_enabled[0]]);
     }
 
     if (mbmi->palette_enabled[0]) {
@@ -1271,7 +1296,9 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
       mbmi->palette_run_length[0] =
           vp9_read_literal(r, get_bit_depth(palette_max_run(bsize)));
       mbmi->palette_run_length[0] = (mbmi->palette_run_length[0]) << 1;
-      mbmi->palette_scan_order[0] = vp9_read_literal(r, 2);
+      mbmi->palette_scan_order[0] =
+          vp9_read_tree(r, vp9_palette_scan_order_tree,
+                        cm->fc.palette_scan_order_prob[bsize - BLOCK_8X8]);
 
       for (i = 0; i < mbmi->palette_size[0]; i++) {
         mbmi->palette_colors[i] = vp9_read_literal(r, 8);
@@ -1308,7 +1335,7 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
       int rows = 4 * num_4x4_blocks_high_lookup[bsize] >>
           xd->plane[1].subsampling_y;
       int cols = 4 * num_4x4_blocks_wide_lookup[bsize] >>
-          xd->plane[1].subsampling_y;
+          xd->plane[1].subsampling_x;
       PALETTE_RUN_LENGTH bits;
       BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
 
@@ -1316,12 +1343,14 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
       if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
         mbmi->palette_size[1] =
             vp9_read_tree(r, vp9_palette_size_tree,
-                          cm->fc.palette_uv_size_prob[uv_bsize - BLOCK_4X4]);
+                          cm->fc.palette_uv_size_prob[bsize - BLOCK_8X8]);
         mbmi->palette_size[1] += 2;
         mbmi->palette_run_length[1] =
             vp9_read_literal(r, get_bit_depth(palette_max_run(uv_bsize)));
         mbmi->palette_run_length[1] = (mbmi->palette_run_length[1]) << 1;
-        mbmi->palette_scan_order[1] = vp9_read_literal(r, 2);
+        mbmi->palette_scan_order[1] =
+            vp9_read_tree(r, vp9_palette_scan_order_tree,
+                          cm->fc.palette_uv_scan_order_prob[bsize - BLOCK_8X8]);
       } else {
         mbmi->palette_size[1] = mbmi->palette_size[0];
       }
@@ -1337,8 +1366,8 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
           mbmi->palette_runs[PALETTE_MAX_RUNS + i] =
               vp9_read_literal(r, get_bit_depth(mbmi->palette_size[1]));
           bits = vp9_read_tree(r, vp9_palette_run_length_tree,
-                               cm->fc.palette_uv_run_length_prob[uv_bsize -
-                                                                 BLOCK_4X4]);
+                               cm->fc.palette_uv_run_length_prob[bsize -
+                                                                 BLOCK_8X8]);
           if (bits == MAX_BITS)
             mbmi->palette_runs[PALETTE_MAX_RUNS + i + 1] =
                 vp9_read_literal(r, d);
@@ -1356,6 +1385,21 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
       }
     }
 
+    if (!inter_block && mbmi->sb_type >= BLOCK_8X8 && cm->allow_palette_mode) {
+      BLOCK_SIZE bsize = mbmi->sb_type;
+      int palette_ctx = 0;
+      const MODE_INFO *above_mi = xd->up_available ?
+          xd->mi[-xd->mi_stride].src_mi : NULL;
+      const MODE_INFO *left_mi = xd->left_available ?
+          xd->mi[-1].src_mi : NULL;
+
+      if (above_mi)
+        palette_ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+      if (left_mi)
+        palette_ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+      update_palette_counts(&cm->counts, mbmi, bsize, palette_ctx);
+    }
+
     if (!mbmi->palette_enabled[0]) {
       mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
                                    !mbmi->skip || !inter_block, r);
@@ -1363,7 +1407,7 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
 #else
     mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
                                      !mbmi->skip || !inter_block, r);
-#endif
+#endif  // CONFIG_PALETTE
 
 #if CONFIG_EXT_TX
     if (inter_block &&
@@ -1390,8 +1434,12 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
     if (!cm->frame_parallel_decoding_mode)
 #if CONFIG_COPY_MODE
       if (mbmi->copy_mode == NOREF)
-#endif
+#endif  // CONFIG_COPY_MODE
         ++cm->counts.intra_inter[ctx][1];
+#if CONFIG_PALETTE
+    mbmi->palette_enabled[0] = 0;
+    mbmi->palette_enabled[1] = 0;
+#endif  // CONFIG_PALETTE
   }
 #endif  // CONFIG_SUPERTX
 
index 3bd125162aa5bbccae4b857d0ceb9b6561534c84..b774b54360f7f51f1a7447e12e8aad13f54833c8 100644 (file)
@@ -46,6 +46,7 @@ static struct vp9_token ext_tx_encodings[EXT_TX_TYPES];
 #endif
 #if CONFIG_PALETTE
 static struct vp9_token palette_size_encodings[PALETTE_SIZES];
+static struct vp9_token palette_scan_order_encodings[PALETTE_SCAN_ORDERS];
 static struct vp9_token palette_run_length_encodings[PALETTE_RUN_LENGTHS];
 #endif
 #if CONFIG_COPY_MODE
@@ -78,6 +79,8 @@ void vp9_entropy_mode_init() {
 #endif
 #if CONFIG_PALETTE
   vp9_tokens_from_tree(palette_size_encodings, vp9_palette_size_tree);
+  vp9_tokens_from_tree(palette_scan_order_encodings,
+                       vp9_palette_scan_order_tree);
   vp9_tokens_from_tree(palette_run_length_encodings,
                        vp9_palette_run_length_tree);
 #endif
@@ -464,10 +467,22 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
 
 #if CONFIG_PALETTE
   if (!is_inter && bsize >= BLOCK_8X8 && cm->allow_palette_mode) {
-    int l, n, i, d, bits;
-
-    vp9_write_bit(w, mbmi->palette_enabled[0]);
-    vp9_write_bit(w, mbmi->palette_enabled[1]);
+    int l, n, i, d, bits, ctx;
+    BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
+    const MODE_INFO *above_mi = xd->up_available ?
+        xd->mi[-xd->mi_stride].src_mi : NULL;
+    const MODE_INFO *left_mi = xd->left_available ?
+        xd->mi[-1].src_mi : NULL;
+
+    ctx = 0;
+    if (above_mi)
+      ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+    if (left_mi)
+      ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+    vp9_write(w, mbmi->palette_enabled[0],
+              cm->fc.palette_enabled_prob[bsize - BLOCK_8X8][ctx]);
+    vp9_write(w, mbmi->palette_enabled[1],
+              cm->fc.palette_uv_enabled_prob[mbmi->palette_enabled[0]]);
 
     if (mbmi->palette_enabled[0]) {
       int rows = 4 * num_4x4_blocks_high_lookup[bsize];
@@ -480,7 +495,10 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
                       &palette_size_encodings[n - 2]);
       vp9_write_literal(w, (l >> 1),
                         get_bit_depth(palette_max_run(bsize)));
-      vp9_write_literal(w, mbmi->palette_scan_order[0], 2);
+      vp9_write_token(w, vp9_palette_scan_order_tree,
+                      cm->fc.palette_scan_order_prob[bsize - BLOCK_8X8],
+                      &palette_scan_order_encodings
+                      [mbmi->palette_scan_order[0]]);
 
       for (i = 0; i < n; i++)
         vp9_write_literal(w, mbmi->palette_colors[i], 8);
@@ -505,17 +523,19 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
           xd->plane[1].subsampling_y;
       int cols = 4 * num_4x4_blocks_wide_lookup[bsize] >>
           xd->plane[1].subsampling_x;
-      BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
       n = mbmi->palette_size[1];
       l = mbmi->palette_run_length[1];
 
       if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
         vp9_write_token(w, vp9_palette_size_tree,
-                        cm->fc.palette_uv_size_prob[uv_bsize - BLOCK_4X4],
+                        cm->fc.palette_uv_size_prob[bsize - BLOCK_8X8],
                         &palette_size_encodings[n - 2]);
         vp9_write_literal(w, (l >> 1),
                           get_bit_depth(palette_max_run(uv_bsize)));
-        vp9_write_literal(w, mbmi->palette_scan_order[1], 2);
+        vp9_write_token(w, vp9_palette_scan_order_tree,
+                        cm->fc.palette_uv_scan_order_prob[bsize - BLOCK_8X8],
+                        &palette_scan_order_encodings
+                        [mbmi->palette_scan_order[1]]);
       }
 
       for (i = 0; i < n; i++)
@@ -530,8 +550,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
                             get_bit_depth(mbmi->palette_size[1]));
           bits = get_bit_depth(runs[i + 1]);
           vp9_write_token(w, vp9_palette_run_length_tree,
-                          cm->fc.palette_uv_run_length_prob[uv_bsize -
-                                                            BLOCK_4X4],
+                          cm->fc.palette_uv_run_length_prob[bsize - BLOCK_8X8],
                                       &palette_run_length_encodings[bits > 6 ?
                                                                 6 : bits - 1]);
           vp9_write_literal(w, runs[i + 1] - 1,
@@ -834,10 +853,18 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
 
 #if CONFIG_PALETTE
   if (bsize >= BLOCK_8X8 && cm->allow_palette_mode) {
-    int l, m1, m2, i, d, bits;
-
-    vp9_write_bit(w, mbmi->palette_enabled[0]);
-    vp9_write_bit(w, mbmi->palette_enabled[1]);
+    int l, m1, m2, i, d, bits, ctx;
+    BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
+
+    ctx = 0;
+    if (above_mi)
+      ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+    if (left_mi)
+      ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+    vp9_write(w, mbmi->palette_enabled[0],
+              cm->fc.palette_enabled_prob[bsize - BLOCK_8X8][ctx]);
+    vp9_write(w, mbmi->palette_enabled[1],
+              cm->fc.palette_uv_enabled_prob[mbmi->palette_enabled[0]]);
 
     if (mbmi->palette_enabled[0]) {
       int rows = 4 * num_4x4_blocks_high_lookup[bsize];
@@ -858,7 +885,10 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
         vp9_write_literal(w, mbmi->palette_delta_bitdepth, PALETTE_DELTA_BIT);
       vp9_write_literal(w, (l >> 1),
                         get_bit_depth(palette_max_run(bsize)));
-      vp9_write_literal(w, mbmi->palette_scan_order[0], 2);
+      vp9_write_token(w, vp9_palette_scan_order_tree,
+                      cm->fc.palette_scan_order_prob[bsize - BLOCK_8X8],
+                      &palette_scan_order_encodings
+                      [mbmi->palette_scan_order[0]]);
 
       if (m1 > 0) {
         for (i = 0; i < m1; i++)
@@ -897,16 +927,18 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
           xd->plane[1].subsampling_y;
       int cols = 4 * num_4x4_blocks_wide_lookup[bsize] >>
           xd->plane[1].subsampling_x;
-      BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
       l = mbmi->palette_run_length[1];
 
       if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
         vp9_write_token(w, vp9_palette_size_tree,
-                        cm->fc.palette_uv_size_prob[uv_bsize - BLOCK_4X4],
+                        cm->fc.palette_uv_size_prob[bsize - BLOCK_8X8],
                         &palette_size_encodings[mbmi->palette_size[1] - 2]);
         vp9_write_literal(w, (l >> 1),
                           get_bit_depth(palette_max_run(uv_bsize)));
-        vp9_write_literal(w, mbmi->palette_scan_order[1], 2);
+        vp9_write_token(w, vp9_palette_scan_order_tree,
+                        cm->fc.palette_uv_scan_order_prob[bsize - BLOCK_8X8],
+                        &palette_scan_order_encodings
+                        [mbmi->palette_scan_order[1]]);
       }
 
       for (i = 0; i < mbmi->palette_size[1]; i++)
@@ -921,8 +953,7 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                             get_bit_depth(mbmi->palette_size[1]));
           bits = get_bit_depth(runs[i + 1]);
           vp9_write_token(w, vp9_palette_run_length_tree,
-                          cm->fc.palette_uv_run_length_prob[uv_bsize -
-                                                            BLOCK_4X4],
+                          cm->fc.palette_uv_run_length_prob[bsize - BLOCK_8X8],
                                         &palette_run_length_encodings[bits > 6 ?
                                                                  6 : bits - 1]);
           vp9_write_literal(w, runs[i + 1] - 1,
index 61ca13528250734567638a3edbb512a3fafaf8d5..06679b4f27f1304cdbb1791528490607e1937222 100644 (file)
@@ -4628,20 +4628,20 @@ static void encode_frame_internal(VP9_COMP *cpi) {
     vpx_usec_timer_start(&emr_timer);
 
 #if CONFIG_FP_MB_STATS
-  if (cpi->use_fp_mb_stats) {
-    input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
-                     &cpi->twopass.this_frame_mb_stats);
-  }
+    if (cpi->use_fp_mb_stats) {
+      input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
+                       &cpi->twopass.this_frame_mb_stats);
+    }
 #endif
 
 #if CONFIG_PALETTE
-  if (frame_is_intra_only(cm)) {
-    cm->current_palette_size = 0;
-    vpx_memset(cm->current_palette_count, 0,
-               PALETTE_BUF_SIZE * sizeof(cm->current_palette_count[0]));
-    cm->palette_counter = 0;
-    cm->block_counter = 0;
-  }
+    if (frame_is_intra_only(cm)) {
+      cm->current_palette_size = 0;
+      vpx_memset(cm->current_palette_count, 0,
+                 PALETTE_BUF_SIZE * sizeof(cm->current_palette_count[0]));
+      cm->palette_counter = 0;
+      cm->block_counter = 0;
+    }
 #endif
 
     encode_tiles(cpi);
@@ -5047,7 +5047,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
         !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
       ++cm->counts.ext_tx[mbmi->tx_size][mbmi->ext_txfrm];
     }
-#endif
+#endif  // CONFIG_EXT_TX
 #if CONFIG_TX_SKIP
     if (bsize >= BLOCK_8X8) {
       int q_idx = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex);
@@ -5062,12 +5062,27 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
       if (try_tx_skip) {
 #else
       if (try_tx_skip && (!(mbmi->skip || seg_skip) || !is_inter_block(mbmi))) {
-#endif
+#endif  // CONFIG_SUPERTX
         ++cm->counts.y_tx_skip[is_inter_block(mbmi)][mbmi->tx_skip[0]];
         ++cm->counts.uv_tx_skip[mbmi->tx_skip[0]][mbmi->tx_skip[1]];
       }
     }
-#endif
+#endif  // CONFIG_TX_SKIP
+#if CONFIG_PALETTE
+      if (!frame_is_intra_only(cm) && !is_inter_block(mbmi) &&
+          bsize >= BLOCK_8X8 && cm->allow_palette_mode) {
+        int palette_ctx = 0;
+        const MODE_INFO *above_mi = xd->up_available ?
+            xd->mi[-xd->mi_stride].src_mi : NULL;
+        const MODE_INFO *left_mi = xd->left_available ?
+            xd->mi[-1].src_mi : NULL;
+        if (above_mi)
+          palette_ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+        if (left_mi)
+          palette_ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+        update_palette_counts(&cm->counts, mbmi, bsize, palette_ctx);
+      }
+#endif  // CONFIG_PALETTE
   }
 }
 
index ce433ea76bf1c02a48b35bb0a2bece16718d95c5..85ea669b217901b857629e297878fe7403ff409d 100644 (file)
@@ -2606,7 +2606,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
 #if CONFIG_PALETTE
     if (loop_count == 0 && frame_is_intra_only(cm))
       cm->allow_palette_mode = 1;
-#endif
+#endif  // CONFIG_PALETTE
 
     // Variance adaptive and in frame q adjustment experiments are mutually
     // exclusive.
index 01e391bbcf4ce8b535e740d7544376c5202b6f4b..859984dd436e7c860889814b3b5dd143bb3522d8 100644 (file)
@@ -1355,7 +1355,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
   int try_tx_skip = q_idx <= TX_SKIP_Q_THRESH_INTRA;
 #endif  // CONFIG_TX_SKIP
 #if CONFIG_PALETTE
-  int palette_selected = 0, best_n = 0, best_l = 0, colors;
+  int palette_selected = 0, best_n = 0, best_l = 0, colors, palette_ctx;
   int best_m1 = 0, best_m2 = 0, palette_delta_bitdepth = 0;
   int rows = 4 * num_4x4_blocks_high_lookup[bsize];
   int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
@@ -1374,6 +1374,13 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
       tx_cache[i] = INT64_MAX;
 
   vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
+#if CONFIG_PALETTE
+  palette_ctx = 0;
+  if (above_mi)
+    palette_ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+  if (left_mi)
+    palette_ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+#endif  // CONFIG_PALETTE
   /* Y Search for intra prediction mode */
 #if CONFIG_FILTERINTRA
   for (mode_ext = 2 * DC_PRED; mode_ext <= 2 * TM_PRED + 1; mode_ext++) {
@@ -1415,7 +1422,9 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #endif
 #if CONFIG_PALETTE
     if (this_rate != INT_MAX && cpi->common.allow_palette_mode)
-      this_rate += vp9_cost_bit(128, 0);
+      this_rate +=
+          vp9_cost_bit(cpi->common.fc.
+                       palette_enabled_prob[bsize - BLOCK_8X8][palette_ctx], 0);
 #endif
     this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
 
@@ -1503,6 +1512,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
     int l, m1, m2, d = get_bit_depth(rows * cols);
     int bits, best_bits = 0, total_bits, best_total_bits;
     int palette_size_cost[PALETTE_SIZES];
+    int palette_scan_order_cost[PALETTE_SCAN_ORDERS];
     int palette_run_length_cost[PALETTE_RUN_LENGTHS];
     double centroids[PALETTE_MAX_SIZE];
     double lb = src[0], ub = src[0], val;
@@ -1521,6 +1531,9 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
     vp9_cost_tokens(palette_size_cost,
                     cpi->common.fc.palette_size_prob[bsize - BLOCK_8X8],
                     vp9_palette_size_tree);
+    vp9_cost_tokens(palette_scan_order_cost,
+                    cpi->common.fc.palette_scan_order_prob[bsize - BLOCK_8X8],
+                    vp9_palette_scan_order_tree);
     vp9_cost_tokens(palette_run_length_cost,
                     cpi->common.fc.palette_run_length_prob[bsize - BLOCK_8X8],
                     vp9_palette_run_length_tree);
@@ -1680,12 +1693,15 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
           continue;
 
         this_rate = this_rate_tokenonly +
-            (1 + vp9_encode_uniform_cost(MIN(k + 1, 8), m1) + PALETTE_DELTA_BIT
-                + get_bit_depth(palette_max_run(bsize)) + 2 +
+            (vp9_encode_uniform_cost(MIN(k + 1, 8), m1) + PALETTE_DELTA_BIT
+                + get_bit_depth(palette_max_run(bsize)) +
                 get_bit_depth(mic->mbmi.current_palette_size) * m1 +
                 best_bits * m1 +
                 8 * m2 + get_bit_depth(k) * (l >> 1)) * vp9_cost_bit(128, 0) +
-                palette_size_cost[k - 2];
+                vp9_cost_bit(cpi->common.fc.palette_enabled_prob
+                             [bsize - BLOCK_8X8][palette_ctx], 1) +
+                             palette_size_cost[k - 2] +
+                             palette_scan_order_cost[ps];
         for (i = 0; i < l; i += 2) {
           int bits = get_bit_depth(mic->mbmi.palette_runs[i + 1]);
           this_rate += palette_run_length_cost[bits > 6 ? 6 : bits - 1];
@@ -1909,7 +1925,8 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
     if (xd->mi[0].src_mi->mbmi.sb_type >= BLOCK_8X8 &&
         xd->plane[1].subsampling_x && xd->plane[1].subsampling_y &&
         cpi->common.allow_palette_mode)
-      this_rate += vp9_cost_bit(128, 0);
+      this_rate += vp9_cost_bit(cpi->common.fc.palette_uv_enabled_prob
+                                [mbmi->palette_enabled[0]], 0);
 #endif  // CONFIG_PALETTE
     this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
 
@@ -2001,6 +2018,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
     if (colors > 1 && colors <= 64) {
       int n, r, c, i, j, max_itr = 200;
       int l, d = get_bit_depth(rows * cols);
+      int palette_scan_order_cost[PALETTE_SCAN_ORDERS];
       int palette_run_length_cost[PALETTE_RUN_LENGTHS];
       int palette_size_cost[PALETTE_SIZES];
       double centroids[2 * PALETTE_MAX_SIZE];
@@ -2014,6 +2032,9 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #endif  // CONFIG_TX_SKIP
 
       i = uv_bsize - BLOCK_4X4;
+      vp9_cost_tokens(palette_scan_order_cost,
+                      cpi->common.fc.palette_uv_scan_order_prob[i],
+                      vp9_palette_scan_order_tree);
       vp9_cost_tokens(palette_size_cost,
                       cpi->common.fc.palette_uv_size_prob[i],
                       vp9_palette_size_tree);
@@ -2114,9 +2135,12 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
             continue;
 
           this_rate = this_rate_tokenonly +
-              (1 + get_bit_depth(palette_max_run(uv_bsize)) + 2 + 2 * 8 * n +
+              (get_bit_depth(palette_max_run(uv_bsize)) + 2 * 8 * n +
                   get_bit_depth(n) * (l >> 1)) * vp9_cost_bit(128, 0) +
-                  palette_size_cost[n - 2];
+                  vp9_cost_bit(cpi->common.fc.palette_uv_enabled_prob
+                               [mbmi->palette_enabled[0]], 1) +
+                               palette_size_cost[n - 2] +
+                               palette_scan_order_cost[ps];
           for (i = 0; i < l; i += 2) {
             int bits = get_bit_depth(
                 mbmi->palette_runs[PALETTE_MAX_RUNS + i + 1]);
@@ -5205,7 +5229,7 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   int copy_mode_context = vp9_get_copy_mode_context(xd);
 #endif  // CONFIG_COPY_MODE
 #if CONFIG_PALETTE
-  int best_n = 0, best_l = 0, colors;
+  int best_n = 0, best_l = 0, colors, palette_ctx;
   int rows = 4 * num_4x4_blocks_high_lookup[bsize];
   int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
   int src_stride = x->plane[0].src.stride;
@@ -5217,6 +5241,10 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   uint16_t best_runs[PALETTE_MAX_RUNS];
   uint16_t palette_runs_uv[TX_SIZES][PALETTE_MAX_RUNS];
   PALETTE_SCAN_ORDER best_ps = H_SCAN, ps_uv[TX_SIZES];
+  const MODE_INFO *above_mi = xd->up_available ?
+      xd->mi[-xd->mi_stride].src_mi : NULL;
+  const MODE_INFO *left_mi = xd->left_available ?
+      xd->mi[-1].src_mi : NULL;
 #endif  // CONFIG_PALETTE
   vp9_zero(best_mbmode);
 
@@ -5363,6 +5391,14 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
     midx = end_pos;
   }
 
+#if CONFIG_PALETTE
+  palette_ctx = 0;
+  if (above_mi)
+    palette_ctx += (above_mi->mbmi.palette_enabled[0] == 1);
+  if (left_mi)
+    palette_ctx += (left_mi->mbmi.palette_enabled[0] == 1);
+#endif  // CONFIG_PALETTE
+
   for (midx = 0; midx < MAX_MODES; ++midx) {
     int mode_index = mode_map[midx];
     int mode_excluded = 0;
@@ -5773,8 +5809,11 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
            cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode], mbmi->filterbit);
 #endif  // CONFIG_FILTERINTRA
 #if CONFIG_PALETTE
-    if (cpi->common.allow_palette_mode && bsize >= BLOCK_8X8)
-      rate2 += vp9_cost_bit(128, 0);
+      if (cpi->common.allow_palette_mode && bsize >= BLOCK_8X8 &&
+          rate2 != INT_MAX)
+        rate2 +=
+            vp9_cost_bit(cm->fc.palette_enabled_prob[bsize - BLOCK_8X8]
+                                                     [palette_ctx], 0);
 #endif  // CONFIG_PALETTE
       if (this_mode != DC_PRED && this_mode != TM_PRED)
         rate2 += intra_cost_penalty;
@@ -6349,6 +6388,7 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
       int l, d = get_bit_depth(rows * cols);
       int palette_size_cost[PALETTE_SIZES];
       int palette_run_length_cost[PALETTE_RUN_LENGTHS];
+      int palette_scan_order_cost[PALETTE_SCAN_ORDERS];
       double centroids[PALETTE_MAX_SIZE];
       double lb = src[0], ub = src[0], val;
       PALETTE_SCAN_ORDER ps;
@@ -6379,6 +6419,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
       vp9_cost_tokens(palette_run_length_cost,
                       cpi->common.fc.palette_run_length_prob[bsize - BLOCK_8X8],
                       vp9_palette_run_length_tree);
+      vp9_cost_tokens(palette_scan_order_cost,
+                      cpi->common.fc.palette_scan_order_prob[bsize - BLOCK_8X8],
+                      vp9_palette_scan_order_tree);
       mbmi->ref_frame[0] = INTRA_FRAME;
       mbmi->mode = DC_PRED;
       for (r = 0; r < rows; r++) {
@@ -6477,9 +6520,12 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
             continue;
 
           total_rate_y = rate_y +
-              (1 + get_bit_depth(palette_max_run(bsize)) + 2 +
-                  8 * k + get_bit_depth(k) * (l >> 1)) * vp9_cost_bit(128, 0) +
-                  palette_size_cost[k - 2];
+              (get_bit_depth(palette_max_run(bsize)) + 8 * k +
+                  get_bit_depth(k) * (l >> 1)) * vp9_cost_bit(128, 0) +
+                  vp9_cost_bit(cm->fc.palette_enabled_prob
+                               [bsize - BLOCK_8X8][palette_ctx], 1) +
+                               palette_size_cost[k - 2] +
+                               palette_scan_order_cost[ps];
           for (i = 0; i < l; i += 2) {
             int bits = get_bit_depth(mbmi->palette_runs[i + 1]);
             total_rate_y += palette_run_length_cost[bits > 6 ? 6 : bits - 1];