shithub: libvpx

Download patch

ref: d8f3bb1837f7ef966b1a380359e84d15bb92e18b
parent: 6e5a1165bef829b3fcc73c36e5c950592b5c6801
author: Ronald S. Bultje <[email protected]>
date: Tue Oct 13 10:07:47 EDT 2015

vp10: merge keyframe/interframe uvintramode/partition probabilities.

This has various benefits:
- simplify implementations because we don't have to switch between
  multiple probability tables depending on frametype
- allows fw subexp and bw adaptivity for partitions/uvmode in keyframes

See issue 1040 point 5.

Change-Id: Ia566aa2863252d130cee9deedcf123bb2a0d3765

--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -186,8 +186,6 @@
   int up_available;
   int left_available;
 
-  const vpx_prob (*partition_probs)[PARTITION_TYPES - 1];
-
   /* Distance of MB away from frame edges */
   int mb_to_left_edge;
   int mb_to_right_edge;
--- a/vp10/common/entropymode.c
+++ b/vp10/common/entropymode.c
@@ -127,6 +127,7 @@
   }
 };
 
+#if !CONFIG_MISC_FIXES
 const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = {
   { 144,  11,  54, 157, 195, 130,  46,  58, 108 },  // y = dc
   { 118,  15, 123, 148, 131, 101,  44,  93, 131 },  // y = v
@@ -139,6 +140,7 @@
   { 116,  12,  64, 120, 140, 125,  49, 115, 121 },  // y = d63
   { 102,  19,  66, 162, 182, 122,  35,  59, 128 }   // y = tm
 };
+#endif
 
 static const vpx_prob default_if_y_probs[BLOCK_SIZE_GROUPS][INTRA_MODES - 1] = {
   {  65,  32,  18, 144, 162, 194,  41,  51,  98 },  // block_size < 8x8
@@ -147,7 +149,7 @@
   { 221, 135,  38, 194, 248, 121,  96,  85,  29 }   // block_size >= 32x32
 };
 
-static const vpx_prob default_if_uv_probs[INTRA_MODES][INTRA_MODES - 1] = {
+static const vpx_prob default_uv_probs[INTRA_MODES][INTRA_MODES - 1] = {
   { 120,   7,  76, 176, 208, 126,  28,  54, 103 },  // y = dc
   {  48,  12, 154, 155, 139,  90,  34, 117, 119 },  // y = v
   {  67,   6,  25, 204, 243, 158,  13,  21,  96 },  // y = h
@@ -160,6 +162,7 @@
   { 101,  21, 107, 181, 192, 103,  19,  67, 125 }   // y = tm
 };
 
+#if !CONFIG_MISC_FIXES
 const vpx_prob vp10_kf_partition_probs[PARTITION_CONTEXTS]
                                      [PARTITION_TYPES - 1] = {
   // 8x8 -> 4x4
@@ -183,6 +186,7 @@
   {  57,  15,   9 },  // l split, a not split
   {  12,   3,   3 },  // a/l both split
 };
+#endif
 
 static const vpx_prob default_partition_probs[PARTITION_CONTEXTS]
                                              [PARTITION_TYPES - 1] = {
@@ -755,7 +759,7 @@
 #endif
 
 static void init_mode_probs(FRAME_CONTEXT *fc) {
-  vp10_copy(fc->uv_mode_prob, default_if_uv_probs);
+  vp10_copy(fc->uv_mode_prob, default_uv_probs);
   vp10_copy(fc->y_mode_prob, default_if_y_probs);
   vp10_copy(fc->switchable_interp_prob, default_switchable_interp_prob);
   vp10_copy(fc->partition_prob, default_partition_probs);
@@ -806,6 +810,7 @@
     vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i],
                 counts->y_mode[i], fc->y_mode_prob[i]);
 
+#if !CONFIG_MISC_FIXES
   for (i = 0; i < INTRA_MODES; ++i)
     vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->uv_mode_prob[i],
                          counts->uv_mode[i], fc->uv_mode_prob[i]);
@@ -813,6 +818,7 @@
   for (i = 0; i < PARTITION_CONTEXTS; i++)
     vpx_tree_merge_probs(vp10_partition_tree, pre_fc->partition_prob[i],
                          counts->partition[i], fc->partition_prob[i]);
+#endif
 
   if (cm->interp_filter == SWITCHABLE) {
     for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
@@ -869,6 +875,14 @@
     vpx_tree_merge_probs(vp10_segment_tree, pre_fc->seg.tree_probs,
                          counts->seg.tree_total, fc->seg.tree_probs);
   }
+
+  for (i = 0; i < INTRA_MODES; ++i)
+    vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->uv_mode_prob[i],
+                         counts->uv_mode[i], fc->uv_mode_prob[i]);
+
+  for (i = 0; i < PARTITION_CONTEXTS; i++)
+    vpx_tree_merge_probs(vp10_partition_tree, pre_fc->partition_prob[i],
+                         counts->partition[i], fc->partition_prob[i]);
 #endif
 }
 
--- a/vp10/common/entropymode.h
+++ b/vp10/common/entropymode.h
@@ -97,11 +97,13 @@
 #endif
 } FRAME_COUNTS;
 
-extern const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
 extern const vpx_prob vp10_kf_y_mode_prob[INTRA_MODES][INTRA_MODES]
                                         [INTRA_MODES - 1];
+#if !CONFIG_MISC_FIXES
+extern const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
 extern const vpx_prob vp10_kf_partition_probs[PARTITION_CONTEXTS]
                                             [PARTITION_TYPES - 1];
+#endif
 extern const vpx_prob
 vp10_default_palette_y_mode_prob[PALETTE_BLOCK_SIZES][PALETTE_Y_MODE_CONTEXTS];
 extern const vpx_prob
--- a/vp10/common/onyxc_int.h
+++ b/vp10/common/onyxc_int.h
@@ -374,14 +374,6 @@
   return cm->frame_type == KEY_FRAME || cm->intra_only;
 }
 
-static INLINE void set_partition_probs(const VP10_COMMON *const cm,
-                                       MACROBLOCKD *const xd) {
-  xd->partition_probs =
-      frame_is_intra_only(cm) ?
-          &vp10_kf_partition_probs[0] :
-          (const vpx_prob (*)[PARTITION_TYPES - 1])cm->fc->partition_prob;
-}
-
 static INLINE void vp10_init_macroblockd(VP10_COMMON *cm, MACROBLOCKD *xd,
                                         tran_low_t *dqcoeff) {
   int i;
@@ -402,13 +394,6 @@
   xd->above_seg_context = cm->above_seg_context;
   xd->mi_stride = cm->mi_stride;
   xd->error_info = &cm->error;
-
-  set_partition_probs(cm, xd);
-}
-
-static INLINE const vpx_prob* get_partition_probs(const MACROBLOCKD *xd,
-                                                  int ctx) {
-  return xd->partition_probs[ctx];
 }
 
 static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) {
--- a/vp10/decoder/decodeframe.c
+++ b/vp10/decoder/decodeframe.c
@@ -922,11 +922,11 @@
   memset(left_ctx, partition_context_lookup[subsize].left, bw);
 }
 
-static PARTITION_TYPE read_partition(MACROBLOCKD *xd, int mi_row, int mi_col,
-                                     vpx_reader *r,
+static PARTITION_TYPE read_partition(VP10_COMMON *cm, MACROBLOCKD *xd,
+                                     int mi_row, int mi_col, vpx_reader *r,
                                      int has_rows, int has_cols, int bsl) {
   const int ctx = dec_partition_plane_context(xd, mi_row, mi_col, bsl);
-  const vpx_prob *const probs = get_partition_probs(xd, ctx);
+  const vpx_prob *const probs = cm->fc->partition_prob[ctx];
   FRAME_COUNTS *counts = xd->counts;
   PARTITION_TYPE p;
 
@@ -961,7 +961,7 @@
   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
     return;
 
-  partition = read_partition(xd, mi_row, mi_col, r, has_rows, has_cols,
+  partition = read_partition(cm, xd, mi_row, mi_col, r, has_rows, has_cols,
                              n8x8_l2);
   subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
   if (!hbs) {
@@ -2120,7 +2120,7 @@
 #endif
   FRAME_CONTEXT *const fc = cm->fc;
   vpx_reader r;
-  int k;
+  int k, i, j;
 
   if (vpx_reader_init(&r, data, partition_size, pbi->decrypt_cb,
                       pbi->decrypt_state))
@@ -2146,11 +2146,18 @@
     for (k = 0; k < MAX_SEGMENTS - 1; k++)
       vp10_diff_update_prob(&r, &cm->fc->seg.tree_probs[k]);
   }
+
+  for (j = 0; j < INTRA_MODES; j++)
+    for (i = 0; i < INTRA_MODES - 1; ++i)
+      vp10_diff_update_prob(&r, &fc->uv_mode_prob[j][i]);
+
+  for (j = 0; j < PARTITION_CONTEXTS; ++j)
+    for (i = 0; i < PARTITION_TYPES - 1; ++i)
+      vp10_diff_update_prob(&r, &fc->partition_prob[j][i]);
 #endif
 
   if (!frame_is_intra_only(cm)) {
     nmv_context *const nmvc = &fc->nmvc;
-    int i, j;
 
     read_inter_mode_probs(fc, &r);
 
@@ -2171,15 +2178,11 @@
       for (i = 0; i < INTRA_MODES - 1; ++i)
         vp10_diff_update_prob(&r, &fc->y_mode_prob[j][i]);
 
-#if CONFIG_MISC_FIXES
-    for (j = 0; j < INTRA_MODES; j++)
-      for (i = 0; i < INTRA_MODES - 1; ++i)
-        vp10_diff_update_prob(&r, &fc->uv_mode_prob[j][i]);
-#endif
-
+#if !CONFIG_MISC_FIXES
     for (j = 0; j < PARTITION_CONTEXTS; ++j)
       for (i = 0; i < PARTITION_TYPES - 1; ++i)
         vp10_diff_update_prob(&r, &fc->partition_prob[j][i]);
+#endif
 
     read_mv_probs(nmvc, cm->allow_high_precision_mv, &r);
   }
--- a/vp10/decoder/decodemv.c
+++ b/vp10/decoder/decodemv.c
@@ -325,7 +325,7 @@
                                    get_y_mode_probs(mi, above_mi, left_mi, 0));
   }
 
-  mbmi->uv_mode = read_intra_mode(r, vp10_kf_uv_mode_prob[mbmi->mode]);
+  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
 
   mbmi->palette_mode_info.palette_size[0] = 0;
   mbmi->palette_mode_info.palette_size[1] = 0;
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -470,7 +470,7 @@
     }
   }
 
-  write_intra_mode(w, mbmi->uv_mode, vp10_kf_uv_mode_prob[mbmi->mode]);
+  write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mbmi->mode]);
 
   if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools &&
       mbmi->mode == DC_PRED)
@@ -525,7 +525,7 @@
                             int hbs, int mi_row, int mi_col,
                             PARTITION_TYPE p, BLOCK_SIZE bsize, vpx_writer *w) {
   const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
-  const vpx_prob *const probs = xd->partition_probs[ctx];
+  const vpx_prob *const probs = cm->fc->partition_prob[ctx];
   const int has_rows = (mi_row + hbs) < cm->mi_rows;
   const int has_cols = (mi_col + hbs) < cm->mi_cols;
 
@@ -603,12 +603,9 @@
 static void write_modes(VP10_COMP *cpi,
                         const TileInfo *const tile, vpx_writer *w,
                         TOKENEXTRA **tok, const TOKENEXTRA *const tok_end) {
-  const VP10_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
   int mi_row, mi_col;
 
-  set_partition_probs(cm, xd);
-
   for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
        mi_row += MI_BLOCK_SIZE) {
     vp10_zero(xd->left_seg_context);
@@ -1350,6 +1347,7 @@
   FRAME_CONTEXT *const fc = cm->fc;
   FRAME_COUNTS *counts = cpi->td.counts;
   vpx_writer header_bc;
+  int i;
 
   vpx_start_encode(&header_bc, data);
 
@@ -1365,11 +1363,17 @@
   update_skip_probs(cm, &header_bc, counts);
 #if CONFIG_MISC_FIXES
   update_seg_probs(cpi, &header_bc);
+
+  for (i = 0; i < INTRA_MODES; ++i)
+    prob_diff_update(vp10_intra_mode_tree, fc->uv_mode_prob[i],
+                     counts->uv_mode[i], INTRA_MODES, &header_bc);
+
+  for (i = 0; i < PARTITION_CONTEXTS; ++i)
+    prob_diff_update(vp10_partition_tree, fc->partition_prob[i],
+                     counts->partition[i], PARTITION_TYPES, &header_bc);
 #endif
 
   if (!frame_is_intra_only(cm)) {
-    int i;
-
     for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
       prob_diff_update(vp10_inter_mode_tree, cm->fc->inter_mode_probs[i],
                        counts->inter_mode[i], INTER_MODES, &header_bc);
@@ -1420,15 +1424,11 @@
       prob_diff_update(vp10_intra_mode_tree, cm->fc->y_mode_prob[i],
                        counts->y_mode[i], INTRA_MODES, &header_bc);
 
-#if CONFIG_MISC_FIXES
-    for (i = 0; i < INTRA_MODES; ++i)
-      prob_diff_update(vp10_intra_mode_tree, cm->fc->uv_mode_prob[i],
-                       counts->uv_mode[i], INTRA_MODES, &header_bc);
-#endif
-
+#if !CONFIG_MISC_FIXES
     for (i = 0; i < PARTITION_CONTEXTS; ++i)
       prob_diff_update(vp10_partition_tree, fc->partition_prob[i],
                        counts->partition[i], PARTITION_TYPES, &header_bc);
+#endif
 
     vp10_write_nmv_probs(cm, cm->allow_high_precision_mv, &header_bc,
                         &counts->mv);
--- a/vp10/encoder/encoder.h
+++ b/vp10/encoder/encoder.h
@@ -456,7 +456,7 @@
 
   int mbmode_cost[INTRA_MODES];
   unsigned int inter_mode_cost[INTER_MODE_CONTEXTS][INTER_MODES];
-  int intra_uv_mode_cost[FRAME_TYPES][INTRA_MODES];
+  int intra_uv_mode_cost[INTRA_MODES];
   int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
   int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
   int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES];
--- a/vp10/encoder/rd.c
+++ b/vp10/encoder/rd.c
@@ -76,9 +76,7 @@
                       vp10_intra_mode_tree);
 
   vp10_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp10_intra_mode_tree);
-  vp10_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME],
-                  vp10_kf_uv_mode_prob[TM_PRED], vp10_intra_mode_tree);
-  vp10_cost_tokens(cpi->intra_uv_mode_cost[INTER_FRAME],
+  vp10_cost_tokens(cpi->intra_uv_mode_cost,
                   fc->uv_mode_prob[TM_PRED], vp10_intra_mode_tree);
 
   for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
@@ -287,7 +285,6 @@
 void vp10_initialize_rd_consts(VP10_COMP *cpi) {
   VP10_COMMON *const cm = &cpi->common;
   MACROBLOCK *const x = &cpi->td.mb;
-  MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
   RD_OPT *const rd = &cpi->rd;
   int i;
 
@@ -303,7 +300,6 @@
                        cm->frame_type != KEY_FRAME) ? 0 : 1;
 
   set_block_thresholds(cm, rd);
-  set_partition_probs(cm, xd);
 
   fill_token_costs(x->token_costs, cm->fc->coef_probs);
 
@@ -310,7 +306,7 @@
   if (cpi->sf.partition_search_type != VAR_BASED_PARTITION ||
       cm->frame_type == KEY_FRAME) {
     for (i = 0; i < PARTITION_CONTEXTS; ++i)
-      vp10_cost_tokens(cpi->partition_cost[i], get_partition_probs(xd, i),
+      vp10_cost_tokens(cpi->partition_cost[i], cm->fc->partition_prob[i],
                       vp10_partition_tree);
   }
 
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -1347,8 +1347,7 @@
     if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
                           &this_distortion, &s, &this_sse, bsize, best_rd))
       continue;
-    this_rate = this_rate_tokenonly +
-                cpi->intra_uv_mode_cost[cpi->common.frame_type][mode];
+    this_rate = this_rate_tokenonly + cpi->intra_uv_mode_cost[mode];
     this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
 
     if (this_rd < best_rd) {
@@ -1371,7 +1370,6 @@
                               int *rate, int *rate_tokenonly,
                               int64_t *distortion, int *skippable,
                               BLOCK_SIZE bsize) {
-  const VP10_COMMON *cm = &cpi->common;
   int64_t unused;
 
   x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
@@ -1378,7 +1376,7 @@
   memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
   super_block_uvrd(cpi, x, rate_tokenonly, distortion,
                    skippable, &unused, bsize, INT64_MAX);
-  *rate = *rate_tokenonly + cpi->intra_uv_mode_cost[cm->frame_type][DC_PRED];
+  *rate = *rate_tokenonly + cpi->intra_uv_mode_cost[DC_PRED];
   return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
 }