|
|
@ -23,7 +23,7 @@ VideoDev_VFW::VideoDev_VFW() {
|
|
|
|
|
|
|
|
|
|
|
|
VideoDev_VFW::~VideoDev_VFW() {
|
|
|
|
VideoDev_VFW::~VideoDev_VFW() {
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
// if (running > 0) CaptureStop();
|
|
|
|
if (running > 0) CaptureStop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -40,8 +40,7 @@ int VideoDev_VFW::GetDeviceList(std::list<std::string> *list) {
|
|
|
|
for(int i=0; i < 10; i++)
|
|
|
|
for(int i=0; i < 10; i++)
|
|
|
|
if(capGetDriverDescription(i, name, sizeof(name), desc, sizeof(desc))) {
|
|
|
|
if(capGetDriverDescription(i, name, sizeof(name), desc, sizeof(desc))) {
|
|
|
|
std::string device;
|
|
|
|
std::string device;
|
|
|
|
|
|
|
|
device = "VfW " + to_string(i) + " " + (string)name + " [" + (string)desc + "]";
|
|
|
|
device = "VFW " + to_string(i) + " " + (string)name + " [" + (string)desc + "]";
|
|
|
|
|
|
|
|
list->push_back(device);
|
|
|
|
list->push_back(device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -58,34 +57,61 @@ int VideoDev_VFW::Open() {
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
cap = capCreateCaptureWindow("VFW", WS_CHILD, 0, 0, 0, 0, HWND_MESSAGE, camid);
|
|
|
|
cap = capCreateCaptureWindow("VfW", /*WS_CHILD|WS_VISIBLE*/0, 0, 0, 0, 0, 0/*HWND_MESSAGE*/, camid);
|
|
|
|
if(!capDriverConnect(cap, 0)) {
|
|
|
|
if(!cap) {
|
|
|
|
printf ("%s:%d %s could not connect to vfw id %d\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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!capDriverConnect(cap, camid)) {
|
|
|
|
|
|
|
|
printf ("%s:%d %s Could not connect to VfW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
capDlgVideoFormat(cap);
|
|
|
|
capDlgVideoFormat(cap);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get current valid width/height
|
|
|
|
BITMAPINFO bi;
|
|
|
|
BITMAPINFO bi;
|
|
|
|
|
|
|
|
int w, h, i = 0;
|
|
|
|
capGetVideoFormat(cap, &bi, sizeof(BITMAPINFO));
|
|
|
|
capGetVideoFormat(cap, &bi, sizeof(BITMAPINFO));
|
|
|
|
conf_width = bi.bmiHeader.biWidth;
|
|
|
|
w = bi.bmiHeader.biWidth;
|
|
|
|
conf_height = bi.bmiHeader.biHeight;
|
|
|
|
h = bi.bmiHeader.biHeight;
|
|
|
|
printf ("%s:%d %s current size %dx%d\n", __FILE__, __LINE__, __FUNCTION__, conf_width, conf_height);
|
|
|
|
printf ("%s:%d %s Current capture size is %dx%d\n", __FILE__, __LINE__, __FUNCTION__, w, h);
|
|
|
|
|
|
|
|
inframe_pixfmt = convert_to_pixelformat(conf_format);
|
|
|
|
conf_format = convert_from_pixelformat(bi.bmiHeader.biCompression);
|
|
|
|
|
|
|
|
printf ("%s:%d %s current format %s\n", __FILE__, __LINE__, __FUNCTION__, conf_format.c_str());
|
|
|
|
// try to set the configured width/height
|
|
|
|
|
|
|
|
if(conf_width != -1) {
|
|
|
|
switch(bi.bmiHeader.biCompression) {
|
|
|
|
bi.bmiHeader.biWidth = conf_width;
|
|
|
|
case MAKEFOURCC('M','J','P','G'):
|
|
|
|
bi.bmiHeader.biHeight = conf_height;
|
|
|
|
inframe_pixfmt = V4L2_PIX_FMT_MJPEG;
|
|
|
|
bi.bmiHeader.biCompression = inframe_pixfmt;
|
|
|
|
break;
|
|
|
|
if(!capSetVideoFormat(cap, &bi, sizeof(BITMAPINFO))) {
|
|
|
|
case MAKEFOURCC('Y','U','Y','2'):
|
|
|
|
printf ("%s:%d %s Could not set capture size %dx%d (%s)\n", __FILE__, __LINE__, __FUNCTION__, conf_width, conf_height, conf_format.c_str());
|
|
|
|
inframe_pixfmt = V4L2_PIX_FMT_YUYV;
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// find out maximum resolution
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
int sizes[][2] = {{320, 240}, {640, 480}, {800, 600}, {1024, 768}, {1280, 1024}, {1920, 1080}, {-1, -1}};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(sizes[i][0] != -1) {
|
|
|
|
|
|
|
|
w = bi.bmiHeader.biWidth = sizes[i][0];
|
|
|
|
|
|
|
|
h = bi.bmiHeader.biHeight = sizes[i][1];
|
|
|
|
|
|
|
|
bi.bmiHeader.biCompression = inframe_pixfmt;
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
|
|
|
if (w >= conf_width && h >= conf_height) {
|
|
|
|
|
|
|
|
conf_width = w;
|
|
|
|
|
|
|
|
conf_height = h;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d %s Current capture format is %s\n", __FILE__, __LINE__, __FUNCTION__, conf_format.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -119,6 +145,7 @@ LRESULT CALLBACK VFW_frame_callback(HWND h, LPVIDEOHDR v) {
|
|
|
|
|
|
|
|
|
|
|
|
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("error callback: %d (%s)\n", nID, lpsz);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -130,10 +157,12 @@ int VideoDev_VFW::CaptureStart() {
|
|
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) {
|
|
|
|
if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) {
|
|
|
|
printf ("%s:%d %s could not set 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ConvertStart(&cdata, inframe_pixfmt);
|
|
|
|
ConvertStart(&cdata, inframe_pixfmt);
|
|
|
@ -150,6 +179,7 @@ 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);
|
|
|
|
ConvertStop(&cdata, inframe_pixfmt);
|
|
|
|
ConvertStop(&cdata, inframe_pixfmt);
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
@ -176,6 +206,52 @@ int VideoDev_VFW::Grab(VideoFrame *vf) {
|
|
|
|
int VideoDev_VFW::GetDeviceFormats(string device, std::list<string> *formats) {
|
|
|
|
int VideoDev_VFW::GetDeviceFormats(string device, std::list<string> *formats) {
|
|
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
camid = atoi (conf_device.c_str());
|
|
|
|
|
|
|
|
cap = capCreateCaptureWindow("VfW", /*WS_CHILD|WS_VISIBLE*/0, 0, 0, 0, 0, 0/*HWND_MESSAGE*/, camid);
|
|
|
|
|
|
|
|
if(!cap) {
|
|
|
|
|
|
|
|
printf ("%s:%d %s Could not open VfW id %d window\n", __FILE__, __LINE__, __FUNCTION__, camid);
|
|
|
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!capDriverConnect(cap, camid)) {
|
|
|
|
|
|
|
|
printf ("%s:%d %s Could not connect to VfW id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
|
|
|
|
|
|
|
|
return VDEV_STATUS_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BITMAPINFO bi;
|
|
|
|
|
|
|
|
capGetVideoFormat(cap, &bi, sizeof(BITMAPINFO));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string vfwformat;
|
|
|
|
|
|
|
|
DWORD f = bi.bmiHeader.biCompression;
|
|
|
|
|
|
|
|
vfwformat = convert_from_pixelformat(f);
|
|
|
|
|
|
|
|
printf ("%s:%d %s Current capture format is %s\n", __FILE__, __LINE__, __FUNCTION__, vfwformat.c_str());
|
|
|
|
|
|
|
|
formats->push_back(vfwformat);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
DWORD vfwformats[][2] = {{MAKEFOURCC('M','J','P','G'), V4L2_PIX_FMT_MJPEG},
|
|
|
|
|
|
|
|
{MAKEFOURCC('Y','U','V','2'), V4L2_PIX_FMT_YUV2},
|
|
|
|
|
|
|
|
{0, 0}};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(vfwformats[i][0] != 0) {
|
|
|
|
|
|
|
|
bi.bmiHeader.biCompression = vfwformats[i][0];
|
|
|
|
|
|
|
|
if(capSetVideoFormat(cap, &bi, sizeof(BITMAPINFO))) {
|
|
|
|
|
|
|
|
vfwformat = convert_from_pixelformat(vfwformats[i][1]);
|
|
|
|
|
|
|
|
printf ("%s:%d %s Capture format %s works\n", __FILE__, __LINE__, __FUNCTION__, vfwformat.c_str());
|
|
|
|
|
|
|
|
formats->push_back(vfwformat.c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
vfwformat = convert_from_pixelformat(vfwformats[i][1]);
|
|
|
|
|
|
|
|
printf ("%s:%d %s Capture format %s does not work\n", __FILE__, __LINE__, __FUNCTION__, vfwformat.c_str());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
capDriverDisconnect(cap);
|
|
|
|
|
|
|
|
cap = NULL;
|
|
|
|
|
|
|
|
camid = -1;
|
|
|
|
|
|
|
|
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
return VDEV_STATUS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|