From 25ca4edf74151dcd871c4012ac9748831526f49f Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Mon, 13 Aug 2018 09:20:21 -0700 Subject: [PATCH] vp9: Small refactor on overshoot detection, for cbr real-time. Change-Id: I70997d35a2371bb4614d716ef0c587fa12ea0f4a --- vp9/encoder/vp9_encoder.c | 4 ++-- vp9/encoder/vp9_ratectrl.c | 12 +++++++----- vp9/encoder/vp9_speed_features.c | 4 ++-- vp9/encoder/vp9_speed_features.h | 25 ++++++++++++++++--------- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 40ea13a9c..56dca855c 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3988,7 +3988,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, // Check if this high_source_sad (scene/slide change) frame should be // encoded at high/max QP, and if so, set the q and adjust some rate // control parameters. - if (cpi->sf.overshoot_detection_rt == 1 && + if (cpi->sf.overshoot_detection_cbr_rt == FAST_DETECTION_MAXQ && (cpi->rc.high_source_sad || (cpi->use_svc && cpi->svc.high_source_sad_superframe))) { if (vp9_encodedframe_overshoot(cpi, -1, &q)) { @@ -4023,7 +4023,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, // overshoot based on the encoded frame size. Only for frames where // high temporal-source SAD is detected. // For SVC: all spatial layers are checked for re-encoding. - if (cpi->sf.overshoot_detection_rt == 2 && + if (cpi->sf.overshoot_detection_cbr_rt == RE_ENCODE_MAXQ && (cpi->rc.high_source_sad || (cpi->use_svc && cpi->svc.high_source_sad_superframe))) { int frame_size = 0; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 64db18f09..a1a32f192 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -2825,11 +2825,13 @@ int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) { if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) thresh_qp = rc->worst_quality >> 1; // If this decision is not based on an encoded frame size but just on - // scene/slide change detection (i.e., re_encode_overshoot_rt = 1), - // for now skip the (frame_size > thresh_rate) condition in this case. + // scene/slide change detection (i.e., re_encode_overshoot_cbr_rt == + // FAST_DETECTION_MAXQ), for now skip the (frame_size > thresh_rate) + // condition in this case. // TODO(marpan): Use a better size/rate condition for this case and // adjust thresholds. - if ((sf->overshoot_detection_rt == 1 || frame_size > thresh_rate) && + if ((sf->overshoot_detection_cbr_rt == FAST_DETECTION_MAXQ || + frame_size > thresh_rate) && cm->base_qindex < thresh_qp) { double rate_correction_factor = cpi->rc.rate_correction_factors[INTER_NORMAL]; @@ -2846,8 +2848,8 @@ int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) { // and the encoded frame used alot of Intra modes, then force hybrid_intra // encoding for the re-encode on this scene change. hybrid_intra will // use rd-based intra mode selection for small blocks. - if (sf->overshoot_detection_rt == 2 && frame_size > (thresh_rate << 1) && - cpi->svc.spatial_layer_id == 0) { + if (sf->overshoot_detection_cbr_rt == RE_ENCODE_MAXQ && + frame_size > (thresh_rate << 1) && cpi->svc.spatial_layer_id == 0) { MODE_INFO **mi = cm->mi_grid_visible; int sum_intra_usage = 0; int mi_row, mi_col; diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 107da2194..d522a623b 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -405,7 +405,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->overshoot_detection_rt = 0; + sf->overshoot_detection_cbr_rt = NO_DETECTION; sf->disable_16x16part_nonkey = 0; sf->disable_golden_ref = 0; sf->enable_tpl_model = 0; @@ -572,7 +572,7 @@ static void set_rt_speed_feature_framesize_independent( if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) sf->nonrd_keyframe = 1; if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && cpi->oxcf.rc_mode == VPX_CBR) - sf->overshoot_detection_rt = 1; + sf->overshoot_detection_cbr_rt = FAST_DETECTION_MAXQ; if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0 && cm->width <= 1280 && cm->height <= 720) { sf->use_altref_onepass = 1; diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h index 7430f0a33..331ca49d7 100644 --- a/vp9/encoder/vp9_speed_features.h +++ b/vp9/encoder/vp9_speed_features.h @@ -222,6 +222,21 @@ typedef struct MESH_PATTERN { int interval; } MESH_PATTERN; +typedef enum { + // No reaction to rate control on a detected slide/scene change. + NO_DETECTION = 0, + + // Set to larger Q (max_q set by user) based only on the + // detected slide/scene change and current/past Q. + FAST_DETECTION_MAXQ = 1, + + // Based on (first pass) encoded frame, if large frame size is detected + // then set to higher Q for the second re-encode. This involves 2 pass + // encoding on slide change, so slower than 1, but more accurate for + // detecting overshoot. + RE_ENCODE_MAXQ = 2 +} OVERSHOOT_DETECTION_CBR_RT; + typedef struct SPEED_FEATURES { MV_SPEED_FEATURES mv; @@ -544,15 +559,7 @@ typedef struct SPEED_FEATURES { // Flag to indicate process for handling overshoot on slide/scene change, // for real-time CBR mode. - // 0: no reaction to rate control on a detected slide/scene change - // (prior to encoding the frame). - // 1: set to larger Q based only on the detected slide/scene change - // and current/past Q. No second pass encoding, so faster than option 2. - // 2: based on (first pass) encoded frame, if large frame size is detected - // then set to higher Q for second encode. This involves 2 pass encoding - // on slide change, so slower than 1, but more accurate for detecting - // overshoot. - int overshoot_detection_rt; + OVERSHOOT_DETECTION_CBR_RT overshoot_detection_cbr_rt; // Disable partitioning of 16x16 blocks. int disable_16x16part_nonkey; -- 2.40.0