Revert "Reduce overshoot in 1 pass rate control"
authorJohn Koleszar <jkoleszar@google.com>
Thu, 23 Jun 2011 15:47:09 +0000 (11:47 -0400)
committerJohn Koleszar <jkoleszar@google.com>
Thu, 23 Jun 2011 15:52:12 +0000 (11:52 -0400)
This reverts commit 212f6183739d448ad5fa2ccf1b4edd30829b2806.

Further testing shows that the overshoot accumulation/damping is too
aggressive on some clips. Allowing the accumulated overshoot to
decay and limiting to damping to golden frames shows some promise.
But some clips show significant overshoot in the buffer window, so
I think this still needs work.

Change-Id: Ic02a9ca34f55229f9cc04786f4fab54cdc1a3ef5

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

index a045760..71e285f 100644 (file)
@@ -214,58 +214,33 @@ static int frame_max_bits(VP8_COMP *cpi)
     int max_bits;
 
     // For CBR we need to also consider buffer fullness.
+    // If we are running below the optimal level then we need to gradually tighten up on max_bits.
     if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
     {
-        max_bits = 2 * cpi->av_per_frame_bandwidth;
-        max_bits -= cpi->buffered_av_per_frame_bandwidth;
-        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
-    }
-    // VBR
-    else
-    {
-        // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
-        max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
-    }
-
-    // Trap case where we are out of bits
-    if (max_bits < 0)
-        max_bits = 0;
+        double buffer_fullness_ratio = (double)cpi->buffer_level / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);
 
-    return max_bits;
-}
+        // For CBR base this on the target average bits per frame plus the maximum sedction rate passed in by the user
+        max_bits = (int)(cpi->av_per_frame_bandwidth * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
 
+        // If our buffer is below the optimum level
+        if (buffer_fullness_ratio < 1.0)
+        {
+            // The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4.
+            int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) ? cpi->av_per_frame_bandwidth >> 2 : max_bits >> 2;
 
-static int gf_group_max_bits(VP8_COMP *cpi)
-{
-    // Max allocation for a golden frame group
-    int max_bits;
+            max_bits = (int)(max_bits * buffer_fullness_ratio);
 
-    // For CBR we need to also consider buffer fullness.
-    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
-    {
-        max_bits = cpi->av_per_frame_bandwidth * cpi->baseline_gf_interval;
-        if (max_bits > cpi->oxcf.optimal_buffer_level)
-        {
-            max_bits -= cpi->oxcf.optimal_buffer_level;
-            max_bits += cpi->buffer_level;
+            if (max_bits < min_max_bits)
+                max_bits = min_max_bits;       // Lowest value we will set ... which should allow the buffer to refil.
         }
-        else
-        {
-            max_bits -= (cpi->buffered_av_per_frame_bandwidth
-                         - cpi->av_per_frame_bandwidth)
-                        * cpi->baseline_gf_interval;
-        }
-
-        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
     }
+    // VBR
     else
     {
         // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
         max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
-        max_bits *=  cpi->baseline_gf_interval;
     }
 
-
     // Trap case where we are out of bits
     if (max_bits < 0)
         max_bits = 0;
@@ -1358,7 +1333,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
     double abs_mv_in_out_accumulator = 0.0;
     double mod_err_per_mb_accumulator = 0.0;
 
-    int max_group_bits;
+    int max_bits = frame_max_bits(cpi);     // Max for a single frame
 
     unsigned int allow_alt_ref =
                     cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
@@ -1711,9 +1686,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
     cpi->twopass.gf_group_bits = (cpi->twopass.gf_group_bits < 0) ? 0 : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits) ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits;
 
     // Clip cpi->twopass.gf_group_bits based on user supplied data rate variability limit (cpi->oxcf.two_pass_vbrmax_section)
-    max_group_bits = gf_group_max_bits(cpi);
-    if (cpi->twopass.gf_group_bits > max_group_bits)
-        cpi->twopass.gf_group_bits = max_group_bits;
+    if (cpi->twopass.gf_group_bits > max_bits * cpi->baseline_gf_interval)
+        cpi->twopass.gf_group_bits = max_bits * cpi->baseline_gf_interval;
 
     // Reset the file position
     reset_fpf_position(cpi, start_pos);
@@ -1808,6 +1782,13 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             }
         }
 
+        // Apply an additional limit for CBR
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            if (cpi->twopass.gf_bits > (cpi->buffer_level >> 1))
+                cpi->twopass.gf_bits = cpi->buffer_level >> 1;
+        }
+
         // Dont allow a negative value for gf_bits
         if (gf_bits < 0)
             gf_bits = 0;
index bebc941..0296d92 100644 (file)
@@ -1477,7 +1477,6 @@ static void init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
     cpi->rolling_actual_bits          = cpi->av_per_frame_bandwidth;
     cpi->long_rolling_target_bits     = cpi->av_per_frame_bandwidth;
     cpi->long_rolling_actual_bits     = cpi->av_per_frame_bandwidth;
-    cpi->buffered_av_per_frame_bandwidth = cpi->av_per_frame_bandwidth;
 
     cpi->total_actual_bits            = 0;
     cpi->total_target_vs_actual       = 0;
@@ -1573,7 +1572,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
         break;
     }
 
-    if (cpi->pass == 0 && cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER)
+    if (cpi->pass == 0)
         cpi->auto_worst_q = 1;
 
     cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
@@ -3454,8 +3453,7 @@ static void encode_frame_to_data_rate
     // For CBR if the buffer reaches its maximum level then we can no longer
     // save up bits for later frames so we might as well use them up
     // on the current frame.
-    if (cpi->pass == 2
-        && (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+    if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
         (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level) && cpi->buffered_mode)
     {
         int Adjustment = cpi->active_worst_quality / 4;       // Max adjustment is 1/4
@@ -3546,9 +3544,6 @@ static void encode_frame_to_data_rate
         }
         else
         {
-            if(cpi->pass != 2)
-                Q = cpi->avg_frame_qindex;
-
             cpi->active_best_quality = inter_minq[Q];
 
             // For the constant/constrained quality mode we dont want
@@ -3850,16 +3845,15 @@ static void encode_frame_to_data_rate
             (cpi->active_worst_quality < cpi->worst_quality)      &&
             (cpi->projected_frame_size > frame_over_shoot_limit))
         {
-            /* step down active_worst_quality such that the corresponding
-             * active_best_quality will be equal to the current
-             * active_worst_quality + 1
-             */
-            int i;
+            int over_size_percent = ((cpi->projected_frame_size - frame_over_shoot_limit) * 100) / frame_over_shoot_limit;
 
-            for(i=cpi->active_worst_quality; i<cpi->worst_quality; i++)
-                if(inter_minq[i] >= cpi->active_worst_quality + 1)
-                    break;
-            cpi->active_worst_quality = i;
+            // If so is there any scope for relaxing it
+            while ((cpi->active_worst_quality < cpi->worst_quality) && (over_size_percent > 0))
+            {
+                cpi->active_worst_quality++;
+                top_index = cpi->active_worst_quality;
+                over_size_percent = (int)(over_size_percent * 0.96);        // Assume 1 qstep = about 4% on frame size.
+            }
 
             // If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
             active_worst_qchanged = TRUE;
@@ -4247,9 +4241,10 @@ static void encode_frame_to_data_rate
 
     // Update the buffer level variable.
     // Non-viewable frames are a special case and are treated as pure overhead.
-    if ( cm->show_frame )
-        cpi->bits_off_target += cpi->av_per_frame_bandwidth;
-    cpi->bits_off_target -= cpi->projected_frame_size;
+    if ( !cm->show_frame )
+        cpi->bits_off_target -= cpi->projected_frame_size;
+    else
+        cpi->bits_off_target += cpi->av_per_frame_bandwidth - cpi->projected_frame_size;
 
     // Rolling monitors of whether we are over or underspending used to help regulate min and Max Q in two pass.
     cpi->rolling_target_bits = ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
@@ -4263,33 +4258,7 @@ static void encode_frame_to_data_rate
     // Debug stats
     cpi->total_target_vs_actual += (cpi->this_frame_target - cpi->projected_frame_size);
 
-    // Update the buffered average bitrate
-    {
-        long long numerator;
-
-        numerator = cpi->oxcf.maximum_buffer_size
-                    - cpi->buffered_av_per_frame_bandwidth
-                    + cpi->projected_frame_size;
-        numerator *= cpi->buffered_av_per_frame_bandwidth;
-        cpi->buffered_av_per_frame_bandwidth = numerator
-                                               / cpi->oxcf.maximum_buffer_size;
-    }
-
-    {
-        long long tmp = (long long)cpi->buffered_av_per_frame_bandwidth
-                        * cpi->oxcf.maximum_buffer_size
-                        / cpi->av_per_frame_bandwidth;
-        cpi->buffer_level = cpi->oxcf.maximum_buffer_size
-                            - tmp
-                            + cpi->oxcf.optimal_buffer_level;
-    }
-
-    // Accumulate overshoot error.
-    cpi->accumulated_overshoot +=
-        (cpi->projected_frame_size > cpi->av_per_frame_bandwidth)
-        ? cpi->projected_frame_size - cpi->av_per_frame_bandwidth
-        : 0;
-
+    cpi->buffer_level = cpi->bits_off_target;
 
     // Update bits left to the kf and gf groups to account for overshoot or undershoot on these frames
     if (cm->frame_type == KEY_FRAME)
index c460b9d..3ca61a7 100644 (file)
@@ -351,10 +351,6 @@ typedef struct VP8_COMP
     int per_frame_bandwidth;          // Current section per frame bandwidth target
     int av_per_frame_bandwidth;        // Average frame size target for clip
     int min_frame_bandwidth;          // Minimum allocation that should be used for any frame
-    int buffered_av_per_frame_bandwidth; // Average bitrate over the last buffer
-    int buffered_av_per_frame_bandwidth_rem; // Average bitrate remainder
-    int accumulated_overshoot;           // Accumulated # of bits spent > target
-
     int inter_frame_target;
     double output_frame_rate;
     long long last_time_stamp_seen;
index 73e1437..54c394d 100644 (file)
@@ -605,10 +605,10 @@ static void calc_gf_params(VP8_COMP *cpi)
 
 static void calc_pframe_target_size(VP8_COMP *cpi)
 {
-    int min_frame_target, max_frame_target;
+    int min_frame_target;
     int Adjustment;
 
-    min_frame_target = 1;
+    min_frame_target = 0;
 
     if (cpi->pass == 2)
     {
@@ -616,19 +616,10 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
 
         if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5))
             min_frame_target = cpi->av_per_frame_bandwidth >> 5;
-
-        max_frame_target = INT_MAX;
     }
-    else
-    {
-        if (min_frame_target < cpi->per_frame_bandwidth / 4)
-            min_frame_target = cpi->per_frame_bandwidth / 4;
+    else if (min_frame_target < cpi->per_frame_bandwidth / 4)
+        min_frame_target = cpi->per_frame_bandwidth / 4;
 
-        /* Don't allow the target to completely deplete the buffer. */
-        max_frame_target = cpi->buffer_level + cpi->av_per_frame_bandwidth;
-        if(max_frame_target < min_frame_target)
-            max_frame_target = min_frame_target;
-    }
 
     // Special alt reference frame case
     if (cpi->common.refresh_alt_ref_frame)
@@ -1121,32 +1112,6 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
 
         }
     }
-
-    if (cpi->pass==0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER){
-        /* determine the accumulated error to apply to this frame. Apply
-         * more of the error when we've been undershooting, less when
-         * we've been overshooting
-         */
-        long long adjust;
-        int bitrate_error;
-
-        bitrate_error = cpi->av_per_frame_bandwidth
-                        - cpi->buffered_av_per_frame_bandwidth;
-
-        adjust = cpi->accumulated_overshoot;
-        adjust *= cpi->av_per_frame_bandwidth + bitrate_error;
-        adjust /= cpi->oxcf.maximum_buffer_size;
-        if (adjust > (cpi->this_frame_target - min_frame_target))
-            adjust = (cpi->this_frame_target - min_frame_target);
-        else if (adjust < 0)
-            adjust = 0;
-
-        cpi->this_frame_target -= adjust;
-        cpi->accumulated_overshoot -= adjust;
-    }
-
-    if(cpi->this_frame_target > max_frame_target)
-        cpi->this_frame_target = max_frame_target;
 }