]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2dec/mpeg2dec.c
09a4ae27cf80fa646f5bba04db445eb56306be73
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2dec / mpeg2dec.c
1
2 /* mpeg2dec.c, main(), initialization, option processing                    */
3
4 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
5
6 /*
7  * Disclaimer of Warranty
8  *
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.
16  *
17  * This disclaimer of warranty extends to the user of these programs and user's
18  * customers, employees, agents, transferees, successors, and assigns.
19  *
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
22  * patents.
23  *
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
27  * design.
28  *
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <fcntl.h>
35 #include <unistd.h> // for lseek
36
37 #define GLOBAL
38 #include "config.h"
39 #include "global.h"
40
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[]));
49
50
51 #if OLD
52 static int  Get_Val _ANSI_ARGS_((char *argv[]));
53 #endif
54
55 /* #define DEBUG */
56
57 static void Clear_Options();
58 #ifdef DEBUG
59 static void Print_Options();
60 #endif
61
62 int main(argc,argv)
63 int argc;
64 char *argv[];
65 {
66   int ret, code;
67
68   Clear_Options();
69
70   /* decode command line arguments */
71   Process_Options(argc,argv);
72
73 #ifdef DEBUG
74   Print_Options();
75 #endif
76
77   ld = &base; /* select base layer context */
78
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)
82   {
83     fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
84     exit(1);
85   }
86
87
88   if(base.Infile != 0)
89   {
90     Initialize_Buffer(); 
91   
92     if(Show_Bits(8)==0x47)
93     {
94       sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
95       Error(Error_Text);
96     }
97
98     next_start_code();
99     code = Show_Bits(32);
100
101     switch(code)
102     {
103     case SEQUENCE_HEADER_CODE:
104       break;
105     case PACK_START_CODE:
106       System_Stream_Flag = 1;
107     case VIDEO_ELEMENTARY_STREAM:
108       System_Stream_Flag = 1;
109       break;
110     default:
111       sprintf(Error_Text,"Unable to recognize stream type\n");
112       Error(Error_Text);
113       break;
114     }
115
116     lseek(base.Infile, 0l, 0);
117     Initialize_Buffer(); 
118   }
119
120   if(base.Infile!=0)
121   {
122     lseek(base.Infile, 0l, 0);
123   }
124
125   Initialize_Buffer(); 
126
127   if(Two_Streams)
128   {
129     ld = &enhan; /* select enhancement layer context */
130
131     if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
132     {
133       sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
134         Enhancement_Layer_Bitstream_Filename);
135
136       Error(Error_Text);
137     }
138
139     Initialize_Buffer();
140     ld = &base;
141   }
142
143   Initialize_Decoder();
144
145   ret = Decode_Bitstream();
146
147   close(base.Infile);
148
149   if (Two_Streams)
150     close(enhan.Infile);
151
152   return 0;
153 }
154
155 /* IMPLEMENTAION specific rouintes */
156 static void Initialize_Decoder()
157 {
158   int i;
159
160   /* Clip table */
161   if (!(Clip=(unsigned char *)malloc(1024)))
162     Error("Clip[] malloc failed\n");
163
164   Clip += 384;
165
166   for (i=-384; i<640; i++)
167     Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
168
169   /* IDCT */
170   if (Reference_IDCT_Flag)
171     Initialize_Reference_IDCT();
172   else
173     Initialize_Fast_IDCT();
174
175 }
176
177 /* mostly IMPLEMENTAION specific rouintes */
178 static void Initialize_Sequence()
179 {
180   int cc, size;
181   static int Table_6_20[3] = {6,8,12};
182
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");
186
187   /* force MPEG-1 parameters for proper decoder behavior */
188   /* see ISO/IEC 13818-2 section D.9.14 */
189   if (!base.MPEG2_Flag)
190   {
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;
197   }
198
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;
204
205   Coded_Picture_Width = 16*mb_width;
206   Coded_Picture_Height = 16*mb_height;
207
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;
213   
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];
216
217   for (cc=0; cc<3; cc++)
218   {
219     if (cc==0)
220       size = Coded_Picture_Width*Coded_Picture_Height;
221     else
222       size = Chroma_Width*Chroma_Height;
223
224     if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
225       Error("backward_reference_frame[] malloc failed\n");
226
227     if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
228       Error("forward_reference_frame[] malloc failed\n");
229
230     if (!(auxframe[cc] = (unsigned char *)malloc(size)))
231       Error("auxframe[] malloc failed\n");
232
233     if(Ersatz_Flag)
234       if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
235         Error("substitute_frame[] malloc failed\n");
236
237
238     if (base.scalable_mode==SC_SPAT)
239     {
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");
245     }
246   }
247
248   /* SCALABILITY: Spatial */
249   if (base.scalable_mode==SC_SPAT)
250   {
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");
253   }
254
255 #ifdef DISPLAY
256   if (Output_Type==T_X11)
257   {
258     Initialize_Display_Process("");
259     Initialize_Dither_Matrix();
260   }
261 #endif /* DISPLAY */
262
263 }
264
265 void Error(text)
266 char *text;
267 {
268   fprintf(stderr,text);
269   exit(1);
270 }
271
272 /* Trace_Flag output */
273 void Print_Bits(code,bits,len)
274 int code,bits,len;
275 {
276   int i;
277   for (i=0; i<len; i++)
278     printf("%d",(code>>(bits-1-i))&1);
279 }
280
281
282
283 /* option processing */
284 static void Process_Options(argc,argv)
285 int argc;                  /* argument count  */
286 char *argv[];              /* argument vector */
287 {
288   int i, LastArg, NextArg;
289
290   /* at least one argument should be present */
291   if (argc<2)
292   {
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\
314          \n");
315     exit(0);
316   }
317
318
319   Output_Type = -1;
320   i = 1;
321
322   /* command-line options are proceeded by '-' */
323
324   while(i < argc)
325   {
326     /* check if this is the last argument */
327     LastArg = ((argc-i)==1);
328
329     /* parse ahead to see if another flag immediately follows current
330        argument (this is used to tell if a filename is missing) */
331     if(!LastArg)
332       NextArg = (argv[i+1][0]=='-');
333     else
334       NextArg = 0;
335
336     /* second character, [1], after '-' is the switch */
337     if(argv[i][0]=='-')
338     {
339       switch(toupper(argv[i][1]))
340       {
341         /* third character. [2], is the value */
342       case 'B':
343         Main_Bitstream_Flag = 1;
344
345         if(NextArg || LastArg)
346         {
347           printf("ERROR: -b must be followed the main bitstream filename\n");
348         }
349         else
350           Main_Bitstream_Filename = argv[++i]; 
351
352         break;
353
354
355       case 'C':
356
357 #ifdef VERIFY
358         Verify_Flag = atoi(&argv[i][2]); 
359
360         if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS))
361         {
362           printf("ERROR: -c level (%d) out of range [%d,%d]\n",
363             Verify_Flag, NO_LAYER, ALL_LAYERS);
364           exit(ERROR);
365         }
366 #else  /* VERIFY */
367         printf("This program not compiled for Verify_Flag option\n");
368 #endif /* VERIFY */
369         break;
370
371       case 'E':
372         Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */
373                    
374         if(NextArg || LastArg)
375         {
376           printf("ERROR: -e must be followed by filename\n");
377           exit(ERROR);
378         }
379         else
380           Enhancement_Layer_Bitstream_Filename = argv[++i]; 
381
382         break;
383
384
385       case 'F':
386         Frame_Store_Flag = 1;
387         break;
388
389       case 'G':
390         Big_Picture_Flag = 1;
391         break;
392
393
394       case 'I':
395 #ifdef VERIFY
396         Stats_Flag = atoi(&argv[i][2]); 
397 #else /* VERIFY */
398         printf("WARNING: This program not compiled for -i option\n");
399 #endif /* VERIFY */     
400         break;
401     
402       case 'L':  /* spatial scalability flag */
403         Spatial_Flag = 1;
404
405        if(NextArg || LastArg)
406        {
407          printf("ERROR: -l must be followed by filename\n");
408          exit(ERROR);
409        }
410        else
411          Lower_Layer_Picture_Filename = argv[++i]; 
412
413         break;
414
415       case 'O':
416   
417         Output_Type = atoi(&argv[i][2]); 
418   
419         if((Output_Type==4) || (Output_Type==5))
420           Output_Picture_Filename = "";  /* no need of filename */
421         else if(NextArg || LastArg)  
422         {
423           printf("ERROR: -o must be followed by filename\n");
424           exit(ERROR);
425         }
426         else
427         /* filename is separated by space, so it becomes the next argument */
428           Output_Picture_Filename = argv[++i]; 
429
430 #ifdef DISPLAY
431         if (Output_Type==T_X11HIQ)
432         {
433           hiQdither = 1;
434           Output_Type=T_X11;
435         }
436 #endif /* DISPLAY */
437         break;
438
439       case 'Q':
440         Quiet_Flag = 1;
441         break;
442
443       case 'R':
444         Reference_IDCT_Flag = 1;
445         break;
446     
447       case 'T':
448 #ifdef TRACE
449         Trace_Flag = 1;
450 #else /* TRACE */
451         printf("WARNING: This program not compiled for -t option\n");
452 #endif /* TRACE */
453         break;
454
455       case 'U':
456         User_Data_Flag = 1;
457
458       case 'V':
459 #ifdef VERBOSE
460         Verbose_Flag = atoi(&argv[i][2]); 
461 #else /* VERBOSE */
462         printf("This program not compiled for -v option\n");
463 #endif /* VERBOSE */
464         break;
465
466
467       case 'X':
468         Ersatz_Flag = 1;
469
470        if(NextArg || LastArg)
471        {
472          printf("ERROR: -x must be followed by filename\n"); 
473          exit(ERROR);
474        }
475        else
476         Substitute_Picture_Filename = argv[++i]; 
477
478         break;
479
480
481
482       default:
483         fprintf(stderr,"undefined option -%c ignored. Exiting program\n", 
484           argv[i][1]);
485
486         exit(ERROR);
487     
488       } /* switch() */
489     } /* if argv[i][0] == '-' */
490     
491     i++;
492
493     /* check for bitstream filename argument (there must always be one, at the very end
494      of the command line arguments */
495
496   } /* while() */
497
498
499   /* options sense checking */
500
501   if(Main_Bitstream_Flag!=1)
502   {
503     printf("There must be a main bitstream specified (-b filename)\n");
504   }
505
506   /* force display process to show frame pictures */
507   if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag)
508     Display_Progressive_Flag = 1;
509   else
510     Display_Progressive_Flag = 0;
511
512 #ifdef VERIFY
513   /* parse the bitstream, do not actually decode it completely */
514   
515
516 #if 0
517   if(Output_Type==-1)
518   {
519     Decode_Layer = Verify_Flag;
520     printf("FYI: Decoding bitstream elements up to: %s\n", 
521       Layer_Table[Decode_Layer]);
522   }
523   else
524 #endif
525     Decode_Layer = ALL_LAYERS;
526
527 #endif /* VERIFY */
528
529   /* no output type specified */
530   if(Output_Type==-1)
531   {
532     Output_Type = 9; 
533     Output_Picture_Filename = "";
534   }
535
536
537 #ifdef DISPLAY
538   if (Output_Type==T_X11)
539   {
540     if(Frame_Store_Flag)
541       Display_Progressive_Flag = 1;
542     else
543       Display_Progressive_Flag = 0;
544
545     Frame_Store_Flag = 1; /* to avoid calling dither() twice */
546   }
547 #endif
548
549
550 }
551
552
553 #ifdef OLD
554 /* 
555    this is an old routine used to convert command line arguments
556    into integers 
557 */
558 static int Get_Val(argv)
559 char *argv[];
560 {
561   int val;
562
563   if (sscanf(argv[1]+2,"%d",&val)!=1)
564     return 0;
565
566   while (isdigit(argv[1][2]))
567     argv[1]++;
568
569   return val;
570 }
571 #endif
572
573
574
575 static int Headers()
576 {
577   int ret;
578
579   ld = &base;
580   
581
582   /* return when end of sequence (0) or picture
583      header has been parsed (1) */
584
585   ret = Get_Hdr();
586
587
588   if (Two_Streams)
589   {
590     ld = &enhan;
591     if (Get_Hdr()!=ret && !Quiet_Flag)
592       fprintf(stderr,"streams out of sync\n");
593     ld = &base;
594   }
595
596   return ret;
597 }
598
599
600
601 static int Decode_Bitstream()
602 {
603   int ret;
604   int Bitstream_Framenum;
605
606   Bitstream_Framenum = 0;
607
608   for(;;)
609   {
610
611 #ifdef VERIFY
612     Clear_Verify_Headers();
613 #endif /* VERIFY */
614
615     ret = Headers();
616     
617     if(ret==1)
618     {
619       ret = video_sequence(&Bitstream_Framenum);
620     }
621     else
622       return(ret);
623   }
624
625 }
626
627
628 static void Deinitialize_Sequence()
629 {
630   int i;
631
632   /* clear flags */
633   base.MPEG2_Flag=0;
634
635   for(i=0;i<3;i++)
636   {
637     free(backward_reference_frame[i]);
638     free(forward_reference_frame[i]);
639     free(auxframe[i]);
640
641     if (base.scalable_mode==SC_SPAT)
642     {
643      free(llframe0[i]);
644      free(llframe1[i]);
645     }
646   }
647
648   if (base.scalable_mode==SC_SPAT)
649     free(lltmp);
650
651 #ifdef DISPLAY
652   if (Output_Type==T_X11) 
653     Terminate_Display_Process();
654 #endif
655 }
656
657
658 static int video_sequence(Bitstream_Framenumber)
659 int *Bitstream_Framenumber;
660 {
661   int Bitstream_Framenum;
662   int Sequence_Framenum;
663   int Return_Value;
664
665   Bitstream_Framenum = *Bitstream_Framenumber;
666   Sequence_Framenum=0;
667
668   Initialize_Sequence();
669
670   /* decode picture whose header has already been parsed in 
671      Decode_Bitstream() */
672
673
674   Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
675
676   /* update picture numbers */
677   if (!Second_Field)
678   {
679     Bitstream_Framenum++;
680     Sequence_Framenum++;
681   }
682
683   /* loop through the rest of the pictures in the sequence */
684   while ((Return_Value=Headers()))
685   {
686     Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
687
688     if (!Second_Field)
689     {
690       Bitstream_Framenum++;
691       Sequence_Framenum++;
692     }
693   }
694
695   /* put last frame */
696   if (Sequence_Framenum!=0)
697   {
698     Output_Last_Frame_of_Sequence(Bitstream_Framenum);
699   }
700
701   Deinitialize_Sequence();
702
703 #ifdef VERIFY
704     Clear_Verify_Headers();
705 #endif /* VERIFY */
706
707   *Bitstream_Framenumber = Bitstream_Framenum;
708   return(Return_Value);
709 }
710
711
712
713 static void Clear_Options()
714 {
715   Verbose_Flag = 0;
716   Output_Type = 0;
717   Output_Picture_Filename = " ";
718   hiQdither  = 0;
719   Output_Type = 0;
720   Frame_Store_Flag = 0;
721   Spatial_Flag = 0;
722   Lower_Layer_Picture_Filename = " ";
723   Reference_IDCT_Flag = 0;
724   Trace_Flag = 0;
725   Quiet_Flag = 0;
726   Ersatz_Flag = 0;
727   Substitute_Picture_Filename  = " ";
728   Two_Streams = 0;
729   Enhancement_Layer_Bitstream_Filename = " ";
730   Big_Picture_Flag = 0;
731   Main_Bitstream_Flag = 0;
732   Main_Bitstream_Filename = " ";
733   Verify_Flag = 0;
734   Stats_Flag  = 0;
735   User_Data_Flag = 0; 
736 }
737
738
739 #ifdef DEBUG
740 static void Print_Options()
741 {
742   
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);
764
765 }
766 #endif