shithub: libvpx

Download patch

ref: 869a39ba60379b031573ed5ba1911088d353a3c1
parent: 36f02bf3c15691e426b0a8e80d1fa0f2ae5afbb2
author: Deb Mukherjee <debargha@google.com>
date: Fri Jun 7 09:24:14 EDT 2013

Cleans up mbskip encoding

Refactors mbskip coding to be compatible with coding of the rest of
the symbols. Adds forward/backward adaptation and removes a lot of
the legacy code.

Results:
fast50: +1.6%
derfraw300: +0.317%

Change-Id: I395a2976d15af044d3b8ded5acfa45f6f065f980

--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -197,6 +197,10 @@
 };
 #endif
 
+const vp9_prob vp9_default_mbskip_probs[MBSKIP_CONTEXTS] = {
+  192, 128, 64
+};
+
 void vp9_init_mbmode_probs(VP9_COMMON *x) {
   vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs,
              sizeof(default_if_uv_probs));
@@ -221,6 +225,8 @@
              sizeof(default_single_ref_p));
   vpx_memcpy(x->fc.tx_probs, vp9_default_tx_probs,
              sizeof(vp9_default_tx_probs));
+  vpx_memcpy(x->fc.mbskip_probs, vp9_default_mbskip_probs,
+             sizeof(vp9_default_mbskip_probs));
 }
 
 #if VP9_SWITCHABLE_FILTERS == 3
@@ -321,7 +327,7 @@
 
 #define MODE_COUNT_SAT 20
 #define MODE_MAX_UPDATE_FACTOR 144
-static int update_mode_ct(int pre_prob, int prob,
+static int update_mode_ct(vp9_prob pre_prob, vp9_prob prob,
                           unsigned int branch_ct[2]) {
   int factor, count = branch_ct[0] + branch_ct[1];
   count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
@@ -344,7 +350,7 @@
     dst_probs[t] = update_mode_ct(pre_probs[t], probs[t], branch_ct[t]);
 }
 
-static int update_mode_ct2(int pre_prob, unsigned int branch_ct[2]) {
+static int update_mode_ct2(vp9_prob pre_prob, unsigned int branch_ct[2]) {
   return update_mode_ct(pre_prob, get_binary_prob(branch_ct[0],
                                                   branch_ct[1]), branch_ct);
 }
@@ -438,6 +444,9 @@
       cm->fc.tx_probs[i] = weighted_prob(cm->fc.pre_tx_probs[i], prob, factor);
     }
   }
+  for (i = 0; i < MBSKIP_CONTEXTS; ++i)
+    fc->mbskip_probs[i] = update_mode_ct2(fc->pre_mbskip_probs[i],
+                                          fc->mbskip_count[i]);
 }
 
 static void set_default_lf_deltas(MACROBLOCKD *xd) {
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -94,6 +94,10 @@
   unsigned int tx_count_32x32p[TX_SIZE_MAX_SB];
   unsigned int tx_count_16x16p[TX_SIZE_MAX_SB - 1];
   unsigned int tx_count_8x8p[TX_SIZE_MAX_SB - 2];
+
+  vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
+  vp9_prob pre_mbskip_probs[MBSKIP_CONTEXTS];
+  unsigned int mbskip_count[MBSKIP_CONTEXTS][2];
 } FRAME_CONTEXT;
 
 typedef enum {
@@ -243,8 +247,6 @@
   MV_REFERENCE_FRAME comp_fixed_ref;
   MV_REFERENCE_FRAME comp_var_ref[2];
   COMPPREDMODE_TYPE comp_pred_mode;
-
-  vp9_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
 
   FRAME_CONTEXT fc;  /* this frame entropy */
   FRAME_CONTEXT frame_contexts[NUM_FRAME_CONTEXTS];
--- a/vp9/common/vp9_pred_common.c
+++ b/vp9/common/vp9_pred_common.c
@@ -368,7 +368,7 @@
     case PRED_SEG_ID:
       return cm->segment_pred_probs[pred_context];
     case PRED_MBSKIP:
-      return cm->mbskip_pred_probs[pred_context];
+      return cm->fc.mbskip_probs[pred_context];
     case PRED_INTRA_INTER:
       return cm->fc.intra_inter_prob[pred_context];
     case PRED_COMP_INTER_INTER:
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -99,8 +99,11 @@
 
   m->mbmi.mb_skip_coeff = vp9_segfeature_active(xd, m->mbmi.segment_id,
                                                 SEG_LVL_SKIP);
-  if (!m->mbmi.mb_skip_coeff)
+  if (!m->mbmi.mb_skip_coeff) {
     m->mbmi.mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
+    cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
+                       [m->mbmi.mb_skip_coeff]++;
+  }
 
   if (cm->txfm_mode == TX_MODE_SELECT &&
       m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
@@ -521,8 +524,11 @@
 
   mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id,
                                               SEG_LVL_SKIP);
-  if (!mbmi->mb_skip_coeff)
+  if (!mbmi->mb_skip_coeff) {
     mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
+    cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
+                       [mbmi->mb_skip_coeff]++;
+  }
 
   // Read the reference frame
   if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_REF_FRAME)) {
@@ -788,9 +794,14 @@
   int k;
 
   // TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
-  vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
-  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-    cm->mbskip_pred_probs[k] = vp9_read_prob(r);
+  // vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
+  for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
+    if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
+      cm->fc.mbskip_probs[k] =
+          vp9_read_prob_diff_update(r, cm->fc.mbskip_probs[k]);
+    }
+    // cm->fc.mbskip_probs[k] = vp9_read_prob(r);
+  }
 
   mb_mode_mv_init(pbi, r);
 }
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -794,6 +794,7 @@
   vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob);
   vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs);
   vp9_copy(fc->pre_tx_probs, fc->tx_probs);
+  vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs);
 
   vp9_zero(fc->coef_counts);
   vp9_zero(fc->eob_branch_counts);
@@ -810,6 +811,7 @@
   vp9_zero(fc->tx_count_8x8p);
   vp9_zero(fc->tx_count_16x16p);
   vp9_zero(fc->tx_count_32x32p);
+  vp9_zero(fc->mbskip_count);
 }
 
 static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) {
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -334,13 +334,18 @@
                 (unsigned int *)cpi->y_mode_count[j]);
 }
 
-void vp9_update_skip_probs(VP9_COMP *cpi) {
+void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *bc) {
   VP9_COMMON *const pc = &cpi->common;
   int k;
 
-  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-    pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
-                                               cpi->skip_true_count[k]);
+  for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
+    vp9_cond_prob_diff_update(bc, &pc->fc.mbskip_probs[k],
+                              VP9_DEF_UPDATE_PROB, pc->fc.mbskip_count[k]);
+    /*
+    pc->fc.mbskip_probs[k] = get_binary_prob(pc->fc.mbskip_count[k][0],
+                                                  pc->fc.mbskip_count[k][1]);
+                                                  */
+  }
 }
 
 static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) {
@@ -1471,6 +1476,7 @@
   vp9_copy(pc->fc.pre_comp_ref_prob, pc->fc.comp_ref_prob);
   vp9_copy(pc->fc.pre_single_ref_prob, pc->fc.single_ref_prob);
   vp9_copy(pc->fc.pre_tx_probs, pc->fc.tx_probs);
+  vp9_copy(pc->fc.pre_mbskip_probs, pc->fc.mbskip_probs);
 
   if (xd->lossless) {
     pc->txfm_mode = ONLY_4X4;
@@ -1484,9 +1490,7 @@
   active_section = 2;
 #endif
 
-  vp9_update_skip_probs(cpi);
-  for (i = 0; i < MBSKIP_CONTEXTS; ++i)
-    vp9_write_prob(&header_bc, pc->mbskip_pred_probs[i]);
+  vp9_update_skip_probs(cpi, &header_bc);
 
   if (pc->frame_type != KEY_FRAME) {
 #ifdef ENTROPY_STATS
--- a/vp9/encoder/vp9_bitstream.h
+++ b/vp9/encoder/vp9_bitstream.h
@@ -12,6 +12,6 @@
 #ifndef VP9_ENCODER_VP9_BITSTREAM_H_
 #define VP9_ENCODER_VP9_BITSTREAM_H_
 
-void vp9_update_skip_probs(VP9_COMP *cpi);
+void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *bc);
 
 #endif  // VP9_ENCODER_VP9_BITSTREAM_H_
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1464,6 +1464,7 @@
   vp9_zero(cm->fc.tx_count_32x32p);
   vp9_zero(cm->fc.tx_count_16x16p);
   vp9_zero(cm->fc.tx_count_8x8p);
+  vp9_zero(cm->fc.mbskip_count);
 
   // Note: this memset assumes above_context[0], [1] and [2]
   // are allocated as part of the same buffer.
@@ -1518,9 +1519,6 @@
   // Reset frame count of inter 0,0 motion vector usage.
   cpi->inter_zz_count = 0;
 
-  cpi->skip_true_count[0] = cpi->skip_true_count[1] = cpi->skip_true_count[2] = 0;
-  cpi->skip_false_count[0] = cpi->skip_false_count[1] = cpi->skip_false_count[2] = 0;
-
   vp9_zero(cm->fc.switchable_interp_count);
   vp9_zero(cpi->best_switchable_interp_count);
 
@@ -2041,7 +2039,7 @@
 
     mbmi->mb_skip_coeff = 1;
     if (output_enabled)
-      cpi->skip_true_count[mb_skip_context]++;
+      cm->fc.mbskip_count[mb_skip_context][1]++;
     vp9_reset_sb_tokens_context(xd,
                  (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize);
   }
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -96,12 +96,7 @@
 FILE *keyfile;
 #endif
 
-#if 0
-extern int skip_true_count;
-extern int skip_false_count;
-#endif
 
-
 #ifdef ENTROPY_STATS
 extern int intra_mode_stats[VP9_INTRA_MODES]
                            [VP9_INTRA_MODES]
@@ -123,8 +118,6 @@
 
 extern void vp9_init_quantizer(VP9_COMP *cpi);
 
-static int base_skip_false_prob[QINDEX_RANGE][3];
-
 // Tables relating active max Q to active min Q
 static int kf_low_motion_minq[QINDEX_RANGE];
 static int kf_high_motion_minq[QINDEX_RANGE];
@@ -201,50 +194,7 @@
     mb->mvsadcost = mb->nmvsadcost;
   }
 }
-static void init_base_skip_probs(void) {
-  int i;
 
-  for (i = 0; i < QINDEX_RANGE; i++) {
-    const double q = vp9_convert_qindex_to_q(i);
-
-    // Exponential decay caluclation of baseline skip prob with clamping
-    // Based on crude best fit of old table.
-    const int t = (int)(564.25 * pow(2.71828, (-0.012 * q)));
-
-    base_skip_false_prob[i][1] = clip_prob(t);
-    base_skip_false_prob[i][2] = clip_prob(t * 3 / 4);
-    base_skip_false_prob[i][0] = clip_prob(t * 5 / 4);
-  }
-}
-
-static void update_base_skip_probs(VP9_COMP *cpi) {
-  VP9_COMMON *cm = &cpi->common;
-  int k;
-
-  if (cm->frame_type != KEY_FRAME) {
-    vp9_update_skip_probs(cpi);
-
-    if (cpi->refresh_alt_ref_frame) {
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
-      cpi->last_skip_probs_q[2] = cm->base_qindex;
-    } else if (cpi->refresh_golden_frame) {
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
-      cpi->last_skip_probs_q[1] = cm->base_qindex;
-    } else {
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
-      cpi->last_skip_probs_q[0] = cm->base_qindex;
-
-      // update the baseline table for the current q
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->base_skip_false_prob[cm->base_qindex][k] =
-            cm->mbskip_pred_probs[k];
-    }
-  }
-}
-
 void vp9_initialize_enc() {
   static int init_done = 0;
 
@@ -254,7 +204,7 @@
     vp9_init_quant_tables();
     vp9_init_me_luts();
     init_minq_luts();
-    init_base_skip_probs();
+    // init_base_skip_probs();
     init_done = 1;
   }
 }
@@ -1288,7 +1238,6 @@
 
   init_config((VP9_PTR)cpi, oxcf);
 
-  memcpy(cpi->base_skip_false_prob, base_skip_false_prob, sizeof(base_skip_false_prob));
   cpi->common.current_video_frame   = 0;
   cpi->kf_overspend_bits            = 0;
   cpi->kf_bitrate_adjustment        = 0;
@@ -2741,45 +2690,7 @@
     vp9_set_quantizer(cpi, q);
 
     if (loop_count == 0) {
-      int k;
 
-      // setup skip prob for costing in mode/mv decision
-      for (k = 0; k < MBSKIP_CONTEXTS; k++)
-        cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[q][k];
-
-      if (cm->frame_type != KEY_FRAME) {
-        if (cpi->refresh_alt_ref_frame) {
-          for (k = 0; k < MBSKIP_CONTEXTS; k++) {
-            if (cpi->last_skip_false_probs[2][k] != 0)
-              cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
-          }
-        } else if (cpi->refresh_golden_frame) {
-          for (k = 0; k < MBSKIP_CONTEXTS; k++) {
-            if (cpi->last_skip_false_probs[1][k] != 0)
-              cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
-          }
-        } else {
-          int k;
-          for (k = 0; k < MBSKIP_CONTEXTS; k++) {
-            if (cpi->last_skip_false_probs[0][k] != 0)
-              cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
-          }
-        }
-
-        // as this is for cost estimate, let's make sure it does not
-        // get extreme either way
-        {
-          int k;
-          for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
-            cm->mbskip_pred_probs[k] = clamp(cm->mbskip_pred_probs[k],
-                                             5, 250);
-
-            if (cpi->is_src_frame_alt_ref)
-              cm->mbskip_pred_probs[k] = 1;
-          }
-        }
-      }
-
       // Set up entropy depending on frame type.
       if (cm->frame_type == KEY_FRAME) {
         /* Choose which entropy context to use. When using a forward reference
@@ -2804,7 +2715,7 @@
 
     // Update the skip mb flag probabilities based on the distribution
     // seen in the last encoder iteration.
-    update_base_skip_probs(cpi);
+    // update_base_skip_probs(cpi);
 
     vp9_clear_system_state();  // __asm emms;
 
@@ -3170,7 +3081,7 @@
 
   // Update the skip mb flag probabilities based on the distribution seen
   // in this frame.
-  update_base_skip_probs(cpi);
+  // update_base_skip_probs(cpi);
 
 #if 0 && CONFIG_INTERNAL_STATS
   {
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -90,6 +90,7 @@
   vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
 
   vp9_prob tx_probs[TX_SIZE_PROBS];
+  vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
 } CODING_CONTEXT;
 
 typedef struct {
@@ -459,8 +460,6 @@
   int inter_zz_count;
   int gf_bad_count;
   int gf_update_recommended;
-  int skip_true_count[3];
-  int skip_false_count[3];
 
   unsigned char *segmentation_map;
 
@@ -479,8 +478,6 @@
   uint64_t time_compress_data;
   uint64_t time_pick_lpf;
   uint64_t time_encode_mb_row;
-
-  int base_skip_false_prob[QINDEX_RANGE][3];
 
   struct twopass_rc {
     unsigned int section_intra_rating;
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -144,6 +144,7 @@
   vp9_copy(cc->coef_probs, cm->fc.coef_probs);
   vp9_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob);
   vp9_copy(cc->tx_probs, cm->fc.tx_probs);
+  vp9_copy(cc->mbskip_probs, cm->fc.mbskip_probs);
 }
 
 void vp9_restore_coding_context(VP9_COMP *cpi) {
@@ -182,6 +183,7 @@
   vp9_copy(cm->fc.coef_probs, cc->coef_probs);
   vp9_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob);
   vp9_copy(cm->fc.tx_probs, cc->tx_probs);
+  vp9_copy(cm->fc.mbskip_probs, cc->mbskip_probs);
 }
 
 void vp9_setup_key_frame(VP9_COMP *cpi) {
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -294,7 +294,7 @@
 
   if (mbmi->mb_skip_coeff) {
     if (!dry_run)
-      cpi->skip_true_count[mb_skip_context] += skip_inc;
+      cm->fc.mbskip_count[mb_skip_context][1] += skip_inc;
     vp9_reset_sb_tokens_context(xd, bsize);
     if (dry_run)
       *t = t_backup;
@@ -302,7 +302,7 @@
   }
 
   if (!dry_run)
-    cpi->skip_false_count[mb_skip_context] += skip_inc;
+    cm->fc.mbskip_count[mb_skip_context][0] += skip_inc;
 
   foreach_transformed_block(xd, bsize, tokenize_b, &arg);
 
--