shithub: libvpx

Download patch

ref: 1eb51a2010c95845d340ac7dafe311e4c1716d66
parent: d8f3bb1837f7ef966b1a380359e84d15bb92e18b
author: Ronald S. Bultje <rsbultje@gmail.com>
date: Tue Oct 13 10:08:24 EDT 2015

vp10: allow forward updates for keyframe y intra mode probabilities.

See issue 1040 point 5.

Change-Id: I51a70b9eade39efba392a1457bd70a3c515525cb

--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -282,15 +282,6 @@
   }
 }
 
-static INLINE const vpx_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 = vp10_above_block_mode(mi, above_mi, block);
-  const PREDICTION_MODE left = vp10_left_block_mode(mi, left_mi, block);
-  return vp10_kf_y_mode_prob[above][left];
-}
-
 typedef void (*foreach_transformed_block_visitor)(int plane, int block,
                                                   BLOCK_SIZE plane_bsize,
                                                   TX_SIZE tx_size,
--- a/vp10/common/entropymode.h
+++ b/vp10/common/entropymode.h
@@ -76,6 +76,7 @@
 } FRAME_CONTEXT;
 
 typedef struct FRAME_COUNTS {
+  unsigned int kf_y_mode[INTRA_MODES][INTRA_MODES][INTRA_MODES];
   unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES];
   unsigned int uv_mode[INTRA_MODES][INTRA_MODES];
   unsigned int partition[PARTITION_CONTEXTS][PARTITION_TYPES];
--- a/vp10/common/onyxc_int.h
+++ b/vp10/common/onyxc_int.h
@@ -302,6 +302,11 @@
   PARTITION_CONTEXT *above_seg_context;
   ENTROPY_CONTEXT *above_context;
   int above_context_alloc_cols;
+
+  // scratch memory for intraonly/keyframe forward updates from default tables
+  // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon
+  // each keyframe and not used afterwards
+  vpx_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1];
 } VP10_COMMON;
 
 // TODO(hkuang): Don't need to lock the whole pool after implementing atomic
@@ -441,6 +446,16 @@
     xd->left_mi = NULL;
     xd->left_mbmi = NULL;
   }
+}
+
+static INLINE const vpx_prob *get_y_mode_probs(const VP10_COMMON *cm,
+                                               const MODE_INFO *mi,
+                                               const MODE_INFO *above_mi,
+                                               const MODE_INFO *left_mi,
+                                               int block) {
+  const PREDICTION_MODE above = vp10_above_block_mode(mi, above_mi, block);
+  const PREDICTION_MODE left = vp10_left_block_mode(mi, left_mi, block);
+  return cm->kf_y_prob[above][left];
 }
 
 static INLINE void update_partition_context(MACROBLOCKD *xd,
--- a/vp10/decoder/decodeframe.c
+++ b/vp10/decoder/decodeframe.c
@@ -2156,7 +2156,15 @@
       vp10_diff_update_prob(&r, &fc->partition_prob[j][i]);
 #endif
 
-  if (!frame_is_intra_only(cm)) {
+  if (frame_is_intra_only(cm)) {
+    vp10_copy(cm->kf_y_prob, vp10_kf_y_mode_prob);
+#if CONFIG_MISC_FIXES
+    for (k = 0; k < INTRA_MODES; k++)
+      for (j = 0; j < INTRA_MODES; j++)
+        for (i = 0; i < INTRA_MODES - 1; ++i)
+          vp10_diff_update_prob(&r, &cm->kf_y_prob[k][j][i]);
+#endif
+  } else {
     nmv_context *const nmvc = &fc->nmvc;
 
     read_inter_mode_probs(fc, &r);
--- a/vp10/decoder/decodemv.c
+++ b/vp10/decoder/decodemv.c
@@ -305,24 +305,24 @@
     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(r, get_y_mode_probs(cm, 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(r, get_y_mode_probs(cm, 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(r, get_y_mode_probs(cm, 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(r, get_y_mode_probs(cm, 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(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
       break;
     default:
       mbmi->mode = read_intra_mode(r,
-                                   get_y_mode_probs(mi, above_mi, left_mi, 0));
+          get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
   }
 
   mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -455,7 +455,8 @@
     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(w, mbmi->mode,
+                     get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
   } else {
     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -465,7 +466,7 @@
       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));
+                         get_y_mode_probs(cm, mi, above_mi, left_mi, block));
       }
     }
   }
@@ -1348,6 +1349,9 @@
   FRAME_COUNTS *counts = cpi->td.counts;
   vpx_writer header_bc;
   int i;
+#if CONFIG_MISC_FIXES
+  int j;
+#endif
 
   vpx_start_encode(&header_bc, data);
 
@@ -1373,7 +1377,15 @@
                      counts->partition[i], PARTITION_TYPES, &header_bc);
 #endif
 
-  if (!frame_is_intra_only(cm)) {
+  if (frame_is_intra_only(cm)) {
+    vp10_copy(cm->kf_y_prob, vp10_kf_y_mode_prob);
+#if CONFIG_MISC_FIXES
+    for (i = 0; i < INTRA_MODES; ++i)
+      for (j = 0; j < INTRA_MODES; ++j)
+        prob_diff_update(vp10_intra_mode_tree, cm->kf_y_prob[i][j],
+                         counts->kf_y_mode[i][j], INTRA_MODES, &header_bc);
+#endif
+  } else {
     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);
--- a/vp10/encoder/encodeframe.c
+++ b/vp10/encoder/encodeframe.c
@@ -2900,7 +2900,9 @@
   }
 }
 
-static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
+static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
+                            const MODE_INFO *above_mi, const MODE_INFO *left_mi,
+                            const int intraonly) {
   const PREDICTION_MODE y_mode = mi->mbmi.mode;
   const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
@@ -2910,10 +2912,25 @@
     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)
-        ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode];
+      for (idx = 0; idx < 2; idx += num_4x4_w) {
+        const int bidx = idy * 2 + idx;
+        const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
+        if (intraonly) {
+          const PREDICTION_MODE a = vp10_above_block_mode(mi, above_mi, bidx);
+          const PREDICTION_MODE l = vp10_left_block_mode(mi, left_mi, bidx);
+          ++counts->kf_y_mode[a][l][bmode];
+        } else {
+          ++counts->y_mode[0][bmode];
+        }
+      }
   } else {
-    ++counts->y_mode[size_group_lookup[bsize]][y_mode];
+    if (intraonly) {
+      const PREDICTION_MODE above = vp10_above_block_mode(mi, above_mi, 0);
+      const PREDICTION_MODE left = vp10_left_block_mode(mi, left_mi, 0);
+      ++counts->kf_y_mode[above][left][y_mode];
+    } else {
+      ++counts->y_mode[size_group_lookup[bsize]][y_mode];
+    }
   }
 
   ++counts->uv_mode[y_mode][uv_mode];
@@ -2953,7 +2970,8 @@
     for (plane = 0; plane < MAX_MB_PLANE; ++plane)
       vp10_encode_intra_block_plane(x, VPXMAX(bsize, BLOCK_8X8), plane);
     if (output_enabled)
-      sum_intra_stats(td->counts, mi);
+      sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
+                      frame_is_intra_only(cm));
 
     if (bsize >= BLOCK_8X8 && output_enabled) {
       if (mbmi->palette_mode_info.palette_size[0] > 0) {