shithub: libvpx

Download patch

ref: b2f37bac65457d327002130a58d98ae2d2dcab7f
parent: 5fbc7a286b4d72883392fdbb10ec52bace662f66
author: Marco Paniconi <marpan@google.com>
date: Mon Dec 3 05:49:41 EST 2018

vp9: Overshoot detection for skipped base layer.

If scene/slide change is detected on current
superframe and max-q set because of high overshoot:
then if the lower/base spatial layer are skipped on
the current superframe, max-q is forced on the
next encoded base/lower spatial layers.

Change-Id: Id61efda86ee545395012e19476d19845e3932678

--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3832,9 +3832,10 @@
   if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) {
     svc->high_source_sad_superframe = cpi->rc.high_source_sad;
     // On scene change reset temporal layer pattern to TL0.
-    // TODO(marpan/jianj): Fix this to handle case where base
-    // spatial layers are skipped, in which case we should insert
-    // and reset to spatial layer 0 on scene change.
+    // Note that if the base/lower spatial layers are skipped: instead of
+    // inserting base layer here, we force max-q for the next superframe
+    // with lower spatial layers: this is done in vp9_encodedframe_overshoot()
+    // when max-q is decided for the current layer.
     if (svc->high_source_sad_superframe && svc->temporal_layer_id > 0) {
       // rc->high_source_sad will get reset so copy it to restore it.
       int tmp_high_source_sad = cpi->rc.high_source_sad;
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -3081,21 +3081,27 @@
       cpi->rc.rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
     }
     // For temporal layers, reset the rate control parametes across all
-    // temporal layers.
+    // temporal layers. If the first_spatial_layer_to_encode > 0, then this
+    // superframe has skipped lower base layers. So in this case we should also
+    // reset and force max-q for spatial layers < first_spatial_layer_to_encode.
     if (cpi->use_svc) {
-      int i = 0;
+      int tl = 0;
+      int sl = 0;
       SVC *svc = &cpi->svc;
-      for (i = 0; i < svc->number_temporal_layers; ++i) {
-        const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i,
-                                           svc->number_temporal_layers);
-        LAYER_CONTEXT *lc = &svc->layer_context[layer];
-        RATE_CONTROL *lrc = &lc->rc;
-        lrc->avg_frame_qindex[INTER_FRAME] = *q;
-        lrc->buffer_level = lrc->optimal_buffer_level;
-        lrc->bits_off_target = lrc->optimal_buffer_level;
-        lrc->rc_1_frame = 0;
-        lrc->rc_2_frame = 0;
-        lrc->rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
+      for (sl = 0; sl < svc->first_spatial_layer_to_encode; ++sl) {
+        for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
+          const int layer =
+              LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
+          LAYER_CONTEXT *lc = &svc->layer_context[layer];
+          RATE_CONTROL *lrc = &lc->rc;
+          lrc->avg_frame_qindex[INTER_FRAME] = *q;
+          lrc->buffer_level = lrc->optimal_buffer_level;
+          lrc->bits_off_target = lrc->optimal_buffer_level;
+          lrc->rc_1_frame = 0;
+          lrc->rc_2_frame = 0;
+          lrc->rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
+          lrc->force_max_q = 1;
+        }
       }
     }
     return 1;