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

📄 xvid_stat.c

📁 mpeg4代码,比较具体
💻 C
📖 第 1 页 / 共 2 页
字号:
      		framepsnr[filenr] = PSNR(XDIM,YDIM*3/2, in_buffer, XDIM, out_buffer, XDIM);			printf("dectime =%6.1f ms PSNR %5.2f\n",dectime, framepsnr[filenr]);		if (ARG_SAVEDECOUTPUT)		{			sprintf(filename, "%sdec%05d.pgm", filepath, filenr);			write_pgm(filename, out_buffer);		}		/* Read the header if it's pgm stream */ 		if (ARG_INPUTTYPE)			status = read_pgmheader(in_file);		filenr++;	} while ( (!status) && (filenr<ARG_MAXFRAMENR) );	      /***************************************************************************** *         Calculate totals and averages for output, print results ****************************************************************************/	totalsize    /= filenr;	totalenctime /= filenr;	totaldectime /= filenr;	for (i=0;i<filenr;i++)	{		switch (frame_type[i])		{		case 0:			Pframes++;			Ppsnr += framepsnr[i];			break;		case 1:			Iframes++;			Ipsnr += framepsnr[i];			break;		default:			break;		}	}		if (Pframes)		Ppsnr /= Pframes;		if (Iframes)		Ipsnr /= Iframes;		/* calculate statistics for every frametype: P,I */	for (i=0;i<filenr;i++)	{			switch (frame_type[i])		{		case 0:			if (framepsnr[i] > Pmaxpsnr)				Pmaxpsnr = framepsnr[i];			if (framepsnr[i] < Pminpsnr)				Pminpsnr = framepsnr[i];			Pvarpsnr += (framepsnr[i] - Ppsnr)*(framepsnr[i] - Ppsnr) /Pframes;			break;		case 1:			if (framepsnr[i] > Imaxpsnr)				Imaxpsnr = framepsnr[i];			if (framepsnr[i] < Pminpsnr)				Iminpsnr = framepsnr[i];			Ivarpsnr += (framepsnr[i] - Ipsnr)*(framepsnr[i] - Ipsnr) /Iframes;		default:			break;		}	}		/* Print all statistics */	printf("Avg. Q%1d %2s ",ARG_QUALITY, (ARG_QUANTI ? " q" : "br"));	printf("%04d ",(ARG_QUANTI)?ARG_QUANTI:ARG_BITRATE);	printf("( %.2f bpp) ", (double)ARG_BITRATE*1000/XDIM/YDIM/ARG_FRAMERATE);	printf("size %6d ", (int)totalsize);	printf("( %4d kbps ",(int)(totalsize*8*ARG_FRAMERATE/1000));	printf("/ %.2f bpp) ",(double)totalsize*8/XDIM/YDIM);	printf("enc: %6.1f fps, dec: %6.1f fps \n",1000/totalenctime, 1000/totaldectime);	printf("PSNR P(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Pframes,Ppsnr,Pminpsnr,Pmaxpsnr,sqrt(Pvarpsnr/filenr));	printf("I(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Iframes,Ipsnr,Iminpsnr,Imaxpsnr,sqrt(Ivarpsnr/filenr));	printf("\n");/***************************************************************************** *                            XviD PART  Stop ****************************************************************************/ release_all:	if (enc_handle)	{			status = enc_stop();		if (status)    			fprintf(stderr, "Encore RELEASE problem return value %d\n", status);	}	if (dec_handle)	{		status = dec_stop();		if (status)    			fprintf(stderr, "Decore RELEASE problem return value %d\n", status);	}	fclose(in_file); free_all_memory:	free(out_buffer);	free(divx_buffer);	free(in_buffer);	return 0;}/***************************************************************************** *                        "statistical" functions * *  these are not needed for encoding or decoding, but for measuring *  time and quality, there in nothing specific to XviD in these * *****************************************************************************//* Return time elapsed time in miliseconds since the program started */static double msecond(){	#ifndef WIN32	struct timeval  tv;	gettimeofday(&tv, 0);	return tv.tv_sec*1.0e3 + tv.tv_usec * 1.0e-3;#else	clock_t clk;	clk = clock();	return clk * 1000 / CLOCKS_PER_SEC;#endif}/*  * Returns the sum of squared distances (SSD) between two images of dimensions * x times y */static double absdistq(int x, int y,					   unsigned char* buf1, int stride1,					   unsigned char* buf2, int stride2){	double dist=0.;	int i,j,val;	for (i=0;i<y;i++)	{			val=0;		for (j=0;j<x;j++)			val+= ((int)buf1[j]-(int)buf2[j])*((int)buf1[j]-(int)buf2[j]);			dist += (double)val;		buf1 += stride1;		buf2 += stride2;	}	return dist/(x*y);}/* * Returns the PSNR between to images. * * This is a common logarithmic measure for "quality" from the world of signal * processing if you don't know what it is, simply accept that higher values * are better. * * PSNR represents the ratio of useful signal over noise signal. In our case, * useful signal is refernce image, noise signal is the difference between * reference and decoded frame from encoded bitstream. * * The problem is this type of value is dependant of image source and so, is * not reliable as a common "quality" indicator. * So PSNR computes the ratio of maximum/noise. Maximum being set to 2^bpp/channel * This way, PSNR is not dependant anymore of image data type. * */static double PSNR(int x, int y,				   unsigned char* buf1, int stride1,				   unsigned char* buf2, int stride2){	return 10*(log10(255*255)-log10( absdistq(x, y, buf1, stride1, buf2, stride2) ));}/***************************************************************************** *                             Usage message *****************************************************************************/static void usage(){	fprintf(stderr, "Usage : xvid_stat [OPTIONS]\n");	fprintf(stderr, "Options :\n");	fprintf(stderr, " -w integer     : frame width ([1.2048])\n");	fprintf(stderr, " -h integer     : frame height ([1.2048])\n");	fprintf(stderr, " -b integer     : target bitrate (>0 | default=900kbit)\n");	fprintf(stderr, " -f float       : target framerate (>0)\n");	fprintf(stderr, " -i string      : input filename (default=stdin)\n");	fprintf(stderr, " -t integer     : input data type (yuv=0, pgm=1)\n");	fprintf(stderr, " -n integer     : number of frames to encode\n");	fprintf(stderr, " -q integer     : quality ([0..5])\n");	fprintf(stderr, " -d boolean     : save decoder output (0 False*, !=0 True)\n");	fprintf(stderr, " -m boolean     : save mpeg4 raw stream (0 False*, !=0 True)\n");	fprintf(stderr, " -help          : prints this help message\n");	fprintf(stderr, " -quant integer : fixed quantizer (disables -b setting)\n");	fprintf(stderr, " (* means default)\n");}/***************************************************************************** *                       Input and output functions * *      the are small and simple routines to read and write PGM and YUV *      image. It's just for convenience, again nothing specific to XviD * *****************************************************************************/static int read_pgmheader(FILE* handle){		int bytes,xsize,ysize,depth;	char dummy[2];		bytes = fread(dummy,1,2,handle);	if ( (bytes < 2) || (dummy[0] != 'P') || (dummy[1] != '5' ))   		return 1;	fscanf(handle,"%d %d %d",&xsize,&ysize,&depth); 	if ( (xsize > 1440) || (ysize > 2880 ) || (depth != 255) )	{		fprintf(stderr,"%d %d %d\n",xsize,ysize,depth);	   	return 2;	}	if ( (XDIM==0) || (YDIM==0) )	{		XDIM=xsize;		YDIM=ysize*2/3;	}	return 0;}static int read_pgmdata(FILE* handle, unsigned char *image){		int i;	char dummy;		unsigned char *y = image;	unsigned char *u = image + XDIM*YDIM;	unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2; 	/* read Y component of picture */	fread(y, 1, XDIM*YDIM, handle); 	for (i=0;i<YDIM/2;i++)	{		/* read U */		fread(u, 1, XDIM/2, handle);		/* read V */		fread(v, 1, XDIM/2, handle);		/* Update pointers */		u += XDIM/2;		v += XDIM/2;	}    /*  I don't know why, but this seems needed */	fread(&dummy, 1, 1, handle);	return 0;}static int read_yuvdata(FILE* handle, unsigned char *image){   	if (fread(image, 1, IMAGE_SIZE(XDIM, YDIM), handle) != (unsigned int)IMAGE_SIZE(XDIM, YDIM)) 		return 1;	else			return 0;}static int write_pgm(char *filename, unsigned char *image){	int loop;	unsigned char *y = image;	unsigned char *u = image + XDIM*YDIM;	unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2;	FILE *filehandle;	filehandle=fopen(filename,"w+b");	if (filehandle)	{		/* Write header */		fprintf(filehandle,"P5\n\n%d %d 255\n", XDIM,YDIM*3/2);		/* Write Y data */		fwrite(y, 1, XDIM*YDIM, filehandle);		for(loop=0; loop<YDIM/2; loop++)		{			/* Write U scanline */			fwrite(u, 1, XDIM/2, filehandle);			/* Write V scanline */			fwrite(v, 1, XDIM/2, filehandle);			/* Update pointers */			u += XDIM/2;			v += XDIM/2;		}		/* Close file */		fclose(filehandle);		return 0;	}	else		return 1;}/***************************************************************************** *     Routines for encoding: init encoder, frame step, release encoder ****************************************************************************/#define FRAMERATE_INCR 1001/* Initialize encoder for first use, pass all needed parameters to the codec */static int enc_init(int use_assembler){	int xerr;		XVID_INIT_PARAM xinit;	XVID_ENC_PARAM xparam;	if(use_assembler) {#ifdef ARCH_IA64		xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;#else		xinit.cpu_flags = 0;#endif	}	else {		xinit.cpu_flags = XVID_CPU_FORCE;	}	xvid_init(NULL, 0, &xinit, NULL);	xparam.width = XDIM;	xparam.height = YDIM;	if ((ARG_FRAMERATE - (int)ARG_FRAMERATE) < SMALL_EPS)	{		xparam.fincr = 1;		xparam.fbase = (int)ARG_FRAMERATE;	}	else	{		xparam.fincr = FRAMERATE_INCR;		xparam.fbase = (int)(FRAMERATE_INCR * ARG_FRAMERATE);	}	xparam.rc_reaction_delay_factor = 16;    xparam.rc_averaging_period = 100;    xparam.rc_buffer = 10;	xparam.rc_bitrate = ARG_BITRATE*1000; 	xparam.min_quantizer = ARG_MINQUANT;	xparam.max_quantizer = ARG_MAXQUANT;	xparam.max_key_interval = (int)ARG_FRAMERATE*10;	/* I use a small value here, since will not encode whole movies, but short clips */	xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL);	enc_handle=xparam.handle;	return xerr;}static int enc_stop(){	int xerr;	xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL);	return xerr;}static int enc_main(unsigned char* image, unsigned char* bitstream,					unsigned char* hints_buffer,					long *streamlength, long* frametype, long* hints_size){	int xerr;	XVID_ENC_FRAME xframe;	XVID_ENC_STATS xstats;	xframe.bitstream = bitstream;	xframe.length = -1; 	/* this is written by the routine */	xframe.image = image;	xframe.colorspace = XVID_CSP_YV12;	/* defined in <xvid.h> */	xframe.intra = -1; /* let the codec decide between I-frame (1) and P-frame (0) */	xframe.quant = ARG_QUANTI;	/* is quant != 0, use a fixed quant (and ignore bitrate) */	xframe.motion = motion_presets[ARG_QUALITY];	xframe.general = general_presets[ARG_QUALITY];	xframe.quant_intra_matrix = xframe.quant_inter_matrix = NULL;	xframe.hint.hintstream = hints_buffer;	if(ARG_HINTMODE == HINT_MODE_SET) {		xframe.hint.hintlength = *hints_size;		xframe.hint.rawhints = 0;		xframe.general |= XVID_HINTEDME_SET;	}	if(ARG_HINTMODE == HINT_MODE_GET) {		xframe.hint.rawhints = 0;		xframe.general |= XVID_HINTEDME_GET;	}	xerr = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xframe, &xstats);	if(ARG_HINTMODE == HINT_MODE_GET)		*hints_size = xframe.hint.hintlength;	/*	 * This is statictical data, e.g. for 2-pass. If you are not	 * interested in any of this, you can use NULL instead of &xstats	 */	*frametype = xframe.intra;	*streamlength = xframe.length;	return xerr;}/***************************************************************************** * Routines for decoding: init encoder, frame step, release encoder ****************************************************************************//* init decoder before first run */static int dec_init(int use_assembler){	int xerr;	XVID_INIT_PARAM xinit;	XVID_DEC_PARAM xparam;	if(use_assembler)#ifdef ARCH_IA64		xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;#else	xinit.cpu_flags = 0;#endif	else		xinit.cpu_flags = XVID_CPU_FORCE;	xvid_init(NULL, 0, &xinit, NULL);	xparam.width = XDIM;	xparam.height = YDIM;	xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);	dec_handle = xparam.handle;	return xerr;}/* decode one frame  */static int dec_main(unsigned char *m4v_buffer, unsigned char *out_buffer,					int m4v_size){	int xerr;	XVID_DEC_FRAME xframe;	xframe.bitstream = m4v_buffer;	xframe.length = m4v_size;	xframe.image = out_buffer;	xframe.stride = XDIM;	xframe.colorspace = XVID_CSP_YV12;             /* XVID_CSP_USER is fastest (no memcopy involved) */	xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, NULL);	return xerr;}/* close decoder to release resources */static int dec_stop(){	int xerr;	xerr = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);	return xerr;}/* EOF */

⌨️ 快捷键说明

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