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: 2007/08/22 16:14:04 $
00007   Version:   $Revision: 1.13 $
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 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <ctype.h>
00024 #include <fcntl.h>
00025 extern "C" {
00026 #define GLOBAL
00027 #include "config.h"
00028 #include "global.h"
00029 
00030 /* private prototypes */
00031 static int  video_sequence        _ANSI_ARGS_((int *framenum));
00032 static int  Decode_Bitstream      _ANSI_ARGS_((void));
00033 static int  Headers               _ANSI_ARGS_((void));
00034 static void Initialize_Sequence   _ANSI_ARGS_((void));
00035 static void Initialize_Decoder    _ANSI_ARGS_((void));
00036 static void Deinitialize_Sequence _ANSI_ARGS_((void));
00037 //static void Process_Options     _ANSI_ARGS_((int argc, char *argv[]));
00038 
00039 /* IMPLEMENTATION specific routines */
00040 static void Initialize_Decoder()
00041 {
00042   int i;
00043 
00044   /* Clip table */
00045   if ( !(Clip=(unsigned char *)malloc(1024)) )
00046     Error("Clip[] malloc failed\n");
00047 
00048   Clip += 384;
00049 
00050   for (i=-384; i<640; i++)
00051     Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
00052 
00053   /* IDCT */
00054   if ( Reference_IDCT_Flag )
00055     Initialize_Reference_IDCT();
00056   else
00057     Initialize_Fast_IDCT();
00058 
00059 }
00060 
00061 /* mostly IMPLEMENTATION specific routines */
00062 static void Initialize_Sequence()
00063 {
00064   int cc, size;
00065   static int Table_6_20[3] = {6,8,12};
00066 
00067   /* check scalability mode of enhancement layer */
00068   if ( Two_Streams && (enhan.scalable_mode!=SC_SNR) 
00069       &&
00070        (base.scalable_mode!=SC_DP) )
00071   {
00072      Error("unsupported scalability mode\n");
00073   }
00074   /* force MPEG-1 parameters for proper decoder behavior */
00075   /* see ISO/IEC 13818-2 section D.9.14 */
00076   if ( !base.MPEG2_Flag )
00077   {
00078     progressive_sequence = 1;
00079     progressive_frame = 1;
00080     picture_structure = FRAME_PICTURE;
00081     frame_pred_frame_dct = 1;
00082     chroma_format = CHROMA420;
00083     matrix_coefficients = 5;
00084   }
00085 
00086   /* round to nearest multiple of coded macroblocks */
00087   /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
00088   mb_width = (horizontal_size+15)/16;
00089   mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
00090                                         : (vertical_size+15)/16;
00091 
00092   Coded_Picture_Width = 16*mb_width;
00093   Coded_Picture_Height = 16*mb_height;
00094 
00095   /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
00096   Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
00097                                            : Coded_Picture_Width>>1;
00098   Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
00099                                             : Coded_Picture_Height>>1;
00100   
00101   /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
00102   block_count = Table_6_20[chroma_format-1];
00103 
00104   for (cc=0; cc<3; cc++)
00105   {
00106     if ( cc==0 )
00107       size = Coded_Picture_Width*Coded_Picture_Height;
00108     else
00109       size = Chroma_Width*Chroma_Height;
00110 
00111     if ( !(backward_reference_frame[cc] = (unsigned char *)malloc(size)) )
00112       Error("backward_reference_frame[] malloc failed\n");
00113 
00114     if ( !(forward_reference_frame[cc] = (unsigned char *)malloc(size)) )
00115       Error("forward_reference_frame[] malloc failed\n");
00116 
00117     if ( !(auxframe[cc] = (unsigned char *)malloc(size)) )
00118       Error("auxframe[] malloc failed\n");
00119 
00120     if ( Ersatz_Flag )
00121       if ( !(substitute_frame[cc] = (unsigned char *)malloc(size)) )
00122         Error("substitute_frame[] malloc failed\n");
00123 
00124 
00125     if ( base.scalable_mode==SC_SPAT )
00126     {
00127       /* this assumes lower layer is 4:2:0 */
00128       if ( !(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
00129         Error("llframe0 malloc failed\n");
00130       if ( !(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
00131         Error("llframe1 malloc failed\n");
00132     }
00133   }
00134 
00135   /* SCALABILITY: Spatial */
00136   if ( base.scalable_mode==SC_SPAT )
00137   {
00138     if ( !(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
00139       Error("lltmp malloc failed\n");
00140   }
00141 
00142 #ifdef DISPLAY
00143   if (Output_Type==T_X11)
00144   {
00145     Initialize_Display_Process("");
00146     Initialize_Dither_Matrix();
00147   }
00148 #endif /* DISPLAY */
00149 
00150 }
00151 
00152 extern void Error(char *text)
00153 {
00154   fprintf(stderr,text);
00155   exit(1);
00156 }
00157 
00158 /* Trace_Flag output */
00159 void Print_Bits(int code, int bits, int len)
00160 {
00161   int i;
00162   for (i=0; i<len; i++)
00163     printf("%d",(code>>(bits-1-i))&1);
00164 }
00165 
00166 static int Headers()
00167 {
00168   int ret;
00169 
00170   ld = &base;
00171  
00172   /* return when end of sequence (0) or picture
00173      header has been parsed (1) */
00174 
00175   ret = Get_Hdr();
00176 
00177 
00178   if (Two_Streams)
00179   {
00180     ld = &enhan;
00181     if (Get_Hdr()!=ret && !Quiet_Flag)
00182       fprintf(stderr,"streams out of sync\n");
00183     ld = &base;
00184   }
00185 
00186   return ret;
00187 }
00188 
00189 
00190 
00191 static int Decode_Bitstream()
00192 {
00193   int ret;
00194   int Bitstream_Framenum;
00195 
00196   Bitstream_Framenum = 0;
00197 
00198   for(;;)
00199   {
00200 
00201 #ifdef VERIFY
00202     Clear_Verify_Headers();
00203 #endif /* VERIFY */
00204 
00205     ret = Headers();
00206     
00207     if ( ret==1 )
00208     {
00209       ret = video_sequence(&Bitstream_Framenum);
00210     }
00211     else
00212       return(ret);
00213   }
00214 
00215 }
00216 
00217 
00218 static void Deinitialize_Sequence()
00219 {
00220   int i;
00221 
00222   /* clear flags */
00223   base.MPEG2_Flag=0;
00224 
00225   for(i=0;i<3;i++)
00226   {
00227     free(backward_reference_frame[i]);
00228     free(forward_reference_frame[i]);
00229     free(auxframe[i]);
00230 
00231     if ( base.scalable_mode==SC_SPAT )
00232     {
00233      free(llframe0[i]);
00234      free(llframe1[i]);
00235     }
00236   }
00237 
00238   if ( base.scalable_mode==SC_SPAT )
00239     free(lltmp);
00240 
00241 #ifdef DISPLAY
00242   if ( Output_Type==T_X11 ) 
00243     Terminate_Display_Process();
00244 #endif
00245 }
00246 
00247 static int video_sequence(int *Bitstream_Framenumber)
00248 {
00249   int Bitstream_Framenum;
00250   int Sequence_Framenum;
00251   int Return_Value;
00252 
00253   Bitstream_Framenum = *Bitstream_Framenumber;
00254   Sequence_Framenum=0;
00255 
00256   Initialize_Sequence();
00257 
00258   /* decode picture whose header has already been parsed in 
00259      Decode_Bitstream() */
00260 
00261 
00262   Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
00263 
00264   /* update picture numbers */
00265   if ( !Second_Field )
00266   {
00267     Bitstream_Framenum++;
00268     Sequence_Framenum++;
00269   }
00270 
00271   /* loop through the rest of the pictures in the sequence */
00272   while ((Return_Value=Headers()))
00273   {
00274     Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
00275 
00276     if ( !Second_Field )
00277     {
00278       Bitstream_Framenum++;
00279       Sequence_Framenum++;
00280     }
00281   }
00282 
00283   /* put last frame */
00284   if (Sequence_Framenum!=0)
00285   {
00286     Output_Last_Frame_of_Sequence(Bitstream_Framenum);
00287   }
00288 
00289   Deinitialize_Sequence();
00290 
00291 #ifdef VERIFY
00292     Clear_Verify_Headers();
00293 #endif /* VERIFY */
00294 
00295   *Bitstream_Framenumber = Bitstream_Framenum;
00296   return(Return_Value);
00297 }
00298 } // End "C" extern
00299 
00300 namespace gdcm 
00301 {
00310 bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t length)
00311 {
00312   int ret, code;
00313 
00314 #if 0
00315   fp->read((char*)image_buffer, length);
00316   ofstream out("/tmp/etiam.mpeg");
00317   out.write((char*)image_buffer, length);
00318   out.close();
00319 #endif
00320 
00321 //  Clear_Options();
00322 
00323   /* decode command line arguments */
00324 //  Process_Options(argc,argv);
00325 
00326 #ifdef DEBUG
00327   Print_Options();
00328 #endif
00329 
00330   ld = &base; /* select base layer context */
00331 
00332   /* open MPEG base layer bitstream file(s) */
00333   /* NOTE: this is either a base layer stream or a spatial enhancement stream */
00334 #if 0
00335   if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
00336   {
00337     fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
00338     exit(1);
00339   }
00340 #else
00341   base.Infile = -1; //DEBUG
00342 #endif
00343 
00344 
00345   if ( base.Infile != 0 )
00346   {
00347     Initialize_Buffer(); 
00348   
00349     if ( Show_Bits(8)==0x47 )
00350     {
00351       sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
00352       Error(Error_Text);
00353     }
00354 
00355     next_start_code();
00356     code = Show_Bits(32);
00357 
00358     switch(code)
00359     {
00360     case SEQUENCE_HEADER_CODE:
00361       break;
00362     case PACK_START_CODE:
00363       System_Stream_Flag = 1;
00364     case VIDEO_ELEMENTARY_STREAM:
00365       System_Stream_Flag = 1;
00366       break;
00367     default:
00368       sprintf(Error_Text,"Unable to recognize stream type\n");
00369       Error(Error_Text);
00370       break;
00371     }
00372 
00373     //lseek(base.Infile, 0l, SEEK_SET);
00374     //fp->seekg(mpeg_start, ios_base::beg);
00375     Initialize_Buffer(); 
00376   }
00377 
00378   if ( base.Infile!=0 )
00379   {
00380     //lseek(base.Infile, 0l, SEEK_SET);
00381     //fp->seekg(mpeg_start, ios_base::beg);
00382   }
00383 
00384   Initialize_Buffer(); 
00385 
00386   if ( Two_Streams )
00387   {
00388   abort();
00389     ld = &enhan; /* select enhancement layer context */
00390 
00391     if ( (enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
00392     {
00393       sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
00394         Enhancement_Layer_Bitstream_Filename);
00395 
00396       Error(Error_Text);
00397     }
00398 
00399     Initialize_Buffer();
00400     ld = &base;
00401   }
00402 
00403   Initialize_Decoder();
00404 
00405   ret = Decode_Bitstream();
00406 
00407   //close(base.Infile);
00408 
00409   if ( Two_Streams )
00410     {
00411     abort();
00412     close(enhan.Infile);
00413     }
00414 
00415   return ret;
00416 }
00417 
00418 } // end namespace gdcm

Generated on Fri Aug 24 12:53:17 2007 for gdcm by  doxygen 1.4.6