]> granicus.if.org Git - libvpx/commitdiff
vp9-svc: Add max_consec_drop to SVC frame drop.
authorMarco Paniconi <marpan@google.com>
Thu, 24 May 2018 18:13:36 +0000 (11:13 -0700)
committerMarco Paniconi <marpan@google.com>
Thu, 24 May 2018 22:19:47 +0000 (15:19 -0700)
For any spatial, limits the amount of consecutive frame drop.

Change-Id: I692d90363f329f571f2b59e12cc680ad2e76065d

test/svc_datarate_test.cc
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_svc_layercontext.c
vp9/encoder/vp9_svc_layercontext.h
vp9/vp9_cx_iface.c
vpx/vp8cx.h

index cf26feb72a325fdaa373d5b890472683ff5fc9df..b9fbd8f4fc48545dfb2e31582d5bf80625e5fc78 100644 (file)
@@ -205,6 +205,7 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest {
         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);
       }
     }
index f5b7b1264bbf17a6839f46ac26b2c6ae371067d4..97e632165bc7c4480b3fdd7ace404b25ab898293 100644 (file)
@@ -4594,24 +4594,26 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
       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 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
           // 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;
index 94d8900c4b79b67d076f255ae594fbf590584537..f243be8dd7d231558ab89b19c8460051fedf9f88 100644 (file)
@@ -457,19 +457,26 @@ static int check_buffer_below_thresh(VP9_COMP *cpi, int drop_mark) {
 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 {
index ce31507b6ff05fa75a3e7a2424af621127740de1..d745ae0dfd3c4e397236a4ddcbde85ca6f28179a 100644 (file)
@@ -56,7 +56,9 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
     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,
index 367c93a2f604f62c2c25e028c896ed5fbb3d0d2a..9be5bb7ea2866ca9d6574c21b8081e69c2336675 100644 (file)
@@ -121,6 +121,8 @@ typedef struct SVC {
   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;
index d6c6ece9168f5c6d498bff8260756f48dea14542..443d896d75abe43661785a2c393d47fb53d53e67 100644 (file)
@@ -1536,6 +1536,7 @@ static vpx_codec_err_t ctrl_set_svc_frame_drop_layer(vpx_codec_alg_priv_t *ctx,
   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;
 }
 
index 97b8ba71c80aa85e0b7db98e1021135c59ee8773..44519e063811c8d883298ab8f74e342ac8dd30ff 100644 (file)
@@ -800,7 +800,8 @@ typedef enum {
 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 */