Add diamond search

This commit is contained in:
Miika Metsoila 2017-12-12 14:37:55 +02:00
parent ea79069dc8
commit b923b63b42
3 changed files with 97 additions and 5 deletions

View file

@ -349,7 +349,7 @@ static int parse_slice_specification(const char* const arg, int32_t * const nsli
int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
{
static const char * const me_names[] = { "hexbs", "tz", "full", "full8", "full16", "full32", "full64", NULL };
static const char * const me_names[] = { "hexbs", "tz", "full", "full8", "full16", "full32", "full64", "dia", NULL };
static const char * const source_scan_type_names[] = { "progressive", "tff", "bff", NULL };
static const char * const overscan_names[] = { "undef", "show", "crop", NULL };

View file

@ -92,6 +92,7 @@ enum kvz_ime_algorithm {
KVZ_IME_FULL16 = 4, //! \since 3.6.0
KVZ_IME_FULL32 = 5, //! \since 3.6.0
KVZ_IME_FULL64 = 6, //! \since 3.6.0
KVZ_IME_DIA = 7, // Experimental. TODO: change into a proper doc comment
};
/**

View file

@ -679,7 +679,7 @@ static void hexagon_search(inter_search_info_t *info, vector2d_t extra_mv)
vector2d_t mv = { info->best_mv.x >> 2, info->best_mv.y >> 2 };
// Current best index, either to merge_cands, large_hebx or small_hexbs.
// Current best index, either to merge_cands, large_hexbs or small_hexbs.
int best_index = 0;
// Search the initial 7 points of the hexagon.
@ -717,9 +717,8 @@ static void hexagon_search(inter_search_info_t *info, vector2d_t extra_mv)
}
// Move the center to the best match.
mv.x += large_hexbs[best_index].x;
mv.y += large_hexbs[best_index].y;
best_index = 0;
//mv.x += large_hexbs[best_index].x;
//mv.y += large_hexbs[best_index].y;
// Do the final step of the search with a small pattern.
for (int i = 1; i < 5; ++i) {
@ -728,6 +727,94 @@ 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)
{
enum diapos {
DIA_UP = 0,
DIA_RIGHT = 1,
DIA_LEFT = 2,
DIA_DOWN = 3,
DIA_CENTER = 4,
};
// a diamond shape with the center included
// 0
// 2 4 1
// 3
static const vector2d_t diamond[5] = {
{0, -1}, {1, 0}, {0, 1}, {-1, 0},
{0, 0}
};
info->best_cost = UINT32_MAX;
// Select starting point from among merge candidates. These should
// include both mv_cand vectors and (0, 0).
select_starting_point(info, extra_mv);
// Check if we should stop search
if (info->state->encoder_control->cfg.me_early_termination &&
early_terminate(info))
{
return;
}
// current motion vector
vector2d_t mv = { info->best_mv.x >> 2, info->best_mv.y >> 2 };
// current best index
enum diapos best_index = DIA_CENTER;
// initial search of the points of the diamond
for (int i = 0; i < 5; ++i) {
if (check_mv_cost(info, mv.x + diamond[i].x, mv.y + diamond[i].y)) {
best_index = i;
}
}
if (best_index == DIA_CENTER) {
// the center point was the best in initial check
return;
}
// Move the center to the best match.
mv.x += diamond[best_index].x;
mv.y += diamond[best_index].y;
// the arrival direction, the index of the diamond member that will be excluded
enum diapos from_dir = DIA_CENTER;
// whether we found a better candidate this iteration
uint8_t better_found;
do {
better_found = 0;
// search the points of the diamond
for (int i = 0; i < 4; ++i) {
// this is where we came from so it's checked already
if (i == from_dir) continue;
if (check_mv_cost(info, mv.x + diamond[i].x, mv.y + diamond[i].y)) {
best_index = i;
better_found = 1;
}
}
if (better_found) {
// Move the center to the best match.
mv.x += diamond[best_index].x;
mv.y += diamond[best_index].y;
// record where we came from to the next iteration
// the xor operation flips the orientation
from_dir = best_index ^ 0x3;
}
} while (better_found);
// and we're done
}
static void search_mv_full(inter_search_info_t *info,
int32_t search_range,
vector2d_t extra_mv)
@ -1162,6 +1249,10 @@ static void search_pu_inter_ref(inter_search_info_t *info,
search_mv_full(info, search_range, mv);
break;
case KVZ_IME_DIA:
diamond_search(info, mv);
break;
default:
hexagon_search(info, mv);
break;