shithub: libvpx

Download patch

ref: 958f372509a7678d787cffeed40e7886a116e27a
parent: 6261fcf3073f190ca9d05a96873032acdf417c9e
author: Marco <marpan@google.com>
date: Thu Feb 18 07:16:01 EST 2016

vp9: 1 pass vbr real-time mode: Adjust gf refresh for scene change.

Use the existing scene/content change detection to better
update/adjust golden frame refresh.

Change only affects 1 pass real-time vbr mode, speed >=5.

Change-Id: I2963a5bb7ca4a19f8cf8511b0a925e502f60e014

--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3363,11 +3363,13 @@
                                       (cpi->oxcf.pass == 0));
 
   // Avoid scaling last_source unless its needed.
-  // Last source is currently only used for screen-content mode,
-  // if partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
+  // Last source is needed if vp9_avg_source_sad() is used, or if
+  // partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
   // estimation is enabled.
   if (cpi->unscaled_last_source != NULL &&
       (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+      (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR &&
+      cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5) ||
       cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION ||
       cpi->noise_estimate.enabled))
     cpi->Last_Source = vp9_scale_if_required(cm,
@@ -3377,10 +3379,12 @@
   vp9_update_noise_estimate(cpi);
 
   if (cpi->oxcf.pass == 0 &&
-      cpi->oxcf.rc_mode == VPX_CBR &&
+      cpi->oxcf.mode == REALTIME &&
+      cpi->oxcf.speed >= 5 &&
       cpi->resize_state == 0 &&
       cm->frame_type != KEY_FRAME &&
-      cpi->oxcf.content == VP9E_CONTENT_SCREEN)
+      (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
+       cpi->oxcf.rc_mode == VPX_VBR))
     vp9_avg_source_sad(cpi);
 
   // TODO(wonkap/marpan): For 1 pass SVC, since only ZERMOV is allowed for
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -2017,6 +2017,8 @@
     const int last_src_ystride = cpi->Last_Source->y_stride;
     int sbi_row, sbi_col;
     const BLOCK_SIZE bsize = BLOCK_64X64;
+    const uint32_t min_thresh = 4000;
+    float thresh = 8.0f;
     // Loop over sub-sample of frame, and compute average sad over 64x64 blocks.
     uint64_t avg_sad = 0;
     int num_samples = 0;
@@ -2047,12 +2049,30 @@
     // between current and the previous frame value(s). Use a minimum threshold
     // for cases where there is small change from content that is completely
     // static.
-    if (avg_sad > VPXMAX(4000, (rc->avg_source_sad << 3)) &&
+    if (cpi->oxcf.rc_mode == VPX_VBR) {
+      thresh = 2.5f;
+    }
+    if (avg_sad >
+        VPXMAX(min_thresh, (unsigned int)(rc->avg_source_sad  * thresh)) &&
         rc->frames_since_key > 1)
       rc->high_source_sad = 1;
     else
       rc->high_source_sad = 0;
     rc->avg_source_sad = (rc->avg_source_sad + avg_sad) >> 1;
+    // For VBR, under scene change/high content change, force golden refresh.
+    if (cpi->oxcf.rc_mode == VPX_VBR &&
+        rc->high_source_sad &&
+        cpi->refresh_golden_frame == 0 &&
+        cpi->ext_refresh_frame_flags_pending == 0) {
+      int target;
+      cpi->refresh_golden_frame = 1;
+      rc->frames_till_gf_update_due = rc->baseline_gf_interval >> 1;
+      if (rc->frames_till_gf_update_due > rc->frames_to_key)
+        rc->frames_till_gf_update_due = rc->frames_to_key;
+      rc->gfu_boost = DEFAULT_GF_BOOST;
+      target = calc_pframe_target_size_one_pass_vbr(cpi);
+      vp9_rc_set_frame_target(cpi, target);
+    }
   }
 }