shithub: libvpx

Download patch

ref: fba011507b1ee160caa82488cfeb4c7ad9471341
parent: b1284dffdb16b82e940e39b226b656801c83289b
author: Marco Paniconi <marpan@google.com>
date: Wed Jul 18 10:36:17 EDT 2018

vp9: Screen-content after slide-change: increase refresh rate

For screen-content real-time CBR mode: on a detected slide change
that is encoded at max Q (to prevent excessive overshoot), increase
the perc_refresh in the cyclic refresh following the slide change.
Use counter to increase refresh up to some #frames from slide change.

This is attempt to increase quality ramp-up after slide change without
causing too much excess overshoot.

Change-Id: Ie4ec4361082803a522f4a8794b3bb0178c9cf307

--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -39,6 +39,7 @@
   }
   assert(MAXQ <= 255);
   memset(cr->last_coded_q_map, MAXQ, last_coded_q_map_size);
+  cr->counter_encode_maxq_scene_change = 0;
   return cr;
 }
 
@@ -466,6 +467,9 @@
   // TODO(marpan): Consider increasing refresh rate after slide change.
   if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) {
     cr->percent_refresh = 10;
+    // Increase the amount of refresh on scene change that is encoded at max Q,
+    // increase for a few cycles of the refresh period (~30 frames).
+    if (cr->counter_encode_maxq_scene_change < 30) cr->percent_refresh = 15;
     cr->rate_ratio_qdelta = 2.0;
     cr->rate_boost_fac = 10;
   }
@@ -533,6 +537,7 @@
              cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map));
       cr->sb_index = 0;
       cr->reduce_refresh = 0;
+      cr->counter_encode_maxq_scene_change = 0;
     }
     return;
   } else {
@@ -539,6 +544,7 @@
     int qindex_delta = 0;
     int qindex2;
     const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth);
+    cr->counter_encode_maxq_scene_change++;
     vpx_clear_system_state();
     // Set rate threshold to some multiple (set to 2 for now) of the target
     // rate (target is given by sb64_target_rate and scaled by 256).
@@ -606,6 +612,7 @@
   cr->sb_index = 0;
   cpi->refresh_golden_frame = 1;
   cpi->refresh_alt_ref_frame = 1;
+  cr->counter_encode_maxq_scene_change = 0;
 }
 
 void vp9_cyclic_refresh_limit_q(const VP9_COMP *cpi, int *q) {
--- a/vp9/encoder/vp9_aq_cyclicrefresh.h
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.h
@@ -68,6 +68,7 @@
   int reduce_refresh;
   double weight_segment;
   int apply_cyclic_refresh;
+  int counter_encode_maxq_scene_change;
 };
 
 struct VP9_COMP;
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -2809,6 +2809,7 @@
     int enumerator;
     // Force a re-encode, and for now use max-QP.
     *q = cpi->rc.worst_quality;
+    cpi->cyclic_refresh->counter_encode_maxq_scene_change = 0;
     // If the frame_size is much larger than the threshold (big content change)
     // and the encoded frame used alot of Intra modes, then force hybrid_intra
     // encoding for the re-encode on this scene change. hybrid_intra will