1 /*=========================================================================
4 Module: $RCSfile: gdcmMpeg.cxx,v $
6 Date: $Date: 2006/05/30 08:19:25 $
7 Version: $Revision: 1.10 $
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();
69 static void DeInitialize_Decoder()
71 free(Clip-384); /* I love magic number */
73 static void Deinitialize_Sequence()
77 /* First cleanup the static buffer in store.c */
85 free(backward_reference_frame[i]);
86 free(forward_reference_frame[i]);
89 if (base.scalable_mode==SC_SPAT)
96 if (base.scalable_mode==SC_SPAT)
100 if (Output_Type==T_X11)
101 Terminate_Display_Process();
105 /* mostly IMPLEMENTAION specific routines */
106 static void Initialize_Sequence()
109 static int Table_6_20[3] = {6,8,12};
111 /* check scalability mode of enhancement layer */
112 if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
113 Error("unsupported scalability mode\n");
115 /* force MPEG-1 parameters for proper decoder behavior */
116 /* see ISO/IEC 13818-2 section D.9.14 */
117 if (!base.MPEG2_Flag)
119 progressive_sequence = 1;
120 progressive_frame = 1;
121 picture_structure = FRAME_PICTURE;
122 frame_pred_frame_dct = 1;
123 chroma_format = CHROMA420;
124 matrix_coefficients = 5;
127 /* round to nearest multiple of coded macroblocks */
128 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
129 mb_width = (horizontal_size+15)/16;
130 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
131 : (vertical_size+15)/16;
133 Coded_Picture_Width = 16*mb_width;
134 Coded_Picture_Height = 16*mb_height;
136 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
137 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
138 : Coded_Picture_Width>>1;
139 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
140 : Coded_Picture_Height>>1;
142 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
143 block_count = Table_6_20[chroma_format-1];
145 for (cc=0; cc<3; cc++)
148 size = Coded_Picture_Width*Coded_Picture_Height;
150 size = Chroma_Width*Chroma_Height;
152 if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
153 Error("backward_reference_frame[] malloc failed\n");
155 if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
156 Error("forward_reference_frame[] malloc failed\n");
158 if (!(auxframe[cc] = (unsigned char *)malloc(size)))
159 Error("auxframe[] malloc failed\n");
162 if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
163 Error("substitute_frame[] malloc failed\n");
166 if (base.scalable_mode==SC_SPAT)
168 /* this assumes lower layer is 4:2:0 */
169 if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
170 Error("llframe0 malloc failed\n");
171 if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
172 Error("llframe1 malloc failed\n");
176 /* SCALABILITY: Spatial */
177 if (base.scalable_mode==SC_SPAT)
179 if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
180 Error("lltmp malloc failed\n");
184 if (Output_Type==T_X11)
186 Initialize_Display_Process("");
187 Initialize_Dither_Matrix();
192 static int video_sequence(int *Bitstream_Framenumber)
193 //int *Bitstream_Framenumber;
195 int Bitstream_Framenum;
196 int Sequence_Framenum;
199 Bitstream_Framenum = *Bitstream_Framenumber;
202 Initialize_Sequence();
204 /* decode picture whose header has already been parsed in
205 Decode_Bitstream() */
208 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
210 /* update picture numbers */
213 Bitstream_Framenum++;
217 /* loop through the rest of the pictures in the sequence */
218 while ((Return_Value=Headers()))
220 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
224 Bitstream_Framenum++;
230 if (Sequence_Framenum!=0)
232 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
235 Deinitialize_Sequence();
238 Clear_Verify_Headers();
241 *Bitstream_Framenumber = Bitstream_Framenum;
242 return(Return_Value);
252 /* return when end of sequence (0) or picture
253 header has been parsed (1) */
261 if (Get_Hdr()!=ret && !Quiet_Flag)
262 fprintf(stderr,"streams out of sync\n");
268 static int Decode_Bitstream()
271 int Bitstream_Framenum;
273 Bitstream_Framenum = 0;
279 Clear_Verify_Headers();
286 ret = video_sequence(&Bitstream_Framenum);
295 /* IMPLEMENTATION specific routines */
296 static void Initialize_Decoder()
301 if (!(Clip=(unsigned char *)malloc(1024)))
302 Error("Clip[] malloc failed\n");
306 for (i=-384; i<640; i++)
307 Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
310 if (Reference_IDCT_Flag)
311 Initialize_Reference_IDCT();
313 Initialize_Fast_IDCT();
318 * \brief routine for MPEG decompression
319 * @param fp pointer to an already open file descriptor
320 * 8 significant bits per pixel
321 * @param image_buffer to receive uncompressed pixels
322 * @param length length
323 * @return 1 on success, 0 on error
325 bool ReadMPEGFile (std::ifstream *fp, char *image_buffer, size_t length)
327 std::streampos mpeg_start = fp->tellg(); // the MPEG stream in our case does not start at 0
329 fp->read((char*)image_buffer, length);
330 std::ofstream out("/tmp/etiam.mpeg");
331 out.write((char*)image_buffer, length);
339 /*base.open_stream = my_open;*/
340 base.seek_stream = my_seek;
341 base.read_stream = my_read;
342 base.close_stream = my_close;
345 Output_Type = T_MEM; //store in mem
346 Output_Picture_Filename = "/tmp/rec%d";
348 Frame_Store_Flag = 1;
350 Lower_Layer_Picture_Filename = "";
351 Reference_IDCT_Flag = 1;
355 Substitute_Picture_Filename = "";
357 Enhancement_Layer_Bitstream_Filename = "";
358 Big_Picture_Flag = 0;
359 Main_Bitstream_Flag = 1;
360 Main_Bitstream_Filename = "/tmp/etiam.mpeg";
361 Main_Bitstream_Filename = "/tmp/ts.mpg";
365 OUTMEM = (char*)image_buffer;
368 ld = &base; /* select base layer context */
370 /* open MPEG base layer bitstream file(s) */
371 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
372 /* if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */
373 /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/
376 //base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
377 //base.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary | std::ios::in);
378 base.Infile->InFd = fp;
380 base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY );
382 if( !base.Infile->InFd)
384 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
393 if(Show_Bits(8)==0x47)
395 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
400 code = Show_Bits(32);
404 case SEQUENCE_HEADER_CODE:
406 case PACK_START_CODE:
407 System_Stream_Flag = 1;
408 case VIDEO_ELEMENTARY_STREAM:
409 System_Stream_Flag = 1;
412 sprintf(Error_Text,"Unable to recognize stream type\n");
417 /*lseek(base.Infile, 0l, SEEK_SET);*/
418 ld->seek_stream(base.Infile,mpeg_start,SEEK_SET);
424 /*lseek(base.Infile, 0l, SEEK_SET);*/
425 ld->seek_stream(base.Infile,mpeg_start,SEEK_SET);
432 ld = &enhan; /* select enhancement layer context */
434 /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/
435 /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/
438 //enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
439 enhan.Infile->InFd->open(Main_Bitstream_Filename, std::ios::binary|std::ios::in);
442 enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY);
444 if (enhan.Infile->InFd)
446 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
447 Enhancement_Layer_Bitstream_Filename);
456 Initialize_Decoder();
458 ret = Decode_Bitstream();
460 /*close(base.Infile);*/
461 ld->close_stream(base.Infile);
464 /*close(enhan.Infile);*/
465 ld->close_stream(enhan.Infile);
467 DeInitialize_Decoder();
470 std::ofstream out2("/tmp/etiam.raw");
471 out2.write((char*)image_buffer, 352*240*3*10);
478 } // end namespace gdcm