|
|
|
|
@ -113,6 +113,24 @@ int VideoDev_VFW::CreateClass() {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Print driver capabilities.
|
|
|
|
|
*/
|
|
|
|
|
void VideoDev_VFW::GetCapabilities() {
|
|
|
|
|
|
|
|
|
|
CAPDRIVERCAPS caps;
|
|
|
|
|
if(!capDriverGetCaps(cap, &caps, sizeof(caps))) {
|
|
|
|
|
printf ("%s:%d %s Unable to get driver capabilities\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf ("%s:%d %s Id: %d\n", __FILE__, __LINE__, __FUNCTION__, caps.wDeviceIndex);
|
|
|
|
|
printf ("%s:%d %s Overlay: %d\n", __FILE__, __LINE__, __FUNCTION__, caps.fHasOverlay);
|
|
|
|
|
printf ("%s:%d %s VideoSource Dialog: %d\n", __FILE__, __LINE__, __FUNCTION__, caps.fHasDlgVideoSource);
|
|
|
|
|
printf ("%s:%d %s VideoFormat Dialog: %d\n", __FILE__, __LINE__, __FUNCTION__, caps.fHasDlgVideoFormat);
|
|
|
|
|
printf ("%s:%d %s VideoDisplay Dialog: %d\n", __FILE__, __LINE__, __FUNCTION__, caps.fHasDlgVideoDisplay);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The callback is run when an error in the capture driver occurred.
|
|
|
|
|
*/
|
|
|
|
|
@ -129,7 +147,7 @@ LRESULT VFW_status_callback (HWND h, int nID, LPCSTR lpsz) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define USE_PREVIEW 1
|
|
|
|
|
#define USE_PREVIEW 0
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Opens the device.
|
|
|
|
|
@ -155,18 +173,33 @@ int VideoDev_VFW::Open() {
|
|
|
|
|
// - the WS_POPUPWINDOW removes window decorations
|
|
|
|
|
// - it does not need a parent window
|
|
|
|
|
// - the window MUST be visible, otherwise video grabbing does not work (no callbacks run)
|
|
|
|
|
#if USE_PREVIEW
|
|
|
|
|
hwnd = CreateWindowEx(0, classNameVfW, "CameraPreview", WS_POPUPWINDOW|WS_VISIBLE, 0, 0, 3, 3, NULL, NULL, hinst, NULL);
|
|
|
|
|
#else
|
|
|
|
|
hwnd = CreateWindowEx(0, classNameVfW, "CameraPreview", WS_POPUPWINDOW|WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, hinst, NULL);
|
|
|
|
|
#endif
|
|
|
|
|
if (!hwnd) {
|
|
|
|
|
printf ("%s:%d %s Could not create window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError());
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
#if USE_PREVIEW
|
|
|
|
|
if(!ShowWindow(hwnd, SW_SHOW)) {
|
|
|
|
|
printf ("%s:%d %s Could not show window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError());
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if(!ShowWindow(hwnd, SW_HIDE)) {
|
|
|
|
|
printf ("%s:%d %s Could not hide window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError());
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// create capture driver window handle, also here minim size is 1x1
|
|
|
|
|
#if USE_PREVIEW
|
|
|
|
|
cap = capCreateCaptureWindow("VFW", WS_CHILD|WS_VISIBLE, 0, 0, 1, 1, hwnd, camid);
|
|
|
|
|
#else
|
|
|
|
|
cap = capCreateCaptureWindow("VFW", WS_CHILD, 0, 0, 0, 0, hwnd, camid);
|
|
|
|
|
#endif
|
|
|
|
|
if(!cap) {
|
|
|
|
|
printf ("%s:%d %s Could not open VFW id %d window\n", __FILE__, __LINE__, __FUNCTION__, camid);
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
@ -186,6 +219,9 @@ int VideoDev_VFW::Open() {
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check capabilities
|
|
|
|
|
GetCapabilities();
|
|
|
|
|
|
|
|
|
|
// let the callbacks know this class pointer
|
|
|
|
|
capSetUserData(cap, this);
|
|
|
|
|
|
|
|
|
|
@ -198,9 +234,9 @@ int VideoDev_VFW::Open() {
|
|
|
|
|
printf ("%s:%d %s Could not get VFW capture setup\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
cp.dwRequestMicroSecPerFrame = 33333;
|
|
|
|
|
cp.dwRequestMicroSecPerFrame = 10000; // rate in us
|
|
|
|
|
cp.fMakeUserHitOKToCapture = 0;
|
|
|
|
|
cp.wPercentDropForError = 90;
|
|
|
|
|
cp.wPercentDropForError = 10;
|
|
|
|
|
cp.fYield = TRUE;
|
|
|
|
|
cp.wNumVideoRequested = 1;
|
|
|
|
|
cp.fCaptureAudio = 0;
|
|
|
|
|
@ -292,7 +328,9 @@ int VideoDev_VFW::Close() {
|
|
|
|
|
LRESULT CALLBACK VFW_frame_callback (HWND h, LPVIDEOHDR v) {
|
|
|
|
|
VideoDev_VFW * obj = (VideoDev_VFW *)capGetUserData(h);
|
|
|
|
|
obj->SetFrameBufferSize(v->dwBytesUsed);
|
|
|
|
|
memcpy(obj->GetFrameBuffer(), v->lpData, obj->GetFrameBufferSize());
|
|
|
|
|
if (obj->GetFrameBuffer()) {
|
|
|
|
|
memcpy(obj->GetFrameBuffer(), v->lpData, obj->GetFrameBufferSize());
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -312,6 +350,18 @@ int VideoDev_VFW::CaptureStart() {
|
|
|
|
|
|
|
|
|
|
pixelformat = inframe_pixfmt;
|
|
|
|
|
|
|
|
|
|
#if USE_PREVIEW
|
|
|
|
|
if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) {
|
|
|
|
|
printf ("%s:%d %s Could not set frame callback to VFW id %d (%ld)\n", __FILE__, __LINE__, __FUNCTION__, camid, GetLastError());
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if(!capSetCallbackOnVideoStream(cap, VFW_frame_callback)) {
|
|
|
|
|
printf ("%s:%d %s Could not set videostream callback to VFW id %d (%ld)\n", __FILE__, __LINE__, __FUNCTION__, camid, GetLastError());
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// disable overlay
|
|
|
|
|
capOverlay(cap, FALSE);
|
|
|
|
|
|
|
|
|
|
@ -328,21 +378,6 @@ int VideoDev_VFW::CaptureStart() {
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) {
|
|
|
|
|
printf ("%s:%d %s Could not set frame callback to VFW id %d (%ld)\n", __FILE__, __LINE__, __FUNCTION__, camid, GetLastError());
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!capSetCallbackOnVideoStream(cap, VFW_frame_callback)) {
|
|
|
|
|
printf ("%s:%d %s Could not set videostream callback to VFW id %d (%ld)\n", __FILE__, __LINE__, __FUNCTION__, camid, GetLastError());
|
|
|
|
|
//return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!capSetCallbackOnYield(cap, VFW_frame_callback)) {
|
|
|
|
|
printf ("%s:%d %s Could not set yield callback to VFW id %d (%ld)\n", __FILE__, __LINE__, __FUNCTION__, camid, GetLastError());
|
|
|
|
|
//return VDEV_STATUS_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -356,10 +391,10 @@ int VideoDev_VFW::CaptureStop() {
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
capCaptureAbort(cap);
|
|
|
|
|
capSetCallbackOnError(cap, NULL);
|
|
|
|
|
capSetCallbackOnFrame(cap, NULL);
|
|
|
|
|
capSetCallbackOnVideoStream(cap, NULL);
|
|
|
|
|
capSetCallbackOnYield(cap, NULL);
|
|
|
|
|
capSetCallbackOnStatus(cap, NULL);
|
|
|
|
|
capSetCallbackOnError(cap, NULL);
|
|
|
|
|
|
|
|
|
|
// free inframe memory
|
|
|
|
|
if (inframe) {
|
|
|
|
|
@ -397,6 +432,7 @@ int VideoDev_VFW::Grab(VideoFrameRaw *vf) {
|
|
|
|
|
if (GetFrameBufferSize() > 0) {
|
|
|
|
|
LockMutex();
|
|
|
|
|
vf->CopyFrom(inframe_pixfmt, inframe_w, inframe_h, GetFrameBufferSize(), inframe);
|
|
|
|
|
SetFrameBufferSize(0);
|
|
|
|
|
UnLockMutex();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
@ -413,7 +449,7 @@ int VideoDev_VFW::Grab(VideoFrameRaw *vf) {
|
|
|
|
|
int VideoDev_VFW::GetDeviceFormats(string device, std::list<string> *formats) {
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|