]> granicus.if.org Git - libvpx/commitdiff
Changes to costing of skip.
authorPaul Wilkins <paulwilkins@google.com>
Wed, 11 Apr 2012 13:37:48 +0000 (14:37 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 11 Apr 2012 13:37:48 +0000 (14:37 +0100)
Update the costing of skip in the recode loop and rd code.

Change-Id: I2e5ebbd7ddf201212b32441321e12626cd0423e9

vp8/encoder/bitstream.c
vp8/encoder/onyx_if.c
vp8/encoder/rdopt.c

index 1ee6653c1b16e9972b851bfca9e5b5d938091a1a..065ea9f1b852ab88f865daa66bb4e8eeddd0b81f 100644 (file)
@@ -120,6 +120,56 @@ static void update_mbintra_mode_probs(VP8_COMP *cpi)
     }
 }
 
+void update_skip_probs(VP8_COMP *cpi)
+{
+#if CONFIG_NEWENTROPY
+    VP8_COMMON *const pc = & cpi->common;
+    int prob_skip_false[3] = {0, 0, 0};
+    int k;
+
+    for (k=0;k<MBSKIP_CONTEXTS;++k)
+    {
+        if ( (cpi->skip_false_count[k] + cpi->skip_true_count[k]) )
+        {
+            prob_skip_false[k] =
+                cpi->skip_false_count[k] * 256 /
+                (cpi->skip_false_count[k] + cpi->skip_true_count[k]);
+
+            if (prob_skip_false[k] <= 1)
+                prob_skip_false[k] = 1;
+
+            if (prob_skip_false[k] > 255)
+                prob_skip_false[k] = 255;
+        }
+        else
+            prob_skip_false[k] = 128;
+
+        pc->mbskip_pred_probs[k] = prob_skip_false[k];
+        vp8_write_literal(w, prob_skip_false[k], 8);
+    }
+
+#else
+    int prob_skip_false = 0;
+
+    if ( (cpi->skip_false_count + cpi->skip_true_count) )
+    {
+        prob_skip_false = cpi->skip_false_count * 256 /
+                          (cpi->skip_false_count + cpi->skip_true_count);
+
+        if (prob_skip_false <= 1)
+            prob_skip_false = 1;
+
+        if (prob_skip_false > 255)
+            prob_skip_false = 255;
+    }
+    else
+        prob_skip_false = 128;
+
+    cpi->prob_skip_false = prob_skip_false;
+
+#endif
+}
+
 static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p)
 {
     vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
@@ -592,12 +642,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
     int mb_row, mb_col;
     int row, col;
 
-#if CONFIG_NEWENTROPY
-    int prob_skip_false[3] = {0, 0, 0};
-#else
-    int prob_skip_false = 0;
-#endif
-
     // Values used in prediction model coding
     vp8_prob pred_prob;
     unsigned char prediction_flag;
@@ -616,45 +660,15 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
     if (pc->mb_no_coeff_skip)
     {
-        // Divide by 0 check. 0 case possible with segment features
 #if CONFIG_NEWENTROPY
         int k;
-        for (k=0;k<MBSKIP_CONTEXTS;++k)
-        {
-            if ( (cpi->skip_false_count[k] + cpi->skip_true_count[k]) )
-            {
-                prob_skip_false[k] = cpi->skip_false_count[k] * 256 /
-                (cpi->skip_false_count[k] + cpi->skip_true_count[k]);
-
-                if (prob_skip_false[k] <= 1)
-                    prob_skip_false[k] = 1;
-
-                if (prob_skip_false[k] > 255)
-                    prob_skip_false[k] = 255;
-            }
-            else
-                prob_skip_false[k] = 255;
 
-            pc->mbskip_pred_probs[k] = prob_skip_false[k];
-            vp8_write_literal(w, prob_skip_false[k], 8);
-        }
+        update_skip_probs( cpi );
+        for (k=0;k<MBSKIP_CONTEXTS;++k)
+            vp8_write_literal(w, cpi->prob_skip_false[k], 8);
 #else
-        if ( (cpi->skip_false_count + cpi->skip_true_count) )
-        {
-            prob_skip_false = cpi->skip_false_count * 256 /
-                              (cpi->skip_false_count + cpi->skip_true_count);
-
-            if (prob_skip_false <= 1)
-                prob_skip_false = 1;
-
-            if (prob_skip_false > 255)
-                prob_skip_false = 255;
-        }
-        else
-            prob_skip_false = 255;
-
-        cpi->prob_skip_false = prob_skip_false;
-        vp8_write_literal(w, prob_skip_false, 8);
+        update_skip_probs( cpi );
+        vp8_write_literal(w, cpi->prob_skip_false, 8);
 #endif
     }
 
@@ -783,7 +797,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                     vp8_encode_bool(w, mi->mb_skip_coeff,
                                     get_pred_prob(pc, xd, PRED_MBSKIP));
 #else
-                    vp8_encode_bool(w, mi->mb_skip_coeff, prob_skip_false);
+                vp8_encode_bool(w, mi->mb_skip_coeff, cpi->prob_skip_false);
 #endif
                 }
 
index 117d3bdc48130dd73fc7ddcfe96a4cad02975a71..a758b19274d99fae0674165556cb517518212952 100644 (file)
@@ -292,6 +292,59 @@ void init_base_skip_probs()
 #endif
     }
 }
+void update_base_skip_probs(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    if (cm->frame_type != KEY_FRAME)
+    {
+        update_skip_probs(cpi);
+
+        if (cm->refresh_alt_ref_frame)
+        {
+#if CONFIG_NEWENTROPY
+            int k;
+            for (k=0; k<MBSKIP_CONTEXTS; ++k)
+                cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
+#else
+            cpi->last_skip_false_probs[2] = cpi->prob_skip_false;
+#endif
+            cpi->last_skip_probs_q[2] = cm->base_qindex;
+        }
+        else if (cpi->common.refresh_golden_frame)
+        {
+#if CONFIG_NEWENTROPY
+            int k;
+            for (k=0; k<MBSKIP_CONTEXTS; ++k)
+                cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
+#else
+            cpi->last_skip_false_probs[1] = cpi->prob_skip_false;
+#endif
+            cpi->last_skip_probs_q[1] = cm->base_qindex;
+        }
+        else
+        {
+#if CONFIG_NEWENTROPY
+            int k;
+            for (k=0; k<MBSKIP_CONTEXTS; ++k)
+                cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
+#else
+            cpi->last_skip_false_probs[0] = cpi->prob_skip_false;
+#endif
+            cpi->last_skip_probs_q[0] = cm->base_qindex;
+
+            // update the baseline table for the current q
+#if CONFIG_NEWENTROPY
+            for (k=0; k<MBSKIP_CONTEXTS; ++k)
+                cpi->base_skip_false_prob[cm->base_qindex][k] =
+                    cm->mbskip_pred_probs[k];
+#else
+            cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false;
+#endif
+        }
+    }
+
+}
 
 void vp8_initialize()
 {
@@ -3207,13 +3260,6 @@ static void encode_frame_to_data_rate
                     if (cpi->last_skip_false_probs[2] != 0)
                         cpi->prob_skip_false = cpi->last_skip_false_probs[2];
 #endif
-
-                    /*
-                                        if(cpi->last_skip_false_probs[2]!=0 && abs(Q- cpi->last_skip_probs_q[2])<=16 )
-                       cpi->prob_skip_false = cpi->last_skip_false_probs[2];
-                                        else if (cpi->last_skip_false_probs[2]!=0)
-                       cpi->prob_skip_false = (cpi->last_skip_false_probs[2]  + cpi->prob_skip_false ) / 2;
-                       */
                 }
                 else if (cpi->common.refresh_golden_frame)
                 {
@@ -3227,13 +3273,6 @@ static void encode_frame_to_data_rate
                     if (cpi->last_skip_false_probs[1] != 0)
                         cpi->prob_skip_false = cpi->last_skip_false_probs[1];
 #endif
-
-                    /*
-                                        if(cpi->last_skip_false_probs[1]!=0 && abs(Q- cpi->last_skip_probs_q[1])<=16 )
-                       cpi->prob_skip_false = cpi->last_skip_false_probs[1];
-                                        else if (cpi->last_skip_false_probs[1]!=0)
-                       cpi->prob_skip_false = (cpi->last_skip_false_probs[1]  + cpi->prob_skip_false ) / 2;
-                       */
                 }
                 else
                 {
@@ -3248,13 +3287,6 @@ static void encode_frame_to_data_rate
                     if (cpi->last_skip_false_probs[0] != 0)
                         cpi->prob_skip_false = cpi->last_skip_false_probs[0];
 #endif
-
-                    /*
-                    if(cpi->last_skip_false_probs[0]!=0 && abs(Q- cpi->last_skip_probs_q[0])<=16 )
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[0];
-                    else if(cpi->last_skip_false_probs[0]!=0)
-                        cpi->prob_skip_false = (cpi->last_skip_false_probs[0]  + cpi->prob_skip_false ) / 2;
-                        */
                 }
 
                 // as this is for cost estimate, let's make sure it does not
@@ -3298,6 +3330,10 @@ static void encode_frame_to_data_rate
         // transform / motion compensation build reconstruction frame
         vp8_encode_frame(cpi);
 
+        // Update the skip mb flag probabilities based on the distribution
+        // seen in the last encoder iteration.
+        update_base_skip_probs( cpi );
+
         cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
         cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
 
@@ -3706,6 +3742,10 @@ static void encode_frame_to_data_rate
             cpi->twopass.gf_group_bits = 0 ;
     }
 
+    // Update the skip mb flag probabilities based on the distribution seen
+    // in this frame.
+    update_base_skip_probs( cpi );
+/*
     if (cm->frame_type != KEY_FRAME)
     {
         if (cpi->common.refresh_alt_ref_frame)
@@ -3751,7 +3791,7 @@ static void encode_frame_to_data_rate
 
         }
     }
-
+*/
 #if 0 && CONFIG_INTERNAL_STATS
     {
         FILE *f = fopen("tmp.stt", "a");
index 2582c64104faebfc0650ecb30147f04c400a1409..19d0c60fca9358f11fb6d133947888862527599f 100644 (file)
@@ -1514,13 +1514,26 @@ int vp8_cost_mv_ref(VP8_COMP *cpi,
                     MB_PREDICTION_MODE m,
                     const int near_mv_ref_ct[4])
 {
-    VP8_COMMON *pc = &cpi->common;
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
+    int segment_id = xd->mode_info_context->mbmi.segment_id;
+
+    // If the mode coding is done entirely at the segment level
+    // we should not account for it at the per mb level in rd code.
+    // Note that if the segment level coding is expanded from single mode
+    // to multiple mode masks as per reference frame coding we will need
+    // to do something different here.
+    if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE) )
+    {
+        VP8_COMMON *pc = &cpi->common;
 
-    vp8_prob p [VP8_MVREFS-1];
-    assert(NEARESTMV <= m  &&  m <= SPLITMV);
-    vp8_mv_ref_probs(pc, p, near_mv_ref_ct);
-    return vp8_cost_token(vp8_mv_ref_tree, p,
-                          vp8_mv_ref_encoding_array - NEARESTMV + m);
+        vp8_prob p [VP8_MVREFS-1];
+        assert(NEARESTMV <= m  &&  m <= SPLITMV);
+        vp8_mv_ref_probs(pc, p, near_mv_ref_ct);
+        return vp8_cost_token(vp8_mv_ref_tree, p,
+                              vp8_mv_ref_encoding_array - NEARESTMV + m);
+    }
+    else
+        return 0;
 }
 
 void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv)
@@ -3241,21 +3254,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                 vp8_cost_bit( get_pred_prob( cm, xd, PRED_COMP ), 1 );
         }
 
-        // Where skip is allowable add in the default per mb cost for the no skip case.
-        // where we then decide to skip we have to delete this and replace it with the
-        // cost of signaling a skip
-        if (cpi->common.mb_no_coeff_skip)
-        {
-#if CONFIG_NEWENTROPY
-            int prob_skip_cost = vp8_cost_bit(
-                get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP), 0);
-#else
-            int prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 0);
-#endif
-            other_cost += prob_skip_cost;
-            rate2 += prob_skip_cost;
-        }
-
         if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
         {
             rate2 += compmode_cost;
@@ -3268,13 +3266,18 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
 
         if (!disable_skip)
         {
-            // Test for the condition where skip block will be activated because there are no non zero coefficients and make any necessary adjustment for rate
-            if (cpi->common.mb_no_coeff_skip)
+            // Test for the condition where skip block will be activated
+            // because there are no non zero coefficients and make any
+            // necessary adjustment for rate. Ignore if skip is coded at
+            // segment level as the cost wont have been added in.
+            if ( cpi->common.mb_no_coeff_skip )
             {
                 int mb_skippable;
+                int mb_skip_allowed;
                 int has_y2 = ( this_mode!=SPLITMV
                                     &&this_mode!=B_PRED
                                     &&this_mode!=I8X8_PRED);
+
                 if((cpi->common.txfm_mode == ALLOW_8X8) && has_y2)
                 {
                     if(x->e_mbd.mode_info_context->mbmi.ref_frame!=INTRA_FRAME)
@@ -3292,37 +3295,59 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                                      & mby_is_skippable(&x->e_mbd, has_y2);
                 }
 
+                // Is Mb level skip allowed for this mb.
+                mb_skip_allowed =
+                    !segfeature_active( xd, segment_id, SEG_LVL_EOB ) ||
+                    get_segdata( xd, segment_id, SEG_LVL_EOB );
+
                 if (mb_skippable)
                 {
-#if CONFIG_NEWENTROPY
-                    vp8_prob skip_prob = get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP);
-#endif
-                    int prob_skip_cost;
+                    // Back out the coefficient coding costs
                     rate2 -= (rate_y + rate_uv);
                     //for best_yrd calculation
                     rate_uv = 0;
 
-#if CONFIG_NEWENTROPY
-                    if (skip_prob)
+                    if ( mb_skip_allowed )
                     {
-                        prob_skip_cost = vp8_cost_bit(skip_prob, 1);
-                        prob_skip_cost -= vp8_cost_bit(skip_prob, 0);
-                        rate2 += prob_skip_cost;
-                        other_cost += prob_skip_cost;
-                    }
+                        int prob_skip_cost;
+
+                        // Cost the skip mb case
+#if CONFIG_NEWENTROPY
+                        vp8_prob skip_prob =
+                            get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP);
+
+                        if (skip_prob)
+                        {
+                            prob_skip_cost = vp8_cost_bit(skip_prob, 1);
+                            rate2 += prob_skip_cost;
+                            other_cost += prob_skip_cost;
+                        }
 #else
-                    // Back out no skip flag costing and add in skip flag costing
-                    if (cpi->prob_skip_false)
-                    {
-                        prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 1);
-                        prob_skip_cost -= vp8_cost_bit(cpi->prob_skip_false, 0);
-                        rate2 += prob_skip_cost;
-                        other_cost += prob_skip_cost;
-                    }
+                        if (cpi->prob_skip_false)
+                        {
+                            prob_skip_cost =
+                                vp8_cost_bit(cpi->prob_skip_false, 1);
+                            rate2 += prob_skip_cost;
+                            other_cost += prob_skip_cost;
+                        }
 #endif
+                    }
+                }
+                // Add in the cost of the no skip flag.
+                else if ( mb_skip_allowed )
+                {
+        #if CONFIG_NEWENTROPY
+                    int prob_skip_cost = vp8_cost_bit(
+                        get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP), 0);
+        #else
+                    int prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 0);
+        #endif
+                    rate2 += prob_skip_cost;
+                    other_cost += prob_skip_cost;
                 }
             }
-            // Calculate the final RD estimate for this mode
+
+            // Calculate the final RD estimate for this mode.
             this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
         }