2 /* mpeg2dec.c, main(), initialization, option processing */
4 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
7 * Disclaimer of Warranty
9 * These software programs are available to the user without any license fee or
10 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
11 * any and all warranties, whether express, implied, or statuary, including any
12 * implied warranties or merchantability or of fitness for a particular
13 * purpose. In no event shall the copyright-holder be liable for any
14 * incidental, punitive, or consequential damages of any kind whatsoever
15 * arising from the use of these programs.
17 * This disclaimer of warranty extends to the user of these programs and user's
18 * customers, employees, agents, transferees, successors, and assigns.
20 * The MPEG Software Simulation Group does not represent or warrant that the
21 * programs furnished hereunder are free of infringement of any third-party
24 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
25 * are subject to royalty fees to patent holders. Many of these patents are
26 * general enough such that they are unavoidable regardless of implementation
39 /* private prototypes */
40 static int video_sequence _ANSI_ARGS_((int *framenum));
41 static int Decode_Bitstream _ANSI_ARGS_((void));
42 static int Headers _ANSI_ARGS_((void));
43 static void Initialize_Sequence _ANSI_ARGS_((void));
44 static void Initialize_Decoder _ANSI_ARGS_((void));
45 static void DeInitialize_Decoder _ANSI_ARGS_((void));
46 static void Deinitialize_Sequence _ANSI_ARGS_((void));
47 static void Process_Options _ANSI_ARGS_((int argc, char *argv[]));
51 static int Get_Val _ANSI_ARGS_((char *argv[]));
56 static void Clear_Options();
58 static void Print_Options();
62 int my_open(char *filename)
65 return open(filename,O_RDONLY|O_BINARY);
68 off_t my_seek(istream *infile, off_t offset, int whence)
71 return fseek(infile->InFd,offset, whence);
73 return lseek(infile->InFd,offset, whence);
76 ssize_t my_read(istream *infile, void *buf, size_t count)
79 size_t r = fread(buf,1,count, infile->InFd);
81 ssize_t r = read(infile->InFd,buf,count);
83 printf( "%d , %d\n", count , r);
86 int my_close(istream *infile)
89 return fclose(infile->InFd);
91 return close(infile->InFd);
95 int my_fopenr(const char *path, const char *mode, istream *os)
98 FILE *fd = fopen(path, mode);
102 return 1; /*success*/
110 int my_fopen(const char *path, const char *mode, ostream *os)
112 FILE *fd = fopen(path, mode);
116 return 1; /*success*/
123 int my_fseek(ostream *stream, long offset, int whence)
125 return fseek(stream->OutFd, offset, whence);
127 int my_fseekr(istream *stream, long offset, int whence)
129 return fseek(stream->InFd, offset, whence);
132 size_t my_fread(void *ptr, size_t size, size_t nmemb, istream *stream)
134 return fread(ptr, size, nmemb, stream->InFd);
137 size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, ostream *stream)
139 return fwrite(ptr, size, nmemb, stream->OutFd);
142 int my_fcloser(istream *fp)
144 return fclose(fp->InFd);
146 int my_fclose(ostream *fp)
148 return fclose(fp->OutFd);
152 int my_printf(const char *format, ...)
157 va_start(argptr, format);
158 ret = vprintf(format, argptr);
164 int my_sprintf(char *str, const char *format, ...)
169 va_start(argptr, format);
170 ret = vsprintf(str,format, argptr);
176 int my_fprintf(const char *format, ...)
181 va_start(argptr, format);
182 ret = vfprintf(stderr,format, argptr);
187 void my_exit(int status)
193 #define GDCM_BUILD_MPEG2DEC
195 #ifdef GDCM_BUILD_MPEG2DEC
201 /*base.open_stream = my_open;*/
202 base.seek_stream = my_seek;
203 base.read_stream = my_read;
204 base.close_stream = my_close;
208 /* decode command line arguments */
209 Process_Options(argc,argv);
215 ld = &base; /* select base layer context */
217 /* open MPEG base layer bitstream file(s) */
218 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
219 /* if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */
220 /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/
224 base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
226 base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY );
228 if( !base.Infile->InFd)
230 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
239 if(Show_Bits(8)==0x47)
241 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
246 code = Show_Bits(32);
250 case SEQUENCE_HEADER_CODE:
252 case PACK_START_CODE:
253 System_Stream_Flag = 1;
254 case VIDEO_ELEMENTARY_STREAM:
255 System_Stream_Flag = 1;
258 sprintf(Error_Text,"Unable to recognize stream type\n");
263 /*lseek(base.Infile, 0l, SEEK_SET);*/
264 ld->seek_stream(base.Infile,0l,SEEK_SET);
270 /*lseek(base.Infile, 0l, SEEK_SET);*/
271 ld->seek_stream(base.Infile,0l,SEEK_SET);
278 ld = &enhan; /* select enhancement layer context */
280 /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/
281 /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/
285 enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
287 enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY);
289 if (enhan.Infile->InFd)
291 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
292 Enhancement_Layer_Bitstream_Filename);
301 Initialize_Decoder();
303 ret = Decode_Bitstream();
305 /*close(base.Infile);*/
306 ld->close_stream(base.Infile);
309 /*close(enhan.Infile);*/
310 ld->close_stream(enhan.Infile);
312 DeInitialize_Decoder();
316 #endif /*GDCM_BUILD_MPEG2DEC*/
318 /* IMPLEMENTATION specific routines */
319 static void Initialize_Decoder()
324 if (!(Clip=(unsigned char *)malloc(1024)))
325 Error("Clip[] malloc failed\n");
329 for (i=-384; i<640; i++)
330 Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
333 if (Reference_IDCT_Flag)
334 Initialize_Reference_IDCT();
336 Initialize_Fast_IDCT();
340 static void DeInitialize_Decoder()
342 free(Clip-384); /* I love magic number */
345 /* mostly IMPLEMENTAION specific routines */
346 static void Initialize_Sequence()
349 static int Table_6_20[3] = {6,8,12};
351 /* check scalability mode of enhancement layer */
352 if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
353 Error("unsupported scalability mode\n");
355 /* force MPEG-1 parameters for proper decoder behavior */
356 /* see ISO/IEC 13818-2 section D.9.14 */
357 if (!base.MPEG2_Flag)
359 progressive_sequence = 1;
360 progressive_frame = 1;
361 picture_structure = FRAME_PICTURE;
362 frame_pred_frame_dct = 1;
363 chroma_format = CHROMA420;
364 matrix_coefficients = 5;
367 /* round to nearest multiple of coded macroblocks */
368 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
369 mb_width = (horizontal_size+15)/16;
370 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
371 : (vertical_size+15)/16;
373 Coded_Picture_Width = 16*mb_width;
374 Coded_Picture_Height = 16*mb_height;
376 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
377 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
378 : Coded_Picture_Width>>1;
379 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
380 : Coded_Picture_Height>>1;
382 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
383 block_count = Table_6_20[chroma_format-1];
385 for (cc=0; cc<3; cc++)
388 size = Coded_Picture_Width*Coded_Picture_Height;
390 size = Chroma_Width*Chroma_Height;
392 if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
393 Error("backward_reference_frame[] malloc failed\n");
395 if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
396 Error("forward_reference_frame[] malloc failed\n");
398 if (!(auxframe[cc] = (unsigned char *)malloc(size)))
399 Error("auxframe[] malloc failed\n");
402 if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
403 Error("substitute_frame[] malloc failed\n");
406 if (base.scalable_mode==SC_SPAT)
408 /* this assumes lower layer is 4:2:0 */
409 if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
410 Error("llframe0 malloc failed\n");
411 if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
412 Error("llframe1 malloc failed\n");
416 /* SCALABILITY: Spatial */
417 if (base.scalable_mode==SC_SPAT)
419 if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
420 Error("lltmp malloc failed\n");
424 if (Output_Type==T_X11)
426 Initialize_Display_Process("");
427 Initialize_Dither_Matrix();
436 fprintf(stderr,text);
440 /* Trace_Flag output */
441 void Print_Bits(code,bits,len)
445 for (i=0; i<len; i++)
446 printf("%d",(code>>(bits-1-i))&1);
451 /* option processing */
452 static void Process_Options(argc,argv)
453 int argc; /* argument count */
454 char *argv[]; /* argument vector */
456 int i, LastArg, NextArg;
458 /* at least one argument should be present */
461 printf("\n%s, %s\n",Version,Author);
462 printf("Usage: mpeg2decode {options}\n"
463 "Options: -b file main bitstream (base or spatial enhancement layer)\n"
464 " -cn file conformance report (n: level)\n"
465 " -e file enhancement layer bitstream (SNR or Data Partitioning)\n"
466 " -f store/display interlaced video in frame format\n"
467 " -g concatenated file format for substitution method (-x)\n"
468 " -in file information & statistics report (n: level)\n"
469 " -l file file name pattern for lower layer sequence\n");
470 printf(" (for spatial scalability)\n"
471 " -on file output format (0:YUV 1:SIF 2:TGA 3:PPM 4:X11 5:X11HiQ)\n"
472 " -q disable warnings to stderr\n"
473 " -r use double precision reference IDCT\n"
474 " -t enable low level tracing to stdout\n"
475 " -u file print user_data to stdio or file\n"
476 " -vn verbose output (n: level)\n"
477 " -x file filename pattern of picture substitution sequence\n\n");
478 printf("File patterns: for sequential filenames, \"printf\" style, e.g. rec%%d\n"
479 " or rec%%d%%c for fieldwise storage\n"
480 "Levels: 0:none 1:sequence 2:picture 3:slice 4:macroblock 5:block\n\n"
481 "Example: mpeg2decode -b bitstream.mpg -f -r -o0 rec%%d\n"
490 /* command-line options are proceeded by '-' */
494 /* check if this is the last argument */
495 LastArg = ((argc-i)==1);
497 /* parse ahead to see if another flag immediately follows current
498 argument (this is used to tell if a filename is missing) */
500 NextArg = (argv[i+1][0]=='-');
504 /* second character, [1], after '-' is the switch */
507 switch(toupper(argv[i][1]))
509 /* third character. [2], is the value */
511 Main_Bitstream_Flag = 1;
513 if(NextArg || LastArg)
515 printf("ERROR: -b must be followed the main bitstream filename\n");
518 Main_Bitstream_Filename = argv[++i];
526 Verify_Flag = atoi(&argv[i][2]);
528 if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS))
530 printf("ERROR: -c level (%d) out of range [%d,%d]\n",
531 Verify_Flag, NO_LAYER, ALL_LAYERS);
535 printf("This program not compiled for Verify_Flag option\n");
540 Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */
542 if(NextArg || LastArg)
544 printf("ERROR: -e must be followed by filename\n");
548 Enhancement_Layer_Bitstream_Filename = argv[++i];
554 Frame_Store_Flag = 1;
558 Big_Picture_Flag = 1;
564 Stats_Flag = atoi(&argv[i][2]);
566 printf("WARNING: This program not compiled for -i option\n");
570 case 'L': /* spatial scalability flag */
573 if(NextArg || LastArg)
575 printf("ERROR: -l must be followed by filename\n");
579 Lower_Layer_Picture_Filename = argv[++i];
585 Output_Type = atoi(&argv[i][2]);
587 if((Output_Type==4) || (Output_Type==5))
588 Output_Picture_Filename = ""; /* no need of filename */
589 else if(NextArg || LastArg)
591 printf("ERROR: -o must be followed by filename\n");
595 /* filename is separated by space, so it becomes the next argument */
596 Output_Picture_Filename = argv[++i];
599 if (Output_Type==T_X11HIQ)
612 Reference_IDCT_Flag = 1;
619 printf("WARNING: This program not compiled for -t option\n");
628 Verbose_Flag = atoi(&argv[i][2]);
630 printf("This program not compiled for -v option\n");
638 if(NextArg || LastArg)
640 printf("ERROR: -x must be followed by filename\n");
644 Substitute_Picture_Filename = argv[++i];
651 fprintf(stderr,"undefined option -%c ignored. Exiting program\n",
657 } /* if argv[i][0] == '-' */
661 /* check for bitstream filename argument (there must always be one, at the very end
662 of the command line arguments */
667 /* options sense checking */
669 if(Main_Bitstream_Flag!=1)
671 printf("There must be a main bitstream specified (-b filename)\n");
674 /* force display process to show frame pictures */
675 if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag)
676 Display_Progressive_Flag = 1;
678 Display_Progressive_Flag = 0;
681 /* parse the bitstream, do not actually decode it completely */
687 Decode_Layer = Verify_Flag;
688 printf("FYI: Decoding bitstream elements up to: %s\n",
689 Layer_Table[Decode_Layer]);
693 Decode_Layer = ALL_LAYERS;
697 /* no output type specified */
701 Output_Picture_Filename = "";
706 if (Output_Type==T_X11)
709 Display_Progressive_Flag = 1;
711 Display_Progressive_Flag = 0;
713 Frame_Store_Flag = 1; /* to avoid calling dither() twice */
723 this is an old routine used to convert command line arguments
726 static int Get_Val(argv)
731 if (sscanf(argv[1]+2,"%d",&val)!=1)
734 while (isdigit(argv[1][2]))
750 /* return when end of sequence (0) or picture
751 header has been parsed (1) */
759 if (Get_Hdr()!=ret && !Quiet_Flag)
760 fprintf(stderr,"streams out of sync\n");
769 static int Decode_Bitstream()
772 int Bitstream_Framenum;
774 Bitstream_Framenum = 0;
780 Clear_Verify_Headers();
787 ret = video_sequence(&Bitstream_Framenum);
796 static void Deinitialize_Sequence()
800 /* First cleanup the static buffer in store.c */
808 free(backward_reference_frame[i]);
809 free(forward_reference_frame[i]);
812 if (base.scalable_mode==SC_SPAT)
819 if (base.scalable_mode==SC_SPAT)
823 if (Output_Type==T_X11)
824 Terminate_Display_Process();
829 static int video_sequence(Bitstream_Framenumber)
830 int *Bitstream_Framenumber;
832 int Bitstream_Framenum;
833 int Sequence_Framenum;
836 Bitstream_Framenum = *Bitstream_Framenumber;
839 Initialize_Sequence();
841 /* decode picture whose header has already been parsed in
842 Decode_Bitstream() */
845 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
847 /* update picture numbers */
850 Bitstream_Framenum++;
854 /* loop through the rest of the pictures in the sequence */
855 while ((Return_Value=Headers()))
857 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
861 Bitstream_Framenum++;
867 if (Sequence_Framenum!=0)
869 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
872 Deinitialize_Sequence();
875 Clear_Verify_Headers();
878 *Bitstream_Framenumber = Bitstream_Framenum;
879 return(Return_Value);
884 static void Clear_Options()
888 Output_Picture_Filename = " ";
891 Frame_Store_Flag = 0;
893 Lower_Layer_Picture_Filename = " ";
894 Reference_IDCT_Flag = 0;
898 Substitute_Picture_Filename = " ";
900 Enhancement_Layer_Bitstream_Filename = " ";
901 Big_Picture_Flag = 0;
902 Main_Bitstream_Flag = 0;
903 Main_Bitstream_Filename = " ";
911 static void Print_Options()
914 printf("Verbose_Flag = %d\n", Verbose_Flag);
915 printf("Output_Type = %d\n", Output_Type);
916 printf("Output_Picture_Filename = %s\n", Output_Picture_Filename);
917 printf("hiQdither = %d\n", hiQdither);
918 printf("Output_Type = %d\n", Output_Type);
919 printf("Frame_Store_Flag = %d\n", Frame_Store_Flag);
920 printf("Spatial_Flag = %d\n", Spatial_Flag);
921 printf("Lower_Layer_Picture_Filename = %s\n", Lower_Layer_Picture_Filename);
922 printf("Reference_IDCT_Flag = %d\n", Reference_IDCT_Flag);
923 printf("Trace_Flag = %d\n", Trace_Flag);
924 printf("Quiet_Flag = %d\n", Quiet_Flag);
925 printf("Ersatz_Flag = %d\n", Ersatz_Flag);
926 printf("Substitute_Picture_Filename = %s\n", Substitute_Picture_Filename);
927 printf("Two_Streams = %d\n", Two_Streams);
928 printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename);
929 printf("Big_Picture_Flag = %d\n", Big_Picture_Flag);
930 printf("Main_Bitstream_Flag = %d\n", Main_Bitstream_Flag);
931 printf("Main_Bitstream_Filename = %s\n", Main_Bitstream_Filename);
932 printf("Verify_Flag = %d\n", Verify_Flag);
933 printf("Stats_Flag = %d\n", Stats_Flag);
934 printf("User_Data_Flag = %d\n", User_Data_Flag);