From 2a9d746c09998b300c4b380c944d2b6ae43bbdc7 Mon Sep 17 00:00:00 2001 From: Debargha Mukherjee Date: Thu, 4 May 2017 17:37:52 -0700 Subject: [PATCH] Add speed feature to control global motion compute Adds a speed feature to control which references to use to compute global motion. Also adds logic to not compute duplicate sets of parameters when reference frames point to the same buffers. Includes some renaming of functions to set good speed features to make things clearer. Change-Id: I641d33441fde98af18cad8d4db49cf7d5d153ead --- av1/encoder/encodeframe.c | 47 +++++++++++++++++++++++++++++------- av1/encoder/speed_features.c | 17 ++++++++++--- av1/encoder/speed_features.h | 12 +++++++++ 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 302d409ec..641c2124f 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c @@ -5124,6 +5124,24 @@ static int gm_get_params_cost(WarpedMotionParams *gm, } return (params_cost << AV1_PROB_COST_SHIFT); } + +static int do_gm_search_logic(SPEED_FEATURES *const sf, int num_refs_using_gm, + int frame) { + (void)num_refs_using_gm; + (void)frame; + switch (sf->gm_search_type) { + case GM_FULL_SEARCH: return 1; + case GM_REDUCED_REF_SEARCH: +#if CONFIG_EXT_REFS + return !(frame == LAST2_FRAME || frame == LAST3_FRAME); +#else + return (num_refs_using_gm < 2); +#endif // CONFIG_EXT_REFS + case GM_DISABLE_SEARCH: return 0; + default: assert(0); + } + return 1; +} #endif // CONFIG_GLOBAL_MOTION static void encode_frame_internal(AV1_COMP *cpi) { @@ -5154,9 +5172,10 @@ static void encode_frame_internal(AV1_COMP *cpi) { #if CONFIG_GLOBAL_MOTION av1_zero(rdc->global_motion_used); + av1_zero(cpi->gmparams_cost); if (cpi->common.frame_type == INTER_FRAME && cpi->source && !cpi->global_motion_search_done) { - YV12_BUFFER_CONFIG *ref_buf; + YV12_BUFFER_CONFIG *ref_buf[TOTAL_REFS_PER_FRAME]; int frame; double params_by_motion[RANSAC_NUM_MOTIONS * (MAX_PARAMDIM - 1)]; const double *params_this_motion; @@ -5166,10 +5185,20 @@ static void encode_frame_internal(AV1_COMP *cpi) { static const double kIdentityParams[MAX_PARAMDIM - 1] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }; + int num_refs_using_gm = 0; for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) { - ref_buf = get_ref_frame_buffer(cpi, frame); - if (ref_buf) { + ref_buf[frame] = get_ref_frame_buffer(cpi, frame); + int pframe; + // check for duplicate buffer + for (pframe = LAST_FRAME; pframe < frame; ++pframe) { + if (ref_buf[frame] == ref_buf[pframe]) break; + } + if (pframe < frame) { + memcpy(&cm->global_motion[frame], &cm->global_motion[pframe], + sizeof(WarpedMotionParams)); + } else if (ref_buf[frame] && + do_gm_search_logic(&cpi->sf, num_refs_using_gm, frame)) { TransformationType model; aom_clear_system_state(); for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES_ENC; ++model) { @@ -5182,7 +5211,7 @@ static void encode_frame_internal(AV1_COMP *cpi) { } compute_global_motion_feature_based( - model, cpi->source, ref_buf, + model, cpi->source, ref_buf[frame], #if CONFIG_HIGHBITDEPTH cpi->common.bit_depth, #endif // CONFIG_HIGHBITDEPTH @@ -5200,10 +5229,10 @@ static void encode_frame_internal(AV1_COMP *cpi) { #if CONFIG_HIGHBITDEPTH xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd, #endif // CONFIG_HIGHBITDEPTH - ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height, - ref_buf->y_stride, cpi->source->y_buffer, - cpi->source->y_width, cpi->source->y_height, - cpi->source->y_stride, 3); + ref_buf[frame]->y_buffer, ref_buf[frame]->y_width, + ref_buf[frame]->y_height, ref_buf[frame]->y_stride, + cpi->source->y_buffer, cpi->source->y_width, + cpi->source->y_height, cpi->source->y_stride, 3); if (erroradv_this_motion < best_erroradvantage) { best_erroradvantage = erroradv_this_motion; // Save the wm_params modified by refine_integerized_param() @@ -5237,11 +5266,11 @@ static void encode_frame_internal(AV1_COMP *cpi) { cm->allow_high_precision_mv))) { set_default_warp_params(&cm->global_motion[frame]); } - if (cm->global_motion[frame].wmtype != IDENTITY) break; } aom_clear_system_state(); } + if (cm->global_motion[frame].wmtype != IDENTITY) num_refs_using_gm++; cpi->gmparams_cost[frame] = gm_get_params_cost(&cm->global_motion[frame], &cm->prev_frame->global_motion[frame], diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c index 20c96761b..9687a7f5c 100644 --- a/av1/encoder/speed_features.c +++ b/av1/encoder/speed_features.c @@ -139,8 +139,10 @@ static void set_good_speed_feature_framesize_dependent(AV1_COMP *cpi, } } -static void set_good_speed_feature(AV1_COMP *cpi, AV1_COMMON *cm, - SPEED_FEATURES *sf, int speed) { +static void set_good_speed_features_framesize_independent(AV1_COMP *cpi, + SPEED_FEATURES *sf, + int speed) { + AV1_COMMON *const cm = &cpi->common; const int boosted = frame_is_boosted(cpi); if (speed >= 1) { @@ -205,6 +207,9 @@ static void set_good_speed_feature(AV1_COMP *cpi, AV1_COMMON *cm, #if CONFIG_EXT_TX sf->tx_type_search.prune_mode = PRUNE_TWO; #endif +#if CONFIG_GLOBAL_MOTION + sf->gm_search_type = GM_DISABLE_SEARCH; +#endif // CONFIG_GLOBAL_MOTION } if (speed >= 4) { @@ -339,12 +344,13 @@ void av1_set_speed_features_framesize_dependent(AV1_COMP *cpi) { } void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) { - SPEED_FEATURES *const sf = &cpi->sf; AV1_COMMON *const cm = &cpi->common; + SPEED_FEATURES *const sf = &cpi->sf; MACROBLOCK *const x = &cpi->td.mb; const AV1EncoderConfig *const oxcf = &cpi->oxcf; int i; + (void)cm; // best quality defaults sf->frame_parameter_update = 1; sf->mv.search_method = NSTEP; @@ -418,13 +424,16 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) { // Set this at the appropriate speed levels sf->use_transform_domain_distortion = 0; +#if CONFIG_GLOBAL_MOTION + sf->gm_search_type = GM_FULL_SEARCH; +#endif // CONFIG_GLOBAL_MOTION if (oxcf->mode == GOOD #if CONFIG_XIPHRC || oxcf->pass == 1 #endif ) - set_good_speed_feature(cpi, cm, sf, oxcf->speed); + set_good_speed_features_framesize_independent(cpi, sf, oxcf->speed); // sf->partition_search_breakout_dist_thr is set assuming max 64x64 // blocks. Normalise this if the blocks are bigger. diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h index af54a1a9a..cb57c6b66 100644 --- a/av1/encoder/speed_features.h +++ b/av1/encoder/speed_features.h @@ -251,6 +251,14 @@ typedef struct MESH_PATTERN { int interval; } MESH_PATTERN; +#if CONFIG_GLOBAL_MOTION +typedef enum { + GM_FULL_SEARCH, + GM_REDUCED_REF_SEARCH, + GM_DISABLE_SEARCH +} GM_SEARCH_TYPE; +#endif // CONFIG_GLOBAL_MOTION + typedef struct SPEED_FEATURES { MV_SPEED_FEATURES mv; @@ -470,6 +478,10 @@ typedef struct SPEED_FEATURES { // Whether to compute distortion in the image domain (slower but // more accurate), or in the transform domain (faster but less acurate). int use_transform_domain_distortion; + +#if CONFIG_GLOBAL_MOTION + GM_SEARCH_TYPE gm_search_type; +#endif // CONFIG_GLOBAL_MOTION } SPEED_FEATURES; struct AV1_COMP; -- GitLab