1 /*=========================================================================
4 Module: $RCSfile: gdcmMpeg.cxx,v $
6 Date: $Date: 2007/09/17 12:20:01 $
7 Version: $Revision: 1.14 $
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");
191 static int Decode_Bitstream()
194 int Bitstream_Framenum;
196 Bitstream_Framenum = 0;
202 Clear_Verify_Headers();
209 ret = video_sequence(&Bitstream_Framenum);
218 static void Deinitialize_Sequence()
227 free(backward_reference_frame[i]);
228 free(forward_reference_frame[i]);
231 if ( base.scalable_mode==SC_SPAT )
238 if ( base.scalable_mode==SC_SPAT )
242 if ( Output_Type==T_X11 )
243 Terminate_Display_Process();
247 static int video_sequence(int *Bitstream_Framenumber)
249 int Bitstream_Framenum;
250 int Sequence_Framenum;
253 Bitstream_Framenum = *Bitstream_Framenumber;
256 Initialize_Sequence();
258 /* decode picture whose header has already been parsed in
259 Decode_Bitstream() */
262 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
264 /* update picture numbers */
267 Bitstream_Framenum++;
271 /* loop through the rest of the pictures in the sequence */
272 while ((Return_Value=Headers()))
274 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
278 Bitstream_Framenum++;
284 if (Sequence_Framenum!=0)
286 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
289 Deinitialize_Sequence();
292 Clear_Verify_Headers();
295 *Bitstream_Framenumber = Bitstream_Framenum;
296 return(Return_Value);
300 namespace GDCM_NAME_SPACE
303 * \brief routine for MPEG decompression
304 * @param fp pointer to an already open file descriptor
305 * 8 significant bits per pixel
306 * @param image_buffer to receive uncompressed pixels
307 * @param length length
308 * @return 1 on success, 0 on error
310 bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t length)
315 fp->read((char*)image_buffer, length);
316 ofstream out("/tmp/etiam.mpeg");
317 out.write((char*)image_buffer, length);
323 /* decode command line arguments */
324 // Process_Options(argc,argv);
330 ld = &base; /* select base layer context */
332 /* open MPEG base layer bitstream file(s) */
333 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
335 if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
337 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
341 base.Infile = -1; //DEBUG
345 if ( base.Infile != 0 )
349 if ( Show_Bits(8)==0x47 )
351 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
356 code = Show_Bits(32);
360 case SEQUENCE_HEADER_CODE:
362 case PACK_START_CODE:
363 System_Stream_Flag = 1;
364 case VIDEO_ELEMENTARY_STREAM:
365 System_Stream_Flag = 1;
368 sprintf(Error_Text,"Unable to recognize stream type\n");
373 //lseek(base.Infile, 0l, SEEK_SET);
374 //fp->seekg(mpeg_start, ios_base::beg);
378 if ( base.Infile!=0 )
380 //lseek(base.Infile, 0l, SEEK_SET);
381 //fp->seekg(mpeg_start, ios_base::beg);
389 ld = &enhan; /* select enhancement layer context */
391 if ( (enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
393 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
394 Enhancement_Layer_Bitstream_Filename);
403 Initialize_Decoder();
405 ret = Decode_Bitstream();
407 //close(base.Infile);
418 } // end namespace gdcm