shithub: libvpx

Download patch

ref: 454877d8748fdbaa3d4e9bcd4994355d50dd6c6d
parent: 2be0ee5f05b3dc0782626b8b10894d5d920bcb96
parent: ab7974d36df5c548c8f3549545d12f42e2b274ce
author: Angie Chiang <angiebird@google.com>
date: Fri Oct 18 15:19:06 EDT 2019

Merge changes I2acc7d6b,I560dccfc,I3fb23f5c,Ifa24a501

* changes:
  Rename num_show_frames by num_coding_frames
  Use compute_arf_boost() in define_gf_group()
  Localize av_err mean_mod_score in define_gf_group
  Move code of deciding gop size into brackets

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2496,21 +2496,10 @@
   double gf_group_inter = 0.0;
   double gf_group_motion = 0.0;
 
-  double mv_ratio_accumulator = 0.0;
   double zero_motion_accumulator = 1.0;
-  double loop_decay_rate = 1.00;
 
-  double this_frame_mv_in_out = 0.0;
-  double mv_in_out_accumulator = 0.0;
-  double abs_mv_in_out_accumulator = 0.0;
-  double mv_ratio_accumulator_thresh;
-  double abs_mv_in_out_thresh;
-  double sr_accumulator = 0.0;
-  const double av_err = get_distribution_av_err(cpi, twopass);
-  const double mean_mod_score = twopass->mean_mod_score;
   unsigned int allow_alt_ref = is_altref_enabled(cpi);
 
-  int flash_detected;
   int active_max_gf_interval;
   int active_min_gf_interval;
   int64_t gf_group_bits;
@@ -2532,11 +2521,6 @@
 
   vpx_clear_system_state();
 
-  // Motion breakout threshold for loop below depends on image size.
-  mv_ratio_accumulator_thresh =
-      (cpi->initial_height + cpi->initial_width) / 4.0;
-  abs_mv_in_out_thresh = ARF_ABS_ZOOM_THRESH;
-
   // Set a maximum and minimum interval for the GF group.
   // If the image appears almost completely static we can extend beyond this.
   {
@@ -2590,88 +2574,102 @@
   }
 
   i = 0;
-  while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
-    const FIRSTPASS_STATS *next_next_frame;
-    const FIRSTPASS_STATS *next_frame;
-    ++i;
+  {
+    double loop_decay_rate = 1.00;
+    double mv_ratio_accumulator = 0.0;
+    double this_frame_mv_in_out = 0.0;
+    double mv_in_out_accumulator = 0.0;
+    double abs_mv_in_out_accumulator = 0.0;
+    double sr_accumulator = 0.0;
+    // Motion breakout threshold for loop below depends on image size.
+    double mv_ratio_accumulator_thresh =
+        (cpi->initial_height + cpi->initial_width) / 4.0;
 
-    next_frame = fps_get_frame_stats(first_pass_info, gf_start_show_idx + i);
-    if (next_frame == NULL) {
-      break;
-    }
+    while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
+      const FIRSTPASS_STATS *next_next_frame;
+      const FIRSTPASS_STATS *next_frame;
+      int flash_detected;
+      ++i;
 
-    // Test for the case where there is a brief flash but the prediction
-    // quality back to an earlier frame is then restored.
-    next_next_frame =
-        fps_get_frame_stats(first_pass_info, gf_start_show_idx + i + 1);
-    flash_detected = detect_flash_from_frame_stats(next_next_frame);
+      next_frame = fps_get_frame_stats(first_pass_info, gf_start_show_idx + i);
+      if (next_frame == NULL) {
+        break;
+      }
 
-    // Update the motion related elements to the boost calculation.
-    accumulate_frame_motion_stats(
-        next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
-        &abs_mv_in_out_accumulator, &mv_ratio_accumulator);
+      // Test for the case where there is a brief flash but the prediction
+      // quality back to an earlier frame is then restored.
+      next_next_frame =
+          fps_get_frame_stats(first_pass_info, gf_start_show_idx + i + 1);
+      flash_detected = detect_flash_from_frame_stats(next_next_frame);
 
-    // Monitor for static sections.
-    if ((rc->frames_since_key + i - 1) > 1) {
-      zero_motion_accumulator =
-          VPXMIN(zero_motion_accumulator,
-                 get_zero_motion_factor(frame_info, next_frame));
-    }
+      // Update the motion related elements to the boost calculation.
+      accumulate_frame_motion_stats(
+          next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
+          &abs_mv_in_out_accumulator, &mv_ratio_accumulator);
 
-    // Accumulate the effect of prediction quality decay.
-    if (!flash_detected) {
-      double last_loop_decay_rate = loop_decay_rate;
-      loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame);
+      // Monitor for static sections.
+      if ((rc->frames_since_key + i - 1) > 1) {
+        zero_motion_accumulator =
+            VPXMIN(zero_motion_accumulator,
+                   get_zero_motion_factor(frame_info, next_frame));
+      }
 
-      // Break clause to detect very still sections after motion. For example,
-      // a static image after a fade or other transition.
-      if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 &&
-          last_loop_decay_rate < 0.9) {
-        int still_interval = 5;
-        if (check_transition_to_still(first_pass_info, gf_start_show_idx + i,
-                                      still_interval)) {
-          allow_alt_ref = 0;
-          break;
+      // Accumulate the effect of prediction quality decay.
+      if (!flash_detected) {
+        double last_loop_decay_rate = loop_decay_rate;
+        loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame);
+
+        // Break clause to detect very still sections after motion. For example,
+        // a static image after a fade or other transition.
+        if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 &&
+            last_loop_decay_rate < 0.9) {
+          int still_interval = 5;
+          if (check_transition_to_still(first_pass_info, gf_start_show_idx + i,
+                                        still_interval)) {
+            allow_alt_ref = 0;
+            break;
+          }
         }
+
+        // Update the accumulator for second ref error difference.
+        // This is intended to give an indication of how much the coded error is
+        // increasing over time.
+        if (i == 1) {
+          sr_accumulator += next_frame->coded_error;
+        } else {
+          sr_accumulator +=
+              (next_frame->sr_coded_error - next_frame->coded_error);
+        }
       }
 
-      // Update the accumulator for second ref error difference.
-      // This is intended to give an indication of how much the coded error is
-      // increasing over time.
-      if (i == 1) {
-        sr_accumulator += next_frame->coded_error;
-      } else {
-        sr_accumulator +=
-            (next_frame->sr_coded_error - next_frame->coded_error);
+      // Break out conditions.
+      // Break at maximum of active_max_gf_interval unless almost totally
+      // static.
+      //
+      // Note that the addition of a test of rc->source_alt_ref_active is
+      // deliberate. The effect of this is that after a normal altref group even
+      // if the material is static there will be one normal length GF group
+      // before allowing longer GF groups. The reason for this is that in cases
+      // such as slide shows where slides are separated by a complex transition
+      // such as a fade, the arf group spanning the transition may not be coded
+      // at a very high quality and hence this frame (with its overlay) is a
+      // poor golden frame to use for an extended group.
+      if ((i >= active_max_gf_interval) &&
+          ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) {
+        break;
       }
+      if (
+          // Don't break out with a very short interval.
+          (i >= active_min_gf_interval) &&
+          // If possible dont break very close to a kf
+          ((rc->frames_to_key - i) >= rc->min_gf_interval) && (i & 0x01) &&
+          (!flash_detected) &&
+          ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) ||
+           (abs_mv_in_out_accumulator > ARF_ABS_ZOOM_THRESH) ||
+           (sr_accumulator > gop_intra_factor * next_frame->intra_error))) {
+        break;
+      }
     }
-
-    // Break out conditions.
-    // Break at maximum of active_max_gf_interval unless almost totally static.
-    //
-    // Note that the addition of a test of rc->source_alt_ref_active is
-    // deliberate. The effect of this is that after a normal altref group even
-    // if the material is static there will be one normal length GF group
-    // before allowing longer GF groups. The reason for this is that in cases
-    // such as slide shows where slides are separated by a complex transition
-    // such as a fade, the arf group spanning the transition may not be coded
-    // at a very high quality and hence this frame (with its overlay) is a
-    // poor golden frame to use for an extended group.
-    if ((i >= active_max_gf_interval) &&
-        ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) {
-      break;
-    }
-    if (
-        // Don't break out with a very short interval.
-        (i >= active_min_gf_interval) &&
-        // If possible dont break very close to a kf
-        ((rc->frames_to_key - i) >= rc->min_gf_interval) && (i & 0x01) &&
-        (!flash_detected) &&
-        ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) ||
-         (abs_mv_in_out_accumulator > abs_mv_in_out_thresh) ||
-         (sr_accumulator > gop_intra_factor * next_frame->intra_error))) {
-      break;
-    }
   }
 
   // Was the group length constrained by the requirement for a new KF?
@@ -2696,8 +2694,16 @@
                           b_frames, avg_inter_frame_qindex);
     rc->source_alt_ref_pending = 1;
   } else {
-    reset_fpf_position(twopass, start_pos);
-    rc->gfu_boost = VPXMIN(MAX_GF_BOOST, calc_arf_boost(cpi, (i - 1), 0));
+    const int f_frames = i - 1;
+    const int b_frames = 0;
+    const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME];
+    // TODO(angiebird): figure out why arf's location is assigned this way
+    const int gld_show_idx =
+        VPXMIN(gf_start_show_idx + 1, fps_get_num_frames(first_pass_info));
+    const int arf_boost =
+        compute_arf_boost(frame_info, first_pass_info, gld_show_idx, f_frames,
+                          b_frames, avg_inter_frame_qindex);
+    rc->gfu_boost = VPXMIN(MAX_GF_BOOST, arf_boost);
     rc->source_alt_ref_pending = 0;
   }
 
@@ -2742,18 +2748,17 @@
 
   rc->baseline_gf_interval = i - rc->source_alt_ref_pending;
 
-  // Reset the file position.
-  reset_fpf_position(twopass, start_pos);
-
   if (rc->source_alt_ref_pending)
     is_alt_ref_flash = detect_flash(twopass, rc->baseline_gf_interval);
 
   {
+    const double av_err = get_distribution_av_err(cpi, twopass);
+    const double mean_mod_score = twopass->mean_mod_score;
     // If the first frame is a key frame or the overlay from a previous arf then
     // the error score / cost of this frame has already been accounted for.
     int start_idx = arf_active_or_kf ? 1 : 0;
-    int num_show_frames = i;
-    for (j = start_idx; j < num_show_frames; ++j) {
+    int num_coding_frames = i;
+    for (j = start_idx; j < num_coding_frames; ++j) {
       int show_idx = gf_start_show_idx + j;
       const FIRSTPASS_STATS *frame_stats =
           fps_get_frame_stats(first_pass_info, show_idx);