shithub: libvpx

Download patch

ref: b6e27d5f0b205f8e72ffe5f9ca516f0a49e0c9c1
parent: e47306eb7ac76f15931c917297b313a0985102e1
author: Paul Wilkins <paulwilkins@google.com>
date: Thu Sep 15 10:36:24 EDT 2011

CQ and two pass rate control.

Changes to the selection of Q limits for two pass
and two pass CQ mode.

Allowance made for Mode and motion vector costs.
Some refactoring of common code.

For Derf and YT sets CQ mode average improvement
circa 1% (SSIM and Global PSNR).

Some increased tendency to undershoot even when
user CQ not reached.

Patch2: Removed some test code accidentally merged.

Change-Id: Icf74d13af77437c08602571dc7a97e747cce5066

--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -152,7 +152,7 @@
 
         fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
                 " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
-                " %12.0f %12.4f\n",
+                " %12.0f %12.0f %12.4f\n",
                 stats->frame,
                 stats->intra_error,
                 stats->coded_error,
@@ -168,6 +168,7 @@
                 stats->MVrv,
                 stats->MVcv,
                 stats->mv_in_out_count,
+                stats->new_mv_count,
                 stats->count,
                 stats->duration);
         fclose(fpfile);
@@ -192,6 +193,7 @@
     section->MVrv       = 0.0;
     section->MVcv       = 0.0;
     section->mv_in_out_count  = 0.0;
+    section->new_mv_count = 0.0;
     section->count      = 0.0;
     section->duration   = 1.0;
 }
@@ -213,10 +215,33 @@
     section->MVrv       += frame->MVrv;
     section->MVcv       += frame->MVcv;
     section->mv_in_out_count  += frame->mv_in_out_count;
+    section->new_mv_count += frame->new_mv_count;
     section->count      += frame->count;
     section->duration   += frame->duration;
 }
 
+static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
+{
+    section->frame -= frame->frame;
+    section->intra_error -= frame->intra_error;
+    section->coded_error -= frame->coded_error;
+    section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err;
+    section->pcnt_inter  -= frame->pcnt_inter;
+    section->pcnt_motion -= frame->pcnt_motion;
+    section->pcnt_second_ref -= frame->pcnt_second_ref;
+    section->pcnt_neutral -= frame->pcnt_neutral;
+    section->MVr        -= frame->MVr;
+    section->mvr_abs     -= frame->mvr_abs;
+    section->MVc        -= frame->MVc;
+    section->mvc_abs     -= frame->mvc_abs;
+    section->MVrv       -= frame->MVrv;
+    section->MVcv       -= frame->MVcv;
+    section->mv_in_out_count  -= frame->mv_in_out_count;
+    section->new_mv_count -= frame->new_mv_count;
+    section->count      -= frame->count;
+    section->duration   -= frame->duration;
+}
+
 static void avg_stats(FIRSTPASS_STATS *section)
 {
     if (section->count < 1.0)
@@ -242,49 +267,16 @@
 // Calculate a modified Error used in distributing bits between easier and harder frames
 static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 {
-    double av_err = cpi->twopass.total_stats->ssim_weighted_pred_err;
+    double av_err = ( cpi->twopass.total_stats->ssim_weighted_pred_err /
+                      cpi->twopass.total_stats->count );
     double this_err = this_frame->ssim_weighted_pred_err;
     double modified_err;
 
-    //double relative_next_iiratio;
-    //double next_iiratio;
-    //double sum_iiratio;
-    //int i;
-
-    //FIRSTPASS_STATS next_frame;
-    //FIRSTPASS_STATS *start_pos;
-
-    /*start_pos = cpi->twopass.stats_in;
-    sum_iiratio = 0.0;
-    i = 0;
-    while ( (i < 1) && input_stats(cpi,&next_frame) != EOF )
-    {
-
-        next_iiratio = next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error);
-        next_iiratio = ( next_iiratio < 1.0 ) ? 1.0 : (next_iiratio > 20.0) ? 20.0 : next_iiratio;
-        sum_iiratio += next_iiratio;
-        i++;
-    }
-    if ( i > 0 )
-    {
-        relative_next_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK(cpi->twopass.avg_iiratio * (double)i);
-    }
-    else
-    {
-        relative_next_iiratio = 1.0;
-    }
-    reset_fpf_position(cpi, start_pos);*/
-
     if (this_err > av_err)
         modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1);
     else
         modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2);
 
-    /*
-    relative_next_iiratio = pow(relative_next_iiratio,0.25);
-    modified_err = modified_err * relative_next_iiratio;
-    */
-
     return modified_err;
 }
 
@@ -516,8 +508,9 @@
     int second_ref_count = 0;
     int intrapenalty = 256;
     int neutral_count = 0;
-
+    int new_mv_count = 0;
     int sum_in_vectors = 0;
+    uint32_t lastmv_as_int = 0;
 
     int_mv zero_ref_mv;
 
@@ -697,6 +690,11 @@
                     {
                         mvcount++;
 
+                        // Was it different from the last non zero vector
+                        if ( d->bmi.mv.as_int != lastmv_as_int )
+                            new_mv_count++;
+                        lastmv_as_int = d->bmi.mv.as_int;
+
                         // Does the Row vector point inwards or outwards
                         if (mb_row < cm->mb_rows / 2)
                         {
@@ -794,6 +792,7 @@
             fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / (double)mvcount;
             fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / (double)mvcount;
             fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2);
+            fps.new_mv_count = new_mv_count;
 
             fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs;
         }
@@ -851,42 +850,117 @@
 }
 extern const int vp8_bits_per_mb[2][QINDEX_RANGE];
 
-#define BASE_ERRPERMB   150
-static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
+// Estimate a cost per mb attributable to overheads such as the coding of
+// modes and motion vectors.
+// Currently simplistic in its assumptions for testing.
+//
+
+
+double bitcost( double prob )
 {
+    return -(log( prob ) / log( 2.0 ));
+}
+static long long estimate_modemvcost(VP8_COMP *cpi,
+                                     FIRSTPASS_STATS * fpstats)
+{
+    int mv_cost;
+    int mode_cost;
+
+    double av_pct_inter = fpstats->pcnt_inter / fpstats->count;
+    double av_pct_motion = fpstats->pcnt_motion / fpstats->count;
+    double av_intra = (1.0 - av_pct_inter);
+
+    double zz_cost;
+    double motion_cost;
+    double intra_cost;
+
+    zz_cost = bitcost(av_pct_inter - av_pct_motion);
+    motion_cost = bitcost(av_pct_motion);
+    intra_cost = bitcost(av_intra);
+
+    // Estimate of extra bits per mv overhead for mbs
+    // << 9 is the normalization to the (bits * 512) used in vp8_bits_per_mb
+    mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9;
+
+    // Crude estimate of overhead cost from modes
+    // << 9 is the normalization to (bits * 512) used in vp8_bits_per_mb
+    mode_cost =
+        (int)( ( ((av_pct_inter - av_pct_motion) * zz_cost) +
+                 (av_pct_motion * motion_cost) +
+                 (av_intra * intra_cost) ) * cpi->common.MBs ) << 9;
+
+    return mv_cost + mode_cost;
+}
+
+static double calc_correction_factor( double err_per_mb,
+                                      double err_devisor,
+                                      double pt_low,
+                                      double pt_high,
+                                      int Q )
+{
+    double power_term;
+    double error_term = err_per_mb / err_devisor;
+    double correction_factor;
+
+    // Adjustment based on Q to power term.
+    power_term = pt_low + (Q * 0.01);
+    power_term = (power_term > pt_high) ? pt_high : power_term;
+
+    // Adjustments to error term
+    // TBD
+
+    // Calculate correction factor
+    correction_factor = pow(error_term, power_term);
+
+    // Clip range
+    correction_factor =
+        (correction_factor < 0.05)
+            ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
+
+    return correction_factor;
+}
+
+static int estimate_max_q(VP8_COMP *cpi,
+                          FIRSTPASS_STATS * fpstats,
+                          int section_target_bandwitdh,
+                          int overhead_bits )
+{
     int Q;
     int num_mbs = cpi->common.MBs;
     int target_norm_bits_per_mb;
 
+    double section_err = (fpstats->coded_error / fpstats->count);
     double err_per_mb = section_err / num_mbs;
-    double correction_factor;
+    double err_correction_factor;
     double corr_high;
     double speed_correction = 1.0;
-    double pow_highq = 0.90;
-    double pow_lowq = 0.40;
+    double inter_pct = (fpstats->pcnt_inter / fpstats->count);
+    double intra_pct = 1.0 - inter_pct;
+    int overhead_bits_per_mb;
 
     if (section_target_bandwitdh <= 0)
         return cpi->twopass.maxq_max_limit;          // Highest value allowed
 
-    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
+    target_norm_bits_per_mb =
+        (section_target_bandwitdh < (1 << 20))
+            ? (512 * section_target_bandwitdh) / num_mbs
+            : 512 * (section_target_bandwitdh / num_mbs);
 
-    // Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
-    if ((cpi->rolling_target_bits > 0) && (cpi->active_worst_quality < cpi->worst_quality))
+    // Calculate a corrective factor based on a rolling ratio of bits spent
+    // vs target bits
+    if ((cpi->rolling_target_bits > 0) &&
+        (cpi->active_worst_quality < cpi->worst_quality))
     {
         double rolling_ratio;
 
-        rolling_ratio = (double)cpi->rolling_actual_bits / (double)cpi->rolling_target_bits;
+        rolling_ratio = (double)cpi->rolling_actual_bits /
+                        (double)cpi->rolling_target_bits;
 
-        //if ( cpi->twopass.est_max_qcorrection_factor > rolling_ratio )
         if (rolling_ratio < 0.95)
-            //cpi->twopass.est_max_qcorrection_factor *= adjustment_rate;
             cpi->twopass.est_max_qcorrection_factor -= 0.005;
-        //else if ( cpi->twopass.est_max_qcorrection_factor < rolling_ratio )
         else if (rolling_ratio > 1.05)
             cpi->twopass.est_max_qcorrection_factor += 0.005;
 
-        //cpi->twopass.est_max_qcorrection_factor /= adjustment_rate;
-
         cpi->twopass.est_max_qcorrection_factor =
             (cpi->twopass.est_max_qcorrection_factor < 0.1)
                 ? 0.1
@@ -894,7 +968,8 @@
                     ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
     }
 
-    // Corrections for higher compression speed settings (reduced compression expected)
+    // Corrections for higher compression speed settings
+    // (reduced compression expected)
     if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
     {
         if (cpi->oxcf.cpu_used <= 5)
@@ -903,10 +978,10 @@
             speed_correction = 1.25;
     }
 
-    // Correction factor used for Q values >= 20
-    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
-    corr_high = (corr_high < 0.05)
-                    ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
+    // Estimate of overhead bits per mb
+    // Correction to overhead bits for min allowed Q.
+    overhead_bits_per_mb = overhead_bits / num_mbs;
+    overhead_bits_per_mb *= pow( 0.98, (double)cpi->twopass.maxq_min_limit );
 
     // Try and pick a max Q that will be high enough to encode the
     // content at the given rate.
@@ -914,19 +989,23 @@
     {
         int bits_per_mb_at_this_q;
 
-        if (Q < 50)
-        {
-            correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
-            correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
-        }
-        else
-            correction_factor = corr_high;
+        // Error per MB based correction factor
+        err_correction_factor =
+            calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
 
-        bits_per_mb_at_this_q = (int)(.5 + correction_factor
+        bits_per_mb_at_this_q =
+            vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;
+
+        bits_per_mb_at_this_q = (int)(.5 + err_correction_factor
             * speed_correction * cpi->twopass.est_max_qcorrection_factor
             * cpi->twopass.section_max_qfactor
-            * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
+            * (double)bits_per_mb_at_this_q);
 
+        // 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.
+        overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
+
         if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
             break;
     }
@@ -934,10 +1013,8 @@
     // Restriction on active max q for constrained quality mode.
     if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
          (Q < cpi->cq_target_quality) )
-         //(Q < cpi->oxcf.cq_level;) )
     {
         Q = cpi->cq_target_quality;
-        //Q = cpi->oxcf.cq_level;
     }
 
     // Adjust maxq_min_limit and maxq_max_limit limits based on
@@ -955,22 +1032,45 @@
 
     return Q;
 }
-static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
+
+// For cq mode estimate a cq level that matches the observed
+// complexity and data rate.
+static int estimate_cq( VP8_COMP *cpi,
+                        FIRSTPASS_STATS * fpstats,
+                        int section_target_bandwitdh,
+                        int overhead_bits )
 {
     int Q;
     int num_mbs = cpi->common.MBs;
     int target_norm_bits_per_mb;
 
+    double section_err = (fpstats->coded_error / fpstats->count);
     double err_per_mb = section_err / num_mbs;
-    double correction_factor;
+    double err_correction_factor;
     double corr_high;
     double speed_correction = 1.0;
-    double pow_highq = 0.90;
-    double pow_lowq = 0.40;
+    double clip_iiratio;
+    double clip_iifactor;
+    double inter_pct = (fpstats->pcnt_inter / fpstats->count);
+    double intra_pct = 1.0 - inter_pct;
+    int overhead_bits_per_mb;
 
-    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
+    if (0)
+    {
+        FILE *f = fopen("epmp.stt", "a");
+        fprintf(f, "%10.2f\n", err_per_mb );
+        fclose(f);
+    }
 
-    // Corrections for higher compression speed settings (reduced compression expected)
+    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
+                              ? (512 * section_target_bandwitdh) / num_mbs
+                              : 512 * (section_target_bandwitdh / num_mbs);
+
+    // Estimate of overhead bits per mb
+    overhead_bits_per_mb = overhead_bits / num_mbs;
+
+    // Corrections for higher compression speed settings
+    // (reduced compression expected)
     if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
     {
         if (cpi->oxcf.cpu_used <= 5)
@@ -979,9 +1079,12 @@
             speed_correction = 1.25;
     }
 
-    // Correction factor used for Q values >= 20
-    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
-    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
+    // II ratio correction factor for clip as a whole
+    clip_iiratio = cpi->twopass.total_stats->intra_error /
+                   DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats->coded_error);
+    clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
+    if (clip_iifactor < 0.80)
+        clip_iifactor = 0.80;
 
     // Try and pick a Q that can encode the content at the given rate.
     for (Q = 0; Q < MAXQ; Q++)
@@ -988,16 +1091,75 @@
     {
         int bits_per_mb_at_this_q;
 
-        if (Q < 50)
-        {
-            correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
-            correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
-        }
+        // Error per MB based correction factor
+        err_correction_factor =
+            calc_correction_factor(err_per_mb, 100.0, 0.40, 0.90, Q);
+
+        bits_per_mb_at_this_q =
+            vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;
+
+        bits_per_mb_at_this_q =
+            (int)( .5 + err_correction_factor *
+                        speed_correction *
+                        clip_iifactor *
+                        (double)bits_per_mb_at_this_q);
+
+        // 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.
+        overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
+
+        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
+            break;
+    }
+
+    // Clip value to range "best allowed to (worst allowed - 1)"
+    Q = cq_level[Q];
+    if ( Q >= cpi->worst_quality )
+        Q = cpi->worst_quality - 1;
+    if ( Q < cpi->best_quality )
+        Q = cpi->best_quality;
+
+    return Q;
+}
+
+static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
+{
+    int Q;
+    int num_mbs = cpi->common.MBs;
+    int target_norm_bits_per_mb;
+
+    double err_per_mb = section_err / num_mbs;
+    double err_correction_factor;
+    double corr_high;
+    double speed_correction = 1.0;
+
+    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
+
+    // Corrections for higher compression speed settings (reduced compression expected)
+    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
+    {
+        if (cpi->oxcf.cpu_used <= 5)
+            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
         else
-            correction_factor = corr_high;
+            speed_correction = 1.25;
+    }
 
-        bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->twopass.est_max_qcorrection_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
+    // Try and pick a Q that can encode the content at the given rate.
+    for (Q = 0; Q < MAXQ; Q++)
+    {
+        int bits_per_mb_at_this_q;
 
+        // Error per MB based correction factor
+        err_correction_factor =
+            calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
+
+        bits_per_mb_at_this_q =
+            (int)( .5 + ( err_correction_factor *
+                          speed_correction *
+                          cpi->twopass.est_max_qcorrection_factor *
+                          (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0 ) );
+
         if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
             break;
     }
@@ -1059,23 +1221,17 @@
     // Combine the various factors calculated above
     combined_correction_factor = speed_correction * iiratio_correction_factor * current_spend_ratio;
 
-    // Correction factor used for Q values >= 20
-    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
-    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
-
     // Try and pick a Q that should be high enough to encode the content at the given rate.
     for (Q = 0; Q < MAXQ; Q++)
     {
-        // Q values < 20 treated as a special case
-        if (Q < 20)
-        {
-            err_correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
-            err_correction_factor = (err_correction_factor < 0.05) ? 0.05 : (err_correction_factor > 5.0) ? 5.0 : err_correction_factor;
-        }
-        else
-            err_correction_factor = corr_high;
+        // Error per MB based correction factor
+        err_correction_factor =
+            calc_correction_factor(err_per_mb, 150.0, pow_lowq, pow_highq, Q);
 
-        bits_per_mb_at_this_q = (int)(.5 + err_correction_factor * combined_correction_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q]);
+        bits_per_mb_at_this_q =
+            (int)(.5 + ( err_correction_factor *
+                         combined_correction_factor *
+                         (double)vp8_bits_per_mb[INTER_FRAME][Q]) );
 
         if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
             break;
@@ -1102,77 +1258,6 @@
     return Q;
 }
 
-// For cq mode estimate a cq level that matches the observed
-// complexity and data rate.
-static int estimate_cq(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
-{
-    int Q;
-    int num_mbs = cpi->common.MBs;
-    int target_norm_bits_per_mb;
-
-    double err_per_mb = section_err / num_mbs;
-    double correction_factor;
-    double corr_high;
-    double speed_correction = 1.0;
-    double pow_highq = 0.90;
-    double pow_lowq = 0.40;
-    double clip_iiratio;
-    double clip_iifactor;
-
-    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
-                              ? (512 * section_target_bandwitdh) / num_mbs
-                              : 512 * (section_target_bandwitdh / num_mbs);
-
-    // Corrections for higher compression speed settings
-    // (reduced compression expected)
-    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
-    {
-        if (cpi->oxcf.cpu_used <= 5)
-            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
-        else
-            speed_correction = 1.25;
-    }
-    // II ratio correction factor for clip as a whole
-    clip_iiratio = cpi->twopass.total_stats->intra_error /
-                   DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats->coded_error);
-    clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
-    if (clip_iifactor < 0.80)
-        clip_iifactor = 0.80;
-
-    // Correction factor used for Q values >= 20
-    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
-    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
-
-    // Try and pick a Q that can encode the content at the given rate.
-    for (Q = 0; Q < MAXQ; Q++)
-    {
-        int bits_per_mb_at_this_q;
-
-        if (Q < 50)
-        {
-            correction_factor =
-                pow( err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
-
-            correction_factor = (correction_factor < 0.05) ? 0.05
-                                    : (correction_factor > 5.0) ? 5.0
-                                        : correction_factor;
-        }
-        else
-            correction_factor = corr_high;
-
-        bits_per_mb_at_this_q =
-            (int)( .5 + correction_factor *
-                        speed_correction *
-                        clip_iifactor *
-                        (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
-
-        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
-            break;
-    }
-
-    return cq_level[Q];
-}
-
 extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate);
 
 void vp8_init_second_pass(VP8_COMP *cpi)
@@ -1183,20 +1268,14 @@
     double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
 
     zero_stats(cpi->twopass.total_stats);
+    zero_stats(cpi->twopass.total_left_stats);
 
     if (!cpi->twopass.stats_in_end)
         return;
 
     *cpi->twopass.total_stats = *cpi->twopass.stats_in_end;
+    *cpi->twopass.total_left_stats = *cpi->twopass.total_stats;
 
-    cpi->twopass.total_error_left = cpi->twopass.total_stats->ssim_weighted_pred_err;
-    cpi->twopass.total_intra_error_left = cpi->twopass.total_stats->intra_error;
-    cpi->twopass.total_coded_error_left = cpi->twopass.total_stats->coded_error;
-    cpi->twopass.start_tot_err_left = cpi->twopass.total_error_left;
-
-    //cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
-    //cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats->count * two_pass_min_rate / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
-
     // each frame can have a different duration, as the frame rate in the source
     // isn't guaranteed to be constant.   The frame rate prior to the first frame
     // encoded in the second pass is a guess.  However the sum duration is not.
@@ -1207,7 +1286,6 @@
     cpi->output_frame_rate = cpi->oxcf.frame_rate;
     cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
     cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats->duration * two_pass_min_rate / 10000000.0);
-    cpi->twopass.clip_bits_total = cpi->twopass.bits_left;
 
     // Calculate a minimum intra value to be used in determining the IIratio
     // scores used in the second pass. We have this minimum to make sure
@@ -1216,8 +1294,6 @@
     cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
     cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
 
-    avg_stats(cpi->twopass.total_stats);
-
     // Scan the first pass file and calculate an average Intra / Inter error score ratio for the sequence
     {
         double sum_iiratio = 0.0;
@@ -2137,7 +2213,7 @@
             cpi->twopass.alt_extra_bits = 0;
     }
 
-    // Adjustment to estimate_max_q based on a measure of complexity of the section
+    // Adjustments based on a measure of complexity of the section
     if (cpi->common.frame_type != KEY_FRAME)
     {
         FIRSTPASS_STATS sectionstats;
@@ -2238,6 +2314,8 @@
 
     FIRSTPASS_STATS *start_pos;
 
+    int overhead_bits;
+
     if (!cpi->twopass.stats_in)
     {
         return ;
@@ -2337,12 +2415,17 @@
     if (cpi->target_bandwidth < 0)
         cpi->target_bandwidth = 0;
 
+
+    // Account for mv, mode and other overheads.
+    overhead_bits = estimate_modemvcost(
+                        cpi, cpi->twopass.total_left_stats );
+
+    // Special case code for first frame.
     if (cpi->common.current_video_frame == 0)
     {
         cpi->twopass.est_max_qcorrection_factor = 1.0;
 
-        // Experimental code to try and set a cq_level in constrained
-        // quality mode.
+        // Set a cq_level in constrained quality mode.
         if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
         {
             int est_cq;
@@ -2349,8 +2432,9 @@
 
             est_cq =
                 estimate_cq( cpi,
-                             (cpi->twopass.total_coded_error_left / frames_left),
-                             (int)(cpi->twopass.bits_left / frames_left));
+                             cpi->twopass.total_left_stats,
+                             (int)(cpi->twopass.bits_left / frames_left),
+                             overhead_bits );
 
             cpi->cq_target_quality = cpi->oxcf.cq_level;
             if ( est_cq > cpi->cq_target_quality )
@@ -2360,10 +2444,13 @@
         // guess at maxq needed in 2nd pass
         cpi->twopass.maxq_max_limit = cpi->worst_quality;
         cpi->twopass.maxq_min_limit = cpi->best_quality;
-        tmp_q = estimate_max_q( cpi,
-                                (cpi->twopass.total_coded_error_left / frames_left),
-                                (int)(cpi->twopass.bits_left / frames_left));
 
+        tmp_q = estimate_max_q(
+                    cpi,
+                    cpi->twopass.total_left_stats,
+                    (int)(cpi->twopass.bits_left / frames_left),
+                    overhead_bits );
+
         // Limit the maxq value returned subsequently.
         // This increases the risk of overspend or underspend if the initial
         // estimate for the clip is bad, but helps prevent excessive
@@ -2383,14 +2470,18 @@
     // radical adjustments to the allowed quantizer range just to use up a
     // few surplus bits or get beneath the target rate.
     else if ( (cpi->common.current_video_frame <
-                  (((unsigned int)cpi->twopass.total_stats->count * 255)>>8)) &&
+                 (((unsigned int)cpi->twopass.total_stats->count * 255)>>8)) &&
               ((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
-                  (unsigned int)cpi->twopass.total_stats->count) )
+                 (unsigned int)cpi->twopass.total_stats->count) )
     {
         if (frames_left < 1)
             frames_left = 1;
 
-        tmp_q = estimate_max_q(cpi, (cpi->twopass.total_coded_error_left / frames_left), (int)(cpi->twopass.bits_left / frames_left));
+        tmp_q = estimate_max_q(
+                    cpi,
+                    cpi->twopass.total_left_stats,
+                    (int)(cpi->twopass.bits_left / frames_left),
+                    overhead_bits );
 
         // Move active_worst_quality but in a damped way
         if (tmp_q > cpi->active_worst_quality)
@@ -2398,13 +2489,14 @@
         else if (tmp_q < cpi->active_worst_quality)
             cpi->active_worst_quality --;
 
-        cpi->active_worst_quality = ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
+        cpi->active_worst_quality =
+            ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
     }
 
     cpi->twopass.frames_to_key --;
-    cpi->twopass.total_error_left      -= this_frame_error;
-    cpi->twopass.total_intra_error_left -= this_frame_intra_error;
-    cpi->twopass.total_coded_error_left -= this_frame_coded_error;
+
+    // Update the total stats remaining sturcture
+    subtract_stats(cpi->twopass.total_left_stats, &this_frame );
 }
 
 
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -309,6 +309,9 @@
     vpx_free(cpi->twopass.total_stats);
     cpi->twopass.total_stats = 0;
 
+    vpx_free(cpi->twopass.total_left_stats);
+    cpi->twopass.total_left_stats = 0;
+
     vpx_free(cpi->twopass.this_frame_stats);
     cpi->twopass.this_frame_stats = 0;
 #endif
@@ -1335,11 +1338,16 @@
 
     cpi->twopass.total_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
 
+    vpx_free(cpi->twopass.total_left_stats);
+    cpi->twopass.total_left_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
+
         vpx_free(cpi->twopass.this_frame_stats);
 
     cpi->twopass.this_frame_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
 
-    if(!cpi->twopass.total_stats || !cpi->twopass.this_frame_stats)
+    if( !cpi->twopass.total_stats ||
+        !cpi->twopass.total_left_stats ||
+        !cpi->twopass.this_frame_stats)
         vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
                            "Failed to allocate firstpass stats");
 #endif
@@ -3511,12 +3519,13 @@
                  (cpi->avg_frame_qindex < cpi->active_worst_quality) )
             {
                 Q = cpi->avg_frame_qindex;
+            }
 
-                if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
-                     (Q < cpi->oxcf.cq_level) )
-                {
-                    Q = cpi->oxcf.cq_level;
-                }
+            // For constrained quality dont allow Q less than the cq level
+            if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
+                 (Q < cpi->cq_target_quality) )
+            {
+                Q = cpi->cq_target_quality;
             }
 
             if ( cpi->pass == 2 )
@@ -3527,6 +3536,13 @@
                     cpi->active_best_quality = gf_high_motion_minq[Q];
                 else
                     cpi->active_best_quality = gf_mid_motion_minq[Q];
+
+                // Constrained quality use slightly lower active best.
+                if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
+                {
+                    cpi->active_best_quality =
+                        cpi->active_best_quality * 15/16;
+                }
             }
             // One pass more conservative
             else
@@ -3537,7 +3553,7 @@
             cpi->active_best_quality = inter_minq[Q];
 
             // For the constant/constrained quality mode we dont want
-            // the quality to rise above the cq level.
+            // q to fall below the cq level.
             if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
                 (cpi->active_best_quality < cpi->cq_target_quality) )
             {
@@ -3590,9 +3606,10 @@
 
     if (cpi->active_best_quality < cpi->best_quality)
         cpi->active_best_quality = cpi->best_quality;
-    else if (cpi->active_best_quality > cpi->active_worst_quality)
-        cpi->active_best_quality = cpi->active_worst_quality;
 
+    if ( cpi->active_worst_quality < cpi->active_best_quality )
+        cpi->active_worst_quality = cpi->active_best_quality;
+
     // Determine initial Q to try
     Q = vp8_regulate_q(cpi, cpi->this_frame_target);
     last_zbin_oq = cpi->zbin_over_quant;
@@ -4294,7 +4311,7 @@
 
         vp8_clear_system_state();  //__asm emms;
 
-        if (cpi->twopass.total_coded_error_left != 0.0)
+        if (cpi->twopass.total_left_stats.coded_error != 0.0)
             fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6d %6d"
                        "%6d %6d %6d %5d %5d %5d %8d %8.2f %10d %10.3f"
                        "%10.3f %8d\n",
@@ -4305,13 +4322,16 @@
                        (cpi->oxcf.starting_buffer_level-cpi->bits_off_target),
                        (int)cpi->total_actual_bits, cm->base_qindex,
                        cpi->active_best_quality, cpi->active_worst_quality,
-                       cpi->ni_av_qi, cpi->cq_target_quality, cpi->zbin_over_quant,
+                       cpi->ni_av_qi, cpi->cq_target_quality,
+                       cpi->zbin_over_quant,
                        //cpi->avg_frame_qindex, cpi->zbin_over_quant,
                        cm->refresh_golden_frame, cm->refresh_alt_ref_frame,
                        cm->frame_type, cpi->gfu_boost,
-                       cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left,
-                       cpi->twopass.total_coded_error_left,
-                       (double)cpi->twopass.bits_left / cpi->twopass.total_coded_error_left,
+                       cpi->twopass.est_max_qcorrection_factor,
+                       (int)cpi->twopass.bits_left,
+                       cpi->twopass.total_left_stats.coded_error,
+                       (double)cpi->twopass.bits_left /
+                           cpi->twopass.total_left_stats.coded_error,
                        cpi->tot_recode_hits);
         else
             fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6d %6d"
@@ -4324,12 +4344,15 @@
                        (cpi->oxcf.starting_buffer_level-cpi->bits_off_target),
                        (int)cpi->total_actual_bits, cm->base_qindex,
                        cpi->active_best_quality, cpi->active_worst_quality,
-                       cpi->ni_av_qi, cpi->cq_target_quality, cpi->zbin_over_quant,
+                       cpi->ni_av_qi, cpi->cq_target_quality,
+                       cpi->zbin_over_quant,
                        //cpi->avg_frame_qindex, cpi->zbin_over_quant,
                        cm->refresh_golden_frame, cm->refresh_alt_ref_frame,
                        cm->frame_type, cpi->gfu_boost,
-                       cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left,
-                       cpi->twopass.total_coded_error_left, cpi->tot_recode_hits);
+                       cpi->twopass.est_max_qcorrection_factor,
+                       (int)cpi->twopass.bits_left,
+                       cpi->twopass.total_left_stats.coded_error,
+                       cpi->tot_recode_hits);
 
         fclose(f);
 
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -108,6 +108,7 @@
     double MVrv;
     double MVcv;
     double mv_in_out_count;
+    double new_mv_count;
     double duration;
     double count;
 }
@@ -523,6 +524,7 @@
         FIRSTPASS_STATS *total_stats;
         FIRSTPASS_STATS *this_frame_stats;
         FIRSTPASS_STATS *stats_in, *stats_in_end, *stats_in_start;
+        FIRSTPASS_STATS *total_left_stats;
         int first_pass_done;
         int64_t bits_left;
         int64_t clip_bits_total;
@@ -530,10 +532,6 @@
         double modified_error_total;
         double modified_error_used;
         double modified_error_left;
-        double total_error_left;
-        double total_intra_error_left;
-        double total_coded_error_left;
-        double start_tot_err_left;
         double kf_intra_err_min;
         double gf_intra_err_min;
         int frames_to_key;
--