vp9-svc: Modify logic for frame dropping with spatial layers.
authorMarco Paniconi <marpan@google.com>
Wed, 28 Mar 2018 19:09:54 +0000 (12:09 -0700)
committerMarco Paniconi <marpan@google.com>
Wed, 28 Mar 2018 20:00:00 +0000 (13:00 -0700)
In the constrained framedrop mode for svc: modify the buffer check
condition relative to (non-zero) dropmark to include uppper spatial layers,
in addition to the current spatial layer.

But keep the single layer check if the buffer goes below zero, since
in this case (buffer underflow) we should force drop of that layer
regardless of upper layers.

Change-Id: Id277f0b4a3ae6275effdd5f5f0c80e3229c17424

vp9/encoder/vp9_ratectrl.c

index ced42fb..d6d5db4 100644 (file)
@@ -393,6 +393,29 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
   rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
 }
 
+static int check_buffer(VP9_COMP *cpi, int drop_mark) {
+  SVC *svc = &cpi->svc;
+  if (!cpi->use_svc || !cpi->svc.framedrop_mode) {
+    RATE_CONTROL *const rc = &cpi->rc;
+    return (rc->buffer_level <= drop_mark);
+  } else {
+    int i;
+    // For SVC in the constrained framedrop mode (svc->framedrop_mode = 1):
+    // the condition on buffer (to drop frame) is checked on current and
+    // upper spatial layers.
+    for (i = svc->spatial_layer_id; i < svc->number_spatial_layers; ++i) {
+      const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id,
+                                         svc->number_temporal_layers);
+      LAYER_CONTEXT *lc = &svc->layer_context[layer];
+      RATE_CONTROL *lrc = &lc->rc;
+      const int drop_mark_layer =
+          (int)(cpi->svc.framedrop_thresh[i] * lrc->optimal_buffer_level / 100);
+      if (!(lrc->buffer_level <= drop_mark_layer)) return 0;
+    }
+    return 1;
+  }
+}
+
 int vp9_rc_drop_frame(VP9_COMP *cpi) {
   const VP9EncoderConfig *oxcf = &cpi->oxcf;
   RATE_CONTROL *const rc = &cpi->rc;
@@ -413,7 +436,7 @@ int vp9_rc_drop_frame(VP9_COMP *cpi) {
           (int)(drop_frames_water_mark * rc->optimal_buffer_level / 100);
       if ((rc->buffer_level > drop_mark) && (rc->decimation_factor > 0)) {
         --rc->decimation_factor;
-      } else if (rc->buffer_level <= drop_mark && rc->decimation_factor == 0) {
+      } else if (check_buffer(cpi, drop_mark) && rc->decimation_factor == 0) {
         rc->decimation_factor = 1;
       }
       if (rc->decimation_factor > 0) {