1 /*=========================================================================
4 Module: $RCSfile: gdcmMpeg.cxx,v $
6 Date: $Date: 2005/10/27 20:08:29 $
7 Version: $Revision: 1.8 $
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);
61 infile->InFd->close();
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 bool ReadMPEGFile (std::ifstream *fp, char *image_buffer, size_t length)
326 std::streampos mpeg_start = fp->tellg(); // the MPEG stream in our case does not start at 0
328 fp->read((char*)image_buffer, length);
329 std::ofstream out("/tmp/etiam.mpeg");
330 out.write((char*)image_buffer, length);
336 /*base.open_stream = my_open;*/
337 base.seek_stream = my_seek;
338 base.read_stream = my_read;
339 base.close_stream = my_close;
342 Output_Type = T_MEM; //store in mem
343 Output_Picture_Filename = "/tmp/rec%d";
345 Frame_Store_Flag = 1;
347 Lower_Layer_Picture_Filename = "";
348 Reference_IDCT_Flag = 1;
352 Substitute_Picture_Filename = "";
354 Enhancement_Layer_Bitstream_Filename = "";
355 Big_Picture_Flag = 0;
356 Main_Bitstream_Flag = 1;
357 Main_Bitstream_Filename = "/tmp/etiam.mpeg";
358 Main_Bitstream_Filename = "/tmp/ts.mpg";
362 OUTMEM = (char*)image_buffer;
365 ld = &base; /* select base layer context */
367 /* open MPEG base layer bitstream file(s) */
368 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
369 /* if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */
370 /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/
373 //base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
374 //base.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary | std::ios::in);
375 base.Infile->InFd = fp;
377 base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY );
379 if( !base.Infile->InFd)
381 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
390 if(Show_Bits(8)==0x47)
392 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
397 code = Show_Bits(32);
401 case SEQUENCE_HEADER_CODE:
403 case PACK_START_CODE:
404 System_Stream_Flag = 1;
405 case VIDEO_ELEMENTARY_STREAM:
406 System_Stream_Flag = 1;
409 sprintf(Error_Text,"Unable to recognize stream type\n");
414 /*lseek(base.Infile, 0l, SEEK_SET);*/
415 ld->seek_stream(base.Infile,mpeg_start,SEEK_SET);
421 /*lseek(base.Infile, 0l, SEEK_SET);*/
422 ld->seek_stream(base.Infile,mpeg_start,SEEK_SET);
429 ld = &enhan; /* select enhancement layer context */
431 /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/
432 /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/
435 //enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
436 enhan.Infile->InFd->open(Main_Bitstream_Filename, std::ios::binary|std::ios::in);
439 enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY);
441 if (enhan.Infile->InFd)
443 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
444 Enhancement_Layer_Bitstream_Filename);
453 Initialize_Decoder();
455 ret = Decode_Bitstream();
457 /*close(base.Infile);*/
458 ld->close_stream(base.Infile);
461 /*close(enhan.Infile);*/
462 ld->close_stream(enhan.Infile);
464 DeInitialize_Decoder();
467 std::ofstream out2("/tmp/etiam.raw");
468 out2.write((char*)image_buffer, 352*240*3*10);
475 } // end namespace gdcm