Video grabbing now works for VfW even without visible preview window

master
Stefan Jahn 3 years ago
parent ec7caf8b22
commit d7786fa8b1

@ -113,6 +113,24 @@ int VideoDev_VFW::CreateClass() {
return 1; 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. * 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; return TRUE;
} }
#define USE_PREVIEW 1 #define USE_PREVIEW 0
/* /*
* Opens the device. * Opens the device.
@ -155,18 +173,33 @@ int VideoDev_VFW::Open() {
// - the WS_POPUPWINDOW removes window decorations // - the WS_POPUPWINDOW removes window decorations
// - it does not need a parent window // - it does not need a parent window
// - the window MUST be visible, otherwise video grabbing does not work (no callbacks run) // - 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); 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) { if (!hwnd) {
printf ("%s:%d %s Could not create window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError()); printf ("%s:%d %s Could not create window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError());
return VDEV_STATUS_ERROR; return VDEV_STATUS_ERROR;
} }
#if USE_PREVIEW
if(!ShowWindow(hwnd, SW_SHOW)) { if(!ShowWindow(hwnd, SW_SHOW)) {
printf ("%s:%d %s Could not show window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError()); printf ("%s:%d %s Could not show window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError());
return VDEV_STATUS_ERROR; 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 // 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); 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) { if(!cap) {
printf ("%s:%d %s Could not open VFW id %d window\n", __FILE__, __LINE__, __FUNCTION__, camid); printf ("%s:%d %s Could not open VFW id %d window\n", __FILE__, __LINE__, __FUNCTION__, camid);
return VDEV_STATUS_ERROR; return VDEV_STATUS_ERROR;
@ -186,6 +219,9 @@ int VideoDev_VFW::Open() {
return VDEV_STATUS_ERROR; return VDEV_STATUS_ERROR;
} }
// check capabilities
GetCapabilities();
// let the callbacks know this class pointer // let the callbacks know this class pointer
capSetUserData(cap, this); 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__); printf ("%s:%d %s Could not get VFW capture setup\n", __FILE__, __LINE__, __FUNCTION__);
return VDEV_STATUS_ERROR; return VDEV_STATUS_ERROR;
} }
cp.dwRequestMicroSecPerFrame = 33333; cp.dwRequestMicroSecPerFrame = 10000; // rate in us
cp.fMakeUserHitOKToCapture = 0; cp.fMakeUserHitOKToCapture = 0;
cp.wPercentDropForError = 90; cp.wPercentDropForError = 10;
cp.fYield = TRUE; cp.fYield = TRUE;
cp.wNumVideoRequested = 1; cp.wNumVideoRequested = 1;
cp.fCaptureAudio = 0; cp.fCaptureAudio = 0;
@ -292,7 +328,9 @@ int VideoDev_VFW::Close() {
LRESULT CALLBACK VFW_frame_callback (HWND h, LPVIDEOHDR v) { LRESULT CALLBACK VFW_frame_callback (HWND h, LPVIDEOHDR v) {
VideoDev_VFW * obj = (VideoDev_VFW *)capGetUserData(h); VideoDev_VFW * obj = (VideoDev_VFW *)capGetUserData(h);
obj->SetFrameBufferSize(v->dwBytesUsed); obj->SetFrameBufferSize(v->dwBytesUsed);
if (obj->GetFrameBuffer()) {
memcpy(obj->GetFrameBuffer(), v->lpData, obj->GetFrameBufferSize()); memcpy(obj->GetFrameBuffer(), v->lpData, obj->GetFrameBufferSize());
}
return TRUE; return TRUE;
} }
@ -312,6 +350,18 @@ int VideoDev_VFW::CaptureStart() {
pixelformat = inframe_pixfmt; 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 // disable overlay
capOverlay(cap, FALSE); capOverlay(cap, FALSE);
@ -328,21 +378,6 @@ int VideoDev_VFW::CaptureStart() {
} }
#endif #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; return VDEV_STATUS_OK;
}; };
@ -356,10 +391,10 @@ int VideoDev_VFW::CaptureStop() {
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
capCaptureAbort(cap); capCaptureAbort(cap);
capSetCallbackOnError(cap, NULL);
capSetCallbackOnFrame(cap, NULL); capSetCallbackOnFrame(cap, NULL);
capSetCallbackOnVideoStream(cap, NULL); capSetCallbackOnVideoStream(cap, NULL);
capSetCallbackOnYield(cap, NULL); capSetCallbackOnStatus(cap, NULL);
capSetCallbackOnError(cap, NULL);
// free inframe memory // free inframe memory
if (inframe) { if (inframe) {
@ -397,6 +432,7 @@ int VideoDev_VFW::Grab(VideoFrameRaw *vf) {
if (GetFrameBufferSize() > 0) { if (GetFrameBufferSize() > 0) {
LockMutex(); LockMutex();
vf->CopyFrom(inframe_pixfmt, inframe_w, inframe_h, GetFrameBufferSize(), inframe); vf->CopyFrom(inframe_pixfmt, inframe_w, inframe_h, GetFrameBufferSize(), inframe);
SetFrameBufferSize(0);
UnLockMutex(); UnLockMutex();
} }
else { else {

@ -28,6 +28,7 @@ private:
int CreateClass(); int CreateClass();
int DestroyClass(); int DestroyClass();
void HandleMessages(); void HandleMessages();
void GetCapabilities();
void print_error(int err); void print_error(int err);
public: public:

Loading…
Cancel
Save