Fix for issue #3645 (http://code.opencv.org/issues/3645).
Implement missing features in CvCaptureCAM_VFW class. Implemented missing CvCaptureCAM_VFW::setProperty() member function (handling CV_CAP_PROP_FRAME_WIDTH, CV_CAP_PROP_FRAME_HEIGHT, CV_CAP_PROP_FPS properties). Extended CvCaptureCAM_VFW::setProperty()/getProperty() functions to handle also CV_CAP_PROP_FPS property. Minor refactoring of CvCaptureCAM_VFW class.
This commit is contained in:
parent
7ba4212529
commit
f27a886314
@ -318,7 +318,7 @@ public:
|
||||
virtual bool open( int index );
|
||||
virtual void close();
|
||||
virtual double getProperty(int);
|
||||
virtual bool setProperty(int, double) { return false; }
|
||||
virtual bool setProperty(int, double);
|
||||
virtual bool grabFrame();
|
||||
virtual IplImage* retrieveFrame(int);
|
||||
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;
|
||||
VIDEOHDR* hdr;
|
||||
DWORD fourcc;
|
||||
int width, height;
|
||||
int widthSet, heightSet;
|
||||
HIC hic;
|
||||
IplImage* frame;
|
||||
};
|
||||
@ -345,6 +347,8 @@ void CvCaptureCAM_VFW::init()
|
||||
fourcc = 0;
|
||||
hic = 0;
|
||||
frame = 0;
|
||||
width = height = -1;
|
||||
widthSet = heightSet = 0;
|
||||
}
|
||||
|
||||
void CvCaptureCAM_VFW::closeHIC()
|
||||
@ -407,16 +411,43 @@ bool CvCaptureCAM_VFW::open( int wIndex )
|
||||
|
||||
memset( &caps, 0, 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 );
|
||||
capSetCallbackOnFrame( hWndC, frameCallback );
|
||||
CAPTUREPARMS p;
|
||||
capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
|
||||
p.dwRequestMicroSecPerFrame = 66667/2;
|
||||
p.dwRequestMicroSecPerFrame = 66667/2; // 30 FPS
|
||||
capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
|
||||
//capPreview( hWndC, 1 );
|
||||
capPreviewScale(hWndC,FALSE);
|
||||
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;
|
||||
}
|
||||
@ -439,10 +470,8 @@ void CvCaptureCAM_VFW::close()
|
||||
bool CvCaptureCAM_VFW::grabFrame()
|
||||
{
|
||||
if( capWnd )
|
||||
{
|
||||
SendMessage( capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
|
||||
return true;
|
||||
}
|
||||
return capGrabFrameNoStop(capWnd) == TRUE;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -452,14 +481,13 @@ IplImage* CvCaptureCAM_VFW::retrieveFrame(int)
|
||||
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;
|
||||
const DWORD sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
|
||||
const int prevWidth = frame ? frame->width : 0;
|
||||
const int prevHeight = frame ? frame->height : 0;
|
||||
|
||||
if( !hdr || hdr->lpData == 0 || sz == 0 )
|
||||
return 0;
|
||||
@ -470,8 +498,8 @@ IplImage* CvCaptureCAM_VFW::retrieveFrame(int)
|
||||
frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
|
||||
}
|
||||
|
||||
if( vfmt.bmiHeader.biCompression != BI_RGB ||
|
||||
vfmt.bmiHeader.biBitCount != 24 )
|
||||
if( vfmt0.biCompression != BI_RGB ||
|
||||
vfmt0.biBitCount != 24 )
|
||||
{
|
||||
BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
|
||||
|
||||
@ -518,15 +546,106 @@ double CvCaptureCAM_VFW::getProperty( int property_id )
|
||||
switch( property_id )
|
||||
{
|
||||
case CV_CAP_PROP_FRAME_WIDTH:
|
||||
return frame ? frame->width : 0;
|
||||
return widthSet;
|
||||
case CV_CAP_PROP_FRAME_HEIGHT:
|
||||
return frame ? frame->height : 0;
|
||||
return heightSet;
|
||||
case CV_CAP_PROP_FOURCC:
|
||||
return fourcc;
|
||||
case CV_CAP_PROP_FPS:
|
||||
{
|
||||
CAPTUREPARMS params = {};
|
||||
if( capCaptureGetSetup(capWnd, ¶ms, sizeof(params)) )
|
||||
return 1e6 / params.dwRequestMicroSecPerFrame;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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, ¶ms, sizeof(params)) )
|
||||
{
|
||||
params.dwRequestMicroSecPerFrame = cvRound(1e6/value);
|
||||
return capCaptureSetSetup(capWnd, ¶ms, 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 )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user