From 7db01784570c676a5a2d4a73a5e3986a846e6491 Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Mon, 5 Nov 2018 17:49:39 -0800 Subject: [PATCH] vp9 screen-content: Adjustments for screen content. Increase search area, use NSTEP, and in some cases avoid bsize below 16x16. This for base spatial layer when many blocks in the frame have motion (from scene detection analysis). Improves quality for scrolling motion. Change-Id: If77b43e738a6c43610d4727a95712667088db564 --- vp9/encoder/vp9_encodeframe.c | 14 ++++++++++++++ vp9/encoder/vp9_ratectrl.c | 4 ++++ vp9/encoder/vp9_ratectrl.h | 1 + vp9/encoder/vp9_speed_features.c | 7 +++++++ 4 files changed, 26 insertions(+) diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index fb25fbc5c..4aae37706 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1378,6 +1378,20 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, x->sb_use_mv_part = 1; x->sb_mvcol_part = mi->mv[0].as_mv.col; x->sb_mvrow_part = mi->mv[0].as_mv.row; + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && + cpi->svc.spatial_layer_id == 0 && + cpi->rc.high_num_blocks_with_motion && !x->zero_temp_sad_source && + cm->width >= 1280 && cm->height >= 720) { + // Disable split below 16x16 block size when scroll motion is detected. + // TODO(marpan/jianj): Improve this condition: issue is that search + // range is hard-coded/limited in vp9_int_pro_motion_estimation() so + // scroll motion may not be detected here. + if ((abs(x->sb_mvrow_part) >= 48 && abs(x->sb_mvcol_part) <= 8) || + y_sad < 100000) { + compute_minmax_variance = 0; + thresholds[2] = INT64_MAX; + } + } } y_sad_last = y_sad; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index c8931ae82..b6526a262 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -363,6 +363,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { rc->high_source_sad = 0; rc->reset_high_source_sad = 0; rc->high_source_sad_lagindex = -1; + rc->high_num_blocks_with_motion = 0; rc->hybrid_intra_scene_change = 0; rc->re_encode_maxq_scene_change = 0; rc->alt_ref_gf_group = 0; @@ -2670,6 +2671,7 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) { if (cm->use_highbitdepth) return; #endif rc->high_source_sad = 0; + rc->high_num_blocks_with_motion = 0; 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 }; @@ -2788,6 +2790,8 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) { } else { rc->avg_source_sad[lagframe_idx] = avg_sad; } + if (num_zero_temp_sad < (num_samples >> 1)) + rc->high_num_blocks_with_motion = 1; } } // For CBR non-screen content mode, check if we should reset the rate diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index a9f75555e..4e827668b 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -175,6 +175,7 @@ typedef struct { uint64_t avg_source_sad[MAX_LAG_BUFFERS]; uint64_t prev_avg_source_sad_lag; int high_source_sad_lagindex; + int high_num_blocks_with_motion; int alt_ref_gf_group; int last_frame_is_src_altref; int high_source_sad; diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 1f9044265..2b0d5e146 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -794,6 +794,13 @@ static void set_rt_speed_feature_framesize_independent( sf->partition_search_type = FIXED_PARTITION; sf->always_this_block_size = BLOCK_64X64; } + // Special case for screen content: increase motion search when high motion + // is detected. + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && cpi->oxcf.speed > 5 && + cpi->rc.high_num_blocks_with_motion && cpi->svc.spatial_layer_id == 0) { + sf->mv.search_method = NSTEP; + sf->mv.fullpel_search_step_param = 2; + } } void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) { -- 2.40.0