parent
0a504ba742
commit
f47074adfb
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* module to read video data from vfw.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <vfw.h>
|
||||
#include <aviriff.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "convert.h"
|
||||
#include "videodev-vfw.h"
|
||||
|
||||
VideoDev_VFW::VideoDev_VFW() {
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
cap = NULL;
|
||||
};
|
||||
|
||||
|
||||
VideoDev_VFW::~VideoDev_VFW() {
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
// if (running > 0) CaptureStop();
|
||||
}
|
||||
|
||||
/*
|
||||
* check for connected devices and return the result in a list.
|
||||
*/
|
||||
int VideoDev_VFW::GetDeviceList(std::list<std::string> *list) {
|
||||
|
||||
char name[256];
|
||||
char desc[256];
|
||||
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
if (list == NULL) return VDEV_STATUS_ERROR;
|
||||
|
||||
for(int i=0; i < 10; i++)
|
||||
if(capGetDriverDescription(i, name, sizeof(name), desc, sizeof(desc))) {
|
||||
std::string device;
|
||||
|
||||
device = "VFW " + to_string(i) + " " + (string)name + " [" + (string)desc + "]";
|
||||
list->push_back(device);
|
||||
}
|
||||
|
||||
return VDEV_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Open Device
|
||||
* prepare the buffer
|
||||
*/
|
||||
int VideoDev_VFW::Open() {
|
||||
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
camid = atoi (conf_device.c_str());
|
||||
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);
|
||||
if(!capDriverConnect(cap, 0)) {
|
||||
printf ("%s:%d %s could not connect to vfw id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
|
||||
return VDEV_STATUS_ERROR;
|
||||
}
|
||||
|
||||
capDlgVideoFormat(cap);
|
||||
|
||||
BITMAPINFO bi;
|
||||
capGetVideoFormat(cap, &bi, sizeof(BITMAPINFO));
|
||||
conf_width = bi.bmiHeader.biWidth;
|
||||
conf_height = bi.bmiHeader.biHeight;
|
||||
printf ("%s:%d %s current size %dx%d\n", __FILE__, __LINE__, __FUNCTION__, conf_width, conf_height);
|
||||
|
||||
conf_format = convert_from_pixelformat(bi.bmiHeader.biCompression);
|
||||
printf ("%s:%d %s current format %s\n", __FILE__, __LINE__, __FUNCTION__, conf_format.c_str());
|
||||
|
||||
switch(bi.bmiHeader.biCompression) {
|
||||
case MAKEFOURCC('M','J','P','G'):
|
||||
inframe_pixfmt = V4L2_PIX_FMT_MJPEG;
|
||||
break;
|
||||
case MAKEFOURCC('Y','U','Y','2'):
|
||||
inframe_pixfmt = V4L2_PIX_FMT_YUYV;
|
||||
break;
|
||||
}
|
||||
|
||||
return VDEV_STATUS_OK;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Close Device
|
||||
* Free videobuffer
|
||||
*/
|
||||
int VideoDev_VFW::Close() {
|
||||
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
capDriverDisconnect(cap);
|
||||
return VDEV_STATUS_OK;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************************************
|
||||
* VideoGrabbing
|
||||
*/
|
||||
|
||||
int VFW_frame_size;
|
||||
unsigned char VFW_frame_buffer[640*480*3];
|
||||
|
||||
LRESULT CALLBACK VFW_frame_callback(HWND h, LPVIDEOHDR v) {
|
||||
VFW_frame_size = v->dwBytesUsed;
|
||||
printf("frame callback: %d bytes\n", VFW_frame_size);
|
||||
memcpy(VFW_frame_buffer, v->lpData, VFW_frame_size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT VFW_error_callback(HWND h, int nID, LPCSTR lpsz) {
|
||||
printf("error callback: %d (%s)\n", nID, lpsz);
|
||||
}
|
||||
|
||||
/*
|
||||
* prepare inframe for raw picture data, will hold a video frame with 16bit per channel or BGR32/BGR24
|
||||
* inframe size = 4*W*H
|
||||
* send the start capture signal to the cam
|
||||
*/
|
||||
int VideoDev_VFW::CaptureStart() {
|
||||
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
capSetCallbackOnError(cap, VFW_error_callback);
|
||||
|
||||
if(!capSetCallbackOnFrame(cap, VFW_frame_callback)) {
|
||||
printf ("%s:%d %s could not set callback to vfw id %d\n", __FILE__, __LINE__, __FUNCTION__, camid);
|
||||
}
|
||||
|
||||
ConvertStart(&cdata, inframe_pixfmt);
|
||||
|
||||
return VDEV_STATUS_OK;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* free inbuffer
|
||||
*/
|
||||
int VideoDev_VFW::CaptureStop() {
|
||||
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
capCaptureAbort(cap);
|
||||
capSetCallbackOnFrame(cap, NULL);
|
||||
ConvertStop(&cdata, inframe_pixfmt);
|
||||
return VDEV_STATUS_OK;
|
||||
};
|
||||
|
||||
/*
|
||||
* try to grab one frame and convert it into RGB32.
|
||||
* If something goes wrong return an error code.
|
||||
* Return code VDEV_STATUS_AGAIN is not an error. There was no video image ready to read.
|
||||
*/
|
||||
// FIXME: SVBGetVideoData needs to be outside of Lock/UnLockMutex - using inside thread inbuffer
|
||||
int VideoDev_VFW::Grab(VideoFrame *vf) {
|
||||
|
||||
//if (inframe == NULL) return VDEV_STATUS_ERROR;
|
||||
|
||||
LockMutex();
|
||||
Convert(&cdata, vf, VFW_frame_buffer, VFW_frame_size, inframe_pixfmt, conf_width, conf_height);
|
||||
UnLockMutex();
|
||||
|
||||
return VDEV_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
int VideoDev_VFW::GetDeviceFormats(string device, std::list<string> *formats) {
|
||||
|
||||
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
return VDEV_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************************************
|
||||
* Controls
|
||||
*/
|
||||
|
||||
/*
|
||||
* set video control identified by id
|
||||
*/
|
||||
int VideoDev_VFW::SetDevCtrl(unsigned int id, int value) {
|
||||
|
||||
return VDEV_STATUS_OK;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* get video control identified by id
|
||||
*/
|
||||
int VideoDev_VFW::GetDevCtrl(unsigned int id, int *value) {
|
||||
return VDEV_STATUS_OK;
|
||||
};
|
||||
|
@ -0,0 +1,35 @@
|
||||
|
||||
#ifndef _H_VIDEODEV_VFW_H_
|
||||
#define _H_VIDEODEV_VFW_H_
|
||||
|
||||
#include "videodev.h"
|
||||
|
||||
class VideoDev_VFW: public VideoDev {
|
||||
private:
|
||||
unsigned char *inframe;
|
||||
int inframe_size;
|
||||
int inframe_w, inframe_h;
|
||||
int inframe_pixfmt;
|
||||
|
||||
ConvertData cdata;
|
||||
int camid;
|
||||
HWND cap;
|
||||
|
||||
int Grab(VideoFrame *vf);
|
||||
int Open();
|
||||
int Close();
|
||||
int CaptureStart();
|
||||
int CaptureStop();
|
||||
int SetDevCtrl(unsigned int id, int value);
|
||||
int GetDevCtrl(unsigned int id, int *value);
|
||||
|
||||
void print_error(int err);
|
||||
public:
|
||||
VideoDev_VFW();
|
||||
~VideoDev_VFW();
|
||||
int GetDeviceList(std::list<std::string> *list);
|
||||
int GetDeviceFormats(string device, std::list<string> *formats);
|
||||
int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in new issue