shithub: libvpx

Download patch

ref: a82f32d59b614cb692b3a2280f56b6327075aca1
parent: 9b73e21c0df8e13259bc9af461a65229d57aeb49
author: angiebird <angiebird@google.com>
date: Wed Oct 23 12:36:08 EDT 2019

Add get_gf_interval_active_range()

Change-Id: I94f3b93a932f351b6c9743932238d7ede2938462

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2458,6 +2458,11 @@
 
 #define MAX_GF_BOOST 5400
 
+typedef struct RANGE {
+  int min;
+  int max;
+} RANGE;
+
 static int get_gop_coding_frame_num(
     int *use_alt_ref, const FRAME_INFO *frame_info,
     const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc,
@@ -2571,6 +2576,50 @@
   return gop_coding_frames;
 }
 
+static RANGE get_active_gf_inverval_range(
+    const FRAME_INFO *frame_info, const RATE_CONTROL *rc, int arf_active_or_kf,
+    int gf_start_show_idx, int active_worst_quality, int last_boosted_qindex) {
+  RANGE active_gf_interval;
+  int int_max_q = (int)(vp9_convert_qindex_to_q(active_worst_quality,
+                                                frame_info->bit_depth));
+  int q_term = (gf_start_show_idx == 0)
+                   ? int_max_q / 32
+                   : (int)(vp9_convert_qindex_to_q(last_boosted_qindex,
+                                                   frame_info->bit_depth) /
+                           6);
+  active_gf_interval.min =
+      rc->min_gf_interval + arf_active_or_kf + VPXMIN(2, int_max_q / 200);
+  active_gf_interval.min =
+      VPXMIN(active_gf_interval.min, rc->max_gf_interval + arf_active_or_kf);
+
+  // The value chosen depends on the active Q range. At low Q we have
+  // bits to spare and are better with a smaller interval and smaller boost.
+  // At high Q when there are few bits to spare we are better with a longer
+  // interval to spread the cost of the GF.
+  active_gf_interval.max = 11 + arf_active_or_kf + VPXMIN(5, q_term);
+
+  // Force max GF interval to be odd.
+  active_gf_interval.max = active_gf_interval.max | 0x01;
+
+  // We have: active_gf_interval.min <=
+  // rc->max_gf_interval + arf_active_or_kf.
+  if (active_gf_interval.max < active_gf_interval.min) {
+    active_gf_interval.max = active_gf_interval.min;
+  } else {
+    active_gf_interval.max =
+        VPXMIN(active_gf_interval.max, rc->max_gf_interval + arf_active_or_kf);
+  }
+
+  // Would the active max drop us out just before the near the next kf?
+  if ((active_gf_interval.max <= rc->frames_to_key) &&
+      (active_gf_interval.max >= (rc->frames_to_key - rc->min_gf_interval))) {
+    active_gf_interval.max = rc->frames_to_key / 2;
+  }
+  active_gf_interval.max =
+      VPXMAX(active_gf_interval.max, active_gf_interval.min);
+  return active_gf_interval;
+}
+
 static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) {
   VP9_COMMON *const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
@@ -2592,8 +2641,6 @@
   int allow_alt_ref = is_altref_enabled(cpi);
   int use_alt_ref;
 
-  int active_max_gf_interval;
-  int active_min_gf_interval;
   int64_t gf_group_bits;
   int gf_arf_bits;
   const int is_key_frame = frame_is_intra_only(cm);
@@ -2604,6 +2651,7 @@
 
   double gop_intra_factor = 1.0;
   int gop_frames;
+  RANGE active_gf_interval;
 
   // Reset the GF group data structures unless this is a key
   // frame in which case it will already have been done.
@@ -2613,47 +2661,9 @@
 
   vpx_clear_system_state();
 
-  // Set a maximum and minimum interval for the GF group.
-  // If the image appears almost completely static we can extend beyond this.
-  {
-    int int_max_q = (int)(vp9_convert_qindex_to_q(twopass->active_worst_quality,
-                                                  cpi->common.bit_depth));
-    int q_term = (cm->current_video_frame == 0)
-                     ? int_max_q / 32
-                     : (int)(vp9_convert_qindex_to_q(rc->last_boosted_qindex,
-                                                     cpi->common.bit_depth) /
-                             6);
-    active_min_gf_interval =
-        rc->min_gf_interval + arf_active_or_kf + VPXMIN(2, int_max_q / 200);
-    active_min_gf_interval =
-        VPXMIN(active_min_gf_interval, rc->max_gf_interval + arf_active_or_kf);
-
-    // The value chosen depends on the active Q range. At low Q we have
-    // bits to spare and are better with a smaller interval and smaller boost.
-    // At high Q when there are few bits to spare we are better with a longer
-    // interval to spread the cost of the GF.
-    active_max_gf_interval = 11 + arf_active_or_kf + VPXMIN(5, q_term);
-
-    // Force max GF interval to be odd.
-    active_max_gf_interval = active_max_gf_interval | 0x01;
-
-    // We have: active_min_gf_interval <=
-    // rc->max_gf_interval + arf_active_or_kf.
-    if (active_max_gf_interval < active_min_gf_interval) {
-      active_max_gf_interval = active_min_gf_interval;
-    } else {
-      active_max_gf_interval = VPXMIN(active_max_gf_interval,
-                                      rc->max_gf_interval + arf_active_or_kf);
-    }
-
-    // Would the active max drop us out just before the near the next kf?
-    if ((active_max_gf_interval <= rc->frames_to_key) &&
-        (active_max_gf_interval >= (rc->frames_to_key - rc->min_gf_interval)))
-      active_max_gf_interval = rc->frames_to_key / 2;
-  }
-  active_max_gf_interval =
-      VPXMAX(active_max_gf_interval, active_min_gf_interval);
-
+  active_gf_interval = get_active_gf_inverval_range(
+      frame_info, rc, arf_active_or_kf, gf_start_show_idx,
+      twopass->active_worst_quality, rc->last_boosted_qindex);
   if (cpi->multi_layer_arf) {
     int layers = 0;
     int max_layers = VPXMIN(MAX_ARF_LAYERS, cpi->oxcf.enable_auto_arf);
@@ -2660,7 +2670,7 @@
     int i;
 
     // Adapt the intra_error factor to active_max_gf_interval limit.
-    for (i = active_max_gf_interval; i > 0; i >>= 1) ++layers;
+    for (i = active_gf_interval.max; i > 0; i >>= 1) ++layers;
 
     layers = VPXMIN(max_layers, layers);
     gop_intra_factor += (layers * 0.25);
@@ -2669,7 +2679,7 @@
   {
     gop_coding_frames = get_gop_coding_frame_num(
         &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx,
-        active_min_gf_interval, active_max_gf_interval, gop_intra_factor,
+        active_gf_interval.min, active_gf_interval.max, gop_intra_factor,
         cpi->oxcf.lag_in_frames);
     use_alt_ref &= allow_alt_ref;
   }