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
35 #include <unistd.h> // for lseek
41 /* private prototypes */
42 static int video_sequence _ANSI_ARGS_((int *framenum));
43 static int Decode_Bitstream _ANSI_ARGS_((void));
44 static int Headers _ANSI_ARGS_((void));
45 static void Initialize_Sequence _ANSI_ARGS_((void));
46 static void Initialize_Decoder _ANSI_ARGS_((void));
47 static void Deinitialize_Sequence _ANSI_ARGS_((void));
48 static void Process_Options _ANSI_ARGS_((int argc, char *argv[]));
52 static int Get_Val _ANSI_ARGS_((char *argv[]));
57 static void Clear_Options();
59 static void Print_Options();
70 /* decode command line arguments */
71 Process_Options(argc,argv);
77 ld = &base; /* select base layer context */
79 /* open MPEG base layer bitstream file(s) */
80 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
81 if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
83 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
92 if(Show_Bits(8)==0x47)
94 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
103 case SEQUENCE_HEADER_CODE:
105 case PACK_START_CODE:
106 System_Stream_Flag = 1;
107 case VIDEO_ELEMENTARY_STREAM:
108 System_Stream_Flag = 1;
111 sprintf(Error_Text,"Unable to recognize stream type\n");
116 lseek(base.Infile, 0l, 0);
122 lseek(base.Infile, 0l, 0);
129 ld = &enhan; /* select enhancement layer context */
131 if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
133 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
134 Enhancement_Layer_Bitstream_Filename);
143 Initialize_Decoder();
145 ret = Decode_Bitstream();
155 /* IMPLEMENTAION specific rouintes */
156 static void Initialize_Decoder()
161 if (!(Clip=(unsigned char *)malloc(1024)))
162 Error("Clip[] malloc failed\n");
166 for (i=-384; i<640; i++)
167 Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
170 if (Reference_IDCT_Flag)
171 Initialize_Reference_IDCT();
173 Initialize_Fast_IDCT();
177 /* mostly IMPLEMENTAION specific rouintes */
178 static void Initialize_Sequence()
181 static int Table_6_20[3] = {6,8,12};
183 /* check scalability mode of enhancement layer */
184 if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
185 Error("unsupported scalability mode\n");
187 /* force MPEG-1 parameters for proper decoder behavior */
188 /* see ISO/IEC 13818-2 section D.9.14 */
189 if (!base.MPEG2_Flag)
191 progressive_sequence = 1;
192 progressive_frame = 1;
193 picture_structure = FRAME_PICTURE;
194 frame_pred_frame_dct = 1;
195 chroma_format = CHROMA420;
196 matrix_coefficients = 5;
199 /* round to nearest multiple of coded macroblocks */
200 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
201 mb_width = (horizontal_size+15)/16;
202 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
203 : (vertical_size+15)/16;
205 Coded_Picture_Width = 16*mb_width;
206 Coded_Picture_Height = 16*mb_height;
208 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
209 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
210 : Coded_Picture_Width>>1;
211 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
212 : Coded_Picture_Height>>1;
214 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
215 block_count = Table_6_20[chroma_format-1];
217 for (cc=0; cc<3; cc++)
220 size = Coded_Picture_Width*Coded_Picture_Height;
222 size = Chroma_Width*Chroma_Height;
224 if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
225 Error("backward_reference_frame[] malloc failed\n");
227 if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
228 Error("forward_reference_frame[] malloc failed\n");
230 if (!(auxframe[cc] = (unsigned char *)malloc(size)))
231 Error("auxframe[] malloc failed\n");
234 if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
235 Error("substitute_frame[] malloc failed\n");
238 if (base.scalable_mode==SC_SPAT)
240 /* this assumes lower layer is 4:2:0 */
241 if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
242 Error("llframe0 malloc failed\n");
243 if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
244 Error("llframe1 malloc failed\n");
248 /* SCALABILITY: Spatial */
249 if (base.scalable_mode==SC_SPAT)
251 if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
252 Error("lltmp malloc failed\n");
256 if (Output_Type==T_X11)
258 Initialize_Display_Process("");
259 Initialize_Dither_Matrix();
268 fprintf(stderr,text);
272 /* Trace_Flag output */
273 void Print_Bits(code,bits,len)
277 for (i=0; i<len; i++)
278 printf("%d",(code>>(bits-1-i))&1);
283 /* option processing */
284 static void Process_Options(argc,argv)
285 int argc; /* argument count */
286 char *argv[]; /* argument vector */
288 int i, LastArg, NextArg;
290 /* at least one argument should be present */
293 printf("\n%s, %s\n",Version,Author);
294 printf("Usage: mpeg2decode {options}\n\
295 Options: -b file main bitstream (base or spatial enhancement layer)\n\
296 -cn file conformance report (n: level)\n\
297 -e file enhancement layer bitstream (SNR or Data Partitioning)\n\
298 -f store/display interlaced video in frame format\n\
299 -g concatenated file format for substitution method (-x)\n\
300 -in file information & statistics report (n: level)\n\
301 -l file file name pattern for lower layer sequence\n\
302 (for spatial scalability)\n\
303 -on file output format (0:YUV 1:SIF 2:TGA 3:PPM 4:X11 5:X11HiQ)\n\
304 -q disable warnings to stderr\n\
305 -r use double precision reference IDCT\n\
306 -t enable low level tracing to stdout\n\
307 -u file print user_data to stdio or file\n\
308 -vn verbose output (n: level)\n\
309 -x file filename pattern of picture substitution sequence\n\n\
310 File patterns: for sequential filenames, \"printf\" style, e.g. rec%%d\n\
311 or rec%%d%%c for fieldwise storage\n\
312 Levels: 0:none 1:sequence 2:picture 3:slice 4:macroblock 5:block\n\n\
313 Example: mpeg2decode -b bitstream.mpg -f -r -o0 rec%%d\n\
322 /* command-line options are proceeded by '-' */
326 /* check if this is the last argument */
327 LastArg = ((argc-i)==1);
329 /* parse ahead to see if another flag immediately follows current
330 argument (this is used to tell if a filename is missing) */
332 NextArg = (argv[i+1][0]=='-');
336 /* second character, [1], after '-' is the switch */
339 switch(toupper(argv[i][1]))
341 /* third character. [2], is the value */
343 Main_Bitstream_Flag = 1;
345 if(NextArg || LastArg)
347 printf("ERROR: -b must be followed the main bitstream filename\n");
350 Main_Bitstream_Filename = argv[++i];
358 Verify_Flag = atoi(&argv[i][2]);
360 if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS))
362 printf("ERROR: -c level (%d) out of range [%d,%d]\n",
363 Verify_Flag, NO_LAYER, ALL_LAYERS);
367 printf("This program not compiled for Verify_Flag option\n");
372 Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */
374 if(NextArg || LastArg)
376 printf("ERROR: -e must be followed by filename\n");
380 Enhancement_Layer_Bitstream_Filename = argv[++i];
386 Frame_Store_Flag = 1;
390 Big_Picture_Flag = 1;
396 Stats_Flag = atoi(&argv[i][2]);
398 printf("WARNING: This program not compiled for -i option\n");
402 case 'L': /* spatial scalability flag */
405 if(NextArg || LastArg)
407 printf("ERROR: -l must be followed by filename\n");
411 Lower_Layer_Picture_Filename = argv[++i];
417 Output_Type = atoi(&argv[i][2]);
419 if((Output_Type==4) || (Output_Type==5))
420 Output_Picture_Filename = ""; /* no need of filename */
421 else if(NextArg || LastArg)
423 printf("ERROR: -o must be followed by filename\n");
427 /* filename is separated by space, so it becomes the next argument */
428 Output_Picture_Filename = argv[++i];
431 if (Output_Type==T_X11HIQ)
444 Reference_IDCT_Flag = 1;
451 printf("WARNING: This program not compiled for -t option\n");
460 Verbose_Flag = atoi(&argv[i][2]);
462 printf("This program not compiled for -v option\n");
470 if(NextArg || LastArg)
472 printf("ERROR: -x must be followed by filename\n");
476 Substitute_Picture_Filename = argv[++i];
483 fprintf(stderr,"undefined option -%c ignored. Exiting program\n",
489 } /* if argv[i][0] == '-' */
493 /* check for bitstream filename argument (there must always be one, at the very end
494 of the command line arguments */
499 /* options sense checking */
501 if(Main_Bitstream_Flag!=1)
503 printf("There must be a main bitstream specified (-b filename)\n");
506 /* force display process to show frame pictures */
507 if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag)
508 Display_Progressive_Flag = 1;
510 Display_Progressive_Flag = 0;
513 /* parse the bitstream, do not actually decode it completely */
519 Decode_Layer = Verify_Flag;
520 printf("FYI: Decoding bitstream elements up to: %s\n",
521 Layer_Table[Decode_Layer]);
525 Decode_Layer = ALL_LAYERS;
529 /* no output type specified */
533 Output_Picture_Filename = "";
538 if (Output_Type==T_X11)
541 Display_Progressive_Flag = 1;
543 Display_Progressive_Flag = 0;
545 Frame_Store_Flag = 1; /* to avoid calling dither() twice */
555 this is an old routine used to convert command line arguments
558 static int Get_Val(argv)
563 if (sscanf(argv[1]+2,"%d",&val)!=1)
566 while (isdigit(argv[1][2]))
582 /* return when end of sequence (0) or picture
583 header has been parsed (1) */
591 if (Get_Hdr()!=ret && !Quiet_Flag)
592 fprintf(stderr,"streams out of sync\n");
601 static int Decode_Bitstream()
604 int Bitstream_Framenum;
606 Bitstream_Framenum = 0;
612 Clear_Verify_Headers();
619 ret = video_sequence(&Bitstream_Framenum);
628 static void Deinitialize_Sequence()
637 free(backward_reference_frame[i]);
638 free(forward_reference_frame[i]);
641 if (base.scalable_mode==SC_SPAT)
648 if (base.scalable_mode==SC_SPAT)
652 if (Output_Type==T_X11)
653 Terminate_Display_Process();
658 static int video_sequence(Bitstream_Framenumber)
659 int *Bitstream_Framenumber;
661 int Bitstream_Framenum;
662 int Sequence_Framenum;
665 Bitstream_Framenum = *Bitstream_Framenumber;
668 Initialize_Sequence();
670 /* decode picture whose header has already been parsed in
671 Decode_Bitstream() */
674 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
676 /* update picture numbers */
679 Bitstream_Framenum++;
683 /* loop through the rest of the pictures in the sequence */
684 while ((Return_Value=Headers()))
686 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
690 Bitstream_Framenum++;
696 if (Sequence_Framenum!=0)
698 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
701 Deinitialize_Sequence();
704 Clear_Verify_Headers();
707 *Bitstream_Framenumber = Bitstream_Framenum;
708 return(Return_Value);
713 static void Clear_Options()
717 Output_Picture_Filename = " ";
720 Frame_Store_Flag = 0;
722 Lower_Layer_Picture_Filename = " ";
723 Reference_IDCT_Flag = 0;
727 Substitute_Picture_Filename = " ";
729 Enhancement_Layer_Bitstream_Filename = " ";
730 Big_Picture_Flag = 0;
731 Main_Bitstream_Flag = 0;
732 Main_Bitstream_Filename = " ";
740 static void Print_Options()
743 printf("Verbose_Flag = %d\n", Verbose_Flag);
744 printf("Output_Type = %d\n", Output_Type);
745 printf("Output_Picture_Filename = %s\n", Output_Picture_Filename);
746 printf("hiQdither = %d\n", hiQdither);
747 printf("Output_Type = %d\n", Output_Type);
748 printf("Frame_Store_Flag = %d\n", Frame_Store_Flag);
749 printf("Spatial_Flag = %d\n", Spatial_Flag);
750 printf("Lower_Layer_Picture_Filename = %s\n", Lower_Layer_Picture_Filename);
751 printf("Reference_IDCT_Flag = %d\n", Reference_IDCT_Flag);
752 printf("Trace_Flag = %d\n", Trace_Flag);
753 printf("Quiet_Flag = %d\n", Quiet_Flag);
754 printf("Ersatz_Flag = %d\n", Ersatz_Flag);
755 printf("Substitute_Picture_Filename = %s\n", Substitute_Picture_Filename);
756 printf("Two_Streams = %d\n", Two_Streams);
757 printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename);
758 printf("Big_Picture_Flag = %d\n", Big_Picture_Flag);
759 printf("Main_Bitstream_Flag = %d\n", Main_Bitstream_Flag);
760 printf("Main_Bitstream_Filename = %s\n", Main_Bitstream_Filename);
761 printf("Verify_Flag = %d\n", Verify_Flag);
762 printf("Stats_Flag = %d\n", Stats_Flag);
763 printf("User_Data_Flag = %d\n", User_Data_Flag);