--- branches/dev-api-4/xvidcore/examples/xvid_decraw.c 2003/03/11 20:15:40 917 +++ branches/dev-api-4/xvidcore/examples/xvid_decraw.c 2003/03/11 23:39:47 918 @@ -19,7 +19,7 @@ * 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.7 2003-02-16 05:11:39 suxen_drol Exp $ + * $Id: xvid_decraw.c,v 1.7.2.1 2003-03-11 23:39:47 edgomez Exp $ * ****************************************************************************/ @@ -41,12 +41,10 @@ * Usage : xvid_decraw <-w width> <-h height> [OPTIONS] * Options : * -asm : use assembly optimizations (default=disabled) - * -w integer : frame width ([1.2048]) - * -h integer : frame height ([1.2048]) * -i string : input filename (default=stdin) * -t integer : input data type (raw=0, mp4u=1) - * -d boolean : save decoder output (0 False*, !=0 True) - * -m boolean : save mpeg4 raw stream to single files (0 False*, !=0 True) + * -d : save decoder output (0 False*, !=0 True) + * -m : save mpeg4 raw stream to single files (0 False*, !=0 True) * -help : This help message * (* means default) * @@ -81,7 +79,7 @@ static char filepath[256] = "./"; static void *dec_handle = NULL; -# define BUFFER_SIZE 10*XDIM*YDIM +# define BUFFER_SIZE (2*1024*1024) /***************************************************************************** * Local prototypes @@ -89,13 +87,12 @@ static double msecond(); static int write_pgm(char *filename, - unsigned char *image); + unsigned char *image); static int dec_init(int use_assembler); static int dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, - int *ostream_size, - int *isframe); + xvid_dec_stats_t *xvid_dec_stats); static int dec_stop(); static void usage(); @@ -108,9 +105,10 @@ unsigned char *mp4_buffer = NULL; unsigned char *mp4_ptr = NULL; unsigned char *out_buffer = NULL; - int bigendian = 0; + unsigned char *type = NULL; int still_left_in_buffer; int delayed_frames; + xvid_dec_stats_t xvid_dec_stats; double totaldectime; @@ -137,25 +135,15 @@ if (strcmp("-asm", argv[i]) == 0 ) { use_assembler = 1; } - else if (strcmp("-w", argv[i]) == 0 && i < argc - 1 ) { - i++; - XDIM = atoi(argv[i]); - } - else if (strcmp("-h", argv[i]) == 0 && i < argc - 1 ) { - i++; - YDIM = atoi(argv[i]); - } - else if (strcmp("-d", argv[i]) == 0 && i < argc - 1 ) { - i++; - ARG_SAVEDECOUTPUT = 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 && i < argc - 1 ) { - i++; - ARG_SAVEMPEGSTREAM = atoi(argv[i]); + else if (strcmp("-m", argv[i]) == 0) { + ARG_SAVEMPEGSTREAM = 1; } else if (strcmp("-help", argv[i])) { usage(); @@ -172,11 +160,6 @@ * Values checking ****************************************************************************/ - if(XDIM <= 0 || XDIM > 2048 || YDIM <= 0 || YDIM > 2048) { - usage(); - return -1; - } - if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) { in_file = stdin; } @@ -185,7 +168,7 @@ in_file = fopen(ARG_INPUTFILE, "rb"); if (in_file == NULL) { fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE); - return -1; + return(-1); } } @@ -199,12 +182,6 @@ if (!mp4_buffer) goto free_all_memory; - /* Memory for frame output */ - out_buffer = (unsigned char *) malloc(XDIM*YDIM*4); - if (!out_buffer) - goto free_all_memory; - - /***************************************************************************** * XviD PART Start ****************************************************************************/ @@ -212,7 +189,7 @@ status = dec_init(use_assembler); if (status) { fprintf(stderr, - "Decore INIT problem, return value %d\n", status); + "Decore INIT problem, return value %d\n", status); goto release_all; } @@ -235,7 +212,6 @@ int mp4_size = (mp4_buffer + BUFFER_SIZE - mp4_ptr); int used_bytes = 0; double dectime; - int notification; /* * If the buffer is half empty or there are no more bytes in it @@ -264,35 +240,50 @@ } - /* This loop flushes N_VOPS (with vop_coded bit set to 0) */ + /* This loop is needed to handle VOL/NVOP reading */ do { /* Decode frame */ dectime = msecond(); - status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes, ¬ification); + used_bytes = dec_main(mp4_ptr, out_buffer, mp4_size, &xvid_dec_stats); dectime = msecond() - dectime; - if (status) { - break; + /* Resize image buffer if needed */ + if(xvid_dec_stats.type == XVID_TYPE_VOL) { + + /* Free old output buffer*/ + if(out_buffer) free(out_buffer); + + /* Copy witdh and height from the vol structure */ + XDIM = xvid_dec_stats.data.vol.width; + YDIM = xvid_dec_stats.data.vol.height; + + /* Allocate the new buffer */ + if((out_buffer = (unsigned char*)malloc(XDIM*YDIM*4)) == NULL) + goto free_all_memory; } /* Update buffer pointers */ - mp4_ptr += used_bytes; - still_left_in_buffer -= used_bytes; + if(used_bytes > 0) { + mp4_ptr += used_bytes; + still_left_in_buffer -= used_bytes; - /* Total size */ - totalsize += used_bytes; + /* Total size */ + totalsize += used_bytes; + } - }while(used_bytes <= 7 && still_left_in_buffer > 0); /* <= 7 bytes is a NVOPS */ + }while(xvid_dec_stats.type != XVID_TYPE_IVOP && + xvid_dec_stats.type != XVID_TYPE_PVOP && + xvid_dec_stats.type != XVID_TYPE_BVOP && + xvid_dec_stats.type != XVID_TYPE_SVOP && + still_left_in_buffer > 0); /* Negative buffer would mean we went too far */ if(still_left_in_buffer < 0) break; - /* Skip when decoder is buffering images or decoding VOL information */ - if(notification != XVID_DEC_VOP) { - /* It's a delay only if it notifies NOTHING */ - if(notification == XVID_DEC_NOTHING) - delayed_frames++; + /* Skip when decoder is buffering images because of bframes */ + if(xvid_dec_stats.type == XVID_TYPE_NOTHING) { + delayed_frames++; continue; } @@ -300,11 +291,26 @@ totaldectime += dectime; /* Prints some decoding stats */ - printf("Frame %5d: dectime(ms) =%6.1f, length(bytes) =%7d\n", - filenr, dectime, used_bytes); + switch(xvid_dec_stats.type) { + case XVID_TYPE_IVOP: + type = "I"; + break; + case XVID_TYPE_PVOP: + type = "P"; + break; + case XVID_TYPE_BVOP: + type = "B"; + break; + case XVID_TYPE_SVOP: + type = "S"; + break; + } + + printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", + filenr, type, dectime, used_bytes); /* Save individual mpeg4 stream if required */ - if (ARG_SAVEMPEGSTREAM) { + if(ARG_SAVEMPEGSTREAM) { FILE *filehandle = NULL; sprintf(filename, "%sframe%05d.m4v", filepath, filenr); @@ -337,21 +343,18 @@ /***************************************************************************** * Flush decoder buffers ****************************************************************************/ + while(delayed_frames--) { /* Fake vars */ - int used_bytes, isframe; + int used_bytes; double dectime; /* Decode frame */ dectime = msecond(); - status = dec_main(NULL, out_buffer, -1, &used_bytes, &isframe); + used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats); dectime = msecond() - dectime; - if (status) { - break; - } - /* Updated data - Count only usefull decode time */ totaldectime += dectime; @@ -362,7 +365,7 @@ /* Save output frame if required */ if (ARG_SAVEDECOUTPUT) { sprintf(filename, "%sdec%05d.pgm", filepath, filenr); - if(write_pgm(filename,out_buffer)) { + if(write_pgm(filename, out_buffer)) { fprintf(stderr, "Error writing decoded PGM frame %s\n", filename); @@ -381,7 +384,7 @@ totaldectime /= filenr; printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n", - totaldectime, 1000/totaldectime, (int)totalsize); + totaldectime, 1000/totaldectime, (int)totalsize); /***************************************************************************** * XviD PART Stop @@ -398,7 +401,7 @@ free(out_buffer); free(mp4_buffer); - return 0; + return(0); } /***************************************************************************** @@ -411,12 +414,10 @@ fprintf(stderr, "Usage : xvid_decraw <-w width> <-h height> [OPTIONS]\n"); fprintf(stderr, "Options :\n"); fprintf(stderr, " -asm : use assembly optimizations (default=disabled)\n"); - fprintf(stderr, " -w integer : frame width ([1.2048])\n"); - fprintf(stderr, " -h integer : frame height ([1.2048])\n"); fprintf(stderr, " -i string : input filename (default=stdin)\n"); fprintf(stderr, " -t integer : input data type (raw=0, mp4u=1)\n"); - fprintf(stderr, " -d boolean : save decoder output (0 False*, !=0 True)\n"); - fprintf(stderr, " -m boolean : save mpeg4 raw stream to individual files (0 False*, !=0 True)\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"); @@ -433,11 +434,11 @@ #ifndef WIN32 struct timeval tv; gettimeofday(&tv, 0); - return (double)tv.tv_sec*1.0e3 + (double)tv.tv_usec*1.0e-3; + return((double)tv.tv_sec*1.0e3 + (double)tv.tv_usec*1.0e-3); #else clock_t clk; clk = clock(); - return clk * 1000 / CLOCKS_PER_SEC; + return(clk * 1000 / CLOCKS_PER_SEC); #endif } @@ -447,7 +448,7 @@ static int write_pgm(char *filename, - unsigned char *image) + unsigned char *image) { int loop; @@ -482,10 +483,10 @@ /* Close file */ fclose(filehandle); - return 0; + return(0); } else - return 1; + return(1); } /***************************************************************************** @@ -496,29 +497,49 @@ static int dec_init(int use_assembler) { - int xerr; + int ret; + + xvid_gbl_init_t xvid_gbl_init; + xvid_dec_create_t xvid_dec_create; + + /*------------------------------------------------------------------------ + * XviD core initialization + *----------------------------------------------------------------------*/ - XVID_INIT_PARAM xinit; - XVID_DEC_PARAM xparam; + /* Version */ + xvid_gbl_init.version = XVID_VERSION; - if(use_assembler) + /* Assembly setting */ + if(use_assembler) #ifdef ARCH_IS_IA64 - xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; + xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; #else - xinit.cpu_flags = 0; + xvid_gbl_init.cpu_flags = 0; #endif - else - xinit.cpu_flags = XVID_CPU_FORCE; + else + xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; + + xvid_global(NULL, 0, &xvid_gbl_init, NULL); - xvid_init(NULL, 0, &xinit, NULL); - xparam.width = XDIM; - xparam.height = YDIM; + /*------------------------------------------------------------------------ + * XviD encoder initialization + *----------------------------------------------------------------------*/ - xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL); + /* Version */ + xvid_dec_create.version = XVID_VERSION; - dec_handle = xparam.handle; + /* + * Image dimensions -- set to 0, xvidcore will resize when ever it is + * needed + */ + xvid_dec_create.width = 0; + xvid_dec_create.height = 0; - return xerr; + ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL); + + dec_handle = xvid_dec_create.handle; + + return(ret); } /* decode one frame */ @@ -526,37 +547,41 @@ dec_main(unsigned char *istream, unsigned char *ostream, int istream_size, - int *ostream_size, - int *notification) + xvid_dec_stats_t *xvid_dec_stats) { - int xerr; - XVID_DEC_FRAME xframe; - XVID_DEC_STATS xstats; + int ret; + + xvid_dec_frame_t xvid_dec_frame; + + /* Set version */ + xvid_dec_frame.version = XVID_VERSION; + xvid_dec_stats->version = XVID_VERSION; - xframe.general = 0; - xframe.bitstream = istream; - xframe.length = istream_size; - xframe.image = ostream; - xframe.stride = XDIM; - xframe.colorspace = XVID_CSP_YV12; + /* No general flags to set */ + xvid_dec_frame.general = 0; - xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, &xstats); + /* Input stream */ + xvid_dec_frame.bitstream = istream; + xvid_dec_frame.length = istream_size; - *ostream_size = xframe.length; + /* Output frame structure */ + xvid_dec_frame.output.plane[0] = ostream; + xvid_dec_frame.output.stride[0] = XDIM; + xvid_dec_frame.output.csp = XVID_CSP_I420; - *notification = xstats.notify; + ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats); - return xerr; + return(ret); } /* close decoder to release resources */ static int dec_stop() { - int xerr; + int ret; - xerr = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); + ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); - return xerr; + return(ret); }