📄 dct-test.c
字号:
#if 1 // dump systematic errors for(i=0; i<64; i++){ if(i%8==0) printf("\n"); printf("%5d ", (int)sysErr[i]); } printf("\n");#endif printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", is_idct ? "IDCT" : "DCT", name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);#if 1 //Speed test /* speed test */ for(i=0;i<64;i++) block1[i] = 0; switch(test){ case 0: for(i=0;i<64;i++) block1[i] = (random() % 512) -256; if (is_idct){ fdct(block1); for(i=0;i<64;i++) block1[i]>>=3; } break; case 1:{ case 2: block1[0] = (random() % 512) -256; block1[1] = (random() % 512) -256; block1[2] = (random() % 512) -256; block1[3] = (random() % 512) -256; }break; } if (form == MMX_PERM) { for(i=0;i<64;i++) block[idct_mmx_perm[i]] = block1[i]; } else if(form == MMX_SIMPLE_PERM) { for(i=0;i<64;i++) block[idct_simple_mmx_perm[i]] = block1[i]; } else { for(i=0; i<64; i++) block[i]= block1[i]; } ti = gettime(); it1 = 0; do { for(it=0;it<NB_ITS_SPEED;it++) { for(i=0; i<64; i++) block[i]= block1[i];// memcpy(block, block1, sizeof(DCTELEM) * 64);// do not memcpy especially not fastmemcpy because it does movntq !!! fdct_func(block); } it1 += NB_ITS_SPEED; ti1 = gettime() - ti; } while (ti1 < 1000000); emms_c(); printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", name, (double)it1 * 1000.0 / (double)ti1);#endif}static uint8_t img_dest[64] __attribute__ ((aligned (8)));static uint8_t img_dest1[64] __attribute__ ((aligned (8)));void idct248_ref(uint8_t *dest, int linesize, int16_t *block){ static int init; static double c8[8][8]; static double c4[4][4]; double block1[64], block2[64], block3[64]; double s, sum, v; int i, j, k; if (!init) { init = 1; for(i=0;i<8;i++) { sum = 0; for(j=0;j<8;j++) { s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0); c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0); sum += c8[i][j] * c8[i][j]; } } for(i=0;i<4;i++) { sum = 0; for(j=0;j<4;j++) { s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0); c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0); sum += c4[i][j] * c4[i][j]; } } } /* butterfly */ s = 0.5 * sqrt(2.0); for(i=0;i<4;i++) { for(j=0;j<8;j++) { block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s; block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s; } } /* idct8 on lines */ for(i=0;i<8;i++) { for(j=0;j<8;j++) { sum = 0; for(k=0;k<8;k++) sum += c8[k][j] * block1[8*i+k]; block2[8*i+j] = sum; } } /* idct4 */ for(i=0;i<8;i++) { for(j=0;j<4;j++) { /* top */ sum = 0; for(k=0;k<4;k++) sum += c4[k][j] * block2[8*(2*k)+i]; block3[8*(2*j)+i] = sum; /* bottom */ sum = 0; for(k=0;k<4;k++) sum += c4[k][j] * block2[8*(2*k+1)+i]; block3[8*(2*j+1)+i] = sum; } } /* clamp and store the result */ for(i=0;i<8;i++) { for(j=0;j<8;j++) { v = block3[8*i+j]; if (v < 0) v = 0; else if (v > 255) v = 255; dest[i * linesize + j] = (int)rint(v); } }}void idct248_error(const char *name, void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block)){ int it, i, it1, ti, ti1, err_max, v; srandom(0); /* just one test to see if code is correct (precision is less important here) */ err_max = 0; for(it=0;it<NB_ITS;it++) { /* XXX: use forward transform to generate values */ for(i=0;i<64;i++) block1[i] = (random() % 256) - 128; block1[0] += 1024; for(i=0; i<64; i++) block[i]= block1[i]; idct248_ref(img_dest1, 8, block); for(i=0; i<64; i++) block[i]= block1[i]; idct248_put(img_dest, 8, block); for(i=0;i<64;i++) { v = abs((int)img_dest[i] - (int)img_dest1[i]); if (v == 255) printf("%d %d\n", img_dest[i], img_dest1[i]); if (v > err_max) err_max = v; }#if 0 printf("ref=\n"); for(i=0;i<8;i++) { int j; for(j=0;j<8;j++) { printf(" %3d", img_dest1[i*8+j]); } printf("\n"); } printf("out=\n"); for(i=0;i<8;i++) { int j; for(j=0;j<8;j++) { printf(" %3d", img_dest[i*8+j]); } printf("\n"); }#endif } printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max); ti = gettime(); it1 = 0; do { for(it=0;it<NB_ITS_SPEED;it++) { for(i=0; i<64; i++) block[i]= block1[i];// memcpy(block, block1, sizeof(DCTELEM) * 64);// do not memcpy especially not fastmemcpy because it does movntq !!! idct248_put(img_dest, 8, block); } it1 += NB_ITS_SPEED; ti1 = gettime() - ti; } while (ti1 < 1000000); emms_c(); printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name, (double)it1 * 1000.0 / (double)ti1);}void help(void){ printf("dct-test [-i] [<test-number>]\n" "test-number 0 -> test with random matrixes\n" " 1 -> test with random sparse matrixes\n" " 2 -> do 3. test from mpeg4 std\n" "-i test IDCT implementations\n" "-4 test IDCT248 implementations\n");}int main(int argc, char **argv){ int test_idct = 0, test_248_dct = 0; int c,i; int test=1; init_fdct(); idct_mmx_init(); for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; for(i=0;i<MAX_NEG_CROP;i++) { cropTbl[i] = 0; cropTbl[i + MAX_NEG_CROP + 256] = 255; } for(;;) { c = getopt(argc, argv, "ih4"); if (c == -1) break; switch(c) { case 'i': test_idct = 1; break; case '4': test_248_dct = 1; break; default : case 'h': help(); return 0; } } if(optind <argc) test= atoi(argv[optind]); printf("ffmpeg DCT/IDCT test\n"); if (test_248_dct) { idct248_error("SIMPLE-C", ff_simple_idct248_put); } else { for (i=0;algos[i].name;i++) if (algos[i].is_idct == test_idct) { dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -