]> granicus.if.org Git - libvpx/commitdiff
vp9-svc: Rate control fix for key base layer
authorMarco Paniconi <marpan@google.com>
Tue, 15 Jan 2019 01:02:59 +0000 (17:02 -0800)
committerMarco Paniconi <marpan@google.com>
Tue, 15 Jan 2019 03:49:42 +0000 (19:49 -0800)
After encoding key frame on base spatial layer,
if the overshoot is significant, reset the
avg_frame_qindex[INTER] on base spatial layer for
all temporal layers.

This forces the active_worst_quality to increase
on subsequent frames/layers and reduces frame dropping.

Change-Id: I53a3cd14131d69120e59a649b7ed1bfde3e940ee

vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_svc_layercontext.c
vp9/encoder/vp9_svc_layercontext.h

index 5ad68e2e58dfbacfea77287d6ee279cff150b6f1..4b9fb27548db542ee373da9cd9ab730d4b9e9958 100644 (file)
@@ -1800,6 +1800,8 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
     }
   }
 
+  if (cpi->use_svc) vp9_svc_adjust_avg_frame_qindex(cpi);
+
   // Keep record of last boosted (KF/KF/ARF) Q value.
   // If the current frame is coded at a lower Q then we also update it.
   // If all mbs in this group are skipped only update if the Q value is
index 3223f714b6ac83bd92686f78094b1062adefe9f6..35155c71fbe76f6b6b3a63b02681131bdda2432d 100644 (file)
@@ -1227,3 +1227,25 @@ void vp9_svc_adjust_frame_rate(VP9_COMP *const cpi) {
       cpi->svc.timebase_fac * cpi->svc.duration[cpi->svc.spatial_layer_id];
   vp9_new_framerate(cpi, 10000000.0 / this_duration);
 }
+
+void vp9_svc_adjust_avg_frame_qindex(VP9_COMP *const cpi) {
+  VP9_COMMON *const cm = &cpi->common;
+  SVC *const svc = &cpi->svc;
+  RATE_CONTROL *const rc = &cpi->rc;
+  // On key frames in CBR mode: reset the avg_frame_index for base layer
+  // (to level closer to worst_quality) if the overshoot is significant.
+  // Reset it for all temporal layers on base spatial layer.
+  if (cm->frame_type == KEY_FRAME && cpi->oxcf.rc_mode == VPX_CBR &&
+      rc->projected_frame_size > 3 * rc->avg_frame_bandwidth) {
+    int tl;
+    rc->avg_frame_qindex[INTER_FRAME] =
+        VPXMAX(rc->avg_frame_qindex[INTER_FRAME],
+               (cm->base_qindex + rc->worst_quality) >> 1);
+    for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
+      const int layer = LAYER_IDS_TO_IDX(0, tl, svc->number_temporal_layers);
+      LAYER_CONTEXT *lc = &svc->layer_context[layer];
+      RATE_CONTROL *lrc = &lc->rc;
+      lrc->avg_frame_qindex[INTER_FRAME] = rc->avg_frame_qindex[INTER_FRAME];
+    }
+  }
+}
index c2564461759496965df3a67646e6b825d132a40e..34795d8411f4b9e4f31c54a2a8c715c34c489a9b 100644 (file)
@@ -262,6 +262,7 @@ void vp9_svc_update_ref_frame(struct VP9_COMP *const cpi);
 
 void vp9_svc_adjust_frame_rate(struct VP9_COMP *const cpi);
 
+void vp9_svc_adjust_avg_frame_qindex(struct VP9_COMP *const cpi);
 #ifdef __cplusplus
 }  // extern "C"
 #endif