diff --git a/tests/sad_tests.c b/tests/sad_tests.c index 2ee04a82..fa0f1b47 100644 --- a/tests/sad_tests.c +++ b/tests/sad_tests.c @@ -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();