--- trunk/xvidcore/examples/xvid_decraw.c 2002/08/17 20:03:36 376 +++ trunk/xvidcore/examples/xvid_decraw.c 2004/04/15 19:44:06 1432 @@ -1,329 +1,724 @@ -/************************************************************************** +/***************************************************************************** * - * XVID MPEG-4 VIDEO CODEC - Example for encoding and decoding + * XVID MPEG-4 VIDEO CODEC + * - Console based decoding test application - * - * 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. + * Copyright(C) 2002-2003 Christoph Lampert + * 2002-2003 Edouard Gomez * - * 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. + * 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. * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * 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.14 2004-04-15 19:44:05 edgomez Exp $ + * + ****************************************************************************/ -/************************************************************************ +/***************************************************************************** * - * Test routine for XviD decoding - * (C) Christoph Lampert, 2002/08/17 + * Application notes : * - * An MPEG-4 bitstream is read from stdin and decoded, - * the speed for this is measured - * - * The program is plain C and needs no libraries except for libxvidcore, - * and maths-lib, so with UN*X you simply compile by - * - * gcc xvid_decraw.c -lxvidcore -lm -o xvid_decraw + * An MPEG-4 bitstream is read from an input file (or stdin) and decoded, + * the speed for this is measured. * - * You have to specify the image dimensions (until the add the feature - * to read this from the bitstream) - * - * Parameters are: xvid_stat XDIM YDIM - * - * output and indivual m4v-files are saved, if corresponding flags are set + * 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 #include -#include // needed for log10 -#include // only needed for gettimeofday +#include +#include +#ifndef WIN32 +#include +#else +#include +#endif -#include "../src/xvid.h" /* comes with XviD */ +#include "xvid.h" -#define ABS_MAXFRAMENR 9999 // max number of frames +/***************************************************************************** + * Global vars in module and constants + ****************************************************************************/ + +/* max number of frames */ +#define ABS_MAXFRAMENR 9999 + +#define USE_PNM 0 +#define USE_TGA 1 + +static int XDIM = 0; +static int YDIM = 0; +static int ARG_SAVEDECOUTPUT = 0; +static int ARG_SAVEMPEGSTREAM = 0; +static char *ARG_INPUTFILE = 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) + +/***************************************************************************** + * Local prototypes + ****************************************************************************/ + +static double msecond(); +static int write_pgm(char *filename, + unsigned char *image); +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(); +int write_image(char *prefix, unsigned char *image); +int write_pnm(char *filename, unsigned char *image); +int write_tga(char *filename, unsigned char *image); -int XDIM=720; -int YDIM=576; -int i,filenr = 0; +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"; +} -int save_dec_flag = 1; // save decompressed bytestream? -int save_m4v_flag = 0; // save bytestream itself? +/***************************************************************************** + * Main program + ****************************************************************************/ -char filepath[256] = "./"; // the path where to save output +int main(int argc, char *argv[]) +{ + unsigned char *mp4_buffer = NULL; + unsigned char *mp4_ptr = NULL; + unsigned char *out_buffer = NULL; + int useful_bytes; + xvid_dec_stats_t xvid_dec_stats; + + double totaldectime; + + long totalsize; + int status; + + int use_assembler = 0; + int debug_level = 0; + + char filename[256]; + + FILE *in_file; + 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("-m", argv[i]) == 0) { + ARG_SAVEMPEGSTREAM = 1; + } else if (strcmp("-c", argv[i]) == 0 && i < argc - 1 ) { + i++; + if (strcmp(argv[i], "rgb16") == 0) { + CSP = XVID_CSP_RGB555; + BPP = 2; + } else if (strcmp(argv[i], "rgb24") == 0) { + CSP = XVID_CSP_BGR; + BPP = 3; + } else if (strcmp(argv[i], "rgb32") == 0) { + CSP = XVID_CSP_BGRA; + BPP = 4; + } else if (strcmp(argv[i], "yv12") == 0) { + CSP = XVID_CSP_YV12; + BPP = 1; + } else { + CSP = XVID_CSP_I420; + BPP = 1; + } + } else if (strcmp("-f", argv[i]) == 0 && i < argc -1) { + i++; + if (strcmp(argv[i], "tga") == 0) { + FORMAT = USE_TGA; + } else { + FORMAT = USE_PNM; + } + } 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 -void *dec_handle = NULL; // handle for decoding +/***************************************************************************** + * Values checking + ****************************************************************************/ -/*********************************************************************/ -/* "statistical" functions */ -/* */ -/* these are not needed for decoding itself, but for measuring */ -/* time (and maybe later quality), there in nothing specific to */ -/* XviD in these */ -/* */ -/*********************************************************************/ + if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) { + in_file = stdin; + } + else { -double msecond() -/* return the current time in seconds(!) */ -{ - struct timeval tv; - gettimeofday(&tv, 0); - return tv.tv_sec + tv.tv_usec * 1.0e-6; -} + in_file = fopen(ARG_INPUTFILE, "rb"); + if (in_file == NULL) { + fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE); + return(-1); + } + } + /* PNM/PGM format can't handle 16/32 bit data */ + if (BPP != 1 && BPP != 3 && FORMAT == USE_PNM) { + FORMAT = USE_TGA; + } -/*********************************************************************/ -/* input and output functions */ -/* */ -/* the are small and simple routines for writing image */ -/* image. It's just for convenience, again nothing specific to XviD */ -/* */ -/*********************************************************************/ +/***************************************************************************** + * 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; + } -int write_pgm(char *filename, unsigned char *image) -{ - FILE *filehandle; - filehandle=fopen(filename,"wb"); - if (filehandle) - { - fprintf(filehandle,"P5\n\n"); // - fprintf(filehandle,"%d %d 255\n",XDIM,YDIM*3/2); - fwrite(image,XDIM,YDIM*3/2,filehandle); - fclose(filehandle); - return 0; - } - else - return 1; -} +/***************************************************************************** + * Main loop + ****************************************************************************/ + + /* Fill the buffer */ + useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, in_file); + + totaldectime = 0; + totalsize = 0; + filenr = 0; + mp4_ptr = mp4_buffer; + + do { + int used_bytes = 0; + double dectime; + + /* + * 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); + + } -int write_ppm(char *filename, unsigned char *image) -{ - FILE *filehandle; - filehandle=fopen(filename,"wb"); - if (filehandle) - { - fprintf(filehandle,"P6\n\n"); // - fprintf(filehandle,"%d %d 255\n",XDIM,YDIM); - fwrite(image,XDIM,YDIM*3,filehandle); + /* This loop is needed to handle VOL/NVOP reading */ + do { + + /* Decode frame */ + dectime = msecond(); + used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats); + dectime = msecond() - dectime; + + /* 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; + } + + }while(xvid_dec_stats.type <= 0 && useful_bytes > 0); + + /* 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 */ + totaldectime += dectime; + + + printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", + filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); + + /* 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) { + sprintf(filename, "%sdec%05d", filepath, filenr); + if(write_image(filename, out_buffer)) { + fprintf(stderr, + "Error writing decoded PGM frame %s\n", + filename); + } + } - fclose(filehandle); - return 0; + filenr++; + + } while ( (status>=0) && (filenr=0 && xvid_dec_stats.type <= 0); + + if (used_bytes < 0) { /* XVID_ERR_END */ + break; + } + + /* Updated data - Count only usefull decode time */ + totaldectime += dectime; + + /* Prints some decoding stats */ + printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", + filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); + + /* Save output frame if required */ + if (ARG_SAVEDECOUTPUT) { + sprintf(filename, "%sdec%05d", filepath, filenr); + if(write_image(filename, out_buffer)) { + fprintf(stderr, + "Error writing decoded frame %s\n", + filename); + } + } + + filenr++; + + }while(1); + +/***************************************************************************** + * Calculate totals and averages for output, print results + ****************************************************************************/ + + if (filenr>0) { + totalsize /= filenr; + totaldectime /= filenr; + printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n", + totaldectime, 1000/totaldectime, (int)totalsize); + }else{ + printf("Nothing was decoded!\n"); } - else - return 1; + +/***************************************************************************** + * 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); } -/*********************************************************************/ -/* Routines for decoding: init encoder, frame step, release encoder */ -/*********************************************************************/ +/***************************************************************************** + * Usage function + ****************************************************************************/ -int dec_init(int use_assembler) /* init decoder before first run */ +static void usage() { - int xerr; - XVID_INIT_PARAM xinit; - XVID_DEC_PARAM xparam; + 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, " -d : save decoder output\n"); + fprintf(stderr, " -c csp : choose colorspace output (rgb16, rgb24, rgb32, yv12, i420)\n"); + fprintf(stderr, " -f format : choose output file format (tga, pnm, pgm)\n"); + fprintf(stderr, " -m : save mpeg4 raw stream to individual files\n"); + fprintf(stderr, " -help : This help message\n"); + fprintf(stderr, " (* means default)\n"); + +} - if(use_assembler) -#ifdef ARCH_IA64 - xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; +/***************************************************************************** + * "helper" functions + ****************************************************************************/ + +/* return the current time in milli seconds */ +static double +msecond() +{ +#ifndef WIN32 + struct timeval tv; + gettimeofday(&tv, 0); + return((double)tv.tv_sec*1.0e3 + (double)tv.tv_usec*1.0e-3); #else - xinit.cpu_flags = 0; + clock_t clk; + clk = clock(); + return(clk * 1000 / CLOCKS_PER_SEC); #endif - else - xinit.cpu_flags = XVID_CPU_FORCE; +} - xvid_init(NULL, 0, &xinit, NULL); - xparam.width = XDIM; - xparam.height = YDIM; +/***************************************************************************** + * output functions + ****************************************************************************/ - xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL); - dec_handle = xparam.handle; +int write_image(char *prefix, unsigned char *image) +{ + char filename[1024]; + char *ext; + int ret; + + if (FORMAT == USE_PNM && BPP == 1) { + ext = "pgm"; + } else if (FORMAT == USE_PNM && BPP == 3) { + ext = "pnm"; + } else if (FORMAT == USE_TGA) { + ext = "tga"; + } else { + fprintf(stderr, "Bug: should not reach this path code -- please report to xvid-devel@xvid.org with command line options used"); + exit(-1); + } - return xerr; -} + sprintf(filename, "%s.%s", prefix, ext); -int dec_main(unsigned char *m4v_buffer, unsigned char *out_buffer,int *m4v_size) -{ /* decode one frame */ + if (FORMAT == USE_PNM) { + ret = write_pnm(filename, image); + } else { + ret = write_tga(filename, image); + } - int xerr; - XVID_DEC_FRAME xframe; + return(ret); +} - xframe.bitstream = m4v_buffer; - xframe.length = 9999; - xframe.image = out_buffer; - xframe.stride = XDIM; - xframe.colorspace = XVID_CSP_YV12; +int write_tga(char *filename, unsigned char *image) +{ + FILE * f; + char hdr[18]; - do { - xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, NULL); + f = fopen(filename, "wb"); + if ( f == NULL) { + return -1; + } - *m4v_size = xframe.length; - xframe.bitstream += *m4v_size; + hdr[0] = 0; /* ID length */ + hdr[1] = 0; /* Color map type */ + hdr[2] = (BPP>1)?2:3; /* Uncompressed true color (2) or greymap (3) */ + hdr[3] = 0; /* Color map specification (not used) */ + hdr[4] = 0; /* Color map specification (not used) */ + hdr[5] = 0; /* Color map specification (not used) */ + hdr[6] = 0; /* Color map specification (not used) */ + hdr[7] = 0; /* Color map specification (not used) */ + hdr[8] = 0; /* LSB X origin */ + hdr[9] = 0; /* MSB X origin */ + hdr[10] = 0; /* LSB Y origin */ + hdr[11] = 0; /* MSB Y origin */ + hdr[12] = (XDIM>>0)&0xff; /* LSB Width */ + hdr[13] = (XDIM>>8)&0xff; /* MSB Width */ + if (BPP > 1) { + hdr[14] = (YDIM>>0)&0xff; /* LSB Height */ + hdr[15] = (YDIM>>8)&0xff; /* MSB Height */ + } else { + hdr[14] = ((YDIM*3)>>1)&0xff; /* LSB Height */ + hdr[15] = ((YDIM*3)>>9)&0xff; /* MSB Height */ + } + hdr[16] = BPP*8; + hdr[17] = 0x00 | (1<<5) /* Up to down */ | (0<<4); /* Image descriptor */ + + /* Write header */ + fwrite(hdr, 1, sizeof(hdr), f); - } while (*m4v_size<7); /* this skips N-VOPs */ - - return xerr; -} +#ifdef ARCH_IS_LITTLE_ENDIAN + /* write first plane */ + fwrite(image, 1, XDIM*YDIM*BPP, f); +#else + { + int i; + for (i=0; i=3) - { XDIM = atoi(argv[1]); - YDIM = atoi(argv[2]); - if ( (XDIM <= 0) || (XDIM >= 2048) || (YDIM <=0) || (YDIM >= 2048) ) - { fprintf(stderr,"Wrong frames size %d %d, trying PGM \n",XDIM, YDIM); + if (BPP == 1) { + int i; + fprintf(f, "P5\n#xvid\n%i %i\n255\n", XDIM, YDIM*3/2); + + fwrite(image, 1, XDIM*YDIM, f); + + for (i=0; i=4 && !strcmp(argv[3],"noasm")) - use_assembler = 0; - -/* allocate memory */ + fclose(f); - divx_buffer = (unsigned char *) malloc(10*XDIM*YDIM); - // this should really be enough memory! - if (!divx_buffer) - goto free_all_memory; - divx_ptr = divx_buffer+10*XDIM*YDIM; - - out_buffer = (unsigned char *) malloc(4*XDIM*YDIM); /* YUV needs less */ - if (!out_buffer) - goto free_all_memory; + return 0; +} +/***************************************************************************** + * Routines for decoding: init decoder, use, and stop decoder + ****************************************************************************/ + +/* init decoder before first run */ +static int +dec_init(int use_assembler, int debug_level) +{ + int ret; + xvid_gbl_init_t xvid_gbl_init; + xvid_dec_create_t xvid_dec_create; -/*********************************************************************/ -/* XviD PART Start */ -/*********************************************************************/ + /*------------------------------------------------------------------------ + * XviD core initialization + *----------------------------------------------------------------------*/ + + /* Version */ + xvid_gbl_init.version = XVID_VERSION; + + /* Assembly setting */ + if(use_assembler) +#ifdef ARCH_IS_IA64 + xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; +#else + xvid_gbl_init.cpu_flags = 0; +#endif + else + xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; - status = dec_init(use_assembler); - if (status) - { - printf("Decore INIT problem, return value %d\n", status); - goto release_all; - } + xvid_gbl_init.debug = debug_level; + xvid_global(NULL, 0, &xvid_gbl_init, NULL); -/*********************************************************************/ -/* Main loop */ -/*********************************************************************/ + /*------------------------------------------------------------------------ + * XviD encoder initialization + *----------------------------------------------------------------------*/ - do - { + /* Version */ + xvid_dec_create.version = XVID_VERSION; - if (divx_ptr > divx_buffer+5*XDIM*YDIM) /* buffer more than half empty */ - { int rest=(divx_buffer+10*XDIM*YDIM-divx_ptr); - if (rest) - memcpy(divx_buffer, divx_ptr, rest); - divx_ptr = divx_buffer; - fread(divx_buffer+rest, 1, 5*XDIM*YDIM, stdin); /* read new data */ - } + /* + * Image dimensions -- set to 0, xvidcore will resize when ever it is + * needed + */ + xvid_dec_create.width = 0; + xvid_dec_create.height = 0; - dectime = -msecond(); - status = dec_main(divx_ptr, out_buffer, &m4v_size); + ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL); - if (status) - { - break; - } - dectime += msecond(); - divx_ptr += m4v_size; + dec_handle = xvid_dec_create.handle; - totalsize += m4v_size; - - printf("Frame %5d: dectime =%6.1f ms length=%7d bytes \n", - filenr, dectime*1000, m4v_size); + return(ret); +} - if (save_m4v_flag) - { - sprintf(filename, "%sframe%05d.m4v", filepath, filenr); - filehandle = fopen(filename, "wb"); - fwrite(divx_buffer, m4v_size, 1, filehandle); - fclose(filehandle); - } - totaldectime += dectime; - - -/*********************************************************************/ -/* analyse the decoded frame and compare to original */ -/*********************************************************************/ - - if (save_dec_flag) - { - sprintf(filename, "%sdec%05d.pgm", filepath, filenr); - write_pgm(filename,out_buffer); - } +/* decode one frame */ +static int +dec_main(unsigned char *istream, + unsigned char *ostream, + int istream_size, + xvid_dec_stats_t *xvid_dec_stats) +{ - filenr++; + int ret; - } while ( (status>=0) && (filenrversion = XVID_VERSION; - totalsize /= filenr; - totaldectime /= filenr; - - fprintf(stderr,"Avg: dectime %5.2f ms, %5.2f fps, filesize =%d\n", - 1000*totaldectime, 1./totaldectime, totalsize); - -/*********************************************************************/ -/* XviD PART Stop */ -/*********************************************************************/ + /* No general flags to set */ + xvid_dec_frame.general = 0; -release_all: + /* Input stream */ + xvid_dec_frame.bitstream = istream; + xvid_dec_frame.length = istream_size; - if (dec_handle) - { - status = dec_stop(); - if (status) - printf("Decore RELEASE problem return value %d\n", status); - } + /* Output frame structure */ + xvid_dec_frame.output.plane[0] = ostream; + xvid_dec_frame.output.stride[0] = XDIM*BPP; + xvid_dec_frame.output.csp = CSP; -free_all_memory: - free(out_buffer); - free(divx_buffer); + ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats); + + return(ret); +} + +/* close decoder to release resources */ +static int +dec_stop() +{ + int ret; + + ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); - return 0; + return(ret); }