|
|
|
|
@ -13,6 +13,7 @@ VideoDevice_V4L2::VideoDevice_V4L2() {
|
|
|
|
|
conf_videofmt = 0;
|
|
|
|
|
fd = -1;
|
|
|
|
|
cfd = -1;
|
|
|
|
|
pthread_mutex_init(&mtx, NULL);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -72,11 +73,12 @@ int VideoDevice_V4L2::Open() {
|
|
|
|
|
if (fd != -1) return 0;
|
|
|
|
|
if (cfd != -1) return 0;
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
//
|
|
|
|
|
// open device and get device name and capabilities | O_NONBLOCK
|
|
|
|
|
if((fd = open(conf_videodev.c_str(), O_RDWR)) == -1){
|
|
|
|
|
debug ("could not open device error: %s", strerror(errno));
|
|
|
|
|
return 0;
|
|
|
|
|
goto v4l2_open_error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
@ -84,7 +86,7 @@ int VideoDevice_V4L2::Open() {
|
|
|
|
|
if (conf_videocdev.length() > 0) {
|
|
|
|
|
if((cfd = open(conf_videocdev.c_str(), O_RDWR)) == -1){
|
|
|
|
|
debug ("could not open ctrl device error: %s", strerror(errno));
|
|
|
|
|
return 0;
|
|
|
|
|
goto v4l2_open_error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -99,8 +101,8 @@ int VideoDevice_V4L2::Open() {
|
|
|
|
|
|
|
|
|
|
if (!(vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
|
|
|
|
|
debug ("Error: device has no video capture capabilities");
|
|
|
|
|
return 0;
|
|
|
|
|
Close();
|
|
|
|
|
goto v4l2_open_error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
@ -120,7 +122,9 @@ int VideoDevice_V4L2::Open() {
|
|
|
|
|
vctl.max = queryctrl.maximum;
|
|
|
|
|
debug ("CTRL: id:%p name:%s range:%d %d step:%d type:%d", queryctrl.id, queryctrl.name,
|
|
|
|
|
queryctrl.minimum, queryctrl.maximum, queryctrl.step, queryctrl.type);
|
|
|
|
|
UnLock();
|
|
|
|
|
GetDevCtrl(queryctrl.id, &vctl.value);
|
|
|
|
|
Lock();
|
|
|
|
|
vidctrls.push_back(vctl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -166,7 +170,7 @@ int VideoDevice_V4L2::Open() {
|
|
|
|
|
close (cfd);
|
|
|
|
|
cfd = -1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
goto v4l2_open_error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note VIDIOC_S_FMT may change width and height.
|
|
|
|
|
@ -200,14 +204,19 @@ int VideoDevice_V4L2::Open() {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UnLock();
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
v4l2_open_error:
|
|
|
|
|
UnLock();
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int VideoDevice_V4L2::InitMMap() {
|
|
|
|
|
struct v4l2_requestbuffers bufreq;
|
|
|
|
|
struct v4l2_buffer bufinfo;
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
debug ("");
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
@ -258,13 +267,13 @@ int VideoDevice_V4L2::InitMMap() {
|
|
|
|
|
|
|
|
|
|
int VideoDevice_V4L2::Close() {
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
if (fd >= 0) {
|
|
|
|
|
UnInit();
|
|
|
|
|
close (fd);
|
|
|
|
|
fd = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UnLock();
|
|
|
|
|
return 1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -316,6 +325,7 @@ int VideoDevice_V4L2::Start() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
switch (conf_iomode) {
|
|
|
|
|
case IOMODE_READ:
|
|
|
|
|
/* Nothing to do. */
|
|
|
|
|
@ -332,6 +342,7 @@ int VideoDevice_V4L2::Start() {
|
|
|
|
|
|
|
|
|
|
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
|
|
|
|
|
debug ("error on VIDIOC_QBUF %s", strerror(errno));
|
|
|
|
|
UnLock();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -340,17 +351,19 @@ int VideoDevice_V4L2::Start() {
|
|
|
|
|
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
|
|
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) {
|
|
|
|
|
debug ("VIDIOC_STREAMON %s", strerror(errno));
|
|
|
|
|
UnLock();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
debug ("wrong IOMODE?");
|
|
|
|
|
UnLock();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
ConvertStart(&cdata, fmt.fmt.pix.pixelformat);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -360,6 +373,8 @@ int VideoDevice_V4L2::Stop() {
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
ConvertStop(&cdata, fmt.fmt.pix.pixelformat);
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
|
|
|
|
|
switch (conf_iomode) {
|
|
|
|
|
case IOMODE_READ:
|
|
|
|
|
/* Nothing to do. */
|
|
|
|
|
@ -368,13 +383,17 @@ int VideoDevice_V4L2::Stop() {
|
|
|
|
|
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
|
|
if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) {
|
|
|
|
|
fprintf(stderr, "%s:%d VIDIOC_STREAMOFF Error:%s\n", __FILE__, __LINE__, strerror(errno));
|
|
|
|
|
UnLock();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf ("%s:%d %s wrong IOMODE?\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
UnLock();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
Close();
|
|
|
|
|
return 1;
|
|
|
|
|
};
|
|
|
|
|
@ -382,13 +401,17 @@ int VideoDevice_V4L2::Stop() {
|
|
|
|
|
|
|
|
|
|
int VideoDevice_V4L2::GetFrame(VideoFrame *destframe, VideoFrameFloat *destfloat) {
|
|
|
|
|
struct v4l2_buffer buf;
|
|
|
|
|
int len;
|
|
|
|
|
int len, ret;
|
|
|
|
|
|
|
|
|
|
if (destframe == NULL && destfloat == NULL) return 0;
|
|
|
|
|
|
|
|
|
|
switch (conf_iomode) {
|
|
|
|
|
case IOMODE_READ:
|
|
|
|
|
if ((len = read (fd, inbuffer[0].data, fmt.fmt.pix.sizeimage)) == -1) {
|
|
|
|
|
Lock();
|
|
|
|
|
len = read (fd, inbuffer[0].data, fmt.fmt.pix.sizeimage);
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
if (len == -1) {
|
|
|
|
|
switch (errno) {
|
|
|
|
|
case EAGAIN:
|
|
|
|
|
return -1;
|
|
|
|
|
@ -410,7 +433,10 @@ int VideoDevice_V4L2::GetFrame(VideoFrame *destframe, VideoFrameFloat *destfloat
|
|
|
|
|
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
|
|
buf.memory = V4L2_MEMORY_MMAP;
|
|
|
|
|
|
|
|
|
|
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
|
|
|
|
|
Lock();
|
|
|
|
|
ret = xioctl(fd, VIDIOC_DQBUF, &buf);
|
|
|
|
|
UnLock();
|
|
|
|
|
if (ret == -1) {
|
|
|
|
|
switch (errno) {
|
|
|
|
|
case EAGAIN:
|
|
|
|
|
return -1;
|
|
|
|
|
@ -429,8 +455,11 @@ int VideoDevice_V4L2::GetFrame(VideoFrame *destframe, VideoFrameFloat *destfloat
|
|
|
|
|
Convert(&cdata, destframe, destfloat, inbuffer[buf.index].data, buf.bytesused,
|
|
|
|
|
fmt.fmt.pix.pixelformat, fmt.fmt.pix.width, fmt.fmt.pix.height);
|
|
|
|
|
}
|
|
|
|
|
Lock();
|
|
|
|
|
ret = xioctl(fd, VIDIOC_QBUF, &buf);
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
|
|
|
|
|
if (ret == -1) {
|
|
|
|
|
debug ("error on VIDIOC_QBUF %s", strerror(errno));
|
|
|
|
|
return 0; }
|
|
|
|
|
|
|
|
|
|
@ -467,11 +496,15 @@ int VideoDevice_V4L2::xioctl(int fd, int request, void *arg) {
|
|
|
|
|
|
|
|
|
|
int VideoDevice_V4L2::SetDevCtrl(unsigned int id, int value) {
|
|
|
|
|
struct v4l2_control ctrl;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
CLEAR(ctrl);
|
|
|
|
|
ctrl.id = id;
|
|
|
|
|
ctrl.value = value;
|
|
|
|
|
if (-1 == xioctl (cfd != -1 ? cfd : fd, VIDIOC_S_CTRL, &ctrl)) {
|
|
|
|
|
Lock();
|
|
|
|
|
ret = xioctl (cfd != -1 ? cfd : fd, VIDIOC_S_CTRL, &ctrl);
|
|
|
|
|
UnLock();
|
|
|
|
|
if (-1 == ret) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -481,10 +514,14 @@ int VideoDevice_V4L2::SetDevCtrl(unsigned int id, int value) {
|
|
|
|
|
|
|
|
|
|
int VideoDevice_V4L2::GetDevCtrl(unsigned int id, int *value) {
|
|
|
|
|
struct v4l2_control ctrl;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
CLEAR(ctrl);
|
|
|
|
|
ctrl.id = id;
|
|
|
|
|
if (-1 == xioctl (cfd != -1 ? cfd : fd, VIDIOC_G_CTRL, &ctrl)) {
|
|
|
|
|
Lock();
|
|
|
|
|
ret = xioctl (cfd != -1 ? cfd : fd, VIDIOC_G_CTRL, &ctrl);
|
|
|
|
|
UnLock();
|
|
|
|
|
if (-1 == ret) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
*value = ctrl.value;
|
|
|
|
|
|