00001
00002 #ifndef vidl_vil1_mpegcodec_helper_h
00003 #define vidl_vil1_mpegcodec_helper_h
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
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
00076
00077
00078
00079
00080 request_type rt;
00081 int position;
00082 int x0, y0, w, h;
00083 bool done;
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
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
00120 unsigned char * buf = (*buffers_->begin()).second;
00121
00122
00123 buffers_->erase(buffers_->begin());
00124
00125
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
00148 buffers_->erase(vmit);
00149
00150
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];
00170 vo_frame_t frame[3];
00171 int width;
00172 int height;
00173 int framenum;
00174
00175
00176 char header[1024];
00177 decode_request * pending_decode;
00178 output_format_t output_format;
00179 int last_frame_decoded;
00180 frame_buffer * buffers;
00181 };
00182
00183
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
00204
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
00211
00212
00213 bool decode_ps(int reads);
00214 bool decode_ts(int packets);
00215 bool decode_es(int reads);
00216
00217
00218
00219
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_;
00234 };
00235
00236 #endif // vidl_vil1_mpegcodec_helper_h