1 /*=========================================================================
4 Module: $RCSfile: gdcmMpeg.cxx,v $
6 Date: $Date: 2007/08/21 12:51:09 $
7 Version: $Revision: 1.12 $
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"
30 /* private prototypes */
31 static int video_sequence _ANSI_ARGS_((int *framenum));
32 static int Decode_Bitstream _ANSI_ARGS_((void));
33 static int Headers _ANSI_ARGS_((void));
34 static void Initialize_Sequence _ANSI_ARGS_((void));
35 static void Initialize_Decoder _ANSI_ARGS_((void));
36 static void Deinitialize_Sequence _ANSI_ARGS_((void));
37 //static void Process_Options _ANSI_ARGS_((int argc, char *argv[]));
39 /* IMPLEMENTATION specific routines */
40 static void Initialize_Decoder()
45 if ( !(Clip=(unsigned char *)malloc(1024)) )
46 Error("Clip[] malloc failed\n");
50 for (i=-384; i<640; i++)
51 Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
54 if ( Reference_IDCT_Flag )
55 Initialize_Reference_IDCT();
57 Initialize_Fast_IDCT();
61 /* mostly IMPLEMENTATION specific routines */
62 static void Initialize_Sequence()
65 static int Table_6_20[3] = {6,8,12};
67 /* check scalability mode of enhancement layer */
68 if ( Two_Streams && (enhan.scalable_mode!=SC_SNR)
70 (base.scalable_mode!=SC_DP) )
72 Error("unsupported scalability mode\n");
74 /* force MPEG-1 parameters for proper decoder behavior */
75 /* see ISO/IEC 13818-2 section D.9.14 */
76 if ( !base.MPEG2_Flag )
78 progressive_sequence = 1;
79 progressive_frame = 1;
80 picture_structure = FRAME_PICTURE;
81 frame_pred_frame_dct = 1;
82 chroma_format = CHROMA420;
83 matrix_coefficients = 5;
86 /* round to nearest multiple of coded macroblocks */
87 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
88 mb_width = (horizontal_size+15)/16;
89 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
90 : (vertical_size+15)/16;
92 Coded_Picture_Width = 16*mb_width;
93 Coded_Picture_Height = 16*mb_height;
95 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
96 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
97 : Coded_Picture_Width>>1;
98 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
99 : Coded_Picture_Height>>1;
101 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
102 block_count = Table_6_20[chroma_format-1];
104 for (cc=0; cc<3; cc++)
107 size = Coded_Picture_Width*Coded_Picture_Height;
109 size = Chroma_Width*Chroma_Height;
111 if ( !(backward_reference_frame[cc] = (unsigned char *)malloc(size)) )
112 Error("backward_reference_frame[] malloc failed\n");
114 if ( !(forward_reference_frame[cc] = (unsigned char *)malloc(size)) )
115 Error("forward_reference_frame[] malloc failed\n");
117 if ( !(auxframe[cc] = (unsigned char *)malloc(size)) )
118 Error("auxframe[] malloc failed\n");
121 if ( !(substitute_frame[cc] = (unsigned char *)malloc(size)) )
122 Error("substitute_frame[] malloc failed\n");
125 if ( base.scalable_mode==SC_SPAT )
127 /* this assumes lower layer is 4:2:0 */
128 if ( !(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
129 Error("llframe0 malloc failed\n");
130 if ( !(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
131 Error("llframe1 malloc failed\n");
135 /* SCALABILITY: Spatial */
136 if ( base.scalable_mode==SC_SPAT )
138 if ( !(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
139 Error("lltmp malloc failed\n");
143 if (Output_Type==T_X11)
145 Initialize_Display_Process("");
146 Initialize_Dither_Matrix();
152 extern void Error(char *text)
154 fprintf(stderr,text);
158 /* Trace_Flag output */
159 void Print_Bits(int code, int bits, int len)
162 for (i=0; i<len; i++)
163 printf("%d",(code>>(bits-1-i))&1);
172 /* return when end of sequence (0) or picture
173 header has been parsed (1) */
181 if (Get_Hdr()!=ret && !Quiet_Flag)
182 fprintf(stderr,"streams out of sync\n");
188 static int Decode_Bitstream()
191 int Bitstream_Framenum;
193 Bitstream_Framenum = 0;
199 Clear_Verify_Headers();
206 ret = video_sequence(&Bitstream_Framenum);
215 static void Deinitialize_Sequence()
224 free(backward_reference_frame[i]);
225 free(forward_reference_frame[i]);
228 if ( base.scalable_mode==SC_SPAT )
235 if ( base.scalable_mode==SC_SPAT )
239 if ( Output_Type==T_X11 )
240 Terminate_Display_Process();
244 static int video_sequence(int *Bitstream_Framenumber)
246 int Bitstream_Framenum;
247 int Sequence_Framenum;
250 Bitstream_Framenum = *Bitstream_Framenumber;
253 Initialize_Sequence();
255 /* decode picture whose header has already been parsed in
256 Decode_Bitstream() */
259 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
261 /* update picture numbers */
264 Bitstream_Framenum++;
268 /* loop through the rest of the pictures in the sequence */
269 while ((Return_Value=Headers()))
271 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
275 Bitstream_Framenum++;
281 if (Sequence_Framenum!=0)
283 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
286 Deinitialize_Sequence();
289 Clear_Verify_Headers();
292 *Bitstream_Framenumber = Bitstream_Framenum;
293 return(Return_Value);
300 * \brief routine for MPEG decompression
301 * @param fp pointer to an already open file descriptor
302 * 8 significant bits per pixel
303 * @param image_buffer to receive uncompressed pixels
304 * @param length length
305 * @return 1 on success, 0 on error
307 bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t length)
312 fp->read((char*)image_buffer, length);
313 ofstream out("/tmp/etiam.mpeg");
314 out.write((char*)image_buffer, length);
320 /* decode command line arguments */
321 // Process_Options(argc,argv);
327 ld = &base; /* select base layer context */
329 /* open MPEG base layer bitstream file(s) */
330 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
332 if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
334 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
338 base.Infile = -1; //DEBUG
342 if ( base.Infile != 0 )
346 if ( Show_Bits(8)==0x47 )
348 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
353 code = Show_Bits(32);
357 case SEQUENCE_HEADER_CODE:
359 case PACK_START_CODE:
360 System_Stream_Flag = 1;
361 case VIDEO_ELEMENTARY_STREAM:
362 System_Stream_Flag = 1;
365 sprintf(Error_Text,"Unable to recognize stream type\n");
370 //lseek(base.Infile, 0l, SEEK_SET);
371 //fp->seekg(mpeg_start, ios_base::beg);
375 if ( base.Infile!=0 )
377 //lseek(base.Infile, 0l, SEEK_SET);
378 //fp->seekg(mpeg_start, ios_base::beg);
386 ld = &enhan; /* select enhancement layer context */
388 if ( (enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
390 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
391 Enhancement_Layer_Bitstream_Filename);
400 Initialize_Decoder();
402 ret = Decode_Bitstream();
404 //close(base.Infile);
415 } // end namespace gdcm