shithub: libvpx

Download patch

ref: 9ca6b46cef904799a1e66538df6f0a7e275ee734
parent: 9cc1f692bdbfcc1495b600eb1af2f7c0ffeb8abe
author: Marco <marpan@google.com>
date: Tue Apr 19 06:46:20 EDT 2016

vp9: Adjust gf period for high average Q and overshoot.

For 1 pass vbr mode.
Increase the gf interval for case where average Q is close to
max and high overshoot is detected.

Small increase in overall avg_psnr/sssim metrics (~0.2/0.1%) for ytlive,
but improves the low-end (low bitrate) for several clips (less overshoot).

Change-Id: Ifba40f25b4861b2e0d9832c82d5359a6a3dce9f2

--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -337,6 +337,7 @@
   rc->total_actual_bits = 0;
   rc->total_target_bits = 0;
   rc->total_target_vs_actual = 0;
+  rc->avg_intersize_gfint = 0;
 
   rc->frames_since_key = 8;  // Sensible default for first frame.
   rc->this_key_frame_forced = 0;
@@ -1419,6 +1420,10 @@
 
   rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
 
+  if (!cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+    rc->avg_intersize_gfint += rc->projected_frame_size;
+  }
+
   if (!cpi->use_svc || is_two_pass_svc(cpi)) {
     if (is_altref_enabled(cpi) && cpi->refresh_alt_ref_frame &&
         (cm->frame_type != KEY_FRAME))
@@ -1500,6 +1505,8 @@
     cm->frame_type = INTER_FRAME;
   }
   if (rc->frames_till_gf_update_due == 0) {
+    rc->avg_intersize_gfint =
+        rc->avg_intersize_gfint / (rc->baseline_gf_interval + 1);
     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0) {
       vp9_cyclic_refresh_set_golden_update(cpi);
     } else {
@@ -1510,6 +1517,13 @@
     if ((rc->frames_to_key <= 7 * rc->baseline_gf_interval >> 2) &&
         (rc->frames_to_key > rc->baseline_gf_interval)) {
       rc->baseline_gf_interval = rc->frames_to_key >> 1;
+    } else {
+      // Increase gf interval at high Q and high overshoot.
+      if (cm->current_video_frame > 30 &&
+          rc->avg_frame_qindex[INTER_FRAME] > (7 * rc->worst_quality) >> 3 &&
+          rc->avg_intersize_gfint > (5 * rc->avg_frame_bandwidth) >> 1) {
+          rc->baseline_gf_interval = (3 * rc->baseline_gf_interval) >> 1;
+      }
     }
     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
     // NOTE: frames_till_gf_update_due must be <= frames_to_key.
@@ -1522,6 +1536,7 @@
     cpi->refresh_golden_frame = 1;
     rc->source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS;
     rc->gfu_boost = DEFAULT_GF_BOOST;
+    rc->avg_intersize_gfint = 0;
   }
   if (cm->frame_type == KEY_FRAME)
     target = calc_iframe_target_size_one_pass_vbr(cpi);
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -162,6 +162,7 @@
   uint64_t avg_source_sad;
   int high_source_sad;
   int count_last_scene_change;
+  int avg_intersize_gfint;
 } RATE_CONTROL;
 
 struct VP9_COMP;