]> granicus.if.org Git - libvpx/commitdiff
Cleans up mbskip encoding
authorDeb Mukherjee <debargha@google.com>
Fri, 7 Jun 2013 20:24:14 +0000 (13:24 -0700)
committerDeb Mukherjee <debargha@google.com>
Fri, 7 Jun 2013 23:00:26 +0000 (16:00 -0700)
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

12 files changed:
vp9/common/vp9_entropymode.c
vp9/common/vp9_onyxc_int.h
vp9/common/vp9_pred_common.c
vp9/decoder/vp9_decodemv.c
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_bitstream.h
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_tokenize.c

index bf57e7ecca0e37ffa946c1696602c9cbd2dbd72a..a70d1a5d49049c3e4c8301e5f8561630a5ab6248 100644 (file)
@@ -197,6 +197,10 @@ const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS] = {
 };
 #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 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
              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 @@ void vp9_adapt_mode_context(VP9_COMMON *pc) {
 
 #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 @@ static void update_mode_probs(int n_modes,
     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 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
       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) {
index dedda206961802af8d72c0701c916ed08b295a55..4cb60f196f2346f6e6da6eaa17049e45468f9947 100644 (file)
@@ -94,6 +94,10 @@ typedef struct frame_contexts {
   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 {
@@ -244,8 +248,6 @@ typedef struct VP9Common {
   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];
   unsigned int  frame_context_idx; /* Context to use/update */
index 73c7278b0fcb581fd30754a36eac87bced9e9fce..f5ea9a48afdecdb49541e4c2d9778dda6e7d9d3b 100644 (file)
@@ -368,7 +368,7 @@ vp9_prob vp9_get_pred_prob(const VP9_COMMON *const cm,
     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:
index 82ea7dc96fa7a146d8aedb9eda4dcd7f36391f1a..8ecf4c983ccb25027c12f17a315843abac2eeb51 100644 (file)
@@ -99,8 +99,11 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
 
   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 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 
   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 @@ void vp9_decode_mode_mvs_init(VP9D_COMP* const pbi, vp9_reader *r) {
   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);
 }
index deb39561dd1ee8eb5979b0cf22c42c15710dcb70..989fbc0c093b5cbce7d21cca2b58506b014d5f3c 100644 (file)
@@ -794,6 +794,7 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
   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 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
   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) {
index 2070432b29ada6629a71d7723cbe5cc333315f10..0e298e01639264052d9abbb873a0d38a643dfb0d 100644 (file)
@@ -334,13 +334,18 @@ static void update_mbintra_mode_probs(VP9_COMP* const cpi,
                 (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 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
   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 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
   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
index f7a8ece64ceaaf6cec26152bc2e28dde04d5df74..b3dbee1a772528078e405d29ad2a17f43d4df9c9 100644 (file)
@@ -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_
index d7810dd66c24dbdad876a084baf4cde9f4b7afbe..72c530a185595e80d34d85f149121def4f28b9e2 100644 (file)
@@ -1464,6 +1464,7 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
   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 @@ static void encode_frame_internal(VP9_COMP *cpi) {
   // 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 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
 
     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);
   }
index 65efb548c9b18a11c3b3ca05fdb1a9d6214106ce..13ed345f005d33b6e997ba62864445d4efb5ea09 100644 (file)
@@ -96,11 +96,6 @@ FILE *kf_list;
 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]
@@ -123,8 +118,6 @@ extern unsigned __int64 Sectionbits[500];
 
 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,49 +194,6 @@ static void set_mvcost(MACROBLOCK *mb) {
     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 @@ void vp9_initialize_enc() {
     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 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
 
   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,44 +2690,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
     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) {
@@ -2804,7 +2715,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
 
     // 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 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
 
   // 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
   {
index b8a60d2f2bd361095bffeddc95c292cfc08c0ce5..259fd277ba22350a3bb15e83c94ca91fd4d4e26e 100644 (file)
@@ -90,6 +90,7 @@ typedef struct {
   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 @@ typedef struct VP9_COMP {
   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;
 
@@ -480,8 +479,6 @@ typedef struct VP9_COMP {
   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;
     unsigned int next_iiratio;
index 60ca355c5a8de8afe42f79afbd49fb17fba1cfa7..7a5d23a77d246c3bea72e5c9c507dcee9dbf3414 100644 (file)
@@ -144,6 +144,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
   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 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
   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) {
index cb05219dd7d9a4d12f688d0c55a53cebe5b0c172..0a290e124c093b823f7e9cce94c7f3c8286f4ae1 100644 (file)
@@ -294,7 +294,7 @@ void vp9_tokenize_sb(VP9_COMP *cpi,
 
   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 @@ void vp9_tokenize_sb(VP9_COMP *cpi,
   }
 
   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);