Merge branch 'me_early_terminate'

Conflicts:
	configure.ac
	src/cfg.c
	src/cli.c
	src/kvazaar.h
	src/search_inter.c
This commit is contained in:
Eemeli Kallio 2016-06-14 15:03:35 +03:00
commit 5af6ab320c
5 changed files with 99 additions and 2 deletions

View file

@ -23,7 +23,7 @@ AC_CONFIG_SRCDIR([src/encmain.c])
#
# Here is a somewhat sane guide to lib versioning: http://apr.apache.org/versioning.html
ver_major=3
ver_minor=7
ver_minor=8
ver_release=0
# Prevents configure from adding a lot of defines to the CFLAGS

View file

@ -109,6 +109,8 @@ int kvz_config_init(kvz_config *cfg)
cfg->mv_constraint = KVZ_MV_CONSTRAIN_NONE;
cfg->crypto_features = KVZ_CRYPTO_OFF;
cfg->me_early_termination = 0;
return 1;
}
@ -298,6 +300,8 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
static const char * const crypto_toggle_names[] = { "off", "on", NULL };
static const char * const crypto_feature_names[] = { "mvs", "mv_signs", "trans_coeffs", "trans_coeff_signs", NULL };
static const char * const me_early_termination_names[] = { "off", "on", "sensitive", NULL };
static const char * const preset_values[11][32] = {
{
"ultrafast",
@ -897,6 +901,12 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
return 1;
}
else if OPT("me-early-termination"){
int8_t mode = 0;
int result = parse_enum(value, me_early_termination_names, &mode);
cfg->me_early_termination = mode;
return result;
}
else
return 0;
#undef OPT

View file

@ -107,6 +107,7 @@ static const struct option long_options[] = {
{ "hash", required_argument, NULL, 0 },
{"cu-split-termination",required_argument, NULL, 0 },
{ "crypto", required_argument, NULL, 0 },
{ "me-early-termination",required_argument, NULL, 0 },
{0, 0, 0, 0}
};
@ -380,6 +381,10 @@ void print_help(void)
" \"zero\": Terminate when splitting gives little\n"
" improvement.\n"
" \"off\": Don't terminate splitting early\n"
" --me-early-termitanion : Specify the me early termination behaviour\n"
" \"off\": Early termination is off\n"
" \"on\": Early termination is on\n"
" \"sensitive\": Sensitive early termination is on\n"
"\n"
" Video Usability Information:\n"
" --sar <width:height> : Specify Sample Aspect Ratio\n"

View file

@ -131,6 +131,7 @@ enum kvz_hash
/**
* \brief cu split termination mode
* \since since 3.8.0
*/
enum kvz_cu_split_termination
{
@ -151,6 +152,17 @@ enum kvz_crypto_features {
KVZ_CRYPTO_ON = (1 << 4) - 1,
};
/**
* \brief me early termination mode
* \since since 3.8.0
*/
enum kvz_me_early_termination
{
KVZ_ME_EARLY_TERMINATION_OFF = 0,
KVZ_ME_EARLY_TERMINATION_ON = 1,
KVZ_ME_EARLY_TERMINATION_SENSITIVE = 2
};
/**
* \brief GoP picture configuration.
*/
@ -258,9 +270,12 @@ typedef struct kvz_config
enum kvz_mv_constraint mv_constraint; /*!< \since 3.3.0 \brief Constrain movement vectors. */
enum kvz_hash hash; /*!< \since 3.5.0 \brief What hash algorithm to use. */
enum kvz_cu_split_termination cu_split_termination; /*!< \brief Mode of cu split termination. */
enum kvz_cu_split_termination cu_split_termination; /*!< \since 3.8.0 \brief Mode of cu split termination. */
enum kvz_crypto_features crypto_features; /*!< \since 3.7.0 */
enum kvz_me_early_termination me_early_termination; /*!< \since 3.8.0 \brief Mode of me early termination. */
} kvz_config;
/**

View file

@ -257,6 +257,61 @@ static int calc_mvd_cost(encoder_state_t * const state, int x, int y, int mv_shi
}
static bool early_terminate(int16_t num_cand, inter_merge_cand_t *merge_cand, vector2d_t *mv_in_out, vector2d_t *mv, const encoder_state_t *const state,
const vector2d_t *orig, unsigned width, unsigned height, int wpp_limit, const kvz_picture *pic, const kvz_picture *ref,
int16_t mv_cand[2][2], int32_t ref_idx, unsigned *best_cost, uint32_t *bitcost_out, uint32_t *best_bitcost,
int(*calc_mvd)(const encoder_state_t * const, int, int, int, int16_t[2][2], inter_merge_cand_t[MRG_MAX_NUM_CANDS],
int16_t, int32_t, uint32_t *))
{
static const vector2d_t small_hexbs[5] = {
{ 0, 0 },
{ 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 },
};
double multiplier = 1;
// If early termination is set to fast set multiplier to 0.9
if (state->encoder_control->cfg->me_early_termination == KVZ_ME_EARLY_TERMINATION_SENSITIVE){
multiplier = 0.95;
}
const vector2d_t *offset;
for (int k = 0; k < 2; ++k){
unsigned best_index = 0;
for (int i = 1; i < 5; ++i) {
offset = &small_hexbs[i];
if (!intmv_within_tile(state, orig, mv->x + offset->x, mv->y + offset->y, width, height, wpp_limit)) {
continue;
}
unsigned cost = kvz_image_calc_sad(pic, ref, orig->x, orig->y,
(state->tile->lcu_offset_x * LCU_WIDTH) + orig->x + mv->x + offset->x,
(state->tile->lcu_offset_y * LCU_WIDTH) + orig->y + mv->y + offset->y,
width, height, -1);
unsigned bitcost;
cost += calc_mvd(state, mv->x + offset->x, mv->y + offset->y, 2, mv_cand, merge_cand, num_cand, ref_idx, &bitcost);
if (cost < multiplier * *best_cost ) {
*best_cost = cost;
best_index = i;
*best_bitcost = bitcost;
}
}
// Adjust the movement vector
mv->x += small_hexbs[best_index].x;
mv->y += small_hexbs[best_index].y;
// if best match is at center we stop the search
if (best_index == 0){
// Return final movement vector in quarter-pixel precision.
mv_in_out->x = mv->x << 2;
mv_in_out->y = mv->y << 2;
*bitcost_out = *best_bitcost;
return true;
}
}
return false;
}
unsigned kvz_tz_pattern_search(encoder_state_t * const state, const kvz_picture *pic, const kvz_picture *ref, unsigned pattern_type,
const vector2d_t *orig, const int iDist, vector2d_t *mv, unsigned best_cost, int *best_dist,
int16_t mv_cand[2][2], inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS], int16_t num_cand, int32_t ref_idx, uint32_t *best_bitcost,
@ -536,6 +591,12 @@ static unsigned tz_search(encoder_state_t * const state,
best_cost = select_starting_point(num_cand, merge_cand, mv_in_out, &mv, state, orig, width, height, wpp_limit,
pic, ref, mv_cand, ref_idx, best_cost, &best_index, &best_bitcost, calc_mvd);
// Check if we should stop search
if (state->encoder_control->cfg->me_early_termination){
if (early_terminate(num_cand, merge_cand, mv_in_out, &mv, state, orig, width, height, wpp_limit,
pic, ref, mv_cand, ref_idx, &best_cost, bitcost_out, &best_bitcost, calc_mvd)) return best_cost;
}
//step 2, grid search
for (iDist = 1; iDist <= iSearchRange; iDist *= 2)
{
@ -685,6 +746,12 @@ static unsigned hexagon_search(encoder_state_t * const state,
best_cost = select_starting_point(num_cand, merge_cand, mv_in_out, &mv, state, orig, width, height, wpp_limit,
pic, ref, mv_cand, ref_idx, best_cost, &best_index, &best_bitcost, calc_mvd);
// Check if we should stop search
if (state->encoder_control->cfg->me_early_termination){
if (early_terminate(num_cand, merge_cand, mv_in_out, &mv, state, orig, width, height, wpp_limit,
pic, ref, mv_cand, ref_idx, &best_cost, bitcost_out, &best_bitcost, calc_mvd)) return best_cost;
}
// Search the initial 7 points of the hexagon.
best_index = 0;
for (i = 0; i < 7; ++i) {