00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ccvt/conv.h"
00027 #include "AVISource.h"
00028
00029
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
00086
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
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 type = Image::COLOUR;
00132 }
00133
00134
00135 AVISource::~AVISource()
00139 {
00140
00141
00142 delete [] buffer;
00143 av_free(pFrameRGB);
00144
00145
00146 av_free(pFrame);
00147
00148
00149 avcodec_close(pCodecCtx);
00150
00151
00152 av_close_input_file(pFormatCtx);
00153
00154
00155
00156
00157
00158
00159
00160 }
00161
00162
00163 ImageSource& AVISource::operator >> (ImageRGB& img)
00169 {
00170 static AVPacket packet;
00171 static int bytesRemaining=0;
00172 static uint8_t *rawData;
00173 static bool fFirstTime=true;
00174 int bytesDecoded;
00175 int frameFinished;
00176
00177
00178
00179 if(fFirstTime)
00180 {
00181 fFirstTime=false;
00182 packet.data=NULL;
00183 }
00184
00185
00186 while(true)
00187 {
00188
00189 while(bytesRemaining > 0)
00190 {
00191
00192 bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
00193 &frameFinished, rawData, bytesRemaining);
00194
00195
00196 if(bytesDecoded < 0)
00197 {
00198 throw "Error while decoding frame";
00199
00200 return *this ;
00201 }
00202
00203 bytesRemaining-=bytesDecoded;
00204 rawData+=bytesDecoded;
00205
00206
00207 if(frameFinished)
00208
00209 cerr << "DEBUG: frameFinished == true" << endl;
00210 return *this;
00211 }
00212
00213
00214
00215 do
00216 {
00217
00218 if(packet.data!=NULL)
00219 av_free_packet(&packet);
00220
00221
00222 if(av_read_packet(pFormatCtx, &packet)<0)
00223 goto loop_exit;
00224 } while(packet.stream_index!=videoStream);
00225
00226 bytesRemaining=packet.size;
00227 rawData=packet.data;
00228 }
00229
00230 loop_exit:
00231
00232
00233 bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
00234 rawData, bytesRemaining);
00235
00236
00237 if(packet.data!=NULL)
00238 av_free_packet(&packet);
00239
00240
00241
00242 img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame,
00243 pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
00244
00245
00246 conv_rgb24_rgb96(width, height, &buffer, img.data[0]);
00247
00248 return *this;
00249 }
00250
00251
00252 ImageSource& AVISource::operator >> (ImageGrey& img)
00259 {
00260 Image tmp((Image&)img);
00261
00262 *this >> (ImageRGB&)tmp;
00263 tmp.update_brightness();
00264 img.copy((ImageGrey&)tmp);
00265 return *this;
00266 }
00267
00268 ImageSource& AVISource::operator >> (Image& img)
00277 {
00278 (type == Image::COLOUR) ? *this >> (ImageRGB&)img
00279 : *this >> (ImageGrey&)img;
00280
00281 return *this;
00282 }
00283
00284 int AVISource::get_no_frames()
00285 {
00286 return (int) frames;
00287 }
00288
00289 void AVISource::get_size(unsigned int& w, unsigned int& h)
00296 {
00297 w = width;
00298 h = height;
00299 }
00300
00301 int AVISource::set_frame(long frame_no)
00307 {
00308
00309 cerr << "NOT YET IMPLEMENTED AVISource::set_frame(long frame_no)" << endl;
00310 return false;
00311 }
00312
00313 void AVISource::get_framerate(float& fr_rate)
00319 {
00320 fr_rate = framerate;
00321 }
00322
00323 bool AVISource::eof() const
00328 {
00329
00330 cerr << "NOT YET IMPLEMENTED AVISource::eof() const" << endl;
00331 return false;
00332 }
00333