shithub: libvpx

Download patch

ref: b9ce9bcbc594741c37423a41f2ed52c27742b95d
parent: 99df6bb62959bfda82c0d636105d8239f147715a
author: Paul Wilkins <paulwilkins@google.com>
date: Fri Nov 25 11:31:56 EST 2011

Extended Q Range:

Addressed a couple of other QIndex dependencies.

Change-Id: I15b224bffd0210d3c7065cb6905156f2ca8e9ea9

--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -882,7 +882,9 @@
                  (av_pct_motion * motion_cost) +
                  (av_intra * intra_cost) ) * cpi->common.MBs ) << 9;
 
-    return mv_cost + mode_cost;
+    //return mv_cost + mode_cost;
+    // TODO PGW Fix overhead costs for extended Q range
+    return 0;
 }
 
 static double calc_correction_factor( double err_per_mb,
@@ -913,6 +915,36 @@
     return correction_factor;
 }
 
+// Given a current maxQ value sets a range for future values.
+// PGW TODO..
+// This code removes direct dependency on QIndex to determin the range
+// (now uses the actual quantizer) but has not been tuned.
+static double adjust_maxq_qrange(VP8_COMP *cpi, int qindex )
+{
+    int i;
+    double q = vp8_convert_qindex_to_q(qindex);
+
+    // Set the max corresponding to real q * 2.0
+    cpi->twopass.maxq_max_limit = cpi->worst_quality;
+    for ( i = qindex; i < cpi->worst_quality; i++ )
+    {
+        if ( vp8_convert_qindex_to_q(qindex) >= (q * 2.0) )
+        {
+            cpi->twopass.maxq_max_limit = i;
+        }
+    }
+
+    // Set the min corresponding to real q * 0.5
+    cpi->twopass.maxq_min_limit = cpi->best_quality;
+    for ( i = qindex; i > cpi->best_quality; i-- )
+    {
+        if ( vp8_convert_qindex_to_q(qindex) <= (q * 0.5) )
+        {
+            cpi->twopass.maxq_min_limit = i;
+        }
+    }
+}
+
 static int estimate_max_q(VP8_COMP *cpi,
                           FIRSTPASS_STATS * fpstats,
                           int section_target_bandwitdh,
@@ -974,6 +1006,7 @@
     // Estimate of overhead bits per mb
     // Correction to overhead bits for min allowed Q.
     // PGW TODO.. This code is broken for the extended Q range
+    //            for now overhead set to 0.
     overhead_bits_per_mb = overhead_bits / num_mbs;
     overhead_bits_per_mb *= pow( 0.98, (double)cpi->twopass.maxq_min_limit );
 
@@ -998,6 +1031,8 @@
         // Mode and motion overhead
         // As Q rises in real encode loop rd code will force overhead down
         // We make a crude adjustment for this here as *.98 per Q step.
+        // PGW TODO.. This code is broken for the extended Q range
+        //            for now overhead set to 0.
         overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
 
         if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
@@ -1012,18 +1047,15 @@
     }
 
     // Adjust maxq_min_limit and maxq_max_limit limits based on
-    // averaga q observed in clip for non kf/gf.arf frames
+    // averaga q observed in clip for non kf/gf/arf frames
     // Give average a chance to settle though.
     // PGW TODO.. This code is broken for the extended Q range
-    /*if ( (cpi->ni_frames >
+    if ( (cpi->ni_frames >
                   ((unsigned int)cpi->twopass.total_stats->count >> 8)) &&
          (cpi->ni_frames > 150) )
     {
-        cpi->twopass.maxq_max_limit = ((cpi->ni_av_qi + 32) < cpi->worst_quality)
-                                  ? (cpi->ni_av_qi + 32) : cpi->worst_quality;
-        cpi->twopass.maxq_min_limit = ((cpi->ni_av_qi - 32) > cpi->best_quality)
-                                  ? (cpi->ni_av_qi - 32) : cpi->best_quality;
-    }*/
+        adjust_maxq_qrange( cpi, cpi->ni_av_qi );
+    }
 
     return Q;
 }
@@ -1102,6 +1134,8 @@
         // Mode and motion overhead
         // As Q rises in real encode loop rd code will force overhead down
         // We make a crude adjustment for this here as *.98 per Q step.
+        // PGW TODO.. This code is broken for the extended Q range
+        //            for now overhead set to 0.
         overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
 
         if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
@@ -2451,10 +2485,7 @@
         // estimate for the clip is bad, but helps prevent excessive
         // variation in Q, especially near the end of a clip
         // where for example a small overspend may cause Q to crash
-        cpi->twopass.maxq_max_limit = ((tmp_q + 32) < cpi->worst_quality)
-                                  ? (tmp_q + 32) : cpi->worst_quality;
-        cpi->twopass.maxq_min_limit = ((tmp_q - 32) > cpi->best_quality)
-                                  ? (tmp_q - 32) : cpi->best_quality;
+        adjust_maxq_qrange(cpi, tmp_q);
 
         cpi->active_worst_quality         = tmp_q;
         cpi->ni_av_qi                     = tmp_q;
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -416,9 +416,7 @@
     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);
+    int high_q = ((int)vp8_convert_qindex_to_q(cpi->ni_av_qi) > 32);
 
     // For now at least dont enable seg features alongside cyclic refresh.
     if ( cpi->cyclic_refresh_mode_enabled ||