]> granicus.if.org Git - libvpx/commitdiff
Segmentation Entropy and tweaks.
authorPaul Wilkins <paulwilkins@google.com>
Fri, 28 Oct 2011 14:27:23 +0000 (15:27 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Mon, 31 Oct 2011 10:59:25 +0000 (10:59 +0000)
Some correction for entropy impact of segment signaled (EOB and ref frame)

Other slight tweaks.

Derf VBR average gain now over 1% (best over 7%)
One YT test clip has gains of circa 30% (VBR)

There is still an issue with noisy clips where making the background static
and coded with 0,0 can have a negative effect, especially at low Q.
This is probably because of the loss of smoothing by fractional pixel filters.

Change-Id: I7a225613c98067b96f8fc7a7e36f95d465b2b834

vp8/encoder/bitstream.c
vp8/encoder/encodeframe.c
vp8/encoder/onyx_if.c
vp8/encoder/tokenize.c

index 395ffa79db6ef84a72c439fd6efe36766267ceaa..7df367f114037f0eb07a3209cf197e261b340d42 100644 (file)
@@ -929,12 +929,19 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
     if (pc->mb_no_coeff_skip)
     {
-        prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count);
+        // Divide by 0 check. 0 case possible with segment features
+        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 <= 1)
+                prob_skip_false = 1;
 
-        if (prob_skip_false > 255)
+            if (prob_skip_false > 255)
+                prob_skip_false = 255;
+        }
+        else
             prob_skip_false = 255;
 
         cpi->prob_skip_false = prob_skip_false;
@@ -1192,12 +1199,19 @@ static void write_kfmodes(VP8_COMP *cpi)
 
     if (c->mb_no_coeff_skip)
     {
-        prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count);
+        // Divide by 0 check. 0 case possible with segment features
+        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 <= 1)
+                prob_skip_false = 1;
 
-        if (prob_skip_false >= 255)
+            if (prob_skip_false > 255)
+                prob_skip_false = 255;
+        }
+        else
             prob_skip_false = 255;
 
         cpi->prob_skip_false = prob_skip_false;
index a6e47f240760b5398193c10f9cdc2fc0a93e8dd7..ec679846e1d20c59699c5c0427c90b1b4b5bb0b5 100644 (file)
@@ -716,7 +716,7 @@ void encode_mb_row(VP8_COMP *cpi,
 
 #endif
 
-            // Count of last ref frame 0,0 useage
+            // Count of last ref frame 0,0 usage
             if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
                 cpi->inter_zz_count ++;
 
@@ -758,7 +758,7 @@ void encode_mb_row(VP8_COMP *cpi,
 
         cpi->tplist[mb_row].stop = *tp;
 
-        // Increment pointer into gf useage flags structure.
+        // Increment pointer into gf usage flags structure.
         x->gf_active_ptr++;
 
         // Increment the activity mask pointers.
@@ -1014,7 +1014,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
                                       &cpi->common.rtcd.subpix, bilinear16x16);
     }
 
-    // Reset frame count of inter 0,0 motion vector useage.
+    // Reset frame count of inter 0,0 motion vector usage.
     cpi->inter_zz_count = 0;
 
     vpx_memset(segment_counts, 0, sizeof(segment_counts));
@@ -1320,7 +1320,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
     }
 #endif
 
-    // Adjust the projected reference frame useage probability numbers to reflect
+    // Adjust the projected reference frame usage probability numbers to reflect
     // what we have just seen. This may be usefull when we make multiple itterations
     // of the recode loop rather than continuing to use values from the previous frame.
     if ((cm->frame_type != KEY_FRAME) && !cm->refresh_alt_ref_frame && !cm->refresh_golden_frame)
@@ -1710,11 +1710,10 @@ int vp8cx_encode_inter_macroblock
             vp8_update_zbin_extra(cpi, x);
     }
 
-#if 0
-//#if CONFIG_SEGFEATURES
-    // Test code using segment 1 only.
-    // Dont increment count if ref frame coded at segment level
-    if ( (xd->mode_info_context->mbmi.segment_id != 1) )
+#if CONFIG_SEGFEATURES
+    // Dont increment usage count if ref frame coded at segment level
+    if ( !segfeature_active( xd, xd->mode_info_context->mbmi.segment_id,
+                             SEG_LVL_REF_FRAME ) )
         cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++;
 #else
     cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++;
index c6547cf4a03a09f3c04404391c5f66bc4d5a86d8..35b45673c74d1c7ac9c366ffd33ebc80725dc65e 100644 (file)
@@ -480,6 +480,10 @@ static void init_seg_features(VP8_COMP *cpi)
     VP8_COMMON *cm = &cpi->common;
     MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
+    int high_q = ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
+                   (cpi->cq_target_quality > 16 ) ) ||
+                 (cpi->ni_av_qi > 32);
+
     // For now at least dont enable seg features alongside cyclic refresh.
     if ( cpi->cyclic_refresh_mode_enabled ||
          (cpi->pass != 2) )
@@ -557,14 +561,12 @@ static void init_seg_features(VP8_COMP *cpi)
                 enable_segfeature(xd, 1, SEG_LVL_ALT_Q);
                 enable_segfeature(xd, 1, SEG_LVL_ALT_LF);
 
-                if ( ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
-                       (cpi->cq_target_quality > 56 ) ) ||
-                     (cpi->ni_av_qi > 64) )
+                if ( high_q )
                 {
                     xd->segment_feature_data[1]
-                                            [SEG_LVL_REF_FRAME] = LAST_FRAME;
+                                            [SEG_LVL_REF_FRAME] = ALTREF_FRAME;
                     xd->segment_feature_data[1][SEG_LVL_MODE] = ZEROMV;
-                    xd->segment_feature_data[1][SEG_LVL_EOB] = 15;
+                    xd->segment_feature_data[1][SEG_LVL_EOB] = 0;
 
                     enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
                     enable_segfeature(xd, 1, SEG_LVL_MODE);
@@ -602,6 +604,15 @@ static void init_seg_features(VP8_COMP *cpi)
             xd->segment_feature_data[1][SEG_LVL_REF_FRAME] = ALTREF_FRAME;
             xd->segment_feature_data[1][SEG_LVL_MODE] = ZEROMV;
 
+            // Skip all MBs if high Q
+            if ( high_q )
+            {
+                enable_segfeature(xd, 0, SEG_LVL_EOB);
+                enable_segfeature(xd, 1, SEG_LVL_EOB);
+                xd->segment_feature_data[0][SEG_LVL_EOB] = 0;
+                xd->segment_feature_data[1][SEG_LVL_EOB] = 0;
+            }
+
             // Enable data udpate
             xd->update_mb_segmentation_data = 1;
         }
index c9fb624f3cac46da91a9163bad2c940b7cee3a48..138f99447ec5a8543a1cc40df78ec553227cd8df 100644 (file)
@@ -491,6 +491,24 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
     int has_y2_block;
     int b;
 
+#if CONFIG_SEGFEATURES
+    // If the MB is going to be skipped because of a segment level flag
+    // exclude this from the skip count stats used to calculate the
+    // transmitted skip probability;
+    int skip_inc;
+    int segment_id = x->mode_info_context->mbmi.segment_id;
+
+    if ( !segfeature_active( x, segment_id, SEG_LVL_EOB ) ||
+         (x->segment_feature_data[segment_id][SEG_LVL_EOB] != 0) )
+    {
+        skip_inc = 1;
+    }
+    else
+        skip_inc = 0;
+#else
+    int skip_inc = 1;
+#endif
+
     has_y2_block = (x->mode_info_context->mbmi.mode != B_PRED
 #if CONFIG_I8X8
                     && x->mode_info_context->mbmi.mode != I8X8_PRED
@@ -508,7 +526,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
 
     if (x->mode_info_context->mbmi.mb_skip_coeff)
     {
-        cpi->skip_true_count++;
+        cpi->skip_true_count += skip_inc;
 
         if (!cpi->common.mb_no_coeff_skip)
         {
@@ -527,7 +545,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
         return;
     }
 
-    cpi->skip_false_count++;
+    cpi->skip_false_count += skip_inc;
 
     plane_type = 3;
     if(has_y2_block)