--- trunk/xvidcore/examples/xvid_decraw.c 2002/09/28 14:27:16 559 +++ trunk/xvidcore/examples/xvid_decraw.c 2003/03/03 11:18:53 902 @@ -3,7 +3,7 @@ * XVID MPEG-4 VIDEO CODEC * - Console based decoding test application - * - * Copyright(C) 2002 Christoph Lampert + * Copyright(C) 2002-2003 Christoph Lampert * * 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 @@ -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.4 2002-09-28 14:27:16 edgomez Exp $ + * $Id: xvid_decraw.c,v 1.9 2003-03-03 11:18:53 chl Exp $ * ****************************************************************************/ @@ -56,7 +56,7 @@ #include #include #include -#ifndef _MSC_VER +#ifndef WIN32 #include #else #include @@ -75,7 +75,6 @@ static int YDIM = 0; static int ARG_SAVEDECOUTPUT = 0; static int ARG_SAVEMPEGSTREAM = 0; -static int ARG_STREAMTYPE = 0; static char *ARG_INPUTFILE = NULL; @@ -84,12 +83,6 @@ # define BUFFER_SIZE 10*XDIM*YDIM -#define LONG_PACK(a,b,c,d) ((long) (((long)(a))<<24) | (((long)(b))<<16) | \ - (((long)(c))<<8) |((long)(d))) - -#define SWAP(a) ( (((a)&0x000000ff)<<24) | (((a)&0x0000ff00)<<8) | \ - (((a)&0x00ff0000)>>8) | (((a)&0xff000000)>>24) ) - /***************************************************************************** * Local prototypes ****************************************************************************/ @@ -99,9 +92,10 @@ 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); + unsigned char *ostream, + int istream_size, + int *ostream_size, + int *isframe); static int dec_stop(); static void usage(); @@ -115,7 +109,9 @@ unsigned char *mp4_ptr = NULL; unsigned char *out_buffer = NULL; int bigendian = 0; - + int still_left_in_buffer; + int delayed_frames; + double totaldectime; long totalsize; @@ -130,7 +126,7 @@ int i; printf("xvid_decraw - raw mpeg4 bitstream decoder "); - printf("written by Christoph Lampert 2002\n\n"); + printf("written by Christoph Lampert 2002-2003\n\n"); /***************************************************************************** * Command line parsing @@ -161,10 +157,6 @@ i++; ARG_SAVEMPEGSTREAM = atoi(argv[i]); } - else if (strcmp("-t", argv[i]) == 0 && i < argc - 1 ) { - i++; - ARG_STREAMTYPE = atoi(argv[i]); - } else if (strcmp("-help", argv[i])) { usage(); return(0); @@ -229,36 +221,13 @@ * Main loop ****************************************************************************/ - totalsize = LONG_PACK('M','P','4','U'); - mp4_ptr = (unsigned char *)&totalsize; - if(*mp4_ptr == 'M') - bigendian = 1; - else - bigendian = 0; - - if(ARG_STREAMTYPE) { - - unsigned char header[4]; - - /* MP4U format : read header */ - if(feof(in_file)) - goto release_all; - fread(header, 4, 1, in_file); - - if(header[0] != 'M' || header[1] != 'P' || - header[2] != '4' || header[3] != 'U') { - fprintf(stderr, "Error, this not a mp4u container file\n"); - goto release_all; - } - - } - else { - fread(mp4_buffer, BUFFER_SIZE, 1, in_file); - } + /* Fill the buffer */ + still_left_in_buffer = fread(mp4_buffer, 1, BUFFER_SIZE, in_file); totaldectime = 0; totalsize = 0; filenr = 0; + delayed_frames = 0; mp4_ptr = mp4_buffer; do { @@ -266,82 +235,75 @@ int mp4_size = (mp4_buffer + BUFFER_SIZE - mp4_ptr); int used_bytes = 0; double dectime; + int notification; - /* Read data from input file */ - if(ARG_STREAMTYPE) { - - /* MP4U container */ - - /* Read stream size first */ - if(feof(in_file)) - break; - fread(&mp4_size, sizeof(long), 1, in_file); + /* + * 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 || + still_left_in_buffer <= 0) { + int rest = (mp4_buffer + BUFFER_SIZE - mp4_ptr); + + /* Move data if needed */ + if (rest) + memcpy(mp4_buffer, mp4_ptr, rest); - /* Mp4U container is big endian */ - if(!bigendian) - mp4_size = SWAP(mp4_size); + /* Update mp4_ptr */ + mp4_ptr = mp4_buffer; - /* Read mp4_size_bytes */ + /* read new data */ if(feof(in_file)) break; - fread(mp4_buffer, mp4_size, 1, in_file); - /* - * When reading mp4u, we don't have to care about buffer - * filling as we know exactly how much bytes there are in - * next frame - */ - mp4_ptr = mp4_buffer; + still_left_in_buffer = rest + fread(mp4_buffer + rest, + 1, + BUFFER_SIZE - rest, + in_file); } - else { - /* Real raw stream */ - /* buffer more than half empty -> Fill it */ - if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2) { - int rest = (mp4_buffer + BUFFER_SIZE - mp4_ptr); - - /* Move data if needed */ - if (rest) - memcpy(mp4_buffer, mp4_ptr, rest); - - /* Update mp4_ptr */ - mp4_ptr = mp4_buffer; - - /* read new data */ - if(feof(in_file)) - break; - fread(mp4_buffer + rest, BUFFER_SIZE - rest, 1, in_file); + /* This loop flushes N_VOPS (with vop_coded bit set to 0) */ + do { + + /* Decode frame */ + dectime = msecond(); + status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes, ¬ification); + dectime = msecond() - dectime; + if (status) { + break; } - } + /* Update buffer pointers */ + mp4_ptr += used_bytes; + still_left_in_buffer -= used_bytes; - /* Decode frame */ - dectime = msecond(); - status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes); - dectime = msecond() - dectime; + /* Total size */ + totalsize += used_bytes; - if (status) { - break; - } + }while(used_bytes <= 7 && still_left_in_buffer > 0); /* <= 7 bytes is a NVOPS */ - /* - * Only needed for real raw stream, mp4u uses - * mp4_ptr = mp4_buffer for each frame - */ - mp4_ptr += used_bytes; + /* 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++; + continue; + } - /* Updated data */ - totalsize += used_bytes; + /* Updated data - Count only usefull decode time */ totaldectime += dectime; - - /* Prints some decoding stats */ - printf("Frame %5d: dectime =%6.1f ms length=%7d bytes \n", - filenr, dectime, used_bytes); - /* Save individual mpeg4 strean if required */ + /* Prints some decoding stats */ + printf("Frame %5d: dectime(ms) =%6.1f, length(bytes) =%7d\n", + filenr, dectime, used_bytes); + + /* Save individual mpeg4 stream if required */ if (ARG_SAVEMPEGSTREAM) { FILE *filehandle = NULL; @@ -349,31 +311,68 @@ filehandle = fopen(filename, "wb"); if(!filehandle) { fprintf(stderr, - "Error writing single mpeg4 stream to file %s\n", - filename); + "Error writing single mpeg4 stream to file %s\n", + filename); } else { - fwrite(mp4_buffer, used_bytes, 1, filehandle); + fwrite(mp4_buffer, 1, used_bytes, filehandle); fclose(filehandle); } } - - + /* Save output frame if required */ if (ARG_SAVEDECOUTPUT) { sprintf(filename, "%sdec%05d.pgm", filepath, filenr); if(write_pgm(filename,out_buffer)) { fprintf(stderr, - "Error writing decoded PGM frame %s\n", - filename); + "Error writing decoded PGM frame %s\n", + filename); } } filenr++; - } while ( (status>=0) && (filenr=0) && (filenr