#pragma optimize("",off)
#endif
-
-CvCapture* cvCaptureFromFile_VFW (const char* filename);
-CvCapture* cvCaptureFromCAM_VFW (int index);
-
/********************* Capturing video from AVI via VFW ************************/
static BITMAPINFOHEADER icvBitmapHeader( int width, int height, int bpp, int compression = BI_RGB )
return bmih;
}
+
static void icvInitCapture_VFW()
{
static int isInitialized = 0;
}
-typedef struct CvCaptureAVI_VFW
+class CvCaptureAVI_VFW : public CvCapture
{
- CvCaptureVTable * vtable;
+public:
+ CvCaptureAVI_VFW()
+ {
+ init();
+ }
+
+ virtual ~CvCaptureAVI_VFW()
+ {
+ close();
+ }
+
+ virtual bool open( const char* filename );
+ virtual void close();
+
+ virtual double getProperty(int);
+ virtual bool setProperty(int, double);
+ virtual bool grabFrame();
+ virtual IplImage* retrieveFrame();
+
+protected:
+ void init();
+
PAVIFILE avifile;
PAVISTREAM avistream;
PGETFRAME getframe;
double fps;
int pos;
int data_offset;
- IplImage frame;
+ IplImage* frame;
CvSize size;
-}
-CvCaptureAVI_VFW;
+};
-static void icvCloseAVI_VFW( CvCaptureAVI_VFW* capture )
+void CvCaptureAVI_VFW::init()
{
- if( capture->getframe )
- {
- AVIStreamGetFrameClose( capture->getframe );
- capture->getframe = 0;
- }
- if( capture->avistream )
- {
- AVIStreamRelease( capture->avistream );
- capture->avistream = 0;
- }
- if( capture->avifile )
- {
- AVIFileRelease( capture->avifile );
- capture->avifile = 0;
- }
- capture->bmih = 0;
- capture->pos = 0;
- capture->film_range.start_index = capture->film_range.end_index = 0;
- memset( &capture->frame, 0, sizeof(capture->frame));
+ avifile = 0;
+ avistream = 0;
+ getframe = 0;
+ memset( &aviinfo, 0, sizeof(aviinfo) );
+ bmih = 0;
+ film_range = cvSlice(0,0);
+ fps = 0;
+ pos = 0;
+ data_offset = 0;
+ frame = 0;
+ size = cvSize(0,0);
}
-static int icvOpenAVI_VFW( CvCaptureAVI_VFW* capture, const char* filename )
+
+void CvCaptureAVI_VFW::close()
{
- HRESULT hr;
+ if( getframe )
+ AVIStreamGetFrameClose( getframe );
+
+ if( avistream )
+ AVIStreamRelease( avistream );
+
+ if( avifile )
+ AVIFileRelease( avifile );
+ cvReleaseImage( &frame );
+ init();
+}
+
+
+bool CvCaptureAVI_VFW::open( const char* filename )
+{
+ close();
icvInitCapture_VFW();
- if( !capture )
- return 0;
+ if( !filename )
+ return false;
- hr = AVIFileOpen( &capture->avifile, filename, OF_READ, NULL );
+ HRESULT hr = AVIFileOpen( &avifile, filename, OF_READ, NULL );
if( SUCCEEDED(hr))
{
- hr = AVIFileGetStream( capture->avifile, &capture->avistream, streamtypeVIDEO, 0 );
+ hr = AVIFileGetStream( avifile, &avistream, streamtypeVIDEO, 0 );
if( SUCCEEDED(hr))
{
- hr = AVIStreamInfo( capture->avistream, &capture->aviinfo,
- sizeof(capture->aviinfo));
+ hr = AVIStreamInfo( avistream, &aviinfo, sizeof(aviinfo));
if( SUCCEEDED(hr))
{
- //int fcc = capture->aviinfo.fccHandler;
- capture->data_offset = 0;
- capture->size.width = capture->aviinfo.rcFrame.right -
- capture->aviinfo.rcFrame.left;
- capture->size.height = capture->aviinfo.rcFrame.bottom -
- capture->aviinfo.rcFrame.top;
- BITMAPINFOHEADER bmih = icvBitmapHeader(
- capture->size.width, capture->size.height, 24 );
+ //int fcc = aviinfo.fccHandler;
+ data_offset = 0;
+ size.width = aviinfo.rcFrame.right - aviinfo.rcFrame.left;
+ size.height = aviinfo.rcFrame.bottom - aviinfo.rcFrame.top;
+ BITMAPINFOHEADER bmih = icvBitmapHeader( size.width, size.height, 24 );
- capture->film_range.start_index = (int)capture->aviinfo.dwStart;
- capture->film_range.end_index = capture->film_range.start_index +
- (int)capture->aviinfo.dwLength;
- capture->fps = ((double)capture->aviinfo.dwRate)/capture->aviinfo.dwScale;
- capture->pos = capture->film_range.start_index;
- capture->getframe = AVIStreamGetFrameOpen( capture->avistream, &bmih );
- if( capture->getframe != 0 )
- return 1;
+ film_range.start_index = (int)aviinfo.dwStart;
+ film_range.end_index = film_range.start_index + (int)aviinfo.dwLength;
+ fps = (double)aviinfo.dwRate/aviinfo.dwScale;
+ pos = film_range.start_index;
+ getframe = AVIStreamGetFrameOpen( avistream, &bmih );
+ if( getframe != 0 )
+ return true;
}
}
}
- icvCloseAVI_VFW( capture );
- return 0;
+ close();
+ return false;
}
-static int icvGrabFrameAVI_VFW( CvCaptureAVI_VFW* capture )
+bool CvCaptureAVI_VFW::grabFrame()
{
- if( capture->avistream )
- {
- capture->bmih = (BITMAPINFOHEADER*)
- AVIStreamGetFrame( capture->getframe, capture->pos++ );
- }
-
- return capture->bmih != 0;
+ if( avistream )
+ bmih = (BITMAPINFOHEADER*)AVIStreamGetFrame( getframe, pos++ );
+ return bmih != 0;
}
-static const IplImage* icvRetrieveFrameAVI_VFW( CvCaptureAVI_VFW* capture )
+IplImage* CvCaptureAVI_VFW::retrieveFrame()
{
- if( capture->avistream && capture->bmih )
+ if( avistream && bmih )
{
- cvInitImageHeader( &capture->frame,
- cvSize( capture->bmih->biWidth,
- capture->bmih->biHeight ),
+ IplImage src;
+ cvInitImageHeader( &src, cvSize( bmih->biWidth, bmih->biHeight ),
IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
- capture->frame.imageData = capture->frame.imageDataOrigin =
- (char*)(capture->bmih + 1) + capture->data_offset;
- return &capture->frame;
+ cvSetData( &src, (char*)(bmih + 1) + data_offset, src.widthStep );
+ if( !frame || frame->width != src.width || frame->height != src.height )
+ {
+ cvReleaseImage( &frame );
+ frame = cvCreateImage( cvGetSize(&src), 8, 3 );
+ }
+
+ cvFlip( &src, frame, 0 );
+ return frame;
}
return 0;
}
-static double icvGetPropertyAVI_VFW( CvCaptureAVI_VFW* capture, int property_id )
+double CvCaptureAVI_VFW::getProperty( int property_id )
{
switch( property_id )
{
case CV_CAP_PROP_POS_MSEC:
- return cvRound(capture->pos*1000./capture->fps);
+ return cvRound(pos*1000./fps);
case CV_CAP_PROP_POS_FRAMES:
- return capture->pos;
+ return pos;
case CV_CAP_PROP_POS_AVI_RATIO:
- return (capture->pos - capture->film_range.start_index)/
- (capture->film_range.end_index - capture->film_range.start_index + 1e-10);
+ return (pos - film_range.start_index)/
+ (film_range.end_index - film_range.start_index + 1e-10);
case CV_CAP_PROP_FRAME_WIDTH:
- return capture->size.width;
+ return size.width;
case CV_CAP_PROP_FRAME_HEIGHT:
- return capture->size.height;
+ return size.height;
case CV_CAP_PROP_FPS:
- return capture->fps;
+ return fps;
case CV_CAP_PROP_FOURCC:
- return capture->aviinfo.fccHandler;
+ return aviinfo.fccHandler;
case CV_CAP_PROP_FRAME_COUNT:
- return capture->film_range.end_index - capture->film_range.start_index;
+ return film_range.end_index - film_range.start_index;
}
return 0;
}
-
-static int icvSetPropertyAVI_VFW( CvCaptureAVI_VFW* capture,
- int property_id, double value )
+bool CvCaptureAVI_VFW::setProperty( int property_id, double value )
{
switch( property_id )
{
case CV_CAP_PROP_POS_FRAMES:
case CV_CAP_PROP_POS_AVI_RATIO:
{
- int pos;
switch( property_id )
{
case CV_CAP_PROP_POS_MSEC:
- pos = cvRound(value*capture->fps*0.001);
+ pos = cvRound(value*fps*0.001);
break;
case CV_CAP_PROP_POS_AVI_RATIO:
- pos = cvRound(value*(capture->film_range.end_index -
- capture->film_range.start_index) +
- capture->film_range.start_index);
+ pos = cvRound(value*(film_range.end_index -
+ film_range.start_index) +
+ film_range.start_index);
break;
default:
pos = cvRound(value);
}
- if( pos < capture->film_range.start_index )
- pos = capture->film_range.start_index;
- if( pos > capture->film_range.end_index )
- pos = capture->film_range.end_index;
- capture->pos = pos;
+ if( pos < film_range.start_index )
+ pos = film_range.start_index;
+ if( pos > film_range.end_index )
+ pos = film_range.end_index;
}
break;
default:
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static CvCaptureVTable captureAVI_VFW_vtable =
-{
- 6,
- (CvCaptureCloseFunc) icvCloseAVI_VFW,
- (CvCaptureGrabFrameFunc) icvGrabFrameAVI_VFW,
- (CvCaptureRetrieveFrameFunc) icvRetrieveFrameAVI_VFW,
- (CvCaptureGetPropertyFunc) icvGetPropertyAVI_VFW,
- (CvCaptureSetPropertyFunc) icvSetPropertyAVI_VFW,
- (CvCaptureGetDescriptionFunc) 0
-};
-
-
-CvCapture* cvCaptureFromFile_VFW (const char* filename)
+CvCapture* cvCreateFileCapture_VFW (const char* filename)
{
- CvCaptureAVI_VFW* capture = 0;
-
- if( filename )
- {
- capture = (CvCaptureAVI_VFW*)cvAlloc( sizeof(*capture));
- memset( capture, 0, sizeof(*capture));
-
- capture->vtable = &captureAVI_VFW_vtable;
-
- if( !icvOpenAVI_VFW( capture, filename ))
- cvReleaseCapture( (CvCapture**)&capture );
- }
-
- return (CvCapture*)capture;
+ CvCaptureAVI_VFW* capture = new CvCaptureAVI_VFW;
+ if( capture->open(filename) )
+ return capture;
+ delete capture;
+ return 0;
}
+
/********************* Capturing video from camera via VFW *********************/
-typedef struct CvCaptureCAM_VFW
+class CvCaptureCAM_VFW : public CvCapture
{
- CvCaptureVTable* vtable;
+public:
+ CvCaptureCAM_VFW() { init(); }
+ virtual ~CvCaptureCAM_VFW() { close(); }
+
+ virtual bool open( int index );
+ virtual void close();
+ virtual double getProperty(int);
+ virtual bool setProperty(int, double) { return false; }
+ virtual bool grabFrame();
+ virtual IplImage* retrieveFrame();
+
+protected:
+ void init();
+ void closeHIC();
+ static LRESULT PASCAL frameCallback( HWND hWnd, VIDEOHDR* hdr );
+
CAPDRIVERCAPS caps;
HWND capWnd;
VIDEOHDR* hdr;
DWORD fourcc;
HIC hic;
- IplImage* rgb_frame;
- IplImage frame;
+ IplImage* frame;
+};
+
+
+void CvCaptureCAM_VFW::init()
+{
+ memset( &caps, 0, sizeof(caps) );
+ capWnd = 0;
+ hdr = 0;
+ fourcc = 0;
+ hic = 0;
+ frame = 0;
+}
+
+void CvCaptureCAM_VFW::closeHIC()
+{
+ if( hic )
+ {
+ ICDecompressEnd( hic );
+ ICClose( hic );
+ hic = 0;
+ }
}
-CvCaptureCAM_VFW;
-static LRESULT PASCAL FrameCallbackProc( HWND hWnd, VIDEOHDR* hdr )
+LRESULT PASCAL CvCaptureCAM_VFW::frameCallback( HWND hWnd, VIDEOHDR* hdr )
{
CvCaptureCAM_VFW* capture = 0;
// Initialize camera input
-static int icvOpenCAM_VFW( CvCaptureCAM_VFW* capture, int wIndex )
+bool CvCaptureCAM_VFW::open( int wIndex )
{
char szDeviceName[80];
char szDeviceVersion[80];
HWND hWndC = 0;
+
+ close();
if( (unsigned)wIndex >= 10 )
wIndex = 0;
if( hWndC )
{
- capture->capWnd = hWndC;
- capture->hdr = 0;
- capture->hic = 0;
- capture->fourcc = (DWORD)-1;
- capture->rgb_frame = 0;
+ capWnd = hWndC;
+ hdr = 0;
+ hic = 0;
+ fourcc = (DWORD)-1;
- memset( &capture->caps, 0, sizeof(capture->caps));
- capDriverGetCaps( hWndC, &capture->caps, sizeof(&capture->caps));
+ memset( &caps, 0, sizeof(caps));
+ capDriverGetCaps( hWndC, &caps, sizeof(&caps));
::MoveWindow( hWndC, 0, 0, 320, 240, TRUE );
- capSetUserData( hWndC, (size_t)capture );
- capSetCallbackOnFrame( hWndC, FrameCallbackProc );
+ capSetUserData( hWndC, (size_t)this );
+ capSetCallbackOnFrame( hWndC, frameCallback );
CAPTUREPARMS p;
capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
p.dwRequestMicroSecPerFrame = 66667/2;
capPreviewScale(hWndC,FALSE);
capPreviewRate(hWndC,1);
}
- return capture->capWnd != 0;
+ return capWnd != 0;
}
-static void icvCloseCAM_VFW( CvCaptureCAM_VFW* capture )
+
+void CvCaptureCAM_VFW::close()
{
- if( capture && capture->capWnd )
+ if( capWnd )
{
- capSetCallbackOnFrame( capture->capWnd, NULL );
- capDriverDisconnect( capture->capWnd );
- DestroyWindow( capture->capWnd );
- cvReleaseImage( &capture->rgb_frame );
- if( capture->hic )
- {
- ICDecompressEnd( capture->hic );
- ICClose( capture->hic );
- }
-
- capture->capWnd = 0;
- capture->hic = 0;
- capture->hdr = 0;
- capture->fourcc = 0;
- capture->rgb_frame = 0;
- memset( &capture->frame, 0, sizeof(capture->frame));
+ capSetCallbackOnFrame( capWnd, NULL );
+ capDriverDisconnect( capWnd );
+ DestroyWindow( capWnd );
+ closeHIC();
}
+ cvReleaseImage( &frame );
+ init();
}
-static int icvGrabFrameCAM_VFW( CvCaptureCAM_VFW* capture )
+bool CvCaptureCAM_VFW::grabFrame()
{
- if( capture->capWnd )
+ if( capWnd )
{
- SendMessage( capture->capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
- return 1;
+ SendMessage( capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
+ return true;
}
- return 0;
+ return false;
}
-static IplImage* icvRetrieveFrameCAM_VFW( CvCaptureCAM_VFW* capture )
+IplImage* CvCaptureCAM_VFW::retrieveFrame()
{
- if( capture->capWnd )
+ BITMAPINFO vfmt;
+ memset( &vfmt, 0, sizeof(vfmt));
+ BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;
+ int sz, prevWidth, prevHeight;
+
+ if( !capWnd )
+ return 0;
+
+ sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
+ prevWidth = frame ? frame->width : 0;
+ prevHeight = frame ? frame->height : 0;
+
+ if( !hdr || hdr->lpData == 0 || sz == 0 )
+ return 0;
+
+ if( !frame || frame->width != vfmt0.biWidth || frame->height != vfmt0.biHeight )
{
- BITMAPINFO vfmt;
- memset( &vfmt, 0, sizeof(vfmt));
- int sz = capGetVideoFormat( capture->capWnd, &vfmt, sizeof(vfmt));
+ cvReleaseImage( &frame );
+ frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
+ }
- if( capture->hdr && capture->hdr->lpData && sz != 0 )
- {
- long code = ICERR_OK;
- char* frame_data = (char*)capture->hdr->lpData;
+ if( vfmt.bmiHeader.biCompression != BI_RGB ||
+ vfmt.bmiHeader.biBitCount != 24 )
+ {
+ BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
- if( vfmt.bmiHeader.biCompression != BI_RGB ||
- vfmt.bmiHeader.biBitCount != 24 )
+ if( hic == 0 || fourcc != vfmt0.biCompression ||
+ prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight )
+ {
+ closeHIC();
+ hic = ICOpen( MAKEFOURCC('V','I','D','C'),
+ vfmt0.biCompression, ICMODE_DECOMPRESS );
+ if( hic )
{
- BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;
- BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
- code = ICERR_ERROR;
-
- if( capture->hic == 0 ||
- capture->fourcc != vfmt0.biCompression ||
- capture->rgb_frame == 0 ||
- vfmt0.biWidth != capture->rgb_frame->width ||
- vfmt0.biHeight != capture->rgb_frame->height )
+ if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK )
{
- if( capture->hic )
- {
- ICDecompressEnd( capture->hic );
- ICClose( capture->hic );
- }
- capture->hic = ICOpen( MAKEFOURCC('V','I','D','C'),
- vfmt0.biCompression, ICMODE_DECOMPRESS );
- if( capture->hic &&
- ICDecompressBegin( capture->hic, &vfmt0, &vfmt1 ) == ICERR_OK )
- {
- cvReleaseImage( &capture->rgb_frame );
- capture->rgb_frame = cvCreateImage(
- cvSize( vfmt0.biWidth, vfmt0.biHeight ), IPL_DEPTH_8U, 3 );
- capture->rgb_frame->origin = IPL_ORIGIN_BL;
-
- code = ICDecompress( capture->hic, 0,
- &vfmt0, capture->hdr->lpData,
- &vfmt1, capture->rgb_frame->imageData );
- frame_data = capture->rgb_frame->imageData;
- }
+ closeHIC();
+ return 0;
}
}
-
- if( code == ICERR_OK )
- {
- cvInitImageHeader( &capture->frame,
- cvSize(vfmt.bmiHeader.biWidth,
- vfmt.bmiHeader.biHeight),
- IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
- capture->frame.imageData = capture->frame.imageDataOrigin = frame_data;
- return &capture->frame;
- }
}
+
+ if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData,
+ &vfmt1, frame->imageData ) != ICERR_OK )
+ {
+ closeHIC();
+ return 0;
+ }
+
+ cvFlip( frame, frame, 0 );
+ }
+ else
+ {
+ IplImage src;
+ cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight),
+ IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
+ cvSetData( &src, hdr->lpData, src.widthStep );
+ cvFlip( &src, frame, 0 );
}
- return 0;
+ return frame;
}
-static double icvGetPropertyCAM_VFW( CvCaptureCAM_VFW* capture, int property_id )
+double CvCaptureCAM_VFW::getProperty( int property_id )
{
switch( property_id )
{
case CV_CAP_PROP_FRAME_WIDTH:
- return capture->frame.width;
+ return frame ? frame->width : 0;
case CV_CAP_PROP_FRAME_HEIGHT:
- return capture->frame.height;
+ return frame ? frame->height : 0;
case CV_CAP_PROP_FOURCC:
- return capture->fourcc;
+ return fourcc;
}
return 0;
}
-
-static CvCaptureVTable captureCAM_VFW_vtable =
+CvCapture* cvCreateCameraCapture_VFW( int index )
{
- 6,
- (CvCaptureCloseFunc)icvCloseCAM_VFW,
- (CvCaptureGrabFrameFunc)icvGrabFrameCAM_VFW,
- (CvCaptureRetrieveFrameFunc)icvRetrieveFrameCAM_VFW,
- (CvCaptureGetPropertyFunc)icvGetPropertyCAM_VFW,
- (CvCaptureSetPropertyFunc)0,
- (CvCaptureGetDescriptionFunc)0
-};
+ CvCaptureCAM_VFW* capture = new CvCaptureCAM_VFW;
+ if( capture->open( index ))
+ return capture;
-CvCapture* cvCaptureFromCAM_VFW( int index )
-{
- CvCaptureCAM_VFW * capture = (CvCaptureCAM_VFW*)cvAlloc( sizeof(*capture));
- memset( capture, 0, sizeof(*capture));
- capture->vtable = &captureCAM_VFW_vtable;
-
- if( icvOpenCAM_VFW( capture, index ))
- return (CvCapture*)capture;
-
- cvReleaseCapture( (CvCapture**)&capture );
- return 0;
+ delete capture;
+ return 0;
}
/*************************** writing AVIs ******************************/
-typedef struct CvAVI_VFW_Writer
+class CvVideoWriter_VFW : public CvVideoWriter
{
+public:
+ CvVideoWriter_VFW() { init(); }
+ virtual ~CvVideoWriter_VFW() { close(); }
+
+ virtual bool open( const char* filename, int fourcc,
+ double fps, CvSize frameSize, bool isColor );
+ virtual void close();
+ virtual bool writeFrame( const IplImage* );
+
+protected:
+ void init();
+ bool createStreams( CvSize frameSize, bool isColor );
+
PAVIFILE avifile;
PAVISTREAM compressed;
PAVISTREAM uncompressed;
double fps;
- CvSize frameSize;
- IplImage * tempFrame;
+ IplImage* tempFrame;
long pos;
int fourcc;
-} CvAVI_VFW_Writer;
+};
-static void icvCloseAVIWriter( CvAVI_VFW_Writer* writer )
+void CvVideoWriter_VFW::init()
{
- if( writer )
- {
- if( writer->uncompressed )
- AVIStreamRelease( writer->uncompressed );
- if( writer->compressed )
- AVIStreamRelease( writer->compressed );
- if( writer->avifile )
- AVIFileRelease( writer->avifile );
- cvReleaseImage( &writer->tempFrame );
- memset( writer, 0, sizeof(*writer));
- }
+ avifile = 0;
+ compressed = uncompressed = 0;
+ fps = 0;
+ tempFrame = 0;
+ pos = 0;
+ fourcc = 0;
+}
+
+void CvVideoWriter_VFW::close()
+{
+ if( uncompressed )
+ AVIStreamRelease( uncompressed );
+ if( compressed )
+ AVIStreamRelease( compressed );
+ if( avifile )
+ AVIFileRelease( avifile );
+ cvReleaseImage( &tempFrame );
+ init();
}
// philipg. Made this code capable of writing 8bpp gray scale bitmaps
-typedef struct tagBITMAPINFO_8Bit
+struct BITMAPINFO_8Bit
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
-} BITMAPINFOHEADER_8BIT;
+};
+
-static int icvInitAVIWriter( CvAVI_VFW_Writer* writer, int fourcc,
- double fps, CvSize frameSize, int is_color )
+bool CvVideoWriter_VFW::open( const char* filename, int _fourcc, double _fps, CvSize frameSize, bool isColor )
{
- if( writer && writer->avifile )
+ close();
+
+ icvInitCapture_VFW();
+ if( AVIFileOpen( &avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK )
{
- AVICOMPRESSOPTIONS copts, *pcopts = &copts;
- AVISTREAMINFO aviinfo;
-
- assert( frameSize.width > 0 && frameSize.height > 0 );
-
- BITMAPINFOHEADER_8BIT bmih;
- int i;
-
- bmih.bmiHeader = icvBitmapHeader( frameSize.width, frameSize.height, is_color ? 24 : 8 );
- for( i = 0; i < 256; i++ )
+ fourcc = _fourcc;
+ fps = _fps;
+ if( frameSize.width > 0 && frameSize.height > 0 &&
+ !createStreams( frameSize, isColor ) )
{
- bmih.bmiColors[i].rgbBlue = (BYTE)i;
- bmih.bmiColors[i].rgbGreen = (BYTE)i;
- bmih.bmiColors[i].rgbRed = (BYTE)i;
- bmih.bmiColors[i].rgbReserved = 0;
- }
-
- memset( &aviinfo, 0, sizeof(aviinfo));
- aviinfo.fccType = streamtypeVIDEO;
- aviinfo.fccHandler = 0;
- // use highest possible accuracy for dwRate/dwScale
- aviinfo.dwScale = (DWORD)((double)0x7FFFFFFF / fps);
- aviinfo.dwRate = cvRound(fps * aviinfo.dwScale);
- aviinfo.rcFrame.top = aviinfo.rcFrame.left = 0;
- aviinfo.rcFrame.right = frameSize.width;
- aviinfo.rcFrame.bottom = frameSize.height;
-
- if( AVIFileCreateStream( writer->avifile,
- &writer->uncompressed, &aviinfo ) == AVIERR_OK )
- {
- copts.fccType = streamtypeVIDEO;
- copts.fccHandler = fourcc != -1 ? fourcc : 0;
- copts.dwKeyFrameEvery = 1;
- copts.dwQuality = (DWORD)-1;
- copts.dwBytesPerSecond = 0;
- copts.dwFlags = AVICOMPRESSF_VALID;
- copts.lpFormat = &bmih;
- copts.cbFormat = (is_color ? sizeof(BITMAPINFOHEADER) : sizeof(bmih));
- copts.lpParms = 0;
- copts.cbParms = 0;
- copts.dwInterleaveEvery = 0;
-
- if( fourcc != -1 ||
- AVISaveOptions( 0, 0, 1, &writer->uncompressed, &pcopts ) == TRUE )
- {
- if( AVIMakeCompressedStream( &writer->compressed,
- writer->uncompressed, pcopts, 0 ) == AVIERR_OK &&
- // check that the resolution was not changed
- bmih.bmiHeader.biWidth == frameSize.width &&
- bmih.bmiHeader.biHeight == frameSize.height &&
- AVIStreamSetFormat( writer->compressed, 0, &bmih, sizeof(bmih)) == AVIERR_OK )
- {
- writer->fps = fps;
- writer->fourcc = (int)copts.fccHandler;
- writer->frameSize = frameSize;
- writer->tempFrame = cvCreateImage( frameSize, 8, (is_color ? 3 : 1) );
- return 1;
- }
- }
+ close();
+ return false;
}
}
- icvCloseAVIWriter( writer );
- return 0;
+ return true;
}
-CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc,
- double fps, CvSize frameSize, int is_color )
+
+bool CvVideoWriter_VFW::createStreams( CvSize frameSize, bool isColor )
{
- CvAVI_VFW_Writer* writer = (CvAVI_VFW_Writer*)cvAlloc( sizeof(CvAVI_VFW_Writer));
- memset( writer, 0, sizeof(*writer));
-
- icvInitCapture_VFW();
-
- if( AVIFileOpen( &writer->avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK )
+ if( !avifile )
+ return false;
+ AVISTREAMINFO aviinfo;
+
+ BITMAPINFO_8Bit bmih;
+ bmih.bmiHeader = icvBitmapHeader( frameSize.width, frameSize.height, isColor ? 24 : 8 );
+ for( int i = 0; i < 256; i++ )
{
- if( frameSize.width > 0 && frameSize.height > 0 )
- {
- if( !icvInitAVIWriter( writer, fourcc, fps, frameSize, is_color ))
- cvReleaseVideoWriter( (CvVideoWriter**)&writer );
- }
- else if( fourcc == -1 )
- {
- icvCloseAVIWriter( writer );
- }
- else
- {
- /* postpone initialization until the first frame is written */
- writer->fourcc = fourcc;
- writer->fps = fps;
- writer->frameSize = frameSize;
- }
+ bmih.bmiColors[i].rgbBlue = (BYTE)i;
+ bmih.bmiColors[i].rgbGreen = (BYTE)i;
+ bmih.bmiColors[i].rgbRed = (BYTE)i;
+ bmih.bmiColors[i].rgbReserved = 0;
}
-
- return (CvVideoWriter*)writer;
-}
-int cvWriteFrame_VFW( CvVideoWriter* _writer, const IplImage* image )
-{
- CvAVI_VFW_Writer* writer = (CvAVI_VFW_Writer*)_writer;
-
- if( writer && (writer->compressed ||
- icvInitAVIWriter( writer, writer->fourcc, writer->fps,
- writer->frameSize, image->nChannels > 1 )))
+ memset( &aviinfo, 0, sizeof(aviinfo));
+ aviinfo.fccType = streamtypeVIDEO;
+ aviinfo.fccHandler = 0;
+ // use highest possible accuracy for dwRate/dwScale
+ aviinfo.dwScale = (DWORD)((double)0x7FFFFFFF / fps);
+ aviinfo.dwRate = cvRound(fps * aviinfo.dwScale);
+ aviinfo.rcFrame.top = aviinfo.rcFrame.left = 0;
+ aviinfo.rcFrame.right = frameSize.width;
+ aviinfo.rcFrame.bottom = frameSize.height;
+
+ if( AVIFileCreateStream( avifile, &uncompressed, &aviinfo ) == AVIERR_OK )
{
- if (image->nChannels != writer->tempFrame->nChannels)
- {
- cvConvertImage( image, writer->tempFrame,
- image->origin == 0 ? CV_CVTIMG_FLIP : 0 );
- image = (const IplImage*)writer->tempFrame;
- }
- // If only flipping is needed, do not call cvConvertImage because when source and destination are single channel, cvConvertImage fails.
- else if (image->origin == 0)
- {
- cvFlip( image, writer->tempFrame, 0 );
- image = (const IplImage*)writer->tempFrame;
- }
- if( AVIStreamWrite( writer->compressed, writer->pos++, 1, image->imageData,
- image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK )
+ AVICOMPRESSOPTIONS copts, *pcopts = &copts;
+ copts.fccType = streamtypeVIDEO;
+ copts.fccHandler = fourcc != -1 ? fourcc : 0;
+ copts.dwKeyFrameEvery = 1;
+ copts.dwQuality = (DWORD)-1;
+ copts.dwBytesPerSecond = 0;
+ copts.dwFlags = AVICOMPRESSF_VALID;
+ copts.lpFormat = &bmih;
+ copts.cbFormat = (isColor ? sizeof(BITMAPINFOHEADER) : sizeof(bmih));
+ copts.lpParms = 0;
+ copts.cbParms = 0;
+ copts.dwInterleaveEvery = 0;
+
+ if( fourcc != -1 || AVISaveOptions( 0, 0, 1, &uncompressed, &pcopts ) == TRUE )
{
- return 1;
+ if( AVIMakeCompressedStream( &compressed, uncompressed, pcopts, 0 ) == AVIERR_OK &&
+ AVIStreamSetFormat( compressed, 0, &bmih, sizeof(bmih)) == AVIERR_OK )
+ {
+ fps = fps;
+ fourcc = (int)copts.fccHandler;
+ frameSize = frameSize;
+ tempFrame = cvCreateImage( frameSize, 8, (isColor ? 3 : 1) );
+ return true;
+ }
}
}
- return 0;
+ return false;
}
-void cvReleaseVideoWriter_VFW( CvVideoWriter** writer )
+
+bool CvVideoWriter_VFW::writeFrame( const IplImage* image )
{
- if( writer && *writer )
+ bool result = false;
+ CV_FUNCNAME( "CvVideoWriter_VFW::writeFrame" );
+
+ __BEGIN__;
+
+ if( !image )
+ EXIT;
+
+ if( !compressed && !createStreams( cvGetSize(image), image->nChannels > 1 ))
+ EXIT;
+
+ if( image->width != tempFrame->width || image->height != tempFrame->height )
+ CV_ERROR( CV_StsUnmatchedSizes,
+ "image size is different from the currently set frame size" );
+
+ if( image->nChannels != tempFrame->nChannels ||
+ image->depth != tempFrame->depth ||
+ image->origin == 0 ||
+ image->widthStep != cvAlign(image->width*image->nChannels*((image->depth & 255)/8), 4))
{
- icvCloseAVIWriter( (CvAVI_VFW_Writer*)*writer );
- cvFree( writer );
+ cvConvertImage( image, tempFrame, image->origin == 0 ? CV_CVTIMG_FLIP : 0 );
+ image = (const IplImage*)tempFrame;
}
-}
+ result = AVIStreamWrite( compressed, pos++, 1, image->imageData,
+ image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK;
+
+ __END__;
+
+ return result;
+}
+CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc,
+ double fps, CvSize frameSize, int isColor )
+{
+ CvVideoWriter_VFW* writer = new CvVideoWriter_VFW;
+ if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))
+ return writer;
+ delete writer;
+ return 0;
+}