Compare commits

...

2 Commits

@ -17,13 +17,14 @@
VideoDev_VFW::VideoDev_VFW() { VideoDev_VFW::VideoDev_VFW() {
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
cap = NULL; hwnd = cap = NULL;
camid = -1; camid = -1;
inframe_pixfmt = 0x0; inframe_pixfmt = 0x0;
inframe_w = -1; inframe_w = -1;
inframe_h = -1; inframe_h = -1;
inframe = NULL; inframe = NULL;
inframe_size = 0; inframe_size = 0;
vfw_size = 0;
}; };
@ -54,21 +55,54 @@ int VideoDev_VFW::GetDeviceList(std::list<std::string> *list) {
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
} }
/* /*
* Open Device * Open Device
* prepare the buffer * prepare the buffer
*/ */
int VideoDev_VFW::Open() { int VideoDev_VFW::Open() {
static int first = 1;
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
camid = atoi (conf_device.c_str()); camid = atoi (conf_device.c_str());
printf ("%s:%d %s Opening VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid); printf ("%s:%d %s Opening VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
// create parent window
//HWND main_hwnd = (HWND)GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET(main_window)));
HINSTANCE hinst = GetModuleHandle(NULL);
char classNameVfW[] = "VFW-Class";
if (first) {
WNDCLASSEX hclass;
hclass.hInstance=hinst;
hclass.lpszClassName=classNameVfW;
hclass.lpfnWndProc=DefWindowProc;
hclass.style=CS_DBLCLKS;
hclass.cbSize=sizeof(WNDCLASSEX);
hclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
hclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
hclass.hCursor=LoadCursor(NULL,IDC_ARROW);
hclass.lpszMenuName=NULL;
hclass.cbClsExtra=0;
hclass.cbWndExtra=0;
hclass.hbrBackground=(HBRUSH)COLOR_BACKGROUND;
if(!RegisterClassEx(&hclass)) {
printf ("%s:%d %s Could not register VFW class\n", __FILE__, __LINE__, __FUNCTION__);
return VDEV_STATUS_ERROR;
}
first = 0;
}
hwnd = CreateWindowEx(0, classNameVfW, "CameraPreview", WS_POPUPWINDOW|WS_VISIBLE, 0, 0, 3, 3, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
printf ("%s:%d %s Could not create window (%ld)\n", __FILE__, __LINE__, __FUNCTION__, GetLastError());
return VDEV_STATUS_ERROR;
}
ShowWindow(hwnd, SW_SHOW);
// connect to driver // connect to driver
cap = capCreateCaptureWindow("VFW", WS_CHILD|WS_VISIBLE, 0, 0, 700, 700, HWND_MESSAGE, camid); cap = capCreateCaptureWindow("VFW", WS_CHILD|WS_VISIBLE, 0, 0, 1, 1, hwnd, camid);
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;
@ -78,16 +112,46 @@ int VideoDev_VFW::Open() {
return VDEV_STATUS_ERROR; return VDEV_STATUS_ERROR;
} }
// set capture format and size // let the callbacks know this class pointer
capSetUserData(cap, this);
CAPTUREPARMS cp;
if(!capCaptureGetSetup(cap, &cp, sizeof(cp))) {
printf ("%s:%d %s Could not get VFW setup\n", __FILE__, __LINE__, __FUNCTION__);
return VDEV_STATUS_ERROR;
}
cp.dwRequestMicroSecPerFrame = 33333;
cp.fMakeUserHitOKToCapture = 0;
cp.wPercentDropForError = 90;
cp.fYield = TRUE;
cp.wNumVideoRequested = 1;
cp.fCaptureAudio = 0;
cp.vKeyAbort = 0;
cp.fAbortLeftMouse = 0;
cp.fAbortRightMouse = 0;
cp.fLimitEnabled = 0;
if(!capCaptureSetSetup(cap, &cp, sizeof(cp))) {
printf ("%s:%d %s Could not set VFW setup\n", __FILE__, __LINE__, __FUNCTION__);
return VDEV_STATUS_ERROR;
}
capOverlay(cap, 0);
capPreviewRate(cap, 10); // rate in ms
capPreviewScale(cap, 0);
capPreview(cap, TRUE);
//capCaptureSequenceNoFile(cap);
// set video source, capture format and size
capDlgVideoSource(cap);
capDlgVideoFormat(cap); capDlgVideoFormat(cap);
// get current valid width/height // get current valid width/height
BITMAPINFO bi; BITMAPINFO bi;
int w, h, i = 0; int i = 0;
capGetVideoFormat(cap, &bi, sizeof(BITMAPINFO)); capGetVideoFormat(cap, &bi, sizeof(BITMAPINFO));
w = bi.bmiHeader.biWidth; inframe_w = bi.bmiHeader.biWidth;
h = bi.bmiHeader.biHeight; inframe_h = bi.bmiHeader.biHeight;
printf ("%s:%d %s Current capture size is %dx%d\n", __FILE__, __LINE__, __FUNCTION__, w, h); printf ("%s:%d %s Current capture size is %dx%d\n", __FILE__, __LINE__, __FUNCTION__, inframe_w, inframe_h);
conf_format = convert_from_pixelformat(bi.bmiHeader.biCompression); conf_format = convert_from_pixelformat(bi.bmiHeader.biCompression);
inframe_pixfmt = bi.bmiHeader.biCompression; inframe_pixfmt = bi.bmiHeader.biCompression;
printf ("%s:%d %s Current capture format is %s\n", __FILE__, __LINE__, __FUNCTION__, conf_format.c_str()); printf ("%s:%d %s Current capture format is %s\n", __FILE__, __LINE__, __FUNCTION__, conf_format.c_str());
@ -104,23 +168,28 @@ int VideoDev_VFW::Open() {
} }
// find out maximum resolution // find out maximum resolution
else { else {
int sizes[][2] = {{320, 240}, {640, 480}, {800, 600}, {1024, 768}, {1280, 1024}, {1920, 1080}, {-1, -1}}; int sizes[][2] = {{320, 240}, {640, 480}, {800, 600}, {1024, 768}, {1280, 720}, {1280, 1024}, {1920, 1080}, {-1, -1}};
while(sizes[i][0] != -1) { while(sizes[i][0] != -1) {
w = bi.bmiHeader.biWidth = sizes[i][0]; inframe_w = bi.bmiHeader.biWidth = sizes[i][0];
h = bi.bmiHeader.biHeight = sizes[i][1]; inframe_h = bi.bmiHeader.biHeight = sizes[i][1];
bi.bmiHeader.biCompression = inframe_pixfmt; bi.bmiHeader.biCompression = inframe_pixfmt;
if(capSetVideoFormat(cap, &bi, sizeof(BITMAPINFO))) { if(capSetVideoFormat(cap, &bi, sizeof(BITMAPINFO))) {
printf ("%s:%d %s Resolution %dx%d (%s) works\n", __FILE__, __LINE__, __FUNCTION__, w, h, conf_format.c_str()); printf ("%s:%d %s Resolution %dx%d (%s) works\n", __FILE__, __LINE__, __FUNCTION__, inframe_w, inframe_h, conf_format.c_str());
if (w >= conf_width && h >= conf_height) { if (inframe_w >= conf_width && inframe_h >= conf_height) {
conf_width = w; conf_width = inframe_w;
conf_height = h; conf_height = inframe_h;
} }
} }
i++; i++;
} }
} }
// translate this special format to what our convert functions can work with
if(inframe_pixfmt == V4L2_PIX_FMT_YUY2) {
inframe_pixfmt = V4L2_PIX_FMT_YUYV;
}
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
}; };
@ -135,7 +204,8 @@ int VideoDev_VFW::Close() {
if(cap) { if(cap) {
capDriverDisconnect(cap); capDriverDisconnect(cap);
DestroyWindow(cap); DestroyWindow(cap);
cap = NULL; DestroyWindow(hwnd);
hwnd = cap = NULL;
} }
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
}; };
@ -146,18 +216,15 @@ int VideoDev_VFW::Close() {
* VideoGrabbing * VideoGrabbing
*/ */
int VFW_frame_size;
unsigned char VFW_frame_buffer[640*480*3];
LRESULT CALLBACK VFW_frame_callback(HWND h, LPVIDEOHDR v) { LRESULT CALLBACK VFW_frame_callback(HWND h, LPVIDEOHDR v) {
VFW_frame_size = v->dwBytesUsed; VideoDev_VFW * obj = (VideoDev_VFW *)capGetUserData(h);
printf("frame callback: %d bytes\n", VFW_frame_size); obj->SetFrameBufferSize(v->dwBytesUsed);
memcpy(VFW_frame_buffer, v->lpData, VFW_frame_size); memcpy(obj->GetFrameBuffer(), v->lpData, obj->GetFrameBufferSize());
return TRUE; return TRUE;
} }
LRESULT VFW_error_callback(HWND h, int nID, LPCSTR lpsz) { LRESULT VFW_error_callback(HWND h, int nID, LPCSTR lpsz) {
printf("error callback: %d (%s)\n", nID, lpsz); printf("%s:%d %s id=%d (%s)\n", __FILE__, __LINE__, __FUNCTION__, nID, lpsz);
return TRUE; return TRUE;
} }
@ -170,19 +237,35 @@ int VideoDev_VFW::CaptureStart() {
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
capPreviewRate(cap, 50); // rate in ms // allocate memory for frame data
capPreview(cap, TRUE); if (inframe != NULL) free (inframe);
inframe_size = 4 * inframe_w * inframe_h;
inframe = (unsigned char*) malloc(inframe_size);
pixelformat = inframe_pixfmt;
if(!capSetCallbackOnError(cap, VFW_error_callback)) { if(!capSetCallbackOnError(cap, VFW_error_callback)) {
printf ("%s:%d %s Could not set error callback to VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid); printf ("%s:%d %s Could not set error callback to VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
return VDEV_STATUS_ERROR;
}
#if 0
if(!capSetCallbackOnVideoStream(cap, VFW_frame_callback)) {
printf ("%s:%d %s Could not set videostream callback to VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
return VDEV_STATUS_ERROR;
} }
if(!capSetCallbackOnYield(cap, VFW_frame_callback)) {
printf ("%s:%d %s Cmould not set yield callback to VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
return VDEV_STATUS_ERROR;
}
#endif
if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) { if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) {
printf ("%s:%d %s Could not set frame callback to VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid); printf ("%s:%d %s Could not set frame callback to VFW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
return VDEV_STATUS_ERROR;
} }
pixelformat = inframe_pixfmt;
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
}; };
@ -197,6 +280,16 @@ int VideoDev_VFW::CaptureStop() {
capCaptureAbort(cap); capCaptureAbort(cap);
capSetCallbackOnError(cap, NULL); capSetCallbackOnError(cap, NULL);
capSetCallbackOnFrame(cap, NULL); capSetCallbackOnFrame(cap, NULL);
capSetCallbackOnVideoStream(cap, NULL);
capSetCallbackOnYield(cap, NULL);
// free inframe memory
if (inframe) {
free (inframe);
inframe_size = 0;
inframe = NULL;
}
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
}; };
@ -208,11 +301,19 @@ int VideoDev_VFW::CaptureStop() {
// FIXME: SVBGetVideoData needs to be outside of Lock/UnLockMutex - using inside thread inbuffer // FIXME: SVBGetVideoData needs to be outside of Lock/UnLockMutex - using inside thread inbuffer
int VideoDev_VFW::Grab(VideoFrameRaw *vf) { int VideoDev_VFW::Grab(VideoFrameRaw *vf) {
//if (inframe == NULL) return VDEV_STATUS_ERROR; MSG msg;
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (inframe == NULL) return VDEV_STATUS_ERROR;
if (GetFrameBufferSize() > 0) {
LockMutex(); LockMutex();
vf->CopyFrom(inframe_pixfmt, conf_width, conf_height, VFW_frame_size, VFW_frame_buffer); vf->CopyFrom(inframe_pixfmt, inframe_w, inframe_h, GetFrameBufferSize(), inframe);
UnLockMutex(); UnLockMutex();
}
return VDEV_STATUS_OK; return VDEV_STATUS_OK;
} }

@ -10,10 +10,11 @@ private:
int inframe_size; int inframe_size;
int inframe_w, inframe_h; int inframe_w, inframe_h;
int inframe_pixfmt; int inframe_pixfmt;
int vfw_size;
ConvertData cdata; ConvertData cdata;
int camid; int camid;
HWND cap; HWND cap, hwnd;
int Grab(VideoFrameRaw *vf); int Grab(VideoFrameRaw *vf);
int Open(); int Open();
@ -30,6 +31,9 @@ public:
int GetDeviceList(std::list<std::string> *list); int GetDeviceList(std::list<std::string> *list);
int GetDeviceFormats(string device, std::list<string> *formats); int GetDeviceFormats(string device, std::list<string> *formats);
int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; }; int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
unsigned char * GetFrameBuffer(void) { return inframe; };
void SetFrameBufferSize(int s) { vfw_size = s; };
int GetFrameBufferSize(void) { return vfw_size; };
}; };
#endif #endif

@ -66,7 +66,7 @@ extern void strfromd (char* dest, int len, char *fmt,...);
#define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16 GBGB.. RGRG.. */
#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
#define V4L2_PIX_FMT_YUV2 v4l2_fourcc('Y', 'U', 'V', '2') /* ??? */ #define V4L2_PIX_FMT_YUY2 v4l2_fourcc('Y', 'U', 'Y', '2') /* ??? */
#define v4l2_fourcc(a, b, c, d)\ #define v4l2_fourcc(a, b, c, d)\
((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))

Loading…
Cancel
Save