/******************************************** * the avi hack for mpeg2movie by * * * * Roman Hochleitner amd Alexander Oelzant * * * * roman@mars.tuwien.ac.at * * aoe@mars.tuwien.ac.at * * * * with a bit of c++ help from Josef Schmid * * and the graphical counter code from * * Andreas Varga alias sid * ******************************************** * USE AT YOUR OWN RISK NO WARRANTY * * (might crash your truck!) * ******************************************** * * * parts borrowed from Eugene Smith * * * * * * This Software is under GPL version 2 * * * * http://www.gnu.org/copyleft/gpl.html * * ---------------------------------------- * * Sat Mar 8 04:51:59.67 CET 2000 * ********************************************/ #include "aviplugin.h" #include #include #include #ifndef fccYUY2 #include #endif #include IAviReadFile* CreateIAviReadFile(const char* name); #ifdef DYNAMIC_LOADING void video_in(void) { } #endif namespace { IAviReadFile *file=0; IAviReadStream *stream; int video_width; int video_height; unsigned int outputtype; float timestamp=0.0; #ifdef AVIFILE_06 CImage *img; #else CImage *img; #endif } //#define fccYV12 mmioFOURCC('Y', 'V', '1', '2')/* Planar mode: Y + V + U (3 planes) */ /* GetEndPos() == cnt_frames */ #ifdef DYNAMIC_LOADING int open_file(char *tplorg) #else int avi_open(char *tplorg) #endif { file=CreateIAviReadFile(tplorg); stream=file->GetStream(0, AviStream::Video); BITMAPINFOHEADER bh; stream->StartStreaming(); // wtf? stream->SetBitDepth(24); stream->GetOutputFormat(&bh, sizeof bh); video_width = abs(bh.biWidth); video_height = abs(bh.biHeight); if ((video_height & 1) == 1) { video_height--; fprintf(stderr, "\nIncompatible video height, reducing height to %d\n", video_height); } /* fprintf(stderr, "videos width=%d height=%d \n", video_width, video_height); */ if ((stream->GetDecoder()->GetCapabilities() & IVideoDecoder::CAP_YUY2)) { stream->GetDecoder()->SetDestFmt(0, fccYUY2); outputtype=fccYUY2; } else /* if ((stream->GetDecoder()->GetCapabilities() & IVideoDecoder::CAP_IYUV)) { stream->GetDecoder()->SetDestFmt(0, fccIYUV); outputtype=fccIYUV; } else if ((stream->GetDecoder()->GetCapabilities() & IVideoDecoder::CAP_YV12)) { stream->GetDecoder()->SetDestFmt(0, fccYV12); outputtype=fccYV12; } else */ outputtype=mmioFOURCC('R','G','B','A'); return(outputtype); } unsigned int avi_outputtype() { return(outputtype); } #ifdef DYNAMIC_LOADING int close_file() #else int avi_close() #endif { delete file; return(0); } #ifdef DYNAMIC_LOADING int get_video_width() #else int avi_video_width() #endif { return(video_width); } #ifdef DYNAMIC_LOADING int get_video_height() #else int avi_video_height() #endif { return(video_height); } #ifdef DYNAMIC_LOADING double get_video_framerate() #else double avi_frame_rate() #endif { return(1.0/(stream->GetFrameTime())); } char *avi_get_frame(unsigned int number) { static int mostrecent = 0; if (((mostrecent) != (number)) || (mostrecent == 0)) { // gotta seek // fprintf(stderr,"seeking to %i\n",number); #ifdef AVIFILE_06 stream->SeekToKeyFrame(number); #else stream->SeekToKeyframe(number); #endif stream->ReadFrame(); // bug in avilib: cannot GetPos() before GetFrame() if (img) #ifdef AVIFILE_06 img->Release(); // free some memory #else img->release(); // free some memory #endif img = stream->GetFrame(); } while ((mostrecent=stream->GetPos())<(number+1)) { // fprintf(stderr,"reading frame %i\n",mostrecent); stream->ReadFrame(); if (img) #ifdef AVIFILE_06 img->Release(); // free some memory #else img->release(); // free some memory #endif img = stream->GetFrame(); timestamp += stream->GetFrameTime(); } // fprintf(stderr,"read %i\n",stream->GetPos()-1); #ifdef AVIFILE_06 return((char *)img->Data()); #else return((char *)img->data()); #endif } // we don't really check sig, just the extension #ifdef DYNAMIC_LOADING extern int check_file(char *fname) #else int avi_check_sig(char *fname) #endif { int len; len=strlen(fname); if (len < 4) return(0); if ((0 == strcmp(fname+len-4,".asf")) || (0 == strcmp(fname+len-4,".ASF")) || (0 == strcmp(fname+len-4,".avi")) || (0 == strcmp(fname+len-4,".AVI"))) return(1); return(0); } #ifdef DYNAMIC_LOADING int eof_file() #else int avi_end_of_video() #endif { return (stream->Eof()); } #ifdef DYNAMIC_LOADING double timestamp() #else double avi_timestamp() #endif { return (0.0); /* not yet implemented */ } #ifdef DYNAMIC_LOADING double pel_ratio() #else double avi_pel_ratio() #endif { double ar,atmp1,atmp2; #if 0 /* aarghh!!! the GetFmt interface was disabled a few versions back, * so all we get is a NULL-pointer - and segfault!!! * fscking morons!!! */ #ifdef AVIFILE_06 ar = (img->GetFmt()->biXPelsPerMeter/img->GetFmt()->biYPelsPerMeter); #else // ar = (img->get_fmt()->biXPelsPerMeter/img->get_fmt()->biYPelsPerMeter); ar = (img->get_fmt()->_info->biXPelsPerMeter/img->get_fmt()->_info->biYPelsPerMeter); #endif atmp1=1-avi_frame_rate()/30000.0*1001.0; if (atmp1<0) atmp1 *= -1.0; atmp2=1-avi_frame_rate()/25.0; if (atmp2<0) atmp2 *= -1.0; if ((double)get_video_width()/(double)get_video_height() if (atmp1