Add more tests for inter SAD

The existing tests only covered the edge cases of border extension, but
not the SIMD optimized versions of reg_sad. This adds proper tests for
current optimized reg_sad implementations and ones we are likely to
have in the future.
This commit is contained in:
Ari Koivula 2016-08-26 14:16:25 +03:00
parent 11defe1595
commit 345ef833d7

View file

@ -59,6 +59,18 @@ static const kvz_pixel pic_data[64] = {
static kvz_picture *g_pic = 0;
static kvz_picture *g_ref = 0;
static kvz_picture *g_big_pic = 0;
static kvz_picture *g_big_ref = 0;
static kvz_picture *g_64x64_zero = 0;
static kvz_picture *g_64x64_max = 0;
static struct sad_test_env_t {
int width;
int height;
void * tested_func;
const strategy_t * strategy;
char msg[255];
} sad_test_env;
//////////////////////////////////////////////////////////////////////////
// SETUP, TEARDOWN AND HELPER FUNCTIONS
@ -73,12 +85,34 @@ static void setup_tests()
for (int i = 0; i < 64; ++i) {
g_ref->y[i] = ref_data[i] + 48;
}
g_big_pic = kvz_image_alloc(KVZ_CSP_420, 64, 64);
for (int i = 0; i < 64*64; ++i) {
g_big_pic->y[i] = (i*i / 32 + i) % 255;
//g_big_pic->y[i] = i % 255;
}
g_big_ref = kvz_image_alloc(KVZ_CSP_420, 64, 64);
for (int i = 0; i < 64 * 64; ++i) {
g_big_ref->y[i] = (i*i / 16 + i) % 255;
//g_big_ref->y[i] = (i / 2) % 255;
}
g_64x64_zero = kvz_image_alloc(KVZ_CSP_420, 64, 64);
memset(g_64x64_zero->y, 0, 64 * 64 * sizeof(kvz_pixel));
g_64x64_max = kvz_image_alloc(KVZ_CSP_420, 64, 64);
memset(g_64x64_max->y, PIXEL_MAX, 64 * 64 * sizeof(kvz_pixel));
}
static void tear_down_tests()
{
kvz_image_free(g_pic);
kvz_image_free(g_ref);
kvz_image_free(g_big_pic);
kvz_image_free(g_big_ref);
kvz_image_free(g_64x64_zero);
kvz_image_free(g_64x64_max);
}
@ -224,11 +258,66 @@ TEST test_bottomright_out(void)
PASS();
}
static unsigned simple_sad(const kvz_pixel* buf1, const kvz_pixel* buf2, unsigned stride,
unsigned width, unsigned height)
{
unsigned sum = 0;
for (unsigned y = 0; y < height; ++y) {
for (unsigned x = 0; x < width; ++x) {
sum += abs((int)buf1[y * stride + x] - (int)buf2[y * stride + x]);
}
}
return sum;
}
struct sad_test_env_t {
kvz_picture *g_pic;
kvz_picture *g_ref;
};
TEST test_reg_sad(void)
{
unsigned width = sad_test_env.width;
unsigned height = sad_test_env.height;
unsigned stride = 64;
unsigned correct_result = simple_sad(g_big_pic->y, g_big_ref->y, stride, width, height);
unsigned(*tested_func)(const kvz_pixel *, const kvz_pixel *, int, int, unsigned, unsigned) = sad_test_env.tested_func;
unsigned result = tested_func(g_big_pic->y, g_big_ref->y, width, height, stride, stride);
sprintf(sad_test_env.msg, "%s(%ux%u):%s",
sad_test_env.strategy->type,
width,
height,
sad_test_env.strategy->strategy_name);
if (result != correct_result) {
FAILm(sad_test_env.msg);
}
PASSm(sad_test_env.msg);
}
TEST test_reg_sad_overflow(void)
{
unsigned width = sad_test_env.width;
unsigned height = sad_test_env.height;
unsigned stride = 64;
unsigned correct_result = simple_sad(g_64x64_zero->y, g_64x64_max->y, stride, width, height);
unsigned(*tested_func)(const kvz_pixel *, const kvz_pixel *, int, int, unsigned, unsigned) = sad_test_env.tested_func;
unsigned result = tested_func(g_64x64_zero->y, g_64x64_max->y, width, height, stride, stride);
sprintf(sad_test_env.msg, "overflow %s(%ux%u):%s",
sad_test_env.strategy->type,
width,
height,
sad_test_env.strategy->strategy_name);
if (result != correct_result) {
FAILm(sad_test_env.msg);
}
PASSm(sad_test_env.msg);
}
//////////////////////////////////////////////////////////////////////////
@ -272,6 +361,29 @@ SUITE(sad_tests)
RUN_TEST(test_bottomleft_out);
RUN_TEST(test_bottom_out);
RUN_TEST(test_bottomright_out);
struct dimension {
int width;
int height;
};
static const struct dimension tested_dims[] = {
// Square motion partitions
{64, 64}, {32, 32}, {16, 16}, {8, 8},
// Symmetric motion partitions
{64, 32}, {32, 64}, {32, 16}, {16, 32}, {16, 8}, {8, 16}, {8, 4}, {4, 8},
// Asymmetric motion partitions
{48, 16}, {16, 48}, {24, 16}, {16, 24}, {12, 4}, {4, 12}
};
sad_test_env.tested_func = strategies.strategies[i].fptr;
sad_test_env.strategy = &strategies.strategies[i];
int num_dim_tests = sizeof(tested_dims) / sizeof(tested_dims[0]);
for (int dim_test = 0; dim_test < num_dim_tests; ++dim_test) {
sad_test_env.width = tested_dims[dim_test].width;
sad_test_env.height = tested_dims[dim_test].height;
RUN_TEST(test_reg_sad);
RUN_TEST(test_reg_sad_overflow);
}
}
tear_down_tests();