Merge branch 'me_steps'

This commit is contained in:
Miika Metsoila 2018-01-16 14:22:59 +02:00
commit 39ed36830e
5 changed files with 57 additions and 7 deletions

View file

@ -137,6 +137,9 @@ Compression tools:
- full: Full Search
- full8, full16, full32, full64
- dia: Diamond Search
--me-steps <integer> : How many search steps does the motion estimation
do before cutting off [-1]
Has effect only for 'hexbs' and 'dia'
--subme <integer> : Set fractional pixel motion estimation level
- 0: only integer motion estimation
- 1: + 1/2-pixel horizontal and vertical

View file

@ -130,6 +130,8 @@ int kvz_config_init(kvz_config *cfg)
cfg->force_level = true; // don't care about level limits by-default
cfg->high_tier = false;
cfg->me_max_steps = (uint32_t)-1;
return 1;
}
@ -1153,6 +1155,23 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
else if (OPT("high-tier")) {
cfg->high_tier = true;
}
else if (OPT("me-steps")) {
char * tailptr = NULL;
errno = 0;
long steps = strtol(value, &tailptr, 0);
if (*tailptr != '\0') {
fprintf(stderr, "Invalid me-steps value: \"%s\"", value);
return 0;
}
if (steps < -1 || errno == ERANGE || steps > UINT32_MAX) {
fprintf(stderr, "me-steps value is out of bounds: \"%s\"", value);
return 0;
}
cfg->me_max_steps = (uint32_t)steps;
}
else {
return 0;
}

View file

@ -125,6 +125,7 @@ static const struct option long_options[] = {
{ "level", required_argument, NULL, 0 },
{ "force-level", required_argument, NULL, 0 },
{ "high-tier", no_argument, NULL, 0 },
{ "me-steps", required_argument, NULL, 0 },
{0, 0, 0, 0}
};
@ -431,6 +432,9 @@ void print_help(void)
" - full: Full Search\n"
" - full8, full16, full32, full64\n"
" - dia: Diamond Search\n"
" --me-steps <integer> : How many search steps does the motion estimation\n"
" do before cutting off [-1]\n"
" Has effect only for 'hexbs' and 'dia'\n"
" --subme <integer> : Set fractional pixel motion estimation level\n"
" - 0: only integer motion estimation\n"
" - 1: + 1/2-pixel horizontal and vertical\n"

View file

@ -361,6 +361,9 @@ typedef struct kvz_config
uint8_t high_tier;
/** \brief The maximum allowed bitrate for this level and tier. */
uint32_t max_bitrate;
/** \brief Maximum steps that hexagonal and diagonal motion estimation can use. -1 to disable */
uint32_t me_max_steps;
} kvz_config;
/**

View file

@ -630,6 +630,7 @@ static void tz_search(inter_search_info_t *info, vector2d_t extra_mv)
*
* \param info search info
* \param extra_mv extra motion vector to check
* \param steps how many steps are done at maximum before exiting, does not affect the final step
*
* Motion vector is searched by first searching iteratively with the large
* hexagon pattern until the best match is at the center of the hexagon.
@ -640,7 +641,7 @@ static void tz_search(inter_search_info_t *info, vector2d_t extra_mv)
* the predicted motion vector is way off. In the future even more additional
* points like 0,0 might be used, such as vectors from top or left.
*/
static void hexagon_search(inter_search_info_t *info, vector2d_t extra_mv)
static void hexagon_search(inter_search_info_t *info, vector2d_t extra_mv, uint32_t steps)
{
// The start of the hexagonal pattern has been repeated at the end so that
// the indices between 1-6 can be used as the start of a 3-point list of new
@ -691,7 +692,10 @@ static void hexagon_search(inter_search_info_t *info, vector2d_t extra_mv)
// Iteratively search the 3 new points around the best match, until the best
// match is in the center.
while (best_index != 0) {
while (best_index != 0 && steps != 0) {
// decrement count if enabled
if (steps > 0) steps -= 1;
// Starting point of the 3 offsets to be searched.
unsigned start;
if (best_index == 1) {
@ -726,8 +730,23 @@ static void hexagon_search(inter_search_info_t *info, vector2d_t extra_mv)
}
}
static void diamond_search(inter_search_info_t *info, vector2d_t extra_mv)
/**
* \brief Do motion search using the diamond algorithm.
*
* \param info search info
* \param extra_mv extra motion vector to check
* \param steps how many steps are done at maximum before exiting
*
* Motion vector is searched by searching iteratively with a diamond-shaped
* pattern. We take care of not checking the direction we came from, but
* further checking for avoiding visits to already visited points is not done.
*
* If a non 0,0 predicted motion vector predictor is given as extra_mv,
* the 0,0 vector is also tried. This is hoped to help in the case where
* the predicted motion vector is way off. In the future even more additional
* points like 0,0 might be used, such as vectors from top or left.
**/
static void diamond_search(inter_search_info_t *info, vector2d_t extra_mv, uint32_t steps)
{
enum diapos {
DIA_UP = 0,
@ -789,6 +808,8 @@ static void diamond_search(inter_search_info_t *info, vector2d_t extra_mv)
do {
better_found = 0;
// decrement count if enabled
if (steps > 0) steps -= 1;
// search the points of the diamond
for (int i = 0; i < 4; ++i) {
@ -810,7 +831,7 @@ static void diamond_search(inter_search_info_t *info, vector2d_t extra_mv)
// the xor operation flips the orientation
from_dir = best_index ^ 0x3;
}
} while (better_found);
} while (better_found && steps != 0);
// and we're done
}
@ -1250,11 +1271,11 @@ static void search_pu_inter_ref(inter_search_info_t *info,
break;
case KVZ_IME_DIA:
diamond_search(info, mv);
diamond_search(info, mv, info->state->encoder_control->cfg.me_max_steps);
break;
default:
hexagon_search(info, mv);
hexagon_search(info, mv, info->state->encoder_control->cfg.me_max_steps);
break;
}