core/vidl_vil1/vidl_vil1_mpegcodec_helper.h

Go to the documentation of this file.
00001 // This is core/vidl_vil1/vidl_vil1_mpegcodec_helper.h
00002 #ifndef vidl_vil1_mpegcodec_helper_h
00003 #define vidl_vil1_mpegcodec_helper_h
00004 //:
00005 // \file
00006 // \brief Contains classes vidl_vil1_mpegcodec_data and vidl_vil1_mpegcodec_helper
00007 // \author l.e.galup
00008 // \date July 2002
00009 //
00010 //  This is a rewrite of the mpeg2dec program. it has been modified
00011 //  to work with the video player, i.e., by implementing a get_section
00012 //  method. this required some buffering, and the ability to decode
00013 //  a file grab at a time. there is some extra legacy code here.
00014 //  though some things seem to serve no purpose, i left them there as hooks
00015 //  for possible evolution of this class.
00016 //
00017 //  the mpeg_codec sends a request to this helper via
00018 //  a decode_request. data is stored in the mpeg_codec_data class, which
00019 //  holds a frame buffer, owned by the mpeg_codec. decoded frames are
00020 //  stored in this frame_buffer, and subsequent user requests for frames
00021 //  just does a memcpy from this frame_buffer into the user supplied buffer.
00022 //
00023 // \verbatim
00024 //  Modifications
00025 //   none
00026 // \endverbatim
00027 
00028 #include <vcl_string.h>
00029 #include <vcl_map.h>
00030 #include <vcl_iostream.h>
00031 
00032 #define BUFFER_SIZE 4096
00033 #define DEMUX_PAYLOAD_START 1
00034 #define PACKETS (BUFFER_SIZE / 188)
00035 
00036 extern "C" {
00037   typedef unsigned char uint8_t;
00038 
00039     // In some versions of Cygwin, uint32_t is typedefed to unsigned
00040     // long in /usr/include/stdint.h.  When that is the case, that
00041     // file also #defines __uint32_t_defined.
00042 
00043     // Instead of these typedefs, perhaps we should be #including the
00044     // system inttypes.h, or the win32/inttypes.h that v3p/mpeg2
00045     // provides.  To do that, look at how v3p/mpeg2/CmakeLists.txt
00046     // adds in include directories for config.h and inttypes.h and
00047     // duplicate that logic to add those directories to
00048     // MPEG2_INCLUDE_DIR in config/cmake/Modules/FindMPEG2.cmake.
00049 
00050     // The root problem here seems to be that mpeg2dec makes a
00051     // config.h and inttypes.h (for win32) for its own use, but does
00052     // not set them up in such a way that other applications using
00053     // mpeg2dec can use those files.  Or, maybe it does when you go
00054     // through its install procedure.
00055 
00056 #ifndef __uint32_t_defined
00057   typedef unsigned int uint32_t;
00058 #endif
00059 #define this c_this
00060 #include <mpeg2dec/video_out.h>
00061 #include <mpeg2dec/mpeg2.h>
00062 #include <mpeg2dec/mm_accel.h>
00063 #undef this
00064 }
00065 
00066 class vidl_vil1_file_sequence;
00067 
00068 class decode_request
00069 {
00070  public:
00071   enum request_type
00072   {
00073     SEEK, FILE_GRAB, SKIP, REWIND
00074   };
00075   //seek seeks from the current file pointer
00076   //position until it gets frame position
00077   //file grab does a single fread from the
00078   //file of size BUFFER_SIZE
00079 
00080   request_type rt;
00081   int position; //which frame is desired
00082   int x0, y0, w, h; // (x0,y0) is upper left corner of roi
00083   bool done; //when this flag is set, the decoder stops
00084 };
00085 
00086 class frame_buffer
00087 {
00088  public:
00089 
00090   frame_buffer()
00091   {
00092     buffers_ = new vcl_map<int,unsigned char *>;
00093   }
00094 
00095   void init(int width, int height, int bits_pixel)
00096   {
00097     //allocate mem 4 ring buffer
00098     for (int i=1; i<30 ; i++)
00099     {
00100       unsigned char * buf = new unsigned char[width*height*(bits_pixel/8)];
00101       (*buffers_)[-i] = buf;
00102     }
00103     return;
00104   }
00105 
00106   ~frame_buffer()
00107   {
00108     vcl_cout << "frame_buffer DTOR. entering.\n";
00109     vcl_map<int,unsigned char *>::iterator vmiuit = buffers_->begin();
00110     for (;vmiuit != buffers_->end(); vmiuit++)
00111       delete[] (*vmiuit).second;
00112     delete buffers_;
00113     vcl_cout << "frame_buffer DTOR. exiting.\n";
00114   }
00115 
00116   unsigned char * get_buff(int i) const {return (*buffers_)[i];}
00117   unsigned char * next(int framenum)
00118   {
00119     //first, get the oldest frame in the buffer
00120     unsigned char * buf = (*buffers_->begin()).second;
00121 
00122     //remove it from the map
00123     buffers_->erase(buffers_->begin());
00124 
00125     //use the memory for the new frame
00126     (*buffers_)[framenum] = buf;
00127 
00128     return buf;
00129   }
00130 
00131   void print()
00132   {
00133     vcl_map<int,unsigned char *>::const_iterator vmiucit = buffers_->begin();
00134     for (;vmiucit != buffers_->end(); vmiucit++)
00135       vcl_cout << (*vmiucit).first << vcl_endl;
00136   }
00137 
00138   int first_frame_num() const { return (*buffers_->begin()).first;}
00139 
00140   bool reset()
00141   {
00142     vcl_map<int,unsigned char *>::iterator vmit = buffers_->begin();
00143     for (int i=-30; vmit != buffers_->end(); vmit++,i++)
00144     {
00145       unsigned char * buf = (*vmit).second;
00146 
00147       //remove it from the map
00148       buffers_->erase(vmit);
00149 
00150       //use the memory for the new frame
00151       (*buffers_)[i] = buf;
00152     }
00153     return true;
00154   }
00155 
00156  private:
00157   vcl_map<int,unsigned char *> * buffers_;
00158 };
00159 
00160 struct vidl_vil1_mpegcodec_data : public vo_instance_t
00161 {
00162  public:
00163   enum output_format_t
00164   {
00165     GREY, RGB
00166   };
00167 
00168   int prediction_index;
00169   vo_frame_t * frame_ptr[3]; //legacy code
00170   vo_frame_t frame[3]; //is the current frame
00171   int width;    //doesn't get set until the first frame gets decoded
00172   int height;   //doesn't get set until the first frame gets decoded
00173   int framenum; //current frame number. starts at -2.
00174                 // this is because we use the first frame to find
00175                 // the stats on the frame.
00176   char header[1024];
00177   decode_request * pending_decode; //request sent by mpeg_codec
00178   output_format_t output_format; //is either gray or rgb
00179   int last_frame_decoded; //this gets incremented after every fread
00180   frame_buffer * buffers;
00181 };
00182 
00183 //this class does the actual decoding.
00184 class vidl_vil1_mpegcodec_helper
00185 {
00186   friend class vidl_vil1_mpegcodec;
00187 
00188  public:
00189   vidl_vil1_mpegcodec_helper(vo_open_t * vopen,
00190                              vcl_string filename,
00191                              frame_buffer * buffers);
00192   ~vidl_vil1_mpegcodec_helper();
00193   bool init();
00194   int execute(decode_request * p);
00195   void print();
00196   int get_width() const {return output_->width;}
00197   int get_height() const {return output_->height;}
00198   int get_last_frame() const {return output_->last_frame_decoded;}
00199   vidl_vil1_mpegcodec_data::output_format_t get_format() const {return output_->output_format;}
00200 
00201  private:
00202   /////////////////////////////////////////////////////////
00203   // the following methods were lifted straight from
00204   // mpeg2dec-0.2.1.
00205   /////////////////////////////////////////////
00206   void decode_mpeg2 (uint8_t * current, uint8_t * end);
00207   int demux (uint8_t * buf, uint8_t * end, int flags);
00208   /////////////////////////////////////////////////////////////
00209 
00210   //these methods were factored out from the above
00211   //they correspond to the demultiplexing done
00212   //per stream protocol
00213   bool decode_ps(int reads);
00214   bool decode_ts(int packets);
00215   bool decode_es(int reads);
00216 
00217   // each of these arguments were static
00218   // and global in the original implementation
00219   // of mpeg2dec
00220   uint8_t buffer_[BUFFER_SIZE];
00221   vcl_string filename_;
00222   vidl_vil1_file_sequence * in_file_;
00223   int demux_track_;
00224   int demux_pid_;
00225   int disable_accel_;
00226   mpeg2dec_t * mpeg2dec_;
00227   vo_open_t * output_open_;
00228   vidl_vil1_mpegcodec_data * output_;
00229   int chunk_size_;
00230   int chunk_number_;
00231   bool (vidl_vil1_mpegcodec_helper::*decoder_routine)(int);
00232 
00233   bool init_; //true once init() has completed
00234 };
00235 
00236 #endif // vidl_vil1_mpegcodec_helper_h

Generated on Tue Dec 2 05:09:13 2008 for core/vidl_vil1 by  doxygen 1.5.1