Merge pull request #2640 from a-wi:2.4

pull/2659/head
Roman Donchenko 11 years ago committed by OpenCV Buildbot
commit cccdcac0c8
  1. 149
      modules/highgui/src/cap_vfw.cpp

@ -318,7 +318,7 @@ public:
virtual bool open( int index ); virtual bool open( int index );
virtual void close(); virtual void close();
virtual double getProperty(int); virtual double getProperty(int);
virtual bool setProperty(int, double) { return false; } virtual bool setProperty(int, double);
virtual bool grabFrame(); virtual bool grabFrame();
virtual IplImage* retrieveFrame(int); virtual IplImage* retrieveFrame(int);
virtual int getCaptureDomain() { return CV_CAP_VFW; } // Return the type of the capture object: CV_CAP_VFW, etc... virtual int getCaptureDomain() { return CV_CAP_VFW; } // Return the type of the capture object: CV_CAP_VFW, etc...
@ -332,6 +332,8 @@ protected:
HWND capWnd; HWND capWnd;
VIDEOHDR* hdr; VIDEOHDR* hdr;
DWORD fourcc; DWORD fourcc;
int width, height;
int widthSet, heightSet;
HIC hic; HIC hic;
IplImage* frame; IplImage* frame;
}; };
@ -345,6 +347,8 @@ void CvCaptureCAM_VFW::init()
fourcc = 0; fourcc = 0;
hic = 0; hic = 0;
frame = 0; frame = 0;
width = height = -1;
widthSet = heightSet = 0;
} }
void CvCaptureCAM_VFW::closeHIC() void CvCaptureCAM_VFW::closeHIC()
@ -407,16 +411,43 @@ bool CvCaptureCAM_VFW::open( int wIndex )
memset( &caps, 0, sizeof(caps)); memset( &caps, 0, sizeof(caps));
capDriverGetCaps( hWndC, &caps, sizeof(caps)); capDriverGetCaps( hWndC, &caps, sizeof(caps));
::MoveWindow( hWndC, 0, 0, 320, 240, TRUE ); CAPSTATUS status = {};
capGetStatus(hWndC, &status, sizeof(status));
::SetWindowPos(hWndC, NULL, 0, 0, status.uiImageWidth, status.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE);
capSetUserData( hWndC, (size_t)this ); capSetUserData( hWndC, (size_t)this );
capSetCallbackOnFrame( hWndC, frameCallback ); capSetCallbackOnFrame( hWndC, frameCallback );
CAPTUREPARMS p; CAPTUREPARMS p;
capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS)); capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
p.dwRequestMicroSecPerFrame = 66667/2; p.dwRequestMicroSecPerFrame = 66667/2; // 30 FPS
capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS)); capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
//capPreview( hWndC, 1 ); //capPreview( hWndC, 1 );
capPreviewScale(hWndC,FALSE); capPreviewScale(hWndC,FALSE);
capPreviewRate(hWndC,1); capPreviewRate(hWndC,1);
// Get frame initial parameters.
const DWORD size = capGetVideoFormatSize(capWnd);
if( size > 0 )
{
unsigned char *pbi = new unsigned char[size];
if( pbi )
{
if( capGetVideoFormat(capWnd, pbi, size) == size )
{
BITMAPINFOHEADER& vfmt = ((BITMAPINFO*)pbi)->bmiHeader;
widthSet = vfmt.biWidth;
heightSet = vfmt.biHeight;
fourcc = vfmt.biCompression;
}
delete []pbi;
}
}
// And alternative way in case of failure.
if( widthSet == 0 || heightSet == 0 )
{
widthSet = status.uiImageWidth;
heightSet = status.uiImageHeight;
}
} }
return capWnd != 0; return capWnd != 0;
} }
@ -439,10 +470,8 @@ void CvCaptureCAM_VFW::close()
bool CvCaptureCAM_VFW::grabFrame() bool CvCaptureCAM_VFW::grabFrame()
{ {
if( capWnd ) if( capWnd )
{ return capGrabFrameNoStop(capWnd) == TRUE;
SendMessage( capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
return true;
}
return false; return false;
} }
@ -452,14 +481,13 @@ IplImage* CvCaptureCAM_VFW::retrieveFrame(int)
BITMAPINFO vfmt; BITMAPINFO vfmt;
memset( &vfmt, 0, sizeof(vfmt)); memset( &vfmt, 0, sizeof(vfmt));
BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader; BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;
int sz, prevWidth, prevHeight;
if( !capWnd ) if( !capWnd )
return 0; return 0;
sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt)); const DWORD sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
prevWidth = frame ? frame->width : 0; const int prevWidth = frame ? frame->width : 0;
prevHeight = frame ? frame->height : 0; const int prevHeight = frame ? frame->height : 0;
if( !hdr || hdr->lpData == 0 || sz == 0 ) if( !hdr || hdr->lpData == 0 || sz == 0 )
return 0; return 0;
@ -470,8 +498,8 @@ IplImage* CvCaptureCAM_VFW::retrieveFrame(int)
frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 ); frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
} }
if( vfmt.bmiHeader.biCompression != BI_RGB || if( vfmt0.biCompression != BI_RGB ||
vfmt.bmiHeader.biBitCount != 24 ) vfmt0.biBitCount != 24 )
{ {
BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 ); BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
@ -518,15 +546,106 @@ double CvCaptureCAM_VFW::getProperty( int property_id )
switch( property_id ) switch( property_id )
{ {
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
return frame ? frame->width : 0; return widthSet;
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
return frame ? frame->height : 0; return heightSet;
case CV_CAP_PROP_FOURCC: case CV_CAP_PROP_FOURCC:
return fourcc; return fourcc;
case CV_CAP_PROP_FPS:
{
CAPTUREPARMS params = {};
if( capCaptureGetSetup(capWnd, &params, sizeof(params)) )
return 1e6 / params.dwRequestMicroSecPerFrame;
}
break;
default:
break;
} }
return 0; return 0;
} }
bool CvCaptureCAM_VFW::setProperty(int property_id, double value)
{
bool handledSize = false;
switch( property_id )
{
case CV_CAP_PROP_FRAME_WIDTH:
width = cvRound(value);
handledSize = true;
break;
case CV_CAP_PROP_FRAME_HEIGHT:
height = cvRound(value);
handledSize = true;
break;
case CV_CAP_PROP_FOURCC:
break;
case CV_CAP_PROP_FPS:
if( value > 0 )
{
CAPTUREPARMS params;
if( capCaptureGetSetup(capWnd, &params, sizeof(params)) )
{
params.dwRequestMicroSecPerFrame = cvRound(1e6/value);
return capCaptureSetSetup(capWnd, &params, sizeof(params)) == TRUE;
}
}
break;
default:
break;
}
if ( handledSize )
{
// If both width and height are set then change frame size.
if( width > 0 && height > 0 )
{
const DWORD size = capGetVideoFormatSize(capWnd);
if( size == 0 )
return false;
unsigned char *pbi = new unsigned char[size];
if( !pbi )
return false;
if( capGetVideoFormat(capWnd, pbi, size) != size )
{
delete []pbi;
return false;
}
BITMAPINFOHEADER& vfmt = ((BITMAPINFO*)pbi)->bmiHeader;
bool success = true;
if( width != vfmt.biWidth || height != vfmt.biHeight )
{
// Change frame size.
vfmt.biWidth = width;
vfmt.biHeight = height;
vfmt.biSizeImage = height * ((width * vfmt.biBitCount + 31) / 32) * 4;
vfmt.biCompression = BI_RGB;
success = capSetVideoFormat(capWnd, pbi, size) == TRUE;
}
if( success )
{
// Adjust capture window size.
CAPSTATUS status = {};
capGetStatus(capWnd, &status, sizeof(status));
::SetWindowPos(capWnd, NULL, 0, 0, status.uiImageWidth, status.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE);
// Store frame size.
widthSet = width;
heightSet = height;
}
delete []pbi;
width = height = -1;
return success;
}
return true;
}
return false;
}
CvCapture* cvCreateCameraCapture_VFW( int index ) CvCapture* cvCreateCameraCapture_VFW( int index )
{ {

Loading…
Cancel
Save