1 /*=========================================================================
4 Module: $RCSfile: gdcmMpeg.cxx,v $
6 Date: $Date: 2005/10/27 19:05:36 $
7 Version: $Revision: 1.6 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
18 #include "gdcmDebug.h"
34 off_t my_seek(istream *infile, off_t offset, int whence)
36 //return fseek(infile->InFd,offset, whence);
40 infile->InFd.seekg(offset, std::ios::beg);
43 infile->InFd.seekg(offset, std::ios::end);
46 infile->InFd.seekg(offset, std::ios::cur);
49 return infile->InFd.tellg();
51 ssize_t my_read(istream *infile, void *buf, size_t count)
53 //return fread(buf,1,count, infile->InFd);
54 infile->InFd.read((char*)buf, count);
55 return infile->InFd.gcount();
58 int my_close(istream *infile)
60 //return fclose(infile->InFd);
68 * \brief routine for MPEG decompression
69 * @param fp pointer to an already open file descriptor
70 * 8 significant bits per pixel
71 * @param image_buffer to receive uncompressed pixels
72 * @param length length
73 * @return 1 on success, 0 on error
76 static void DeInitialize_Decoder()
78 free(Clip-384); /* I love magic number */
80 static void Deinitialize_Sequence()
84 /* First cleanup the static buffer in store.c */
92 free(backward_reference_frame[i]);
93 free(forward_reference_frame[i]);
96 if (base.scalable_mode==SC_SPAT)
103 if (base.scalable_mode==SC_SPAT)
107 if (Output_Type==T_X11)
108 Terminate_Display_Process();
112 /* mostly IMPLEMENTAION specific routines */
113 static void Initialize_Sequence()
116 static int Table_6_20[3] = {6,8,12};
118 /* check scalability mode of enhancement layer */
119 if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
120 Error("unsupported scalability mode\n");
122 /* force MPEG-1 parameters for proper decoder behavior */
123 /* see ISO/IEC 13818-2 section D.9.14 */
124 if (!base.MPEG2_Flag)
126 progressive_sequence = 1;
127 progressive_frame = 1;
128 picture_structure = FRAME_PICTURE;
129 frame_pred_frame_dct = 1;
130 chroma_format = CHROMA420;
131 matrix_coefficients = 5;
134 /* round to nearest multiple of coded macroblocks */
135 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
136 mb_width = (horizontal_size+15)/16;
137 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
138 : (vertical_size+15)/16;
140 Coded_Picture_Width = 16*mb_width;
141 Coded_Picture_Height = 16*mb_height;
143 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
144 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
145 : Coded_Picture_Width>>1;
146 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
147 : Coded_Picture_Height>>1;
149 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
150 block_count = Table_6_20[chroma_format-1];
152 for (cc=0; cc<3; cc++)
155 size = Coded_Picture_Width*Coded_Picture_Height;
157 size = Chroma_Width*Chroma_Height;
159 if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
160 Error("backward_reference_frame[] malloc failed\n");
162 if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
163 Error("forward_reference_frame[] malloc failed\n");
165 if (!(auxframe[cc] = (unsigned char *)malloc(size)))
166 Error("auxframe[] malloc failed\n");
169 if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
170 Error("substitute_frame[] malloc failed\n");
173 if (base.scalable_mode==SC_SPAT)
175 /* this assumes lower layer is 4:2:0 */
176 if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
177 Error("llframe0 malloc failed\n");
178 if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
179 Error("llframe1 malloc failed\n");
183 /* SCALABILITY: Spatial */
184 if (base.scalable_mode==SC_SPAT)
186 if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
187 Error("lltmp malloc failed\n");
191 if (Output_Type==T_X11)
193 Initialize_Display_Process("");
194 Initialize_Dither_Matrix();
199 static int video_sequence(int *Bitstream_Framenumber)
200 //int *Bitstream_Framenumber;
202 int Bitstream_Framenum;
203 int Sequence_Framenum;
206 Bitstream_Framenum = *Bitstream_Framenumber;
209 Initialize_Sequence();
211 /* decode picture whose header has already been parsed in
212 Decode_Bitstream() */
215 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
217 /* update picture numbers */
220 Bitstream_Framenum++;
224 /* loop through the rest of the pictures in the sequence */
225 while ((Return_Value=Headers()))
227 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
231 Bitstream_Framenum++;
237 if (Sequence_Framenum!=0)
239 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
242 Deinitialize_Sequence();
245 Clear_Verify_Headers();
248 *Bitstream_Framenumber = Bitstream_Framenum;
249 return(Return_Value);
259 /* return when end of sequence (0) or picture
260 header has been parsed (1) */
268 if (Get_Hdr()!=ret && !Quiet_Flag)
269 fprintf(stderr,"streams out of sync\n");
275 static int Decode_Bitstream()
278 int Bitstream_Framenum;
280 Bitstream_Framenum = 0;
286 Clear_Verify_Headers();
293 ret = video_sequence(&Bitstream_Framenum);
302 /* IMPLEMENTATION specific routines */
303 static void Initialize_Decoder()
308 if (!(Clip=(unsigned char *)malloc(1024)))
309 Error("Clip[] malloc failed\n");
313 for (i=-384; i<640; i++)
314 Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
317 if (Reference_IDCT_Flag)
318 Initialize_Reference_IDCT();
320 Initialize_Fast_IDCT();
324 /* option processing */
325 static void Process_Options(int argc, const char *argv[])
326 //int argc; /* argument count */
327 //char *argv[]; /* argument vector */
329 int i, LastArg, NextArg;
331 /* at least one argument should be present */
334 printf("\n%s, %s\n",Version,Author);
335 printf("Usage: mpeg2decode {options}\n"
336 "Options: -b file main bitstream (base or spatial enhancement layer)\n"
337 " -cn file conformance report (n: level)\n"
338 " -e file enhancement layer bitstream (SNR or Data Partitioning)\n"
339 " -f store/display interlaced video in frame format\n"
340 " -g concatenated file format for substitution method (-x)\n"
341 " -in file information & statistics report (n: level)\n"
342 " -l file file name pattern for lower layer sequence\n");
343 printf(" (for spatial scalability)\n"
344 " -on file output format (0:YUV 1:SIF 2:TGA 3:PPM 4:X11 5:X11HiQ)\n"
345 " -q disable warnings to stderr\n"
346 " -r use double precision reference IDCT\n"
347 " -t enable low level tracing to stdout\n"
348 " -u file print user_data to stdio or file\n"
349 " -vn verbose output (n: level)\n"
350 " -x file filename pattern of picture substitution sequence\n\n");
351 printf("File patterns: for sequential filenames, \"printf\" style, e.g. rec%%d\n"
352 " or rec%%d%%c for fieldwise storage\n"
353 "Levels: 0:none 1:sequence 2:picture 3:slice 4:macroblock 5:block\n\n"
354 "Example: mpeg2decode -b bitstream.mpg -f -r -o0 rec%%d\n"
363 /* command-line options are proceeded by '-' */
367 /* check if this is the last argument */
368 LastArg = ((argc-i)==1);
370 /* parse ahead to see if another flag immediately follows current
371 argument (this is used to tell if a filename is missing) */
373 NextArg = (argv[i+1][0]=='-');
377 /* second character, [1], after '-' is the switch */
380 switch(toupper(argv[i][1]))
382 /* third character. [2], is the value */
384 Main_Bitstream_Flag = 1;
386 if(NextArg || LastArg)
388 printf("ERROR: -b must be followed the main bitstream filename\n");
391 Main_Bitstream_Filename = argv[++i];
399 Verify_Flag = atoi(&argv[i][2]);
401 if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS))
403 printf("ERROR: -c level (%d) out of range [%d,%d]\n",
404 Verify_Flag, NO_LAYER, ALL_LAYERS);
408 printf("This program not compiled for Verify_Flag option\n");
413 Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */
415 if(NextArg || LastArg)
417 printf("ERROR: -e must be followed by filename\n");
421 Enhancement_Layer_Bitstream_Filename = argv[++i];
427 Frame_Store_Flag = 1;
431 Big_Picture_Flag = 1;
437 Stats_Flag = atoi(&argv[i][2]);
439 printf("WARNING: This program not compiled for -i option\n");
443 case 'L': /* spatial scalability flag */
446 if(NextArg || LastArg)
448 printf("ERROR: -l must be followed by filename\n");
452 Lower_Layer_Picture_Filename = argv[++i];
458 Output_Type = atoi(&argv[i][2]);
460 if((Output_Type==4) || (Output_Type==5))
461 Output_Picture_Filename = ""; /* no need of filename */
462 else if(NextArg || LastArg)
464 printf("ERROR: -o must be followed by filename\n");
468 /* filename is separated by space, so it becomes the next argument */
469 Output_Picture_Filename = argv[++i];
472 if (Output_Type==T_X11HIQ)
485 Reference_IDCT_Flag = 1;
492 printf("WARNING: This program not compiled for -t option\n");
501 Verbose_Flag = atoi(&argv[i][2]);
503 printf("This program not compiled for -v option\n");
511 if(NextArg || LastArg)
513 printf("ERROR: -x must be followed by filename\n");
517 Substitute_Picture_Filename = argv[++i];
524 fprintf(stderr,"undefined option -%c ignored. Exiting program\n",
530 } /* if argv[i][0] == '-' */
534 /* check for bitstream filename argument (there must always be one, at the very end
535 of the command line arguments */
540 /* options sense checking */
542 if(Main_Bitstream_Flag!=1)
544 printf("There must be a main bitstream specified (-b filename)\n");
547 /* force display process to show frame pictures */
548 if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag)
549 Display_Progressive_Flag = 1;
551 Display_Progressive_Flag = 0;
554 /* parse the bitstream, do not actually decode it completely */
560 Decode_Layer = Verify_Flag;
561 printf("FYI: Decoding bitstream elements up to: %s\n",
562 Layer_Table[Decode_Layer]);
566 Decode_Layer = ALL_LAYERS;
570 /* no output type specified */
574 Output_Picture_Filename = "";
579 if (Output_Type==T_X11)
582 Display_Progressive_Flag = 1;
584 Display_Progressive_Flag = 0;
586 Frame_Store_Flag = 1; /* to avoid calling dither() twice */
593 static void Clear_Options()
597 Output_Picture_Filename = " ";
600 Frame_Store_Flag = 0;
602 Lower_Layer_Picture_Filename = " ";
603 Reference_IDCT_Flag = 0;
607 Substitute_Picture_Filename = " ";
609 Enhancement_Layer_Bitstream_Filename = " ";
610 Big_Picture_Flag = 0;
611 Main_Bitstream_Flag = 0;
612 Main_Bitstream_Filename = " ";
617 static void Print_Options()
620 printf("Verbose_Flag = %d\n", Verbose_Flag);
621 printf("Output_Type = %d\n", Output_Type);
622 printf("Output_Picture_Filename = %s\n", Output_Picture_Filename);
623 printf("hiQdither = %d\n", hiQdither);
624 printf("Output_Type = %d\n", Output_Type);
625 printf("Frame_Store_Flag = %d\n", Frame_Store_Flag);
626 printf("Spatial_Flag = %d\n", Spatial_Flag);
627 printf("Lower_Layer_Picture_Filename = %s\n", Lower_Layer_Picture_Filename);
628 printf("Reference_IDCT_Flag = %d\n", Reference_IDCT_Flag);
629 printf("Trace_Flag = %d\n", Trace_Flag);
630 printf("Quiet_Flag = %d\n", Quiet_Flag);
631 printf("Ersatz_Flag = %d\n", Ersatz_Flag);
632 printf("Substitute_Picture_Filename = %s\n", Substitute_Picture_Filename);
633 printf("Two_Streams = %d\n", Two_Streams);
634 printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename);
635 printf("Big_Picture_Flag = %d\n", Big_Picture_Flag);
636 printf("Main_Bitstream_Flag = %d\n", Main_Bitstream_Flag);
637 printf("Main_Bitstream_Filename = %s\n", Main_Bitstream_Filename);
638 printf("Verify_Flag = %d\n", Verify_Flag);
639 printf("Stats_Flag = %d\n", Stats_Flag);
640 printf("User_Data_Flag = %d\n", User_Data_Flag);
644 bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t length)
647 fp->read((char*)image_buffer, length);
648 std::ofstream out("/tmp/etiam.mpeg");
649 out.write((char*)image_buffer, length);
655 /*base.open_stream = my_open;*/
656 base.seek_stream = my_seek;
657 base.read_stream = my_read;
658 base.close_stream = my_close;
662 // const char *argv[] = {"mpeg2decode", "-b", "/tmp/etiam.mpeg", "-f", "-r", "-o3", "/tmp/rec%d"};
664 // /* decode command line arguments */
665 // Process_Options(argc,argv);
670 Output_Picture_Filename = "/tmp/rec%d";
673 Frame_Store_Flag = 1;
675 Lower_Layer_Picture_Filename = "";
676 Reference_IDCT_Flag = 1;
680 Substitute_Picture_Filename = "";
682 Enhancement_Layer_Bitstream_Filename = "";
683 Big_Picture_Flag = 0;
684 Main_Bitstream_Flag = 1;
685 Main_Bitstream_Filename = "/tmp/etiam.mpeg";
691 ld = &base; /* select base layer context */
693 /* open MPEG base layer bitstream file(s) */
694 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
695 /* if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */
696 /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/
699 //base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
700 base.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary | std::ios::in);
702 base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY );
704 if( !base.Infile->InFd)
706 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
715 if(Show_Bits(8)==0x47)
717 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
722 code = Show_Bits(32);
726 case SEQUENCE_HEADER_CODE:
728 case PACK_START_CODE:
729 System_Stream_Flag = 1;
730 case VIDEO_ELEMENTARY_STREAM:
731 System_Stream_Flag = 1;
734 sprintf(Error_Text,"Unable to recognize stream type\n");
739 /*lseek(base.Infile, 0l, SEEK_SET);*/
740 ld->seek_stream(base.Infile,0l,SEEK_SET);
746 /*lseek(base.Infile, 0l, SEEK_SET);*/
747 ld->seek_stream(base.Infile,0l,SEEK_SET);
754 ld = &enhan; /* select enhancement layer context */
756 /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/
757 /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/
760 //enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
761 enhan.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary|std::ios::in);
763 enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY);
765 if (enhan.Infile->InFd)
767 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
768 Enhancement_Layer_Bitstream_Filename);
777 Initialize_Decoder();
779 ret = Decode_Bitstream();
781 /*close(base.Infile);*/
782 ld->close_stream(base.Infile);
785 /*close(enhan.Infile);*/
786 ld->close_stream(enhan.Infile);
788 DeInitialize_Decoder();
793 } // end namespace gdcm