⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xvid_bench.c

📁 mpeg4 video codec mpeg4 video codec
💻 C
📖 第 1 页 / 共 4 页
字号:
	nb = 0;	pos = 0;	t = -gettime_usec();	while(1) {	  int y;		memset(&xframe, 0, sizeof(xframe));		xframe.version = XVID_VERSION;		xframe.bitstream = buf + pos;		xframe.length = buf_size - pos;		xframe.output.plane[0] = (uint8_t*)(((size_t)yuv_out + 15) & ~15);		xframe.output.plane[1] = (uint8_t*)xframe.output.plane[0] + bps*height;		xframe.output.plane[2] = (uint8_t*)xframe.output.plane[1] + bps/2;		xframe.output.stride[0] = bps;		xframe.output.stride[1] = bps;		xframe.output.stride[2] = bps;		xframe.output.csp = XVID_CSP_I420;		xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);		if (xerr<0) {			printf("ERROR: decoding failed for frame #%d (err=%d)!\n", nb, xerr);			break;		}		else if (xerr==0)		  break;    else if (verbose>0) printf("#%d %d\n", nb, xerr );		pos += xerr;		nb++;    for(y=0; y<height/2; ++y) {		  chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+0)*bps, width, chksum);			chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+1)*bps, width, chksum);			chksum = calc_crc((uint8_t*)xframe.output.plane[1] + y*bps, width/2, chksum);			chksum = calc_crc((uint8_t*)xframe.output.plane[2] + y*bps, width/2, chksum);		}		if (pos==buf_size)			break;	}	t += gettime_usec();	if (ref_chksum==0) {	  if (t>0.)		  printf( "%d frames decoded in %.3f s -> %.1f FPS   Checksum:0x%.8x\n", nb, t*1.e-6f, (float)(nb*1.e6f/t), chksum );  }  else {    		printf("FPS:%.1f Checksum: 0x%.8x Expected:0x%.8x | %s\n", 		  t>0. ? (float)(nb*1.e6f/t) : 0.f, chksum, ref_chksum, (chksum==ref_chksum) ? "OK" : "ERROR");  } End:	if (yuv_out!=0) free(yuv_out);	if (buf!=0) free(buf);	if (dechandle!=0) {		xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);		if (xerr==XVID_ERR_FAIL)			printf("ERROR: destroy-decoder failed (err=%d)!\n", xerr);	}	if (f!=0) fclose(f);}/********************************************************************* * non-regression tests *********************************************************************/void test_bugs1(){	CPU *cpu;	uint16_t mpeg_quant_matrices[64*8];	printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );	for(cpu = cpu_list; cpu->name!=0; ++cpu)	{		int i;		int16_t  Src[8*8], Dst[8*8];		if (!init_cpu(cpu))			continue;		for(i=0; i<64; ++i) Src[i] = i-32;		set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );		dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);		printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);		printf( "  Out[]= " );		for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);		printf( "\n" );	}	printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );	for(cpu = cpu_list; cpu->name!=0; ++cpu)	{		int i;		int16_t  Src[8*8], Dst[8*8];		if (!init_cpu(cpu))			continue;		for(i=0; i<64; ++i) Src[i] = i-32;		set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );		dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);		printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);		printf( "  Out[]= " );		for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);		printf( "\n" ); 	}}void test_dct_precision_diffs(){	CPU *cpu;	DECLARE_ALIGNED_MATRIX(Blk, 8, 8, int16_t, 16);	DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, int16_t, 16);	printf( "\n =====  fdct/idct precision diffs =====\n" );	for(cpu = cpu_list; cpu->name!=0; ++cpu)	{		int i;		if (!init_cpu(cpu))			continue;		for(i=0; i<8*8; ++i) {			Blk0[i] = (i*7-i*i) & 0x7f;			Blk[i] = Blk0[i];		}		fdct(Blk);		idct(Blk);		printf( " fdct+idct diffs with CPU=%s: \n", cpu->name );		for(i=0; i<8; ++i) {			int j;			for(j=0; j<8; ++j) printf( " %d ", Blk[i*8+j]-Blk0[i*8+j]); 			printf("\n"); 		}		printf("\n"); 	}}void test_quant_bug(){	const int max_Q = 31;	int i, n, qm, q;	CPU *cpu;	DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);	DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);	uint8_t Quant[8*8];	CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };	uint16_t Crcs_Inter[2][32];	uint16_t Crcs_Intra[2][32];	DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);	printf( "\n =====  test MPEG4-quantize bug =====\n" );	for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;#if 1	for(qm=1; qm<=255; ++qm)	{		for(i=0; i<8*8; ++i) Quant[i] = qm;		set_inter_matrix( mpeg_quant_matrices, Quant );		for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)		{			uint16_t s;			if (!init_cpu(cpu))				continue;			for(q=1; q<=max_Q; ++q) {				emms();				quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );				emms();				for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;				Crcs_Inter[n][q] = s;			}		}		for(q=1; q<=max_Q; ++q)			for(i=0; i<n-1; ++i)				if (Crcs_Inter[i][q]!=Crcs_Inter[i+1][q])					printf( "Discrepancy Inter: qm=%d, q=%d  -> %d/%d !\n",							qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);	}#endif#if 1	for(qm=1; qm<=255; ++qm)	{		for(i=0; i<8*8; ++i) Quant[i] = qm;		set_intra_matrix( mpeg_quant_matrices, Quant );		for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)		{			uint16_t s;			if (!init_cpu(cpu))				continue;			for(q=1; q<=max_Q; ++q) {				emms();				quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);				emms();				for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;				Crcs_Intra[n][q] = s;			}		}		for(q=1; q<=max_Q; ++q)			for(i=0; i<n-1; ++i)				if (Crcs_Intra[i][q]!=Crcs_Intra[i+1][q])					printf( "Discrepancy Intra: qm=%d, q=%d  -> %d/%d!\n",							qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);	}#endif}/*********************************************************************/static uint32_t __inline log2bin_v1(uint32_t value){  int n = 0;  while (value) {    value >>= 1;    n++;  }  return n;}static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };static uint32_t __inline log2bin_v2(uint32_t value){  int n = 0;  if (value & 0xffff0000) {    value >>= 16;    n += 16;  }  if (value & 0xff00) {    value >>= 8;    n += 8;  }  if (value & 0xf0) {    value >>= 4;    n += 4;  } return n + log2_tab_16[value];}void test_log2bin(){	const int nb_tests = 3000*speed_ref;  int n, crc1=0, crc2=0;  uint32_t s, s0;  double t1, t2;  t1 = gettime_usec();  s0 = (int)(t1*31.241);  for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)    crc1 += log2bin_v1(s);  t1 = (gettime_usec()-t1) / nb_tests;  t2 = gettime_usec();  for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)    crc2 += log2bin_v2(s);  t2 = (gettime_usec() - t2) / nb_tests;  printf( "log2bin_v1: %.3f sec  crc=%d\n", t1, crc1 );  printf( "log2bin_v2: %.3f sec  crc=%d\n", t2, crc2 );  if (crc1!=crc2) printf( " CRC ERROR !\n" );}/*********************************************************************/static void __inline old_gcd(int *num, int *den){ int i = *num;  while (i > 1) {       if (*num % i == 0 && *den % i == 0) {      *num /= i;         *den /= i;      i = *num;      continue;    }    i--;  }}static uint32_t gcd(int num, int den){  int tmp;  while( (tmp=num%den) ) { num = den; den = tmp; }  return den;}static void __inline new_gcd(int *num, int *den){  const int div = gcd(*num, *den);  if (num) {    *num /= div;    *den /= div;  }}void test_gcd(){	const int nb_tests = 10*speed_ref;  int i;  uint32_t crc1=0, crc2=0;  uint32_t n0, n, d0, d;  double t1, t2;  t1 = gettime_usec();  n0 = 0xfffff & (int)(t1*31.241);  d0 = 0xfffff & (int)( ((n0*4123)%17) | 1 );  for(n=n0, d=d0, i=0; i<nb_tests; ++i) {    old_gcd(&n, &d);    crc1 = (((crc1>>4)^d) + ((crc1<<2)^n) ) & 0xffffff;    n = d;    d = (d*12363+31) & 0xffff;    d |= !d;  }  t1 = (gettime_usec()-t1) / nb_tests;  t2 = gettime_usec();  for(n=n0, d=d0, i=0; i<nb_tests; ++i) {    new_gcd(&n, &d);    crc2 = (((crc2>>4)^d) + ((crc2<<2)^n) ) & 0xffffff;    n = d;    d = (d*12363+31) & 0xffff;    d |= !d;  }  t2 = (gettime_usec() - t2) / nb_tests;  printf( "old_gcd: %.3f sec  crc=%d\n", t1, crc1 );  printf( "new_gcd: %.3f sec  crc=%d\n", t2, crc2 );  if (crc1!=crc2) printf( " CRC ERROR !\n" );}/********************************************************************* * test compiler *********************************************************************/void test_compiler() {  int nb_err = 0;  int32_t v;  if (sizeof(uint16_t)<2) {    printf( "ERROR: sizeof(uint16_t)<2 !!\n" );    nb_err++;  }  if (sizeof(int16_t)<2) {    printf( "ERROR: sizeof(int16_t)<2 !!\n" );    nb_err++;  }  if (sizeof(uint8_t)!=1) {    printf( "ERROR: sizeof(uint8_t)!=1 !!\n" );    nb_err++;  }  if (sizeof(int8_t)!=1) {    printf( "ERROR: sizeof(int8_t)!=1 !!\n" );    nb_err++;  }  if (sizeof(uint32_t)<4) {    printf( "ERROR: sizeof(uint32_t)<4 !!\n" );    nb_err++;  }  if (sizeof(int32_t)<4) {    printf( "ERROR: sizeof(int32_t)<4 !!\n" );    nb_err++;  }         /* yes, i know, this test is silly. But better be safe than sorry. :) */  for(v=1000; v>=0; v--) {    if ( (v>>2) != v/4)      nb_err++;  }  for(v=-1000; v!=-1; v++) {    if ( (v>>2) != (v/4)-!!(v%4))      nb_err++;  }  if (nb_err!=0) {    printf( "ERROR! please post your platform/compiler specs to xvid-devel@xvid.org !\n" );  }}/********************************************************************* * main *********************************************************************/static void arg_missing(const char *opt){  printf( "missing argument after option '%s'\n", opt);  exit(-1);}int main(int argc, const char *argv[]){	int c, what = 0;	int width, height;	uint32_t chksum = 0;  const char * test_bitstream = 0;	cpu_mask = 0;  // default => will use autodectect	for(c=1; c<argc; ++c)	{	  if (!strcmp(argv[c], "-v")) verbose++;	  else if (!strcmp(argv[c], "-c"))      cpu_mask = 0 /* PLAIN_C */ | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-mmx"))    cpu_mask = XVID_CPU_MMX    | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-mmxext")) cpu_mask = XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-sse2"))   cpu_mask = XVID_CPU_SSE2   | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-3dnow"))  cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-3dnowe")) cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_3DNOWEXT | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-altivec")) cpu_mask = XVID_CPU_ALTIVEC | XVID_CPU_FORCE;	  else if (!strcmp(argv[c], "-spd")) {      if (++c==argc) arg_missing( argv[argc-1] );      speed_ref = atoi(argv[c]);    }	  else if (argv[c][0]!='-') {	    what = atoi(argv[c]);	    if (what==9) {	      if (c+4>argc) {	        printf("usage: %s %d bitstream width height (checksum)\n", argv[0], what);	        exit(-1);        }        test_bitstream = argv[++c];	      width  = atoi(argv[++c]);	      height = atoi(argv[++c]);	      if (c+1<argc && argv[c+1][0]!='-') {	        if (sscanf(argv[c+1], "0x%x", &chksum)!=1) {	          printf( "can't read checksum value.\n" );	          exit(-1);          }          else c++;        }//        printf( "[%s] %dx%d (0x%.8x)\n", test_bitstream, width, height, chksum);      }    }    else {      printf( "unrecognized option '%s'\n", argv[c]);      exit(-1);    }  }	if (what==0 || what==1) test_dct();	if (what==0 || what==2) test_mb();	if (what==0 || what==3) test_sad();	if (what==0 || what==4) test_transfer();	if (what==0 || what==5) test_quant();	if (what==0 || what==6) test_cbp();	if (what==0 || what==10) test_sse();	if (what==0 || what==11) test_log2bin();	if (what==0 || what==12) test_gcd();	if (what==0 || what==13) test_compiler();	if (what==7) {		test_IEEE1180_compliance(-256, 255, 1);		test_IEEE1180_compliance(-256, 255,-1);		test_IEEE1180_compliance(  -5,   5, 1);		test_IEEE1180_compliance(  -5,   5,-1);		test_IEEE1180_compliance(-300, 300, 1);		test_IEEE1180_compliance(-300, 300,-1);	}	if (what==8) test_dct_saturation(-256, 255);	if (test_bitstream)	  test_dec(test_bitstream, width, height, chksum);	if (what==-1) {		test_dct_precision_diffs();		test_bugs1();	}	if (what==-2)		test_quant_bug();	if ((what >= 0 && what <= 6) || what == 10) {		printf("\n\n"			   "NB: If a function isn't optimised for a specific set of intructions,\n"			   "    a C function is used instead. So don't panic if some functions\n"			   "    may appear to be slow.\n");	}#ifdef ARCH_IS_IA32	if (what == 0 || what == 5) {		printf("\n"			   "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"			   "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"			   "    test goes far behind the usual limits of real encoding. Please do not report\n"			   "    this error to the developers.\n");	}#endif	return 0;}/*********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -