mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Add hexagon-based motion vector search.
This commit is contained in:
parent
9d02dfdd13
commit
8910037936
112
src/search.c
112
src/search.c
|
@ -87,6 +87,113 @@ unsigned get_block_sad(picture *pic, picture *ref,
|
|||
return result;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} vector2d;
|
||||
|
||||
/**
|
||||
* This is used in the hexagon_search to select 3 points to search.
|
||||
*
|
||||
* 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
|
||||
* points to search.
|
||||
*
|
||||
* 6 o-o 1 / 7
|
||||
* / \
|
||||
* 5 o 0 o 2 / 8
|
||||
* \ /
|
||||
* 4 o-o 3
|
||||
*/
|
||||
const vector2d large_hexbs[10] = {
|
||||
{ 0, 0 },
|
||||
{ 1, -2 }, { 2, 0 }, { 1, 2 }, { -1, 2 }, { -2, 0 }, { -1, -2 },
|
||||
{ 1, -2 }, { 2, 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* This is used as the last step of the hexagon search.
|
||||
*/
|
||||
const vector2d small_hexbs[5] = {
|
||||
{ 0, 0 },
|
||||
{ -1, -1 }, { -1, 0 }, { 1, 0 }, { 1, 1 }
|
||||
};
|
||||
|
||||
void hexagon_search(picture *pic, picture *ref,
|
||||
cu_info *cur_cu, int orig_x, int orig_y, int x, int y,
|
||||
unsigned depth)
|
||||
{
|
||||
int block_width = CU_WIDTH_FROM_DEPTH(depth);
|
||||
unsigned best_cost = -1;
|
||||
unsigned i;
|
||||
unsigned best_index = 0; // in large_hexbs[]
|
||||
|
||||
// Search the initial 7 points of the hexagon.
|
||||
for (i = 0; i < 7; ++i) {
|
||||
const vector2d *pattern = large_hexbs + i;
|
||||
unsigned cost = get_block_sad(pic, ref, orig_x, orig_y,
|
||||
orig_x + x + pattern->x, orig_y + y + pattern->y,
|
||||
block_width, block_width);
|
||||
if (cost > 0 && cost < best_cost) {
|
||||
best_cost = cost;
|
||||
best_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Iteratively search the 3 new points around the best match, until the best
|
||||
// match is in the center.
|
||||
while (best_index != 0) {
|
||||
unsigned start; // Starting point of the 3 offsets to be searched.
|
||||
if (best_index == 1) {
|
||||
start = 6;
|
||||
} else if (best_index == 8) {
|
||||
start = 1;
|
||||
} else {
|
||||
start = best_index - 1;
|
||||
}
|
||||
|
||||
// Move the center to the best match.
|
||||
x += large_hexbs[best_index].x;
|
||||
y += large_hexbs[best_index].y;
|
||||
best_index = 0;
|
||||
|
||||
// Iterate through the next 3 points.
|
||||
for (i = 0; i < 3; ++i) {
|
||||
const vector2d *offset = large_hexbs + start + i;
|
||||
unsigned cost = get_block_sad(pic, ref, orig_x, orig_y,
|
||||
orig_x + x + offset->x, orig_y + y + offset->y,
|
||||
block_width, block_width);
|
||||
if (cost > 0 && cost < best_cost) {
|
||||
best_cost = cost;
|
||||
best_index = start + i;
|
||||
}
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
|
||||
// Do the final step of the search with a small pattern.
|
||||
x += large_hexbs[best_index].x;
|
||||
y += large_hexbs[best_index].y;
|
||||
best_index = 0;
|
||||
for (i = 1; i < 5; ++i) {
|
||||
const vector2d *offset = small_hexbs + i;
|
||||
unsigned cost = get_block_sad(pic, ref, orig_x, orig_y,
|
||||
orig_x + x + offset->x, orig_y + y + offset->y,
|
||||
block_width, block_width);
|
||||
if (cost > 0 && cost < best_cost) {
|
||||
best_cost = cost;
|
||||
best_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
x += small_hexbs[best_index].x;
|
||||
y += small_hexbs[best_index].y;
|
||||
best_index = 0;
|
||||
cur_cu->inter.cost = best_cost + 1; // +1 so that cost is > 0.
|
||||
cur_cu->inter.mv[0] = x << 2;
|
||||
cur_cu->inter.mv[1] = y << 2;
|
||||
}
|
||||
|
||||
void search_mv(picture *pic, picture *ref,
|
||||
cu_info *cur_cu, int orig_x, int orig_y, int x, int y,
|
||||
unsigned depth)
|
||||
|
@ -373,9 +480,14 @@ void search_tree(encoder_control *encoder,
|
|||
cur_cu, 8, x, y,
|
||||
start_x, start_y, depth);
|
||||
} else {
|
||||
/*
|
||||
search_mv(cur_pic, ref_pic,
|
||||
cur_cu, x, y,
|
||||
start_x, start_y, depth);
|
||||
*/
|
||||
hexagon_search(cur_pic, ref_pic,
|
||||
cur_cu, x, y,
|
||||
start_x, start_y, depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue