]> granicus.if.org Git - libvpx/commitdiff
vp9: Changes for scene detection overshoot and SVC.
authorMarco Paniconi <marpan@google.com>
Mon, 16 Apr 2018 23:15:05 +0000 (16:15 -0700)
committerMarco Paniconi <marpan@google.com>
Wed, 18 Apr 2018 19:39:56 +0000 (12:39 -0700)
Refactor the scene detection for 1 pass cbr to allow the
scene detection to be checked once per superframe (on the base layer),
using the full resolution sources.

If scene change is detected: check for re-encoding due to
large overshoot for all spatial layers withing the superframe.

Add speed feature to control the re-encode step.
Keep the re-encode step on for now.

Small change in nonrd_pickmode to remove the possible skip of golden
reference for SVC, when the high_source_sad is set for the superframe.

Change only affects SVC encoding with screen-content mode enabled.

Change-Id: If4cfb52cb0dd0f0fce1c4214fa8b413f8f803d56

examples/vp9_spatial_svc_encoder.c
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_speed_features.c
vp9/encoder/vp9_speed_features.h
vp9/encoder/vp9_svc_layercontext.c
vp9/encoder/vp9_svc_layercontext.h

index 747f79ffba171402f21dbcf1ae21baa8766d6768..091c6954d12246fb448249894eb00d64ecde3fdb 100644 (file)
@@ -730,6 +730,8 @@ int main(int argc, const char **argv) {
 
   vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
 
+  vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
+
   // Encode frames
   while (!end_of_stream) {
     vpx_codec_iter_t iter = NULL;
index 31b6214aeb2a89d65ea848c713677fd9ba43c075..9ec539733356973a6b99514265062b8c1168f4e0 100644 (file)
@@ -3683,12 +3683,15 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
   // For other cases (e.g., CBR mode) use it for 5 <= speed < 8 for now
   // (need to check encoding time cost for doing this for speed 8).
   cpi->rc.high_source_sad = 0;
-  if (cpi->compute_source_sad_onepass && cm->show_frame &&
+  if (cm->show_frame &&
       (cpi->oxcf.rc_mode == VPX_VBR ||
        cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
        (cpi->oxcf.speed >= 5 && cpi->oxcf.speed < 8 && !cpi->use_svc)))
     vp9_scene_detection_onepass(cpi);
 
+  if (cpi->svc.spatial_layer_id == 0)
+    cpi->svc.high_source_sad_superframe = cpi->rc.high_source_sad;
+
   // 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).
@@ -3774,10 +3777,10 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
 
   // Check if we should drop this frame because of high overshoot.
   // Only for frames where high temporal-source SAD is detected.
-  if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
-      cpi->resize_state == ORIG && cm->frame_type != KEY_FRAME &&
-      cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
-      cpi->rc.high_source_sad == 1) {
+  // For SVC: all spatial layers are checked for re-encoding.
+  if (cpi->sf.re_encode_overshoot_rt &&
+      (cpi->rc.high_source_sad ||
+       (cpi->use_svc && cpi->svc.high_source_sad_superframe))) {
     int frame_size = 0;
     // Get an estimate of the encoded frame size.
     save_coding_context(cpi);
index a9c7c7d3d19728b8e294c44f4875743569ad6472..3aee4663683a0ea236b27ad4155d6e8a682d81bc 100644 (file)
@@ -1503,10 +1503,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
   int svc_mv_col = 0;
   int svc_mv_row = 0;
   unsigned int thresh_svc_skip_golden = 500;
+  if (cpi->svc.spatial_layer_id > 0 && cpi->svc.high_source_sad_superframe)
+    thresh_svc_skip_golden = 0;
   // Lower the skip threshold if lower spatial layer is better quality relative
   // to current layer.
-  if (cpi->svc.spatial_layer_id > 0 && cm->base_qindex > 150 &&
-      cm->base_qindex > cpi->svc.lower_layer_qindex + 15)
+  else if (cpi->svc.spatial_layer_id > 0 && cm->base_qindex > 150 &&
+           cm->base_qindex > cpi->svc.lower_layer_qindex + 15)
     thresh_svc_skip_golden = 100;
   // Increase skip threshold if lower spatial layer is lower quality relative
   // to current layer.
index c9632e904e024acd3f93c12a1bf8bf1c59f1716b..748a0ddd82d93f0399e2825c69a7fccde8e386c3 100644 (file)
@@ -2284,18 +2284,34 @@ static void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi,
 void vp9_scene_detection_onepass(VP9_COMP *cpi) {
   VP9_COMMON *const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
+  YV12_BUFFER_CONFIG const *unscaled_src = cpi->un_scaled_source;
+  YV12_BUFFER_CONFIG const *unscaled_last_src = cpi->unscaled_last_source;
+  uint8_t *src_y;
+  int src_ystride;
+  int src_width;
+  int src_height;
+  uint8_t *last_src_y;
+  int last_src_ystride;
+  int last_src_width;
+  int last_src_height;
+  if (cpi->un_scaled_source == NULL || cpi->unscaled_last_source == NULL ||
+      (cpi->use_svc && cpi->svc.current_superframe == 0))
+    return;
+  src_y = unscaled_src->y_buffer;
+  src_ystride = unscaled_src->y_stride;
+  src_width = unscaled_src->y_width;
+  src_height = unscaled_src->y_height;
+  last_src_y = unscaled_last_src->y_buffer;
+  last_src_ystride = unscaled_last_src->y_stride;
+  last_src_width = unscaled_last_src->y_width;
+  last_src_height = unscaled_last_src->y_height;
 #if CONFIG_VP9_HIGHBITDEPTH
   if (cm->use_highbitdepth) return;
 #endif
   rc->high_source_sad = 0;
-  if (cpi->Last_Source != NULL &&
-      cpi->Last_Source->y_width == cpi->Source->y_width &&
-      cpi->Last_Source->y_height == cpi->Source->y_height) {
+  if (cpi->svc.spatial_layer_id == 0 && src_width == last_src_width &&
+      src_height == last_src_height) {
     YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
-    uint8_t *src_y = cpi->Source->y_buffer;
-    int src_ystride = cpi->Source->y_stride;
-    uint8_t *last_src_y = cpi->Last_Source->y_buffer;
-    int last_src_ystride = cpi->Last_Source->y_stride;
     int start_frame = 0;
     int frames_to_buffer = 1;
     int frame = 0;
index b44f880988c079a8855c9693f31666c64bc1647e..c0f985cbda01b2fbc3d08f86641308a316518de5 100644 (file)
@@ -374,6 +374,7 @@ static void set_rt_speed_feature_framesize_independent(
   sf->use_compound_nonrd_pickmode = 0;
   sf->nonrd_keyframe = 0;
   sf->svc_use_lowres_part = 0;
+  sf->re_encode_overshoot_rt = 0;
 
   if (speed >= 1) {
     sf->allow_txfm_domain_distortion = 1;
@@ -534,6 +535,10 @@ static void set_rt_speed_feature_framesize_independent(
     // Keep nonrd_keyframe = 1 for non-base spatial layers to prevent
     // increase in encoding time.
     if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) sf->nonrd_keyframe = 1;
+    if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
+        cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG &&
+        cpi->oxcf.content == VP9E_CONTENT_SCREEN)
+      sf->re_encode_overshoot_rt = 1;
   }
 
   if (speed >= 6) {
index 50d52bc23a4be28b358b6b488b9a0102e6598c87..15e8dacbd5448bb24657a4747d723ff163abbc04 100644 (file)
@@ -508,6 +508,10 @@ typedef struct SPEED_FEATURES {
 
   // For SVC: enables use of partition from lower spatial resolution.
   int svc_use_lowres_part;
+
+  // Enable re-encoding on scene change with potential high overshoot,
+  // for real-time encoding flow.
+  int re_encode_overshoot_rt;
 } SPEED_FEATURES;
 
 struct VP9_COMP;
index 88b8daf4ca2371d9e870bf1456db80cd1fb37c88..42a197769ea3615bf1742ca16448f7c0c21aaaf3 100644 (file)
@@ -712,6 +712,8 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
     cpi->svc.non_reference_frame = 1;
   }
 
+  if (cpi->svc.spatial_layer_id == 0) cpi->svc.high_source_sad_superframe = 0;
+
   if (vp9_set_size_literal(cpi, width, height) != 0)
     return VPX_CODEC_INVALID_PARAM;
 
index a7fa26924f36b37900ab5aa4afab5d13ec17101f..022fd00f7950bc19708b26e8daa4d97a4047424e 100644 (file)
@@ -118,6 +118,11 @@ typedef struct SVC {
   SVC_LAYER_DROP_MODE framedrop_mode;
 
   INTER_LAYER_PRED disable_inter_layer_pred;
+
+  // Flag to indicate scene change at current superframe, scene detection is
+  // currently checked for each superframe prior to encoding, on the full
+  // resolution source.
+  int high_source_sad_superframe;
 } SVC;
 
 struct VP9_COMP;