X-Git-Url: https://git.sesse.net/?p=fjl;a=blobdiff_plain;f=idct_test.c;h=bd39c7467e5f0e79ff361daf7b97df92968a55c1;hp=b4cec384353703be6fb547b4db84114a1bb11eeb;hb=19a58db08afd149a862506936093423db756a2dc;hpb=7a58d5cefdccb21fb1bfb1b86a816fd686ccce66 diff --git a/idct_test.c b/idct_test.c index b4cec38..bd39c74 100644 --- a/idct_test.c +++ b/idct_test.c @@ -3,10 +3,12 @@ #include #include #include -#include -#include +#include "benchmark.h" #include "idct.h" +#include "idct_reference.h" +#include "idct_float.h" +#include "idct_imprecise_int.h" // Generate random coefficients in the range [-15..15]. void gen_random_coeffs(int16_t* dst, size_t len) @@ -26,23 +28,26 @@ void gen_random_coeffs(int16_t* dst, size_t len) // Test that the input is pretty close to the reference for random inputs. // (If the reference funtion is given in, this becomes a simple test of its // determinism.) -void test_random_inputs(idct_func_t* idct) +void test_random_inputs(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct) { int16_t coeff[DCTSIZE2]; uint32_t quant[DCTSIZE2]; uint8_t output[DCTSIZE2]; uint8_t reference[DCTSIZE2]; - + // Unit quantization (ie., no scaling). for (unsigned i = 0; i < DCTSIZE2; ++i) { quant[i] = 1; } + + void* userdata_reference = idct_reference_alloc(quant); + void* userdata = idct_alloc(quant); for (unsigned i = 0; i < 1000; ++i) { gen_random_coeffs(coeff, DCTSIZE2); - (*idct)(coeff, quant, output); - (idct_reference)(coeff, quant, reference); + (*idct)(coeff, userdata, output); + (idct_reference)(coeff, userdata_reference, reference); // Find the RMS difference. int diff_squared = 0; @@ -52,30 +57,42 @@ void test_random_inputs(idct_func_t* idct) assert(diff_squared <= 5); } + + idct_reference_free(userdata_reference); + idct_free(userdata); } // Test that a single DC coefficient becomes spread out to all blocks. -void test_dc_becomes_spread_out(idct_func_t* idct) +void test_dc_becomes_spread_out(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct) { int16_t coeff[DCTSIZE2] = { 0 }; uint32_t quant[DCTSIZE2]; uint8_t output[DCTSIZE2]; - + // Unit quantization (ie., no scaling). for (unsigned i = 0; i < DCTSIZE2; ++i) { quant[i] = 1; } - for (unsigned i = 0; i < 255*8; ++i) { - uint32_t reference_value = i / 8; + void* userdata = idct_alloc(quant); + + for (unsigned i = -255*8; i < 255*16; ++i) { + int reference_value = i / 8 + 128; + if (reference_value < 0) { + reference_value = 0; + } else if (reference_value > 255) { + reference_value = 255; + } coeff[0] = i; - (*idct)(coeff, quant, output); + (*idct)(coeff, userdata, output); for (unsigned i = 0; i < DCTSIZE2; ++i) { assert(abs(output[i] - reference_value) <= 1); } } + + idct_free(userdata); } double timediff(const struct timeval* a, const struct timeval* b) @@ -84,7 +101,7 @@ double timediff(const struct timeval* a, const struct timeval* b) (double)(b->tv_usec - a->tv_usec) * 1e-6; } -void test_performance(idct_func_t* idct) +void test_performance(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct) { const unsigned num_runs = (idct == idct_reference) ? 5000 : 5000000; @@ -99,36 +116,43 @@ void test_performance(idct_func_t* idct) quant[i] = 1; } - struct timeval start, now; - gettimeofday(&start, NULL); + void* userdata = idct_alloc(quant); + + start_benchmark_timer(); for (unsigned i = 0; i < num_runs; ++i) { - (*idct)(coeff, quant, output); + (*idct)(coeff, userdata, output); } - gettimeofday(&now, NULL); - - double diff = timediff(&start, &now); - printf("%u runs in %.2f seconds = %.2f DCTs/sec\n", + double diff = stop_benchmark_timer(); + printf("%u runs in %.2f CPU seconds = %.2f IDCTs/sec\n", num_runs, diff, num_runs / diff); + + idct_free(userdata); } -void test_all_idct(idct_func_t* idct) +void test_all_idct(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct) { printf(" test_dc_becomes_spread_out()\n"); - test_dc_becomes_spread_out(idct); + test_dc_becomes_spread_out(idct_alloc, idct_free, idct); printf(" test_random_inputs()\n"); - test_random_inputs(idct); + test_random_inputs(idct_alloc, idct_free, idct); printf(" performance test: "); - test_performance(idct); + test_performance(idct_alloc, idct_free, idct); } int main(void) { printf("idct_reference:\n"); - test_all_idct(idct_reference); + test_all_idct(idct_reference_alloc, idct_reference_free, idct_reference); + + printf("idct_float:\n"); + test_all_idct(idct_float_alloc, idct_float_free, idct_float); + + printf("idct_imprecise_int:\n"); + test_all_idct(idct_imprecise_int_alloc, idct_imprecise_int_free, idct_imprecise_int); printf("All tests pass.\n"); return 0;