]> granicus.if.org Git - libvpx/commitdiff
Two pass rate control code changes.
authorPaul Wilkins <paulwilkins@google.com>
Wed, 23 Nov 2011 17:18:31 +0000 (17:18 +0000)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 23 Nov 2011 17:18:31 +0000 (17:18 +0000)
This comitt brings accross changes from the public branch
commit number Icf74d13af77437c08602571dc7a97e747cce5066.

The main puurpose of this comit relates to CQ mode but it
also includes some refactoring of the two pass code which
I hope will make tuning the experimental branch for the new
quantizer range a little less painfull.

Change-Id: I278e989436a928fc1fe7761068960048f9d7a376

vp8/encoder/firstpass.c
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h

index 35adb9d108af26494769bfe033c764cf350d2c45..4f3b75ce21c6abeaa629709779a56938e741a167 100644 (file)
@@ -146,7 +146,7 @@ static void output_stats(const VP8_COMP            *cpi,
 
         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,
@@ -162,6 +162,7 @@ static void output_stats(const VP8_COMP            *cpi,
                 stats->MVrv,
                 stats->MVcv,
                 stats->mv_in_out_count,
+                stats->new_mv_count,
                 stats->count,
                 stats->duration);
         fclose(fpfile);
@@ -186,6 +187,7 @@ static void zero_stats(FIRSTPASS_STATS *section)
     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;
 }
@@ -207,10 +209,33 @@ static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
     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)
@@ -236,49 +261,16 @@ static void avg_stats(FIRSTPASS_STATS *section)
 // 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;
 }
 
@@ -510,8 +502,9 @@ void vp8_first_pass(VP8_COMP *cpi)
     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;
 
@@ -542,7 +535,7 @@ void vp8_first_pass(VP8_COMP *cpi)
     //if ( 0 )
     {
         int flag[2] = {1, 1};
-        vp8_initialize_rd_consts(cpi, cm->base_qindex+cm->y1dc_delta_q);
+        vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
         vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
         vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
     }
@@ -691,6 +684,11 @@ void vp8_first_pass(VP8_COMP *cpi)
                     {
                         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)
                         {
@@ -788,6 +786,7 @@ void vp8_first_pass(VP8_COMP *cpi)
             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;
         }
@@ -844,42 +843,117 @@ void vp8_first_pass(VP8_COMP *cpi)
 
 }
 
-#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
@@ -887,7 +961,8 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
                     ? 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)
@@ -896,10 +971,10 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
             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.
@@ -907,18 +982,22 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
     {
         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 =
+            vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;
 
-        bits_per_mb_at_this_q = (int)(.5 + correction_factor
+        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;
@@ -927,10 +1006,8 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
     // 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
@@ -948,6 +1025,97 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
 
     return Q;
 }
+
+// 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 err_correction_factor;
+    double corr_high;
+    double speed_correction = 1.0;
+    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;
+
+    if (0)
+    {
+        FILE *f = fopen("epmp.stt", "a");
+        fprintf(f, "%10.2f\n", err_per_mb );
+        fclose(f);
+    }
+
+    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)
+            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;
+
+    // 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, 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;
@@ -955,11 +1123,9 @@ static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_band
     int target_norm_bits_per_mb;
 
     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;
 
     target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
 
@@ -972,28 +1138,20 @@ static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_band
             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;
-
     // 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;
+        // 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 *
-                       speed_correction *
-                       cpi->twopass.est_max_qcorrection_factor *
-                       (double)vp8_bits_per_mb(INTER_FRAME,Q) / 1.0);
+            (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;
@@ -1056,26 +1214,17 @@ static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_ta
     // 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) );
+            (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 +1251,6 @@ static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_ta
     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,19 +1261,13 @@ void vp8_init_second_pass(VP8_COMP *cpi)
     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_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));
+    *cpi->twopass.total_left_stats = *cpi->twopass.total_stats;
 
     // 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
@@ -1207,7 +1279,6 @@ void vp8_init_second_pass(VP8_COMP *cpi)
     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 +1287,6 @@ void vp8_init_second_pass(VP8_COMP *cpi)
     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;
@@ -2238,6 +2307,8 @@ void vp8_second_pass(VP8_COMP *cpi)
 
     FIRSTPASS_STATS *start_pos;
 
+    int overhead_bits;
+
     if (!cpi->twopass.stats_in)
     {
         return ;
@@ -2337,20 +2408,26 @@ void vp8_second_pass(VP8_COMP *cpi)
     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;
 
             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,9 +2437,12 @@ void vp8_second_pass(VP8_COMP *cpi)
         // 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
@@ -2383,14 +2463,18 @@ void vp8_second_pass(VP8_COMP *cpi)
     // 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 +2482,14 @@ void vp8_second_pass(VP8_COMP *cpi)
         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 );
 }
 
 
index ec5ff64ef2eeb7c5f01c197c620b6ca58d84ac9a..2dcddc0d11ce2a590ba61b5f40c0cf54fd05f528 100644 (file)
@@ -339,6 +339,9 @@ static void dealloc_compressor_data(VP8_COMP *cpi)
     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
@@ -1553,11 +1556,16 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi)
 
     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
@@ -3812,12 +3820,13 @@ static void encode_frame_to_data_rate
                  (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 )
@@ -3828,6 +3837,13 @@ static void encode_frame_to_data_rate
                     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
@@ -3838,7 +3854,7 @@ static void encode_frame_to_data_rate
             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) )
             {
@@ -3891,8 +3907,9 @@ static void encode_frame_to_data_rate
 
     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);
@@ -4622,7 +4639,7 @@ static void encode_frame_to_data_rate
 
         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",
@@ -4633,13 +4650,16 @@ static void encode_frame_to_data_rate
                        (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"
@@ -4652,15 +4672,19 @@ static void encode_frame_to_data_rate
                        (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);
 
+        if ( 0 )
         {
             FILE *fmodes = fopen("Modes.stt", "a");
             int i;
index 465faeec7d0f1e414b2b5adf6678c9d0857f4d71..622f25068418aaac988deb6770890eb1c041a1a6 100644 (file)
@@ -120,6 +120,7 @@ typedef struct
     double MVrv;
     double MVcv;
     double mv_in_out_count;
+    double new_mv_count;
     double duration;
     double count;
 }
@@ -567,6 +568,7 @@ typedef struct VP8_COMP
         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;
@@ -574,10 +576,6 @@ typedef struct VP8_COMP
         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;