]> granicus.if.org Git - libvpx/commitdiff
vp9-realtime: Move frame dropper to after scene detection.
authorMarco Paniconi <marpan@google.com>
Sat, 26 May 2018 04:51:33 +0000 (21:51 -0700)
committerMarco Paniconi <marpan@google.com>
Tue, 29 May 2018 05:21:40 +0000 (22:21 -0700)
Move frame dropper to after scene detection and noise estimation.
Scene detection and noise estimation operate on source data and
update metrics along sequence, so they should be moved before
the frame dropper.

Also we don't want to drop on scene change, as the scene detection
and (possible) re-encode step will be missed.

Change-Id: I3d9e16d785bd5ace6707db2abce77ddc110bfef4

vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_ratectrl.c

index b90bda7dffc3e88d156638615c9de08345351ecf..fca8f331d9a051cb1daeafad39d98ef26f9ca08c 100644 (file)
@@ -3612,8 +3612,8 @@ static void save_encode_params(VP9_COMP *cpi) {
 }
 #endif
 
-static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
-                                       uint8_t *dest) {
+static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
+                                      uint8_t *dest) {
   VP9_COMMON *const cm = &cpi->common;
   int q = 0, bottom_index = 0, top_index = 0;  // Dummy variables.
   const INTERP_FILTER filter_scaler =
@@ -3730,6 +3730,17 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
   if (cpi->svc.spatial_layer_id == 0)
     cpi->svc.high_source_sad_superframe = cpi->rc.high_source_sad;
 
+  // For 1 pass CBR, check if we are dropping this frame.
+  // Never drop on key frame, or if base layer is key for svc.
+  // Don't drop on scene change.
+  if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
+      cm->frame_type != KEY_FRAME && !cpi->rc.high_source_sad &&
+      !cpi->svc.high_source_sad_superframe &&
+      (!cpi->use_svc ||
+       !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) {
+    if (vp9_rc_drop_frame(cpi)) return 0;
+  }
+
   // For 1 pass CBR SVC, only ZEROMV is allowed for spatial reference frame
   // when svc->force_zero_mode_spatial_ref = 1. Under those conditions we can
   // avoid this frame-level upsampling (for non intra_only frames).
@@ -3836,6 +3847,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
   // seen in the last encoder iteration.
   // update_base_skip_probs(cpi);
   vpx_clear_system_state();
+  return 1;
 }
 
 #define MAX_QSTEP_ADJ 4
@@ -4589,57 +4601,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
     }
   }
 
-  // For 1 pass CBR, check if we are dropping this frame.
-  // Never drop on key frame, or if base layer is key for svc.
-  if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR &&
-      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 && svc->spatial_layer_id > 0 &&
-        svc->drop_spatial_layer[svc->spatial_layer_id - 1])
-      svc_prev_layer_dropped = 1;
-    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) {
-        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
-          // layer counter (which is incremented in vp9_inc_frame_in_layer())
-          // won't be incremented, so on a dropped frame we try the same
-          // temporal_layer_id on next incoming frame. This is to avoid an
-          // issue with temporal alignement with full superframe dropping.
-          vp9_inc_frame_in_layer(cpi);
-        }
-        if (svc->spatial_layer_id == svc->number_spatial_layers - 1) {
-          int i;
-          int all_layers_drop = 1;
-          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) svc->skip_enhancement_layer = 0;
-        }
-      }
-      return;
-    }
-  }
-
   vpx_clear_system_state();
 
 #if CONFIG_INTERNAL_STATS
@@ -4652,7 +4613,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
 #endif
 
   if (cpi->sf.recode_loop == DISALLOW_RECODE) {
-    encode_without_recode_loop(cpi, size, dest);
+    if (!encode_without_recode_loop(cpi, size, dest)) return;
   } else {
     encode_with_recode_loop(cpi, size, dest);
   }
index f243be8dd7d231558ab89b19c8460051fedf9f88..2c339ae255c056043cad2d6b9dd5166f780ce9e7 100644 (file)
@@ -454,7 +454,7 @@ static int check_buffer_below_thresh(VP9_COMP *cpi, int drop_mark) {
   }
 }
 
-int vp9_rc_drop_frame(VP9_COMP *cpi) {
+static int drop_frame(VP9_COMP *cpi) {
   const VP9EncoderConfig *oxcf = &cpi->oxcf;
   RATE_CONTROL *const rc = &cpi->rc;
   SVC *svc = &cpi->svc;
@@ -507,6 +507,53 @@ int vp9_rc_drop_frame(VP9_COMP *cpi) {
   }
 }
 
+int vp9_rc_drop_frame(VP9_COMP *cpi) {
+  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 && svc->spatial_layer_id > 0 &&
+      svc->drop_spatial_layer[svc->spatial_layer_id - 1])
+    svc_prev_layer_dropped = 1;
+  if ((svc_prev_layer_dropped && svc->framedrop_mode != LAYER_DROP) ||
+      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) {
+      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
+        // layer counter (which is incremented in vp9_inc_frame_in_layer())
+        // won't be incremented, so on a dropped frame we try the same
+        // temporal_layer_id on next incoming frame. This is to avoid an
+        // issue with temporal alignement with full superframe dropping.
+        vp9_inc_frame_in_layer(cpi);
+      }
+      if (svc->spatial_layer_id == svc->number_spatial_layers - 1) {
+        int i;
+        int all_layers_drop = 1;
+        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) svc->skip_enhancement_layer = 0;
+      }
+    }
+    return 1;
+  }
+  return 0;
+}
+
 static double get_rate_correction_factor(const VP9_COMP *cpi) {
   const RATE_CONTROL *const rc = &cpi->rc;
   double rcf;