00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "ccvt/conv.h"
00029 #include "AVISource.h"
00030
00031
00032 AVISource::AVISource(char* path)
00038 {
00039
00040
00041 av_register_all();
00042
00043
00044 if(av_open_input_file(&pFormatCtx, path, NULL, 0, NULL)!=0)
00045 throw "couldn't open avi file";
00046
00047
00048 if(av_find_stream_info(pFormatCtx)<0)
00049 throw "couldn't find avi stream information";
00050
00051
00052 dump_format(pFormatCtx, 0, path, false);
00053
00054
00055 videoStream=-1;
00056 for(i=0; i<pFormatCtx->nb_streams; i++){
00057 if(pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO){
00058 videoStream=i;
00059 break;
00060 }
00061 }
00062 if(videoStream==-1)
00063 throw "didn't find an avi video stream";
00064
00065
00066 pCodecCtx=&pFormatCtx->streams[videoStream]->codec;
00067
00068
00069 pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
00070 if(pCodec==NULL)
00071 throw "avi codec not found";
00072
00073
00074
00075
00076 if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
00077 pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
00078
00079
00080 if(avcodec_open(pCodecCtx, pCodec)<0)
00081 throw "could not open avi codec";
00082
00083
00084
00085 if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
00086 pCodecCtx->frame_rate_base=1000;
00087
00088
00089 pFrame=avcodec_alloc_frame();
00090
00091
00092 pFrameRGB=avcodec_alloc_frame();
00093 if(pFrameRGB==NULL)
00094 throw "cannot allocate aviframe structure";
00095
00096
00097 numBytes=avpicture_get_size(PIX_FMT_RGB24,
00098 pCodecCtx->width,
00099 pCodecCtx->height);
00100 buffer=new uint8_t[numBytes];
00101
00102
00103 avpicture_fill((AVPicture *)pFrameRGB,
00104 buffer,
00105 PIX_FMT_RGB24,
00106 pCodecCtx->width,
00107 pCodecCtx->height);
00108
00109
00110
00111
00112 width = pCodecCtx->width;
00113 height = pCodecCtx->height;
00114 frames = 0 ;
00115 framerate = pCodecCtx->frame_rate;
00116
00117
00118 buff = new (unsigned char*)[height];
00119 for (unsigned int i = 0; i < height - 1; i++)
00120 buff[i] = new (unsigned char)[width*3];
00121
00122
00123 buff[height - 1] = new (unsigned char)[width*3 + 4];
00124
00125
00126 type = Image::COLOUR;
00127 }
00128
00129 AVISource::~AVISource()
00133 {
00134
00135 delete [] buffer;
00136 av_free(pFrameRGB);
00137
00138
00139 av_free(pFrame);
00140
00141
00142 avcodec_close(pCodecCtx);
00143
00144
00145 av_close_input_file(pFormatCtx);
00146
00147
00148 for (unsigned int i = 0; i < height; i++)
00149 delete [] buff[i];
00150
00151
00152 delete [] buff;
00153 }
00154
00155
00156 ImageSource& AVISource::operator >> (ImageRGB& img)
00162 {
00163 static AVPacket packet;
00164 static int bytesRemaining=0;
00165 static uint8_t *rawData;
00166 static bool fFirstTime=true;
00167 int bytesDecoded;
00168 int frameFinished;
00169
00170
00171
00172 if(fFirstTime)
00173 {
00174 fFirstTime=false;
00175 packet.data=NULL;
00176 }
00177
00178
00179 while(true)
00180 {
00181
00182 while(bytesRemaining > 0)
00183 {
00184
00185 bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
00186 &frameFinished, rawData, bytesRemaining);
00187
00188
00189 if(bytesDecoded < 0)
00190 {
00191 throw "Error while decoding frame";
00192
00193 return *this ;
00194 }
00195
00196 bytesRemaining-=bytesDecoded;
00197 rawData+=bytesDecoded;
00198
00199
00200 if(frameFinished)
00201
00202
00203
00204 goto conv_img;
00205 }
00206
00207
00208
00209 do
00210 {
00211
00212 if(packet.data!=NULL)
00213 av_free_packet(&packet);
00214
00215
00216 if(av_read_packet(pFormatCtx, &packet)<0)
00217 goto loop_exit;
00218 } while(packet.stream_index!=videoStream);
00219
00220 bytesRemaining=packet.size;
00221 rawData=packet.data;
00222 }
00223
00224 loop_exit:
00225
00226
00227 bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
00228 rawData, bytesRemaining);
00229
00230
00231 if(packet.data!=NULL)
00232 av_free_packet(&packet);
00233
00234
00235
00236 conv_img:
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 uint8_t* s = buffer;
00269 int* d = (int*) img.data[0];
00270
00271 for (unsigned int j = 0; j < height; j++) {
00272 for (unsigned int i = 0; i < width; i++) {
00273 *(d++) = (int) *(s++);
00274 *(d++) = (int) *(s++);
00275 *(d++) = (int) *(s++);
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284 return *this;
00285 }
00286
00287
00288 ImageSource& AVISource::operator >> (ImageGrey& img)
00295 {
00296 Image tmp((Image&)img);
00297
00298 *this >> (ImageRGB&)tmp;
00299 tmp.update_brightness();
00300 img.copy((ImageGrey&)tmp);
00301 return *this;
00302 }
00303
00304 ImageSource& AVISource::operator >> (Image& img)
00313 {
00314 (type == Image::COLOUR) ? *this >> (ImageRGB&)img
00315 : *this >> (ImageGrey&)img;
00316
00317 return *this;
00318 }
00319
00320 int AVISource::get_no_frames()
00321 {
00322 return (int) frames;
00323 }
00324
00325 void AVISource::get_size(unsigned int& w, unsigned int& h)
00332 {
00333 w = width;
00334 h = height;
00335 }
00336
00337 int AVISource::set_frame(long frame_no)
00343 {
00344
00345 cerr << "NOT YET IMPLEMENTED AVISource::set_frame(long frame_no)" << endl;
00346 return false;
00347 }
00348
00349 void AVISource::get_framerate(float& fr_rate)
00355 {
00356 fr_rate = framerate;
00357 }
00358
00359 bool AVISource::eof() const
00364 {
00365
00366 cerr << "NOT YET IMPLEMENTED AVISource::eof() const" << endl;
00367 return false;
00368 }
00369