shithub: libvpx

Download patch

ref: 0529320a9e7082648f7cbec421103d80c38b67b2
parent: e237fd7c5ad8c0caf341ca50a4ea65495edce74f
author: Paul Wilkins <paulwilkins@google.com>
date: Tue May 15 10:58:13 EDT 2012

Firstpass.c refactoring

Removed unused function.

Added tentative code to take error score of an older frame
into account when calculating Q range. However, for now
it is disabled pending merging other changes and testing.

Change-Id: Ie89955e70319dac31b79e3b833e3352712a061ec

--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -617,7 +617,7 @@
                    }
                 }
 
-                // Experimental search in a second reference frame ((0,0) based only)
+                // Experimental search in an older reference frame
                 if (cm->current_video_frame > 1)
                 {
                     first_pass_motion_search(cpi, x, &zero_ref_mv,
@@ -799,17 +799,13 @@
         accumulate_stats(cpi->twopass.total_stats, &fps);
     }
 
-    // Copy the previous Last Frame into the GF buffer if specific conditions for doing so are met
+    // Copy the previous Last Frame back into gf and and arf buffers if
+    // the prediction is good enough.
     if ((cm->current_video_frame > 0) &&
-        (cpi->twopass.this_frame_stats->pcnt_inter > 0.20) &&
-        ((cpi->twopass.this_frame_stats->intra_error /
-            cpi->twopass.this_frame_stats->coded_error) > 2.0))
+        (cpi->twopass.this_frame_stats->pcnt_inter > 0.20))
     {
         vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
     }
-    {
-        vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
-    }
 
     // swap frame pointers so last frame refers to the frame we just compressed
     vp8_swap_yv12_buffer(lst_yv12, new_yv12);
@@ -886,7 +882,9 @@
     return 0;
 }
 
-static double calc_correction_factor( double err_per_mb,
+static double calc_correction_factor( VP8_COMP *cpi,
+                                      FIRSTPASS_STATS * fpstats,
+                                      double err_per_mb,
                                       double err_divisor,
                                       double pt_low,
                                       double pt_high,
@@ -895,7 +893,10 @@
     double power_term;
     double error_term = err_per_mb / err_divisor;
     double correction_factor;
+    double sr_err_diff;
+    double sr_correction;
 
+
     // Adjustment based on actual quantizer to power term.
     power_term = (vp8_convert_qindex_to_q(Q) * 0.01) + pt_low;
     power_term = (power_term > pt_high) ? pt_high : power_term;
@@ -903,10 +904,25 @@
     // Adjustments to error term
     // TBD
 
-    // Calculate correction factor
+    // Calculate a correction factor based on error per mb
     correction_factor = pow(error_term, power_term);
 
-    // Clip range
+#if 0
+    // Look at the drop in prediction quality between the last frame
+    // and the GF buffer (which contained an older frame).
+    sr_err_diff =
+            (fpstats->sr_coded_error - fpstats->coded_error) /
+            (fpstats->count * cpi->common.MBs * 32);
+    sr_correction = pow( sr_err_diff, 0.5 );
+    if ( sr_correction < 0.5 )
+        sr_correction = 0.5;
+    else if ( sr_correction > 1.25 )
+        sr_correction = 1.25;
+
+    correction_factor = correction_factor * sr_correction;
+#endif
+
+    // Clip final factor range
     correction_factor =
         (correction_factor < 0.05)
             ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
@@ -1017,15 +1033,17 @@
 
         // Error per MB based correction factor
         err_correction_factor =
-            calc_correction_factor(err_per_mb, ERR_DIVISOR, 0.36, 0.90, Q);
+            calc_correction_factor(cpi, fpstats, err_per_mb,
+                                   ERR_DIVISOR, 0.36, 0.90, Q) *
+            speed_correction *
+            cpi->twopass.est_max_qcorrection_factor *
+            cpi->twopass.section_max_qfactor;
 
         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)bits_per_mb_at_this_q);
+        bits_per_mb_at_this_q = (int)(.5 + err_correction_factor *
+                                      (double)bits_per_mb_at_this_q);
 
         // Mode and motion overhead
         // As Q rises in real encode loop rd code will force overhead down
@@ -1032,7 +1050,7 @@
         // 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);
+        //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;
@@ -1119,8 +1137,8 @@
 
         // Error per MB based correction factor
         err_correction_factor =
-            calc_correction_factor(err_per_mb, 100.0, 0.36, 0.90, Q);
-
+            calc_correction_factor(cpi, fpstats, err_per_mb,
+                                   100.0, 0.36, 0.90, Q);
         bits_per_mb_at_this_q =
             vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;
 
@@ -1151,96 +1169,6 @@
     return Q;
 }
 
-// Estimate a worst case Q for a KF group
-static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, double group_iiratio)
-{
-    int Q;
-    int num_mbs = cpi->common.MBs;
-    int target_norm_bits_per_mb = (512 * section_target_bandwitdh) / num_mbs;
-    int bits_per_mb_at_this_q;
-
-    double err_per_mb = section_err / num_mbs;
-    double err_correction_factor;
-    double corr_high;
-    double speed_correction = 1.0;
-    double current_spend_ratio = 1.0;
-
-    double pow_highq = (POW1 < 0.6) ? POW1 + 0.3 : 0.90;
-    double pow_lowq = (POW1 < 0.7) ? POW1 + 0.1 : 0.80;
-
-    double iiratio_correction_factor = 1.0;
-
-    double combined_correction_factor;
-
-    // Trap special case where the target is <= 0
-    if (target_norm_bits_per_mb <= 0)
-        return MAXQ * 2;
-
-    // Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
-    // This is clamped to the range 0.1 to 10.0
-    if (cpi->long_rolling_target_bits <= 0)
-        current_spend_ratio = 10.0;
-    else
-    {
-        current_spend_ratio = (double)cpi->long_rolling_actual_bits / (double)cpi->long_rolling_target_bits;
-        current_spend_ratio = (current_spend_ratio > 10.0) ? 10.0 : (current_spend_ratio < 0.1) ? 0.1 : current_spend_ratio;
-    }
-
-    // Calculate a correction factor based on the quality of prediction in the sequence as indicated by intra_inter error score ratio (IIRatio)
-    // The idea here is to favour subsampling in the hardest sections vs the easyest.
-    iiratio_correction_factor = 1.0 - ((group_iiratio - 6.0) * 0.1);
-
-    if (iiratio_correction_factor < 0.5)
-        iiratio_correction_factor = 0.5;
-
-    // Corrections for higher compression speed settings (reduced compression expected)
-    if (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;
-    }
-
-    // Combine the various factors calculated above
-    combined_correction_factor = speed_correction * iiratio_correction_factor * current_spend_ratio;
-
-    // Try and pick a Q that should be high enough to encode the content at the given rate.
-    for (Q = 0; Q < MAXQ; Q++)
-    {
-        // Error per MB based correction factor
-        err_correction_factor =
-            calc_correction_factor(err_per_mb, ERR_DIVISOR, 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)) );
-
-        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
-            break;
-    }
-
-    // If we could not hit the target even at Max Q then estimate what Q would have bee required
-    while ((bits_per_mb_at_this_q > target_norm_bits_per_mb)  && (Q < (MAXQ * 2)))
-    {
-
-        bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q);
-        Q++;
-    }
-
-    if (0)
-    {
-        FILE *f = fopen("estkf_q.stt", "a");
-        fprintf(f, "%8d %8d %8d %8.2f %8.3f %8.2f %8.3f %8.3f %8.3f %8d\n", cpi->common.current_video_frame, bits_per_mb_at_this_q,
-                target_norm_bits_per_mb, err_per_mb, err_correction_factor,
-                current_spend_ratio, group_iiratio, iiratio_correction_factor,
-                (double)cpi->buffer_level / (double)cpi->oxcf.optimal_buffer_level, Q);
-        fclose(f);
-    }
-
-    return Q;
-}
 
 extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate);