--- xvid_decraw.c 2003/01/12 17:21:04 1.1.2.1 +++ xvid_decraw.c 2003/01/13 00:37:20 1.1.2.2 @@ -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.1.2.1 2003/01/12 17:21:04 edgomez Exp $ + * $Id: xvid_decraw.c,v 1.1.2.2 2003/01/13 00:37:20 edgomez Exp $ * ****************************************************************************/ @@ -115,7 +115,8 @@ unsigned char *mp4_ptr = NULL; unsigned char *out_buffer = NULL; int bigendian = 0; - + int still_left_in_packet; + double totaldectime; long totalsize; @@ -259,6 +260,7 @@ totaldectime = 0; totalsize = 0; filenr = 0; + still_left_in_packet = 0; mp4_ptr = mp4_buffer; do { @@ -268,35 +270,56 @@ double dectime; /* Read data from input file */ - if(ARG_STREAMTYPE) { + if(ARG_STREAMTYPE ) { - /* MP4U container */ + /* + * MP4U container + * + * When dealing with mp4u, we have to take care about PBB...B packets + * generated with some XviD options. + * + * We use the still_left_in_packet variable to keep trace of how many + * bytes we loaded at a time. + */ - /* Read stream size first */ - if(feof(in_file)) - break; - fread(&mp4_size, sizeof(long), 1, in_file); + /* Still real frames in loaded packet ? */ + if(still_left_in_packet < 7) { - /* Mp4U container is big endian */ - if(!bigendian) - mp4_size = SWAP(mp4_size); + /* Read stream size first */ + if(feof(in_file)) + break; + fread(&still_left_in_packet, sizeof(long), 1, in_file); - /* Read mp4_size_bytes */ - if(feof(in_file)) - break; - fread(mp4_buffer, mp4_size, 1, in_file); + /* Mp4U container is big endian */ + if(!bigendian) + mp4_size = SWAP(still_left_in_packet); - /* - * 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; + /* Read mp4_size_bytes */ + if(feof(in_file)) + break; + fread(mp4_buffer, still_left_in_packet, 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; + + } } else { - /* Real raw stream */ + /* + * Real raw stream + * + * In raw stream mode,we don't have to care how many bytes there're + * still in packet because we simply let the decore decode frames + * without taking care of buffer overruns or underruns. + * + */ + still_left_in_packet = 0; /* buffer more than half empty -> Fill it */ if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2) { @@ -312,36 +335,45 @@ /* read new data */ if(feof(in_file)) break; + fread(mp4_buffer + rest, BUFFER_SIZE - rest, 1, in_file); } } - /* Decode frame */ - dectime = msecond(); - status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes); - dectime = msecond() - dectime; - - if (status) { - break; - } - - /* - * Only needed for real raw stream, mp4u uses - * mp4_ptr = mp4_buffer for each frame - */ - mp4_ptr += used_bytes; + /* The do loop is just to flush NVOPS */ + do { + + /* Decode frame */ + dectime = msecond(); + status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes); + dectime = msecond() - dectime; + + if (status) { + break; + } + + /* + * Only needed for real raw stream, mp4u uses + * mp4_ptr = mp4_buffer for each frame + */ + mp4_ptr += used_bytes; + still_left_in_packet -= used_bytes; - /* Updated data */ - totalsize += used_bytes; + /* Total size */ + totalsize += used_bytes; + + }while(used_bytes <= 7); /* <= 7 bytes is a NVOPS */ + + /* 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 */ + filenr, dectime, used_bytes); + + /* Save individual mpeg4 stream if required */ if (ARG_SAVEMPEGSTREAM) { FILE *filehandle = NULL; @@ -349,29 +381,28 @@ 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); 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