54 |
* Global vars in module and constants |
* Global vars in module and constants |
55 |
****************************************************************************/ |
****************************************************************************/ |
56 |
|
|
|
/* max number of frames */ |
|
|
#define ABS_MAXFRAMENR 9999 |
|
|
|
|
57 |
#define USE_PNM 0 |
#define USE_PNM 0 |
58 |
#define USE_TGA 1 |
#define USE_TGA 1 |
59 |
|
|
71 |
|
|
72 |
#define BUFFER_SIZE (2*1024*1024) |
#define BUFFER_SIZE (2*1024*1024) |
73 |
|
|
74 |
|
static const int display_buffer_bytes = 0; |
75 |
|
|
76 |
|
#define MIN_USEFUL_BYTES 1 |
77 |
|
|
78 |
/***************************************************************************** |
/***************************************************************************** |
79 |
* Local prototypes |
* Local prototypes |
80 |
****************************************************************************/ |
****************************************************************************/ |
81 |
|
|
82 |
static double msecond(); |
static double msecond(); |
|
static int write_pgm(char *filename, |
|
|
unsigned char *image); |
|
83 |
static int dec_init(int use_assembler, int debug_level); |
static int dec_init(int use_assembler, int debug_level); |
84 |
static int dec_main(unsigned char *istream, |
static int dec_main(unsigned char *istream, |
85 |
unsigned char *ostream, |
unsigned char *ostream, |
87 |
xvid_dec_stats_t *xvid_dec_stats); |
xvid_dec_stats_t *xvid_dec_stats); |
88 |
static int dec_stop(); |
static int dec_stop(); |
89 |
static void usage(); |
static void usage(); |
90 |
|
static int write_image(char *prefix, unsigned char *image); |
91 |
|
static int write_pnm(char *filename, unsigned char *image); |
92 |
|
static int write_tga(char *filename, unsigned char *image); |
93 |
|
|
94 |
const char * type2str(int type) |
const char * type2str(int type) |
95 |
{ |
{ |
112 |
unsigned char *mp4_ptr = NULL; |
unsigned char *mp4_ptr = NULL; |
113 |
unsigned char *out_buffer = NULL; |
unsigned char *out_buffer = NULL; |
114 |
int useful_bytes; |
int useful_bytes; |
115 |
|
int chunk; |
116 |
xvid_dec_stats_t xvid_dec_stats; |
xvid_dec_stats_t xvid_dec_stats; |
117 |
|
|
118 |
double totaldectime; |
double totaldectime; |
186 |
} |
} |
187 |
} |
} |
188 |
|
|
189 |
|
#if defined(_MSC_VER) |
190 |
|
if (ARG_INPUTFILE==NULL) { |
191 |
|
fprintf(stderr, "Warning: MSVC build does not read EOF correctly from stdin. Use the -i switch.\n\n"); |
192 |
|
} |
193 |
|
#endif |
194 |
|
|
195 |
/***************************************************************************** |
/***************************************************************************** |
196 |
* Values checking |
* Values checking |
197 |
****************************************************************************/ |
****************************************************************************/ |
246 |
totalsize = 0; |
totalsize = 0; |
247 |
filenr = 0; |
filenr = 0; |
248 |
mp4_ptr = mp4_buffer; |
mp4_ptr = mp4_buffer; |
249 |
|
chunk = 0; |
250 |
|
|
251 |
do { |
do { |
252 |
int used_bytes = 0; |
int used_bytes = 0; |
267 |
mp4_ptr = mp4_buffer; |
mp4_ptr = mp4_buffer; |
268 |
|
|
269 |
/* read new data */ |
/* read new data */ |
270 |
if(feof(in_file)) |
if(!feof(in_file)) { |
|
break; |
|
271 |
|
|
272 |
useful_bytes += fread(mp4_buffer + already_in_buffer, |
useful_bytes += fread(mp4_buffer + already_in_buffer, |
273 |
1, BUFFER_SIZE - already_in_buffer, |
1, BUFFER_SIZE - already_in_buffer, |
274 |
in_file); |
in_file); |
275 |
|
} |
276 |
} |
} |
277 |
|
|
278 |
|
|
304 |
|
|
305 |
fprintf(stderr, "Resized frame buffer to %dx%d\n", XDIM, YDIM); |
fprintf(stderr, "Resized frame buffer to %dx%d\n", XDIM, YDIM); |
306 |
} |
} |
307 |
|
|
308 |
|
/* Save individual mpeg4 stream if required */ |
309 |
|
if(ARG_SAVEMPEGSTREAM) { |
310 |
|
FILE *filehandle = NULL; |
311 |
|
|
312 |
|
sprintf(filename, "%svolhdr.m4v", filepath); |
313 |
|
filehandle = fopen(filename, "wb"); |
314 |
|
if(!filehandle) { |
315 |
|
fprintf(stderr, |
316 |
|
"Error writing vol header mpeg4 stream to file %s\n", |
317 |
|
filename); |
318 |
|
} else { |
319 |
|
fwrite(mp4_ptr, 1, used_bytes, filehandle); |
320 |
|
fclose(filehandle); |
321 |
|
} |
322 |
|
} |
323 |
} |
} |
324 |
|
|
325 |
/* Update buffer pointers */ |
/* Update buffer pointers */ |
331 |
totalsize += used_bytes; |
totalsize += used_bytes; |
332 |
} |
} |
333 |
|
|
334 |
}while(xvid_dec_stats.type <= 0 && useful_bytes > 0); |
if (display_buffer_bytes) { |
335 |
|
printf("Data chunk %d: %d bytes consumed, %d bytes in buffer\n", chunk++, used_bytes, useful_bytes); |
336 |
|
} |
337 |
|
} while (xvid_dec_stats.type <= 0 && useful_bytes > MIN_USEFUL_BYTES); |
338 |
|
|
339 |
/* Check if there is a negative number of useful bytes left in buffer |
/* Check if there is a negative number of useful bytes left in buffer |
340 |
* This means we went too far */ |
* This means we went too far */ |
345 |
totaldectime += dectime; |
totaldectime += dectime; |
346 |
|
|
347 |
|
|
348 |
|
if (!display_buffer_bytes) { |
349 |
printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", |
printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", |
350 |
filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); |
filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); |
351 |
|
} |
352 |
|
|
353 |
/* Save individual mpeg4 stream if required */ |
/* Save individual mpeg4 stream if required */ |
354 |
if(ARG_SAVEMPEGSTREAM) { |
if(ARG_SAVEMPEGSTREAM) { |
372 |
sprintf(filename, "%sdec%05d", filepath, filenr); |
sprintf(filename, "%sdec%05d", filepath, filenr); |
373 |
if(write_image(filename, out_buffer)) { |
if(write_image(filename, out_buffer)) { |
374 |
fprintf(stderr, |
fprintf(stderr, |
375 |
"Error writing decoded PGM frame %s\n", |
"Error writing decoded frame %s\n", |
376 |
filename); |
filename); |
377 |
} |
} |
378 |
} |
} |
379 |
|
|
380 |
filenr++; |
filenr++; |
381 |
|
|
382 |
} while ( (status>=0) && (filenr<ABS_MAXFRAMENR)); |
} while (useful_bytes>MIN_USEFUL_BYTES || !feof(in_file)); |
383 |
|
|
384 |
|
useful_bytes = 0; /* Empty buffer */ |
385 |
|
|
386 |
/***************************************************************************** |
/***************************************************************************** |
387 |
* Flush decoder buffers |
* Flush decoder buffers |
397 |
dectime = msecond(); |
dectime = msecond(); |
398 |
used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats); |
used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats); |
399 |
dectime = msecond() - dectime; |
dectime = msecond() - dectime; |
400 |
|
if (display_buffer_bytes) { |
401 |
|
printf("Data chunk %d: %d bytes consumed, %d bytes in buffer\n", chunk++, used_bytes, useful_bytes); |
402 |
|
} |
403 |
}while(used_bytes>=0 && xvid_dec_stats.type <= 0); |
}while(used_bytes>=0 && xvid_dec_stats.type <= 0); |
404 |
|
|
405 |
if (used_bytes < 0) { /* XVID_ERR_END */ |
if (used_bytes < 0) { /* XVID_ERR_END */ |
410 |
totaldectime += dectime; |
totaldectime += dectime; |
411 |
|
|
412 |
/* Prints some decoding stats */ |
/* Prints some decoding stats */ |
413 |
|
if (!display_buffer_bytes) { |
414 |
printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", |
printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n", |
415 |
filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); |
filenr, type2str(xvid_dec_stats.type), dectime, used_bytes); |
416 |
|
} |
417 |
|
|
418 |
/* Save output frame if required */ |
/* Save output frame if required */ |
419 |
if (ARG_SAVEDECOUTPUT) { |
if (ARG_SAVEDECOUTPUT) { |
420 |
sprintf(filename, "%sdec%05d", filepath, filenr); |
sprintf(filename, "%sdec%05d", filepath, filenr); |
421 |
if(write_image(filename, out_buffer)) { |
if(write_image(filename, out_buffer)) { |
422 |
fprintf(stderr, |
fprintf(stderr, |
423 |
"Error writing decoded PGM frame %s\n", |
"Error writing decoded frame %s\n", |
424 |
filename); |
filename); |
425 |
} |
} |
426 |
} |
} |
433 |
* Calculate totals and averages for output, print results |
* Calculate totals and averages for output, print results |
434 |
****************************************************************************/ |
****************************************************************************/ |
435 |
|
|
436 |
|
if (filenr>0) { |
437 |
totalsize /= filenr; |
totalsize /= filenr; |
438 |
totaldectime /= filenr; |
totaldectime /= filenr; |
|
|
|
439 |
printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n", |
printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n", |
440 |
totaldectime, 1000/totaldectime, (int)totalsize); |
totaldectime, 1000/totaldectime, (int)totalsize); |
441 |
|
}else{ |
442 |
|
printf("Nothing was decoded!\n"); |
443 |
|
} |
444 |
|
|
445 |
/***************************************************************************** |
/***************************************************************************** |
446 |
* XviD PART Stop |
* XviD PART Stop |
496 |
#else |
#else |
497 |
clock_t clk; |
clock_t clk; |
498 |
clk = clock(); |
clk = clock(); |
499 |
return(clk * 1000 / CLOCKS_PER_SEC); |
return(clk * 1000.0 / CLOCKS_PER_SEC); |
500 |
#endif |
#endif |
501 |
} |
} |
502 |
|
|
504 |
* output functions |
* output functions |
505 |
****************************************************************************/ |
****************************************************************************/ |
506 |
|
|
507 |
int write_image(char *prefix, unsigned char *image) |
static int write_image(char *prefix, unsigned char *image) |
508 |
{ |
{ |
509 |
char filename[1024]; |
char filename[1024]; |
510 |
char *ext; |
char *ext; |
532 |
return(ret); |
return(ret); |
533 |
} |
} |
534 |
|
|
535 |
int write_tga(char *filename, unsigned char *image) |
static int write_tga(char *filename, unsigned char *image) |
536 |
{ |
{ |
537 |
FILE * f; |
FILE * f; |
538 |
char hdr[18]; |
char hdr[18]; |
575 |
#else |
#else |
576 |
{ |
{ |
577 |
int i; |
int i; |
578 |
for (i=0; i<width*height*BPP;i+=BPP) { |
for (i=0; i<XDIM*YDIM*BPP;i+=BPP) { |
579 |
if (BPP == 1) { |
if (BPP == 1) { |
580 |
fputc(image+i, f); |
fputc(*(image+i), f); |
581 |
} else if (BPP == 2) { |
} else if (BPP == 2) { |
582 |
fputc(image+i+1, f); |
fputc(*(image+i+1), f); |
583 |
fputc(image+i+0, f); |
fputc(*(image+i+0), f); |
584 |
} else if (BPP == 3) { |
} else if (BPP == 3) { |
585 |
fputc(image+i+2, f); |
fputc(*(image+i+2), f); |
586 |
fputc(image+i+1, f); |
fputc(*(image+i+1), f); |
587 |
fputc(image+i+0, f); |
fputc(*(image+i+0), f); |
588 |
} else if (BPP == 4) { |
} else if (BPP == 4) { |
589 |
fputc(image+i+3, f); |
fputc(*(image+i+3), f); |
590 |
fputc(image+i+2, f); |
fputc(*(image+i+2), f); |
591 |
fputc(image+i+1, f); |
fputc(*(image+i+1), f); |
592 |
fputc(image+i+0, f); |
fputc(*(image+i+0), f); |
593 |
} |
} |
594 |
} |
} |
595 |
} |
} |
613 |
return(0); |
return(0); |
614 |
} |
} |
615 |
|
|
616 |
int write_pnm(char *filename, unsigned char *image) |
static int write_pnm(char *filename, unsigned char *image) |
617 |
{ |
{ |
618 |
FILE * f; |
FILE * f; |
619 |
|
|
652 |
|
|
653 |
return 0; |
return 0; |
654 |
} |
} |
655 |
|
|
656 |
/***************************************************************************** |
/***************************************************************************** |
657 |
* Routines for decoding: init decoder, use, and stop decoder |
* Routines for decoding: init decoder, use, and stop decoder |
658 |
****************************************************************************/ |
****************************************************************************/ |
666 |
xvid_gbl_init_t xvid_gbl_init; |
xvid_gbl_init_t xvid_gbl_init; |
667 |
xvid_dec_create_t xvid_dec_create; |
xvid_dec_create_t xvid_dec_create; |
668 |
|
|
669 |
|
/* Reset the structure with zeros */ |
670 |
|
memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t)); |
671 |
|
memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t)); |
672 |
|
|
673 |
/*------------------------------------------------------------------------ |
/*------------------------------------------------------------------------ |
674 |
* XviD core initialization |
* XviD core initialization |
675 |
*----------------------------------------------------------------------*/ |
*----------------------------------------------------------------------*/ |
724 |
|
|
725 |
xvid_dec_frame_t xvid_dec_frame; |
xvid_dec_frame_t xvid_dec_frame; |
726 |
|
|
727 |
|
/* Reset all structures */ |
728 |
|
memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t)); |
729 |
|
memset(xvid_dec_stats, 0, sizeof(xvid_dec_stats_t)); |
730 |
|
|
731 |
/* Set version */ |
/* Set version */ |
732 |
xvid_dec_frame.version = XVID_VERSION; |
xvid_dec_frame.version = XVID_VERSION; |
733 |
xvid_dec_stats->version = XVID_VERSION; |
xvid_dec_stats->version = XVID_VERSION; |