Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

gdcmMpeg.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002                                                                                 
00003   Program:   gdcm
00004   Module:    $RCSfile: gdcmMpeg.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2005/11/04 15:46:52 $
00007   Version:   $Revision: 1.9 $
00008                                                                                 
00009   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
00010   l'Image). All rights reserved. See Doc/License.txt or
00011   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
00012                                                                                 
00013      This software is distributed WITHOUT ANY WARRANTY; without even
00014      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00015      PURPOSE.  See the above copyright notices for more information.
00016                                                                                 
00017 =========================================================================*/
00018 #include "gdcmDebug.h"
00019 
00020 #include <fstream>
00021 
00022 
00023 typedef struct
00024 {
00025   std::ifstream *InFd;
00026 } istream;
00027 extern "C" {
00028 #define GLOBAL
00029 #include "config.h"
00030 #include "global.h"
00031 }
00032 
00033 
00034 off_t my_seek(istream *infile, off_t offset, int whence)
00035 {
00036   //return fseek(infile->InFd,offset, whence);
00037   switch(whence)
00038     {
00039     case SEEK_SET:
00040       infile->InFd->seekg(offset, std::ios::beg);
00041       break;
00042     case SEEK_END:
00043       infile->InFd->seekg(offset, std::ios::end);
00044       break;
00045     case SEEK_CUR:
00046       infile->InFd->seekg(offset, std::ios::cur);
00047       break;
00048     }
00049   return infile->InFd->tellg();
00050 }
00051 ssize_t my_read(istream *infile, void *buf, size_t count)
00052 {
00053   //return fread(buf,1,count, infile->InFd);
00054   infile->InFd->read((char*)buf, count);
00055   return infile->InFd->gcount();
00056 }
00057 
00058 int my_close(istream *infile)
00059 {
00060   //return fclose(infile->InFd);
00061   infile->InFd->close();
00062   return 0;
00063 }
00064 
00065 namespace gdcm 
00066 {
00075 static int Headers();
00076 static void DeInitialize_Decoder()
00077 {
00078   free(Clip-384); /* I love magic number */
00079 }
00080 static void Deinitialize_Sequence()
00081 {
00082   int i;
00083 
00084   /* First cleanup the static buffer in store.c */
00085   FreeStaticBuffer();
00086 
00087   /* clear flags */
00088   base.MPEG2_Flag=0;
00089 
00090   for(i=0;i<3;i++)
00091   {
00092     free(backward_reference_frame[i]);
00093     free(forward_reference_frame[i]);
00094     free(auxframe[i]);
00095 
00096     if (base.scalable_mode==SC_SPAT)
00097     {
00098      free(llframe0[i]);
00099      free(llframe1[i]);
00100     }
00101   }
00102 
00103   if (base.scalable_mode==SC_SPAT)
00104     free(lltmp);
00105 
00106 #ifdef DISPLAY
00107   if (Output_Type==T_X11) 
00108     Terminate_Display_Process();
00109 #endif
00110 }
00111 
00112 /* mostly IMPLEMENTAION specific routines */
00113 static void Initialize_Sequence()
00114 {
00115   int cc, size;
00116   static int Table_6_20[3] = {6,8,12};
00117 
00118   /* check scalability mode of enhancement layer */
00119   if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
00120     Error("unsupported scalability mode\n");
00121 
00122   /* force MPEG-1 parameters for proper decoder behavior */
00123   /* see ISO/IEC 13818-2 section D.9.14 */
00124   if (!base.MPEG2_Flag)
00125   {
00126     progressive_sequence = 1;
00127     progressive_frame = 1;
00128     picture_structure = FRAME_PICTURE;
00129     frame_pred_frame_dct = 1;
00130     chroma_format = CHROMA420;
00131     matrix_coefficients = 5;
00132   }
00133 
00134   /* round to nearest multiple of coded macroblocks */
00135   /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
00136   mb_width = (horizontal_size+15)/16;
00137   mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
00138                                         : (vertical_size+15)/16;
00139 
00140   Coded_Picture_Width = 16*mb_width;
00141   Coded_Picture_Height = 16*mb_height;
00142 
00143   /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
00144   Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
00145                                            : Coded_Picture_Width>>1;
00146   Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
00147                                             : Coded_Picture_Height>>1;
00148   
00149   /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
00150   block_count = Table_6_20[chroma_format-1];
00151 
00152   for (cc=0; cc<3; cc++)
00153   {
00154     if (cc==0)
00155       size = Coded_Picture_Width*Coded_Picture_Height;
00156     else
00157       size = Chroma_Width*Chroma_Height;
00158 
00159     if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
00160       Error("backward_reference_frame[] malloc failed\n");
00161 
00162     if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
00163       Error("forward_reference_frame[] malloc failed\n");
00164 
00165     if (!(auxframe[cc] = (unsigned char *)malloc(size)))
00166       Error("auxframe[] malloc failed\n");
00167 
00168     if(Ersatz_Flag)
00169       if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
00170         Error("substitute_frame[] malloc failed\n");
00171 
00172 
00173     if (base.scalable_mode==SC_SPAT)
00174     {
00175       /* this assumes lower layer is 4:2:0 */
00176       if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
00177         Error("llframe0 malloc failed\n");
00178       if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
00179         Error("llframe1 malloc failed\n");
00180     }
00181   }
00182 
00183   /* SCALABILITY: Spatial */
00184   if (base.scalable_mode==SC_SPAT)
00185   {
00186     if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
00187       Error("lltmp malloc failed\n");
00188   }
00189 
00190 #ifdef DISPLAY
00191   if (Output_Type==T_X11)
00192   {
00193     Initialize_Display_Process("");
00194     Initialize_Dither_Matrix();
00195   }
00196 #endif /* DISPLAY */
00197 
00198 }
00199 static int video_sequence(int *Bitstream_Framenumber)
00200 //int *Bitstream_Framenumber;
00201 {
00202   int Bitstream_Framenum;
00203   int Sequence_Framenum;
00204   int Return_Value;
00205 
00206   Bitstream_Framenum = *Bitstream_Framenumber;
00207   Sequence_Framenum=0;
00208 
00209   Initialize_Sequence();
00210 
00211   /* decode picture whose header has already been parsed in 
00212      Decode_Bitstream() */
00213 
00214 
00215   Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
00216 
00217   /* update picture numbers */
00218   if (!Second_Field)
00219   {
00220     Bitstream_Framenum++;
00221     Sequence_Framenum++;
00222   }
00223 
00224   /* loop through the rest of the pictures in the sequence */
00225   while ((Return_Value=Headers()))
00226   {
00227     Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
00228 
00229     if (!Second_Field)
00230     {
00231       Bitstream_Framenum++;
00232       Sequence_Framenum++;
00233     }
00234   }
00235 
00236   /* put last frame */
00237   if (Sequence_Framenum!=0)
00238   {
00239     Output_Last_Frame_of_Sequence(Bitstream_Framenum);
00240   }
00241 
00242   Deinitialize_Sequence();
00243 
00244 #ifdef VERIFY
00245     Clear_Verify_Headers();
00246 #endif /* VERIFY */
00247 
00248   *Bitstream_Framenumber = Bitstream_Framenum;
00249   return(Return_Value);
00250 }
00251 
00252 static int Headers()
00253 {
00254   int ret;
00255 
00256   ld = &base;
00257   
00258 
00259   /* return when end of sequence (0) or picture
00260      header has been parsed (1) */
00261 
00262   ret = Get_Hdr();
00263 
00264 
00265   if (Two_Streams)
00266   {
00267     ld = &enhan;
00268     if (Get_Hdr()!=ret && !Quiet_Flag)
00269       fprintf(stderr,"streams out of sync\n");
00270     ld = &base;
00271   }
00272 
00273   return ret;
00274 }
00275 static int Decode_Bitstream()
00276 {
00277   int ret;
00278   int Bitstream_Framenum;
00279 
00280   Bitstream_Framenum = 0;
00281 
00282   for(;;)
00283   {
00284 
00285 #ifdef VERIFY
00286     Clear_Verify_Headers();
00287 #endif /* VERIFY */
00288 
00289     ret = Headers();
00290     
00291     if(ret==1)
00292     {
00293       ret = video_sequence(&Bitstream_Framenum);
00294     }
00295     else
00296       return(ret);
00297   }
00298 
00299 }
00300 
00301 
00302 /* IMPLEMENTATION specific routines */
00303 static void Initialize_Decoder()
00304 {
00305   int i;
00306 
00307   /* Clip table */
00308   if (!(Clip=(unsigned char *)malloc(1024)))
00309     Error("Clip[] malloc failed\n");
00310 
00311   Clip += 384;
00312 
00313   for (i=-384; i<640; i++)
00314     Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
00315 
00316   /* IDCT */
00317   if (Reference_IDCT_Flag)
00318     Initialize_Reference_IDCT();
00319   else
00320     Initialize_Fast_IDCT();
00321 
00322 }
00323 
00324 bool ReadMPEGFile (std::ifstream *fp, char *image_buffer, size_t length)
00325 {
00326   std::streampos mpeg_start = fp->tellg(); // the MPEG stream in our case does not start at 0
00327 #if 0
00328   fp->read((char*)image_buffer, length);
00329   std::ofstream out("/tmp/etiam.mpeg");
00330   out.write((char*)image_buffer, length);
00331   out.close();
00332 #else
00333   (void)length;
00334 #endif
00335 
00336   int ret, code;
00337   istream bos,eos;
00338   /*base.open_stream = my_open;*/
00339   base.seek_stream = my_seek;
00340   base.read_stream = my_read;
00341   base.close_stream = my_close;
00342 
00343   Verbose_Flag                         = 0;
00344   Output_Type                          = T_MEM; //store in mem
00345   Output_Picture_Filename              = "/tmp/rec%d";
00346   hiQdither                            = 0;
00347   Frame_Store_Flag                     = 1;
00348   Spatial_Flag                         = 0;
00349   Lower_Layer_Picture_Filename         = "";
00350   Reference_IDCT_Flag                  = 1;
00351   Trace_Flag                           = 0;
00352   Quiet_Flag                           = 0;
00353   Ersatz_Flag                          = 0;
00354   Substitute_Picture_Filename          = "";
00355   Two_Streams                          = 0;
00356   Enhancement_Layer_Bitstream_Filename = "";
00357   Big_Picture_Flag                     = 0;
00358   Main_Bitstream_Flag                  = 1;
00359   Main_Bitstream_Filename              = "/tmp/etiam.mpeg";
00360   Main_Bitstream_Filename              = "/tmp/ts.mpg";
00361   Verify_Flag                          = 0;
00362   Stats_Flag                           = 0;
00363   User_Data_Flag                       = 0;
00364   OUTMEM                               = (char*)image_buffer;
00365 
00366 
00367   ld = &base; /* select base layer context */
00368 
00369   /* open MPEG base layer bitstream file(s) */
00370   /* NOTE: this is either a base layer stream or a spatial enhancement stream */
00371 /*  if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0) */
00372   /*base.Infile = ld->open_stream(Main_Bitstream_Filename);*/
00373   base.Infile = &bos;
00374 #ifdef FILESTAR
00375   //base.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
00376   //base.Infile->InFd.open(Main_Bitstream_Filename, std::ios::binary | std::ios::in);
00377   base.Infile->InFd = fp;
00378 #else
00379   base.Infile->InFd = open(Main_Bitstream_Filename,O_RDONLY|O_BINARY );
00380 #endif
00381   if( !base.Infile->InFd)
00382   {
00383     fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
00384     exit(1);
00385   }
00386 
00387 
00388   if(base.Infile != 0)
00389   {
00390     Initialize_Buffer();
00391 
00392     if(Show_Bits(8)==0x47)
00393     {
00394       sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
00395       Error(Error_Text);
00396     }
00397 
00398     next_start_code();
00399     code = Show_Bits(32);
00400 
00401     switch(code)
00402     {
00403     case SEQUENCE_HEADER_CODE:
00404       break;
00405     case PACK_START_CODE:
00406       System_Stream_Flag = 1;
00407     case VIDEO_ELEMENTARY_STREAM:
00408       System_Stream_Flag = 1;
00409       break;
00410     default:
00411       sprintf(Error_Text,"Unable to recognize stream type\n");
00412       Error(Error_Text);
00413       break;
00414     }
00415 
00416     /*lseek(base.Infile, 0l, SEEK_SET);*/
00417     ld->seek_stream(base.Infile,mpeg_start,SEEK_SET);
00418     Initialize_Buffer(); 
00419   }
00420 
00421   if(base.Infile!=0)
00422   {
00423     /*lseek(base.Infile, 0l, SEEK_SET);*/
00424     ld->seek_stream(base.Infile,mpeg_start,SEEK_SET);
00425   }
00426 
00427   Initialize_Buffer(); 
00428 
00429   if(Two_Streams)
00430   {
00431     ld = &enhan; /* select enhancement layer context */
00432 
00433     /*if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)*/
00434     /*enhan.Infile = ld->open_stream(Enhancement_Layer_Bitstream_Filename);*/
00435     enhan.Infile = &eos;
00436 #ifdef FILESTAR
00437     //enhan.Infile->InFd = fopen(Main_Bitstream_Filename, "rb");
00438     enhan.Infile->InFd->open(Main_Bitstream_Filename, std::ios::binary|std::ios::in);
00439     abort();
00440 #else
00441     enhan.Infile->InFd = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY);
00442 #endif
00443     if (enhan.Infile->InFd)
00444     {
00445       sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
00446         Enhancement_Layer_Bitstream_Filename);
00447 
00448       Error(Error_Text);
00449     }
00450 
00451     Initialize_Buffer();
00452     ld = &base;
00453   }
00454 
00455   Initialize_Decoder();
00456 
00457   ret = Decode_Bitstream();
00458 
00459   /*close(base.Infile);*/
00460   ld->close_stream(base.Infile);
00461 
00462   if (Two_Streams)
00463     /*close(enhan.Infile);*/
00464     ld->close_stream(enhan.Infile);
00465 
00466   DeInitialize_Decoder();
00467 
00468 #if 0
00469   std::ofstream out2("/tmp/etiam.raw");
00470   out2.write((char*)image_buffer, 352*240*3*10);
00471   out2.close();
00472 #endif
00473 
00474   return ret;
00475 }
00476 
00477 } // end namespace gdcm

Generated on Fri Jan 20 10:14:25 2006 for gdcm by  doxygen 1.4.4