shithub: libvpx

Download patch

ref: fc1c5d1c9cba8829995c68d07e827bc9bcccd9e8
parent: 8446af7e9a12c5725e845564f40272dd9185c1cc
author: Marco Paniconi <marpan@google.com>
date: Thu May 24 07:13:36 EDT 2018

vp9-svc: Add max_consec_drop to SVC frame drop.

For any spatial, limits the amount of consecutive frame drop.

Change-Id: I692d90363f329f571f2b59e12cc680ad2e76065d

--- a/test/svc_datarate_test.cc
+++ b/test/svc_datarate_test.cc
@@ -205,6 +205,7 @@
         svc_drop_frame.framedrop_mode = LAYER_DROP;
         for (i = 0; i < number_spatial_layers_; i++)
           svc_drop_frame.framedrop_thresh[i] = 30;
+        svc_drop_frame.max_consec_drop = 30;
         encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
       }
     }
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4594,24 +4594,26 @@
       cm->frame_type != KEY_FRAME &&
       (!cpi->use_svc ||
        !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) {
+    SVC *svc = &cpi->svc;
     int svc_prev_layer_dropped = 0;
     // In the constrained or full_superframe framedrop mode for svc
     // (framedrop_mode !=  LAYER_DROP), if the previous spatial layer was
     // dropped, drop the current spatial layer.
-    if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 &&
-        cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1])
+    if (cpi->use_svc && svc->spatial_layer_id > 0 &&
+        svc->drop_spatial_layer[svc->spatial_layer_id - 1])
       svc_prev_layer_dropped = 1;
-    if ((svc_prev_layer_dropped && cpi->svc.framedrop_mode != LAYER_DROP) ||
+    if ((svc_prev_layer_dropped && svc->framedrop_mode != LAYER_DROP) ||
         vp9_rc_drop_frame(cpi)) {
       vp9_rc_postencode_update_drop_frame(cpi);
       cpi->ext_refresh_frame_flags_pending = 0;
       cpi->last_frame_dropped = 1;
       if (cpi->use_svc) {
-        cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1;
-        cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1;
-        cpi->svc.skip_enhancement_layer = 1;
-        if (cpi->svc.framedrop_mode == LAYER_DROP ||
-            cpi->svc.drop_spatial_layer[0] == 0) {
+        svc->last_layer_dropped[svc->spatial_layer_id] = 1;
+        svc->drop_spatial_layer[svc->spatial_layer_id] = 1;
+        svc->drop_count[svc->spatial_layer_id]++;
+        svc->skip_enhancement_layer = 1;
+        if (svc->framedrop_mode == LAYER_DROP ||
+            svc->drop_spatial_layer[0] == 0) {
           // For the case of constrained drop mode where the base is dropped
           // (drop_spatial_layer[0] == 1), which means full superframe dropped,
           // we don't increment the svc frame counters. In particular temporal
@@ -4621,16 +4623,16 @@
           // issue with temporal alignement with full superframe dropping.
           vp9_inc_frame_in_layer(cpi);
         }
-        if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
+        if (svc->spatial_layer_id == svc->number_spatial_layers - 1) {
           int i;
           int all_layers_drop = 1;
-          for (i = 0; i < cpi->svc.spatial_layer_id; i++) {
-            if (cpi->svc.drop_spatial_layer[i] == 0) {
+          for (i = 0; i < svc->spatial_layer_id; i++) {
+            if (svc->drop_spatial_layer[i] == 0) {
               all_layers_drop = 0;
               break;
             }
           }
-          if (all_layers_drop == 1) cpi->svc.skip_enhancement_layer = 0;
+          if (all_layers_drop == 1) svc->skip_enhancement_layer = 0;
         }
       }
       return;
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -457,19 +457,26 @@
 int vp9_rc_drop_frame(VP9_COMP *cpi) {
   const VP9EncoderConfig *oxcf = &cpi->oxcf;
   RATE_CONTROL *const rc = &cpi->rc;
+  SVC *svc = &cpi->svc;
   int drop_frames_water_mark = oxcf->drop_frames_water_mark;
-  if (cpi->use_svc)
-    drop_frames_water_mark =
-        cpi->svc.framedrop_thresh[cpi->svc.spatial_layer_id];
+  if (cpi->use_svc) {
+    // If we have dropped max_consec_drop frames, then we don't
+    // drop this spatial layer, and reset counter to 0.
+    if (svc->drop_count[svc->spatial_layer_id] == svc->max_consec_drop) {
+      svc->drop_count[svc->spatial_layer_id] = 0;
+      return 0;
+    } else {
+      drop_frames_water_mark = svc->framedrop_thresh[svc->spatial_layer_id];
+    }
+  }
   if (!drop_frames_water_mark ||
-      (cpi->svc.spatial_layer_id > 0 &&
-       cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP)) {
+      (svc->spatial_layer_id > 0 &&
+       svc->framedrop_mode == FULL_SUPERFRAME_DROP)) {
     return 0;
   } else {
-    if ((rc->buffer_level < 0 &&
-         cpi->svc.framedrop_mode != FULL_SUPERFRAME_DROP) ||
+    if ((rc->buffer_level < 0 && svc->framedrop_mode != FULL_SUPERFRAME_DROP) ||
         (check_buffer_below_thresh(cpi, -1) &&
-         cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP)) {
+         svc->framedrop_mode == FULL_SUPERFRAME_DROP)) {
       // Always drop if buffer is below 0.
       return 1;
     } else {
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -56,7 +56,9 @@
     svc->downsample_filter_phase[sl] = 8;  // Set to 8 for averaging filter.
     svc->framedrop_thresh[sl] = oxcf->drop_frames_water_mark;
     svc->fb_idx_upd_tl0[sl] = -1;
+    svc->drop_count[sl] = 0;
   }
+  svc->max_consec_drop = INT_MAX;
 
   if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
     if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, SMALL_FRAME_WIDTH,
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -121,6 +121,8 @@
   int last_layer_dropped[VPX_MAX_LAYERS];
   int drop_spatial_layer[VPX_MAX_LAYERS];
   int framedrop_thresh[VPX_MAX_LAYERS];
+  int drop_count[VPX_MAX_LAYERS];
+  int max_consec_drop;
   SVC_LAYER_DROP_MODE framedrop_mode;
 
   INTER_LAYER_PRED disable_inter_layer_pred;
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -1536,6 +1536,7 @@
   cpi->svc.framedrop_mode = data->framedrop_mode;
   for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl)
     cpi->svc.framedrop_thresh[sl] = data->framedrop_thresh[sl];
+  cpi->svc.max_consec_drop = data->max_consec_drop;
   return VPX_CODEC_OK;
 }
 
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -800,7 +800,8 @@
 typedef struct vpx_svc_frame_drop {
   int framedrop_thresh[VPX_SS_MAX_LAYERS]; /**< Frame drop thresholds */
   SVC_LAYER_DROP_MODE
-  framedrop_mode; /**< Layer-based or constrained dropping. */
+  framedrop_mode;      /**< Layer-based or constrained dropping. */
+  int max_consec_drop; /**< Maximum consecutive drops, for any layer. */
 } vpx_svc_frame_drop_t;
 
 /*!\cond */