Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

AVISource.cpp.bak

00001 /**************************************************************************
00010  *
00011  * Source code for Real Time Image Library (libRTImage)
00012  *
00013  * Leeds Vision Group give permission for this code to be copied, modified 
00014  * and distributed within the University of Leeds subject to the following 
00015  * conditions:-
00016  *
00017  * - The code is not to be used for commercial gain.
00018  * - The code and use thereof will be attributed to the author where
00019  *   appropriate (inluding demonstrations which rely on it's use).
00020  * - All modified, distributions of the source files will retain this header.
00021  *
00022  ****************************************************************************/
00023  
00024 //#define ORIGINAL_VER
00025  
00026 #include "ccvt/conv.h"
00027 #include "AVISource.h"
00028 
00029 //char *Y, *U, *V ; // commented out by cjn 14-09-01
00030                     // already declared in class AVISource
00031 
00032 AVISource::AVISource(char* path)
00038 {
00039 
00040         // Register all formats and codecs
00041         av_register_all();
00042         
00043         // Open video file
00044         if(av_open_input_file(&pFormatCtx, path, NULL, 0, NULL)!=0)
00045                 throw "couldn't open avi file";
00046 
00047         // Retrieve stream information
00048         if(av_find_stream_info(pFormatCtx)<0)
00049                 throw "couldn't find avi stream information";
00050 
00051         // Dump information about file onto standard error
00052         dump_format(pFormatCtx, 0, path, false);
00053         
00054         // Find the first video stream
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         // Get a pointer to the codec context for the video stream
00066         pCodecCtx=&pFormatCtx->streams[videoStream]->codec;
00067 
00068         // Find the decoder for the video stream
00069         pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
00070         if(pCodec==NULL)
00071                 throw "avi codec not found";
00072                                                                                 
00073         // Inform the codec that we can handle truncated bitstreams -- i.e.,
00074         // bitstreams where frame boundaries can fall in the middle of
00075         // packets
00076         if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
00077                 pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
00078                                                                                 
00079         // Open codec
00080         if(avcodec_open(pCodecCtx, pCodec)<0)
00081                 throw "could not open avi codec";
00082                                                                                 
00083         // Hack to correct wrong frame rates that seem to be generated by
00084         // some codecs
00085         //if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
00086         //      pCodecCtx->frame_rate_base=1000;
00087                                                                                 
00088         // Allocate video frame 
00089         pFrame=avcodec_alloc_frame();
00090 
00091         // Allocate an AVFrame structure
00092         pFrameRGB=avcodec_alloc_frame();
00093         if(pFrameRGB==NULL)
00094                 throw "cannot allocate aviframe structure";
00095                                                                                 
00096         // Determine required buffer size and allocate buffer
00097         numBytes=avpicture_get_size(PIX_FMT_RGB24, 
00098                                     pCodecCtx->width, 
00099                                     pCodecCtx->height);
00100         buffer=new uint8_t[numBytes];
00101                                                                                 
00102         // Assign appropriate parts of buffer to image planes in pFrameRGB
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         // allocate memory for rgb rows
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         // last row need space for mmx scratch area
00123 //      buff[height - 1] = new (unsigned char)[width*3 + 4];
00124 
00125         // Allocate memory for YUV data
00126 //        Y = new char[width*height] ;
00127 //        U = new char[width*height/4] ;
00128 //        V = new char[width*height/4] ;
00129         
00130         // default palette type for this ImageSource is colour 
00131         type = Image::COLOUR;
00132 }
00133 
00134 
00135 AVISource::~AVISource()
00139 {
00140                                               
00141     // Free the RGB image
00142     delete [] buffer;
00143     av_free(pFrameRGB);
00144                                                                                 
00145     // Free the YUV frame
00146     av_free(pFrame);
00147                                                                                 
00148     // Close the codec
00149     avcodec_close(pCodecCtx);
00150                                                                                 
00151     // Close the video file
00152     av_close_input_file(pFormatCtx);
00153         
00154         // free the memory for each of the rows
00155         //for (unsigned int i = 0; i < height; i++)
00156         //      delete [] buff[i];
00157         
00158         // free the rest of the memory
00159         //delete [] buff;
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     // First time we're called, set packet.data to NULL to indicate it
00178     // doesn't have to be freed
00179     if(fFirstTime)
00180     {
00181         fFirstTime=false;
00182         packet.data=NULL;
00183     }
00184 
00185     // Decode packets until we have decoded a complete frame
00186     while(true)
00187     {
00188         // Work on the current packet until we have decoded all of it
00189         while(bytesRemaining > 0)
00190         {
00191             // Decode the next chunk of data
00192             bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
00193                 &frameFinished, rawData, bytesRemaining);
00194 
00195             // Was there an error?
00196             if(bytesDecoded < 0)
00197             {
00198                  throw "Error while decoding frame";
00199                  //return false;
00200                  return *this ;
00201             }
00202 
00203             bytesRemaining-=bytesDecoded;
00204             rawData+=bytesDecoded;
00205 
00206             // Did we finish the current frame? Then we can return
00207             if(frameFinished)
00208                 //return true;
00209                 cerr << "DEBUG: frameFinished == true" << endl;
00210                 return *this;
00211         }
00212 
00213         // Read the next packet, skipping all packets that aren't for this
00214         // stream
00215         do
00216         {
00217             // Free old packet
00218             if(packet.data!=NULL)
00219                 av_free_packet(&packet);
00220 
00221             // Read new packet
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     // Decode the rest of the last frame
00233     bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, 
00234         rawData, bytesRemaining);
00235 
00236     // Free last packet
00237     if(packet.data!=NULL)
00238         av_free_packet(&packet);
00239 
00240     //return frameFinished!=0;
00241         
00242     img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame,
00243             pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
00244 
00245     // convert the frame to rgb96
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         //SLOW HACK
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 //    return mpeg3_set_frame(file, frame_no, 0) ;
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     //return (bool)(mpeg3_end_of_video(file, 0));
00330     cerr << "NOT YET IMPLEMENTED AVISource::eof() const" << endl;
00331     return false;
00332 }
00333 

Generated at Fri Aug 13 17:29:20 2004 for libRTImage by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001