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

📄 xvid_decraw.c

📁 xvid解码的精简版本.非常好的版本,节省了分离xvid源代码的过程
💻 C
字号:
/***************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - Console based decoding test application  - * *  Copyright(C) 2002-2003 Christoph Lampert *               2002-2003 Edouard Gomez <ed.gomez@free.fr> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * * $Id: xvid_decraw.c,v 1.22 2005/10/07 15:02:28 suxen_drol Exp $ * ****************************************************************************//***************************************************************************** *		                     *  Application notes : *		                     *  An MPEG-4 bitstream is read from an input file (or stdin) and decoded, *  the speed for this is measured. * *  The program is plain C and needs no libraries except for libxvidcore,  *  and maths-lib. *		                    *  Use ./xvid_decraw -help for a list of options *  ****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "xvid.h"/***************************************************************************** *               Global vars in module and constants ****************************************************************************/#define USE_PNM 0#define USE_TGA 1static int XDIM = 0;static int YDIM = 0;static int ARG_SAVEDECOUTPUT = 0;static int ARG_SAVEMPEGSTREAM = 0;static char *ARG_INPUTFILE = NULL;
static char *ARG_OUTPUTFILE = NULL;static int CSP = XVID_CSP_I420;static int BPP = 1;static int FORMAT = USE_PNM;static char filepath[256] = "./";static void *dec_handle = NULL;#define BUFFER_SIZE (2*1024*1024)static const int display_buffer_bytes = 0;#define MIN_USEFUL_BYTES 1/***************************************************************************** *               Local prototypes ****************************************************************************/static int dec_init(int use_assembler, int debug_level);static int dec_main(unsigned char *istream,					unsigned char *ostream,					int istream_size,					xvid_dec_stats_t *xvid_dec_stats);static int dec_stop();static void usage();static int write_image(char *prefix, unsigned char *image);const char * type2str(int type){    if (type==XVID_TYPE_IVOP)        return "I";    if (type==XVID_TYPE_PVOP)        return "P";    if (type==XVID_TYPE_BVOP)        return "B";    return "S";}/***************************************************************************** *        Main program ****************************************************************************/int main(int argc, char *argv[]){	unsigned char *mp4_buffer = NULL;	unsigned char *mp4_ptr    = NULL;	unsigned char *out_buffer = NULL;	int useful_bytes;	int chunk;	xvid_dec_stats_t xvid_dec_stats;		  	long totalsize;	int status;  	int use_assembler = 0;	int debug_level = 0;  	char filename[256];  	FILE *in_file;
	FILE *out_file=NULL;	int filenr;	int i;	printf("xvid_decraw - raw mpeg4 bitstream decoder ");	printf("written by Christoph Lampert 2002-2003\n\n");/***************************************************************************** * Command line parsing ****************************************************************************/	for (i=1; i< argc; i++) { 		if (strcmp("-asm", argv[i]) == 0 ) {			use_assembler = 1;		} else if (strcmp("-debug", argv[i]) == 0 && i < argc - 1 ) {			i++;			if (sscanf(argv[i], "0x%x", &debug_level) != 1) {				debug_level = atoi(argv[i]);			}		} else if (strcmp("-d", argv[i]) == 0) {			ARG_SAVEDECOUTPUT = 1;		} else if (strcmp("-i", argv[i]) == 0 && i < argc - 1 ) {			i++;			ARG_INPUTFILE = argv[i];		}else if (strcmp("-o", argv[i]) == 0 && i < argc - 1 ) {
			i++;
			ARG_OUTPUTFILE = argv[i];
		} else if (strcmp("-m", argv[i]) == 0) {			ARG_SAVEMPEGSTREAM = 1;		}  else if (strcmp("-help", argv[i]) == 0) {			usage();			return(0);		} else {			usage();			exit(-1);		}	}  #if defined(_MSC_VER)	if (ARG_INPUTFILE==NULL) {		fprintf(stderr, "Warning: MSVC build does not read EOF correctly from stdin. Use the -i switch.\n\n");	}#endif/***************************************************************************** * Values checking ****************************************************************************/	if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) {		in_file = stdin;	}	else {		in_file = fopen(ARG_INPUTFILE, "rb");		if (in_file == NULL) {			fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE);			return(-1);		}	}
        out_file = fopen(ARG_OUTPUTFILE,"wb+");	/* PNM/PGM format can't handle 16/32 bit data */	if (BPP != 1 && BPP != 3 && FORMAT == USE_PNM) {		FORMAT = USE_TGA;	}/***************************************************************************** *        Memory allocation ****************************************************************************/	/* Memory for encoded mp4 stream */	mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);	mp4_ptr = mp4_buffer;	if (!mp4_buffer)		goto free_all_memory;	    /***************************************************************************** *        XviD PART  Start ****************************************************************************/	status = dec_init(use_assembler, debug_level);	if (status) {		fprintf(stderr,				"Decore INIT problem, return value %d\n", status);		goto release_all;	}/***************************************************************************** *	                         Main loop ****************************************************************************/	/* Fill the buffer */	useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, in_file);		totalsize = 0;	filenr = 0;	mp4_ptr = mp4_buffer;	chunk = 0;		do {		int used_bytes = 0;				/*		 * If the buffer is half empty or there are no more bytes in it		 * then fill it.		 */		if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2) {			int already_in_buffer = (mp4_buffer + BUFFER_SIZE - mp4_ptr);			/* Move data if needed */			if (already_in_buffer > 0)				memcpy(mp4_buffer, mp4_ptr, already_in_buffer);			/* Update mp4_ptr */			mp4_ptr = mp4_buffer; 			/* read new data */            if(feof(in_file))				break;			useful_bytes += fread(mp4_buffer + already_in_buffer,								  1, BUFFER_SIZE - already_in_buffer,								  in_file);		}		/* This loop is needed to handle VOL/NVOP reading */		do {			/* Decode frame */						used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats);						/* Resize image buffer if needed */			if(xvid_dec_stats.type == XVID_TYPE_VOL) {				/* Check if old buffer is smaller */				if(XDIM*YDIM < xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height) {					/* Copy new witdh and new height from the vol structure */					XDIM = xvid_dec_stats.data.vol.width;					YDIM = xvid_dec_stats.data.vol.height;					/* Free old output buffer*/					if(out_buffer) free(out_buffer);					/* Allocate the new buffer */					out_buffer = (unsigned char*)malloc(XDIM*YDIM*4);					if(out_buffer == NULL)						goto free_all_memory;					fprintf(stderr, "Resized frame buffer to %dx%d\n", XDIM, YDIM);				}							}			/* Update buffer pointers */			if(used_bytes > 0) {				mp4_ptr += used_bytes;				useful_bytes -= used_bytes;				/* Total size */				totalsize += used_bytes;			}			if (display_buffer_bytes) {				printf("Data chunk %d: %d bytes consumed, %d bytes in buffer\n", chunk++, used_bytes, useful_bytes);			}		} while (xvid_dec_stats.type <= 0 && useful_bytes > MIN_USEFUL_BYTES);		/* Check if there is a negative number of useful bytes left in buffer		 * This means we went too far */        if(useful_bytes < 0)            break;		    	/* Updated data - Count only usefull decode time */							/* Save individual mpeg4 stream if required */		if(ARG_SAVEMPEGSTREAM) {			FILE *filehandle = NULL;			sprintf(filename, "%sframe%05d.m4v", filepath, filenr);			filehandle = fopen(filename, "wb");			if(!filehandle) {				fprintf(stderr,						"Error writing single mpeg4 stream to file %s\n",						filename);			}			else {				fwrite(mp4_ptr-used_bytes, 1, used_bytes, filehandle);				fclose(filehandle);			}		}						/* Save output frame if required */		if (ARG_SAVEDECOUTPUT) {					
			fwrite(out_buffer,1,1.5*XDIM*YDIM,out_file);		}         		} while (useful_bytes>MIN_USEFUL_BYTES || !feof(in_file));	useful_bytes = 0; /* Empty buffer *//***************************************************************************** *     Flush decoder buffers ****************************************************************************/	do {		/* Fake vars */		int used_bytes;		        do {		   		    used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats);		   			if (display_buffer_bytes) {				printf("Data chunk %d: %d bytes consumed, %d bytes in buffer\n", chunk++, used_bytes, useful_bytes);			}        } while(used_bytes>=0 && xvid_dec_stats.type <= 0);        if (used_bytes < 0) {   /* XVID_ERR_END */            break;        }		/* Updated data - Count only usefull decode time */				/* Prints some decoding stats */		if (!display_buffer_bytes) {			printf("Frame %5d: type = %s,  length(bytes) =%7d\n",					filenr, type2str(xvid_dec_stats.type),  used_bytes);		}		/* Save output frame if required */				}while(1);	/***************************************************************************** *     Calculate totals and averages for output, print results ****************************************************************************/	/***************************************************************************** *      XviD PART  Stop ****************************************************************************/ release_all:  	if (dec_handle) {	  	status = dec_stop();		if (status)    			fprintf(stderr, "decore RELEASE problem return value %d\n", status);	} free_all_memory:	free(out_buffer);	free(mp4_buffer);	return(0);}/***************************************************************************** *               Usage function ****************************************************************************/static void usage(){	fprintf(stderr, "Usage : xvid_decraw [OPTIONS]\n");	fprintf(stderr, "Options :\n");	fprintf(stderr, " -asm           : use assembly optimizations (default=disabled)\n");	fprintf(stderr, " -debug         : debug level (debug=0)\n");	fprintf(stderr, " -i string      : input filename (default=stdin)\n");
	fprintf(stderr, " -o string      : output filename (default=NULL)\n");	fprintf(stderr, " -d             : save decoder output\n");	fprintf(stderr, " -m             : save mpeg4 raw stream to individual files\n");	fprintf(stderr, " -help          : This help message\n");	fprintf(stderr, " (* means default)\n");}/***************************************************************************** * Routines for decoding: init decoder, use, and stop decoder ****************************************************************************//* init decoder before first run */static intdec_init(int use_assembler, int debug_level){	int ret;	xvid_gbl_init_t   xvid_gbl_init;	xvid_dec_create_t xvid_dec_create;	/* Reset the structure with zeros */	memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t));	memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t));	/*------------------------------------------------------------------------	 * XviD core initialization	 *----------------------------------------------------------------------*/	/* Version */	xvid_gbl_init.version = XVID_VERSION;	/* Assembly setting */		    xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;	xvid_gbl_init.debug = debug_level;	xvid_global(NULL, 0, &xvid_gbl_init, NULL);	/*------------------------------------------------------------------------	 * XviD encoder initialization	 *----------------------------------------------------------------------*/	/* Version */	xvid_dec_create.version = XVID_VERSION;	/*	 * Image dimensions -- set to 0, xvidcore will resize when ever it is	 * needed	 */	xvid_dec_create.width = 0;	xvid_dec_create.height = 0;	ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL);	dec_handle = xvid_dec_create.handle;	return(ret);}/* decode one frame  */static intdec_main(unsigned char *istream,		 unsigned char *ostream,		 int istream_size,		 xvid_dec_stats_t *xvid_dec_stats){	int ret;	xvid_dec_frame_t xvid_dec_frame;	/* Reset all structures */	memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t));	memset(xvid_dec_stats, 0, sizeof(xvid_dec_stats_t));	/* Set version */	xvid_dec_frame.version = XVID_VERSION;	xvid_dec_stats->version = XVID_VERSION;	/* No general flags to set */	xvid_dec_frame.general          = 0;	/* Input stream */	xvid_dec_frame.bitstream        = istream;	xvid_dec_frame.length           = istream_size;	/* Output frame structure */	xvid_dec_frame.output.plane[0]  = ostream;	xvid_dec_frame.output.stride[0] = XDIM*BPP;	xvid_dec_frame.output.csp = CSP;	ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats);	return(ret);}/* close decoder to release resources */static intdec_stop(){	int ret;	ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);	return(ret);}

⌨️ 快捷键说明

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