1 /*=========================================================================
4 Module: $RCSfile: gdcmMpeg.cxx,v $
6 Date: $Date: 2005/05/21 18:43:52 $
7 Version: $Revision: 1.1 $
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 /* IMPLEMENTAION specific rouintes */
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 IMPLEMENTAION specific rouintes */
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) && (base.scalable_mode!=SC_DP))
69 Error("unsupported scalability mode\n");
71 /* force MPEG-1 parameters for proper decoder behavior */
72 /* see ISO/IEC 13818-2 section D.9.14 */
75 progressive_sequence = 1;
76 progressive_frame = 1;
77 picture_structure = FRAME_PICTURE;
78 frame_pred_frame_dct = 1;
79 chroma_format = CHROMA420;
80 matrix_coefficients = 5;
83 /* round to nearest multiple of coded macroblocks */
84 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
85 mb_width = (horizontal_size+15)/16;
86 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
87 : (vertical_size+15)/16;
89 Coded_Picture_Width = 16*mb_width;
90 Coded_Picture_Height = 16*mb_height;
92 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
93 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
94 : Coded_Picture_Width>>1;
95 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
96 : Coded_Picture_Height>>1;
98 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
99 block_count = Table_6_20[chroma_format-1];
101 for (cc=0; cc<3; cc++)
104 size = Coded_Picture_Width*Coded_Picture_Height;
106 size = Chroma_Width*Chroma_Height;
108 if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
109 Error("backward_reference_frame[] malloc failed\n");
111 if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
112 Error("forward_reference_frame[] malloc failed\n");
114 if (!(auxframe[cc] = (unsigned char *)malloc(size)))
115 Error("auxframe[] malloc failed\n");
118 if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
119 Error("substitute_frame[] malloc failed\n");
122 if (base.scalable_mode==SC_SPAT)
124 /* this assumes lower layer is 4:2:0 */
125 if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
126 Error("llframe0 malloc failed\n");
127 if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
128 Error("llframe1 malloc failed\n");
132 /* SCALABILITY: Spatial */
133 if (base.scalable_mode==SC_SPAT)
135 if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
136 Error("lltmp malloc failed\n");
140 if (Output_Type==T_X11)
142 Initialize_Display_Process("");
143 Initialize_Dither_Matrix();
149 extern void Error(char *text)
151 fprintf(stderr,text);
155 /* Trace_Flag output */
156 void Print_Bits(int code, int bits, int len)
159 for (i=0; i<len; i++)
160 printf("%d",(code>>(bits-1-i))&1);
170 /* return when end of sequence (0) or picture
171 header has been parsed (1) */
179 if (Get_Hdr()!=ret && !Quiet_Flag)
180 fprintf(stderr,"streams out of sync\n");
189 static int Decode_Bitstream()
192 int Bitstream_Framenum;
194 Bitstream_Framenum = 0;
200 Clear_Verify_Headers();
207 ret = video_sequence(&Bitstream_Framenum);
216 static void Deinitialize_Sequence()
225 free(backward_reference_frame[i]);
226 free(forward_reference_frame[i]);
229 if (base.scalable_mode==SC_SPAT)
236 if (base.scalable_mode==SC_SPAT)
240 if (Output_Type==T_X11)
241 Terminate_Display_Process();
246 static int video_sequence(int *Bitstream_Framenumber)
248 int Bitstream_Framenum;
249 int Sequence_Framenum;
252 Bitstream_Framenum = *Bitstream_Framenumber;
255 Initialize_Sequence();
257 /* decode picture whose header has already been parsed in
258 Decode_Bitstream() */
261 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
263 /* update picture numbers */
266 Bitstream_Framenum++;
270 /* loop through the rest of the pictures in the sequence */
271 while ((Return_Value=Headers()))
273 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
277 Bitstream_Framenum++;
283 if (Sequence_Framenum!=0)
285 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
288 Deinitialize_Sequence();
291 Clear_Verify_Headers();
294 *Bitstream_Framenumber = Bitstream_Framenum;
295 return(Return_Value);
302 * \brief routine for MPEG decompression
303 * @param fp pointer to an already open file descriptor
304 * 8 significant bits per pixel
305 * @param image_buffer to receive uncompressed pixels
306 * @param statesuspension Suspension State basically it should be 3 otherwise more complex to handle
307 * @return 1 on success, 0 on error
309 bool ReadMPEGFile (std::ifstream *fp, void *image_buffer)
315 /* decode command line arguments */
316 // Process_Options(argc,argv);
322 ld = &base; /* select base layer context */
324 /* open MPEG base layer bitstream file(s) */
325 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
327 if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
329 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
333 base.Infile = -1; //DEBUG
341 if(Show_Bits(8)==0x47)
343 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
348 code = Show_Bits(32);
352 case SEQUENCE_HEADER_CODE:
354 case PACK_START_CODE:
355 System_Stream_Flag = 1;
356 case VIDEO_ELEMENTARY_STREAM:
357 System_Stream_Flag = 1;
360 sprintf(Error_Text,"Unable to recognize stream type\n");
365 //lseek(base.Infile, 0l, SEEK_SET);
366 //fp->seekg(mpeg_start, ios_base::beg);
372 //lseek(base.Infile, 0l, SEEK_SET);
373 //fp->seekg(mpeg_start, ios_base::beg);
381 ld = &enhan; /* select enhancement layer context */
383 if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
385 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
386 Enhancement_Layer_Bitstream_Filename);
395 Initialize_Decoder();
397 ret = Decode_Bitstream();
399 //close(base.Infile);
410 } // end namespace gdcm