Key frame and GF sizing changes.
authorPaul Wilkins <paulwilkins@google.com>
Thu, 7 Jun 2012 12:39:20 +0000 (13:39 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Fri, 8 Jun 2012 09:49:22 +0000 (10:49 +0100)
Changes to the equations for kf and gf minQ and to
the boost calculations for kg and gf

Change-Id: I312031c910e6a575334f49075c32f49a8dfff239

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

index 8c7818c..a89ef12 100644 (file)
@@ -52,8 +52,8 @@ extern void vp8_alloc_compressor_data(VP8_COMP *cpi);
 
 #define IIFACTOR   12.5
 #define IIKFACTOR1 12.5
-#define IIKFACTOR2 12.5
-#define RMAX       96.0
+#define IIKFACTOR2 15.0
+#define RMAX       128.0
 #define GF_RMAX    96.0
 #define ERR_DIVISOR   150.0
 
@@ -1716,8 +1716,12 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             decay_accumulator = decay_accumulator * loop_decay_rate;
 
             // Monitor for static sections.
-            zero_motion_accumulator *=
-                (next_frame.pcnt_inter - next_frame.pcnt_motion);
+            if ( (next_frame.pcnt_inter - next_frame.pcnt_motion) <
+                 zero_motion_accumulator )
+            {
+                zero_motion_accumulator =
+                    (next_frame.pcnt_inter - next_frame.pcnt_motion);
+            }
 
             // Break clause to detect very still sections after motion
             // (for example a staic image after a fade or other transition).
@@ -2525,7 +2529,7 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
     boost_score = 0.0;
     loop_decay_rate = 1.00;       // Starting decay rate
 
-    for (i = 0 ; i < cpi->twopass.frames_to_key ; i++)
+    for (i = 0; i < cpi->twopass.frames_to_key; i++)
     {
         double r;
 
@@ -2543,8 +2547,12 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             r = RMAX;
 
         // Monitor for static sections.
-        zero_motion_accumulator *=
-            (next_frame.pcnt_inter - next_frame.pcnt_motion);
+        if ( (next_frame.pcnt_inter - next_frame.pcnt_motion) <
+             zero_motion_accumulator )
+        {
+            zero_motion_accumulator =
+                (next_frame.pcnt_inter - next_frame.pcnt_motion);
+        }
 
         // How fast is prediction quality decaying
         loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
@@ -2582,15 +2590,14 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
                 kf_boost = 300;
         }
 
-        // bigger frame sizes need larger kf boosts, smaller frames smaller boosts...
-        if ((lst_yv12->y_width * lst_yv12->y_height) > (320 * 240))
-            kf_boost += 12 * (lst_yv12->y_width * lst_yv12->y_height) / (320 * 240);
-        else if ((lst_yv12->y_width * lst_yv12->y_height) < (320 * 240))
-            kf_boost -= 25 * (320 * 240) / (lst_yv12->y_width * lst_yv12->y_height);
-
         if (kf_boost < 250)                                                      // Min KF boost
             kf_boost = 250;
 
+        // Make a not of baseline boost and the zero motion
+        // accumulator value for use elsewhere.
+        cpi->kf_boost = kf_boost;
+        cpi->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0);
+
         // We do three calculations for kf size.
         // The first is based on the error score for the whole kf group.
         // The second (optionaly) on the key frames own error if this is
index a66e71a..3896d97 100644 (file)
@@ -181,7 +181,6 @@ int vp8cx_base_skip_false_prob[QINDEX_RANGE];
 static int kf_low_motion_minq[QINDEX_RANGE];
 static int kf_high_motion_minq[QINDEX_RANGE];
 static int gf_low_motion_minq[QINDEX_RANGE];
-static int gf_mid_motion_minq[QINDEX_RANGE];
 static int gf_high_motion_minq[QINDEX_RANGE];
 static int inter_minq[QINDEX_RANGE];
 
@@ -227,26 +226,20 @@ void init_minq_luts()
                                                       -0.000015,
                                                       0.074,
                                                       0.0 );
-
         kf_high_motion_minq[i] = calculate_minq_index( maxq,
-                                                       0.00000034,
+                                                       0.0000004,
                                                        -0.000125,
-                                                       0.13,
+                                                       0.14,
                                                        0.0 );
         gf_low_motion_minq[i] = calculate_minq_index( maxq,
-                                                      0.0000016,
-                                                      -0.00078,
-                                                      0.315,
-                                                      0.0 );
-        gf_mid_motion_minq[i] = calculate_minq_index( maxq,
-                                                      0.00000415,
-                                                      -0.0017,
-                                                      0.425,
+                                                      0.0000015,
+                                                      -0.0009,
+                                                      0.33,
                                                       0.0 );
         gf_high_motion_minq[i] = calculate_minq_index( maxq,
-                                                       0.00000725,
-                                                       -0.00235,
-                                                       0.47,
+                                                       0.0000021,
+                                                       -0.00125,
+                                                       0.45,
                                                        0.0  );
         inter_minq[i] = calculate_minq_index( maxq,
                                               0.00000271,
@@ -3016,10 +3009,28 @@ static void encode_frame_to_data_rate
 
     if ( cm->frame_type == KEY_FRAME )
     {
-        if (cpi->gfu_boost > 600)
-           cpi->active_best_quality = kf_low_motion_minq[Q];
+        int high = 2000;
+        int low = 400;
+
+        if ( cpi->kf_boost > high )
+            cpi->active_best_quality = kf_low_motion_minq[Q];
+        else if ( cpi->kf_boost < low )
+            cpi->active_best_quality = kf_high_motion_minq[Q];
         else
-           cpi->active_best_quality = kf_high_motion_minq[Q];
+        {
+            int gap = high - low;
+            int offset = high - cpi->kf_boost;
+            int qdiff = kf_high_motion_minq[Q] - kf_low_motion_minq[Q];
+            int adjustment = ((offset * qdiff) + (gap>>1)) / gap;
+
+            cpi->active_best_quality = kf_low_motion_minq[Q] + adjustment;
+        }
+
+        // Make an adjustment based on the %s static
+        // The main impact of this is at lower Q to prevent overly large key
+        // frames unless a lot of the image is static.
+        if (cpi->kf_zeromotion_pct < 64 )
+            cpi->active_best_quality += 4 - (cpi->kf_zeromotion_pct >> 4);
 
         // Special case for key frames forced because we have reached
         // the maximum key frame interval. Here force the Q to a range
@@ -3040,6 +3051,9 @@ static void encode_frame_to_data_rate
 
     else if (cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame)
     {
+        int high = 2000;
+        int low = 400;
+
         // Use the lower of cpi->active_worst_quality and recent
         // average Q as basis for GF/ARF Q limit unless last frame was
         // a key frame.
@@ -3056,12 +3070,19 @@ static void encode_frame_to_data_rate
             Q = cpi->cq_target_quality;
         }
 
-        if ( cpi->gfu_boost > 1000 )
+        if ( cpi->gfu_boost > high )
             cpi->active_best_quality = gf_low_motion_minq[Q];
-        else if ( cpi->gfu_boost < 400 )
+        else if ( cpi->gfu_boost < low )
             cpi->active_best_quality = gf_high_motion_minq[Q];
         else
-            cpi->active_best_quality = gf_mid_motion_minq[Q];
+        {
+            int gap = high - low;
+            int offset = high - cpi->gfu_boost;
+            int qdiff = gf_high_motion_minq[Q] - gf_low_motion_minq[Q];
+            int adjustment = ((offset * qdiff) + (gap>>1)) / gap;
+
+            cpi->active_best_quality = gf_low_motion_minq[Q] + adjustment;
+        }
 
         // Constrained quality use slightly lower active best.
         if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
@@ -3765,7 +3786,7 @@ static void encode_frame_to_data_rate
     // in this frame.
     update_base_skip_probs( cpi );
 
-#if 0 && CONFIG_INTERNAL_STATS
+#if 1 && CONFIG_INTERNAL_STATS
     {
         FILE *f = fopen("tmp.stt", "a");
         int recon_err;
@@ -3780,7 +3801,7 @@ static void encode_frame_to_data_rate
             fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d"
                        "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f"
                        "%6d %5d %5d %5d %8d %8.2f %10d %10.3f"
-                       "%10.3f %8d %10d\n",
+                       "%10.3f %8d %10d %10d %10d\n",
                        cpi->common.current_video_frame, cpi->this_frame_target,
                        cpi->projected_frame_size, loop_size_estimate,
                        (cpi->projected_frame_size - cpi->this_frame_target),
@@ -3803,12 +3824,13 @@ static void encode_frame_to_data_rate
                        cpi->twopass.total_left_stats->coded_error,
                        (double)cpi->twopass.bits_left /
                            cpi->twopass.total_left_stats->coded_error,
-                       cpi->tot_recode_hits, recon_err);
+                       cpi->tot_recode_hits, recon_err, cpi->kf_boost,
+                       cpi->kf_zeromotion_pct);
         else
             fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d"
                        "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f"
                        "%6d %5d %5d %5d %8d %8.2f %10d %10.3f"
-                       "%8d %10d\n",
+                       "%8d %10d %10d %10d\n",
                        cpi->common.current_video_frame,
                        cpi->this_frame_target, cpi->projected_frame_size,
                        loop_size_estimate,
@@ -3830,7 +3852,8 @@ static void encode_frame_to_data_rate
                        cpi->twopass.est_max_qcorrection_factor,
                        (int)cpi->twopass.bits_left,
                        cpi->twopass.total_left_stats->coded_error,
-                       cpi->tot_recode_hits, recon_err);
+                       cpi->tot_recode_hits, recon_err, cpi->kf_boost,
+                       cpi->kf_zeromotion_pct);
 
         fclose(f);
 
index b181a60..580b044 100644 (file)
@@ -471,8 +471,9 @@ typedef struct VP8_COMP
     unsigned int frame_branch_ct_8x8 [BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES][2];
 
     int gfu_boost;
-    int kf_boost;
     int last_boost;
+    int kf_boost;
+    int kf_zeromotion_pct;
 
     int target_bandwidth;
     struct vpx_codec_pkt_list  *output_pkt_list;