mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-30 20:54:07 +00:00
Add fast transform skip estimation to rough intra search.
This commit is contained in:
parent
28d1532578
commit
f164a5ba79
33
src/search.c
33
src/search.c
|
@ -60,6 +60,9 @@
|
||||||
#ifndef CMUL
|
#ifndef CMUL
|
||||||
# define CMUL 1.0
|
# define CMUL 1.0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MN // fast tr_skip Magic Number
|
||||||
|
# define MN 0.0
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used in the hexagon_search to select 3 points to search.
|
* This is used in the hexagon_search to select 3 points to search.
|
||||||
|
@ -1070,13 +1073,31 @@ static void sort_modes(int8_t *modes, double *costs, int length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned get_cost(pixel *pred, pixel *orig_block, cost_pixel_nxn_func *satd_func, cost_pixel_nxn_func *sad_func, int width)
|
||||||
|
{
|
||||||
|
unsigned cost = satd_func(pred, orig_block);
|
||||||
|
if (MN != 0 && width == 4) {
|
||||||
|
// If the mode looks better with SAD than SATD it might be a good
|
||||||
|
// candidate for transform skip. How much better SAD has to be is
|
||||||
|
// controlled by MN.
|
||||||
|
unsigned sad_cost = MN * sad_func(pred, orig_block);
|
||||||
|
if (sad_cost < cost) {
|
||||||
|
cost = sad_cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int8_t search_intra_rough(encoder_state * const encoder_state,
|
static int8_t search_intra_rough(encoder_state * const encoder_state,
|
||||||
pixel *orig, int32_t origstride,
|
pixel *orig, int32_t origstride,
|
||||||
pixel *rec, int16_t recstride,
|
pixel *rec, int16_t recstride,
|
||||||
int width, int8_t *intra_preds,
|
int width, int8_t *intra_preds,
|
||||||
int8_t modes[35], double costs[35])
|
int8_t modes[35], double costs[35])
|
||||||
{
|
{
|
||||||
cost_pixel_nxn_func *cost_func = pixels_get_sad_func(width);
|
cost_pixel_nxn_func *satd_func = pixels_get_satd_func(width);
|
||||||
|
cost_pixel_nxn_func *sad_func = pixels_get_sad_func(width);
|
||||||
|
|
||||||
// Temporary block arrays
|
// Temporary block arrays
|
||||||
pixel _pred[LCU_WIDTH * LCU_WIDTH + 1 + SIMD_ALIGNMENT];
|
pixel _pred[LCU_WIDTH * LCU_WIDTH + 1 + SIMD_ALIGNMENT];
|
||||||
|
@ -1099,7 +1120,7 @@ static int8_t search_intra_rough(encoder_state * const encoder_state,
|
||||||
int16_t x, y;
|
int16_t x, y;
|
||||||
for (y = -1; y < recstride; y++) {
|
for (y = -1; y < recstride; y++) {
|
||||||
ref[1][y*recstride - 1] = rec[y*recstride - 1];
|
ref[1][y*recstride - 1] = rec[y*recstride - 1];
|
||||||
}
|
}
|
||||||
for (x = 0; x < recstride; x++) {
|
for (x = 0; x < recstride; x++) {
|
||||||
ref[1][x - recstride] = rec[x - recstride];
|
ref[1][x - recstride] = rec[x - recstride];
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1148,7 @@ static int8_t search_intra_rough(encoder_state * const encoder_state,
|
||||||
// the recursive search.
|
// the recursive search.
|
||||||
for (int mode = 2; mode <= 34; mode += offset) {
|
for (int mode = 2; mode <= 34; mode += offset) {
|
||||||
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
||||||
costs[modes_selected] = cost_func(pred, orig_block);
|
costs[modes_selected] = get_cost(pred, orig_block, satd_func, sad_func, width);
|
||||||
modes[modes_selected] = mode;
|
modes[modes_selected] = mode;
|
||||||
|
|
||||||
min_cost = MIN(min_cost, costs[modes_selected]);
|
min_cost = MIN(min_cost, costs[modes_selected]);
|
||||||
|
@ -1147,7 +1168,7 @@ static int8_t search_intra_rough(encoder_state * const encoder_state,
|
||||||
int8_t mode = modes[0] - offset;
|
int8_t mode = modes[0] - offset;
|
||||||
if (mode >= 2) {
|
if (mode >= 2) {
|
||||||
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
||||||
costs[modes_selected] = cost_func(pred, orig_block);
|
costs[modes_selected] = get_cost(pred, orig_block, satd_func, sad_func, width);
|
||||||
modes[modes_selected] = mode;
|
modes[modes_selected] = mode;
|
||||||
++modes_selected;
|
++modes_selected;
|
||||||
}
|
}
|
||||||
|
@ -1155,7 +1176,7 @@ static int8_t search_intra_rough(encoder_state * const encoder_state,
|
||||||
mode = modes[0] + offset;
|
mode = modes[0] + offset;
|
||||||
if (mode <= 34) {
|
if (mode <= 34) {
|
||||||
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
||||||
costs[modes_selected] = cost_func(pred, orig_block);
|
costs[modes_selected] = get_cost(pred, orig_block, satd_func, sad_func, width);
|
||||||
modes[modes_selected] = mode;
|
modes[modes_selected] = mode;
|
||||||
++modes_selected;
|
++modes_selected;
|
||||||
}
|
}
|
||||||
|
@ -1178,7 +1199,7 @@ static int8_t search_intra_rough(encoder_state * const encoder_state,
|
||||||
|
|
||||||
if (!has_mode) {
|
if (!has_mode) {
|
||||||
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
intra_get_pred(encoder_state->encoder_control, ref, recstride, pred, width, mode, 0);
|
||||||
costs[modes_selected] = cost_func(pred, orig_block);
|
costs[modes_selected] = get_cost(pred, orig_block, satd_func, sad_func, width);
|
||||||
modes[modes_selected] = mode;
|
modes[modes_selected] = mode;
|
||||||
++modes_selected;
|
++modes_selected;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue