From: Yaowu Xu Date: Tue, 20 May 2014 18:36:44 +0000 (-0700) Subject: Enable various thresholds of motion detection X-Git-Tag: v1.4.0~1521^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3bda7ec1bab9b7336cf3218d1e7596f79930208c;p=libvpx Enable various thresholds of motion detection This commit changed to enable the encoder to adjust motion dection speed threshold based on picture size. In addition, cpu-used 1 now does a partition search every other frame instead of every third frame for low resolution inputs. The change has no quality/speed impact for 720p and above. Test showed the change increase encoding time by between 3% to 6% for cpu-used 2 encodiong of 360p sequences. It also has a compression gain about .3%. For cpu-used 2, the change resolved some very disturbing visual artifacts in certain sequences when large block partitionings and transforms are used as a result of copying the partition from a previous frame. Change-Id: Ic7fd22508cdb811d4ca935655adbf20109286cfa --- diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index f7cb05b78..73e32ce68 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1312,7 +1312,8 @@ static int is_background(VP9_COMP *cpi, const TileInfo *const tile, return x->in_static_area; } -static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { +static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8, + const int motion_thresh) { const int mis = cm->mi_stride; int block_row, block_col; @@ -1321,8 +1322,8 @@ static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { for (block_col = 0; block_col < 8; ++block_col) { const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col]; if (prev_mi) { - if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 || - abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8) + if (abs(prev_mi->mbmi.mv[0].as_mv.row) > motion_thresh || + abs(prev_mi->mbmi.mv[0].as_mv.col) > motion_thresh) return 1; } } @@ -2318,7 +2319,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, || cpi->rc.is_src_frame_alt_ref || ((sf->use_lastframe_partitioning == LAST_FRAME_PARTITION_LOW_MOTION) && - sb_has_motion(cm, prev_mi))) { + sb_has_motion(cm, prev_mi, sf->lf_motion_threshold))) { // If required set upper and lower partition size limits if (sf->auto_min_max_partition_size) { set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); @@ -2331,7 +2332,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, cpi->pc_root); } else { if (sf->constrain_copy_partition && - sb_has_motion(cm, prev_mi)) + sb_has_motion(cm, prev_mi, sf->lf_motion_threshold)) constrain_copy_partitioning(cpi, tile, mi, prev_mi, mi_row, mi_col, BLOCK_16X16); else diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 93e23eee2..4ba5a59a3 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -80,12 +80,16 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, } if (speed >= 2) { - if (MIN(cm->width, cm->height) >= 720) + if (MIN(cm->width, cm->height) >= 720) { + sf->lf_motion_threshold = LOW_MOITION_THRESHOLD; + sf->last_partitioning_redo_frequency = 3; sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT; - else + } else { sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; - + sf->last_partitioning_redo_frequency = 2; + sf->lf_motion_threshold = NO_MOITION_THRESHOLD; + } sf->adaptive_pred_interp_filter = 2; sf->reference_masking = 1; sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH | @@ -97,7 +101,6 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX; sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION; sf->adjust_partitioning_from_last_frame = 1; - sf->last_partitioning_redo_frequency = 3; } if (speed >= 3) { @@ -108,6 +111,8 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm, else sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT; + sf->lf_motion_threshold = LOW_MOITION_THRESHOLD; + sf->last_partitioning_redo_frequency = 3; sf->recode_loop = ALLOW_RECODE_KFMAXBW; sf->adaptive_rd_thresh = 3; sf->mode_skip_start = 6; @@ -198,6 +203,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm, SPEED_FEATURES *sf, sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX; sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION; + sf->lf_motion_threshold = LOW_MOITION_THRESHOLD; sf->adjust_partitioning_from_last_frame = 1; sf->last_partitioning_redo_frequency = 3; diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h index 46806c9a9..6d2cbb9a9 100644 --- a/vp9/encoder/vp9_speed_features.h +++ b/vp9/encoder/vp9_speed_features.h @@ -43,6 +43,11 @@ typedef enum { // Other methods to come } SUBPEL_SEARCH_METHODS; +typedef enum { + NO_MOITION_THRESHOLD = 0, + LOW_MOITION_THRESHOLD = 7 +} MOTION_THRESHOLD; + typedef enum { LAST_FRAME_PARTITION_OFF = 0, LAST_FRAME_PARTITION_LOW_MOTION = 1, @@ -200,6 +205,10 @@ typedef struct SPEED_FEATURES { // partitioning. LAST_FRAME_PARTITION_METHOD use_lastframe_partitioning; + // The threshold is to determine how slow the motino is, it is used when + // use_lastframe_partitioning is set to LAST_FRAME_PARTITION_LOW_MOTION + MOTION_THRESHOLD lf_motion_threshold; + // Determine which method we use to determine transform size. We can choose // between options like full rd, largest for prediction size, largest // for intra and model coefs for the rest.