diff -up pwlib-1.10.10/plugins/vidinput_v4l2/vidinput_v4l2.cxx~ pwlib-1.10.10/plugins/vidinput_v4l2/vidinput_v4l2.cxx --- pwlib-1.10.10/plugins/vidinput_v4l2/vidinput_v4l2.cxx~ 2008-07-28 10:44:19.000000000 +0200 +++ pwlib-1.10.10/plugins/vidinput_v4l2/vidinput_v4l2.cxx 2008-07-28 10:55:56.000000000 +0200 @@ -157,6 +157,20 @@ PCREATE_VIDINPUT_PLUGIN(V4L2); #include "vidinput_names.h" +/* FIXME replace with autoconf detection */ +#define HAVE_LIBV4L + +#ifdef HAVE_LIBV4L +#include <libv4l2.h> +#else +#define v4l2_fd_open(fd, flags) (fd) +#define v4l2_close close +#define v4l2_ioctl ioctl +#define v4l2_read read +#define v4l2_mmap mmap +#define v4l2_munmap munmap +#endif + class V4L2Names : public V4LXNames { @@ -250,6 +264,7 @@ BOOL PVideoInputDevice_V4L2::Open(const { struct utsname buf; PString version; + int libv4l2_fd; uname (&buf); @@ -276,10 +291,20 @@ BOOL PVideoInputDevice_V4L2::Open(const // the camera while the child is still running. ::fcntl(videoFd, F_SETFD, FD_CLOEXEC); + /* Note the v4l2_xxx functions are designed so that if they get passed an + unknown fd, the will behave exactly as their regular xxx counterparts, so + if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom + cam format to normal formats conversion). Chances are big we will still + fail then though, as normally v4l2_fd_open only fails if the device is not + a v4l2 device. */ + libv4l2_fd = v4l2_fd_open(videoFd, 0); + if (libv4l2_fd != -1) + videoFd = libv4l2_fd; + // get the device capabilities - if (::ioctl(videoFd, VIDIOC_QUERYCAP, &videoCapability) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_QUERYCAP, &videoCapability) < 0) { PTRACE(1,"PVidInDev\tQUERYCAP failed : " << ::strerror(errno)); - ::close (videoFd); + v4l2_close (videoFd); videoFd = -1; return FALSE; } @@ -295,7 +320,7 @@ BOOL PVideoInputDevice_V4L2::Open(const // get the capture parameters videoStreamParm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (::ioctl(videoFd, VIDIOC_G_PARM, &videoStreamParm) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_G_PARM, &videoStreamParm) < 0) { PTRACE(1,"PVidInDev\tG_PARM failed : " << ::strerror(errno)); canSetFrameRate = FALSE; @@ -325,7 +350,7 @@ BOOL PVideoInputDevice_V4L2::Close() Stop(); ClearMapping(); - ::close(videoFd); + v4l2_close(videoFd); PTRACE(6,"PVidInDev\tclose, fd=" << videoFd); @@ -364,7 +389,7 @@ BOOL PVideoInputDevice_V4L2::Start() buf.memory = V4L2_MEMORY_MMAP; buf.index = i; - if (::ioctl(videoFd, VIDIOC_QBUF, &buf) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_QBUF, &buf) < 0) { PTRACE(3,"PVidInDev\tVIDIOC_QBUF failed for buffer " << i << ": " << ::strerror(errno)); return FALSE; } @@ -375,7 +400,7 @@ BOOL PVideoInputDevice_V4L2::Start() enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (::ioctl(videoFd, VIDIOC_STREAMON, &type) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_STREAMON, &type) < 0) { PTRACE(3,"PVidInDev\tSTREAMON failed : " << ::strerror(errno)); return FALSE; } @@ -395,7 +420,7 @@ BOOL PVideoInputDevice_V4L2::Stop() int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; started = FALSE; - if (::ioctl(videoFd, VIDIOC_STREAMOFF, &type) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_STREAMOFF, &type) < 0) { PTRACE(3,"PVidInDev\tSTREAMOFF failed : " << ::strerror(errno)); return FALSE; } @@ -446,7 +471,7 @@ BOOL PVideoInputDevice_V4L2::SetVideoFor {V4L2_STD_SECAM, "SECAM"} }; // set the video standard - if (::ioctl(videoFd, VIDIOC_S_STD, &fmt[newFormat].code) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_S_STD, &fmt[newFormat].code) < 0) { PTRACE(1,"VideoInputDevice\tS_STD failed : " << ::strerror(errno)); } @@ -464,7 +489,7 @@ int PVideoInputDevice_V4L2::GetNumChanne struct v4l2_input videoEnumInput; videoEnumInput.index = 0; while (1) { - if (::ioctl(videoFd, VIDIOC_ENUMINPUT, &videoEnumInput) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_ENUMINPUT, &videoEnumInput) < 0) { break; } else @@ -486,7 +511,7 @@ BOOL PVideoInputDevice_V4L2::SetChannel( } // set the channel - if (::ioctl(videoFd, VIDIOC_S_INPUT, &channelNumber) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_S_INPUT, &channelNumber) < 0) { PTRACE(1,"VideoInputDevice\tS_INPUT failed : " << ::strerror(errno)); return FALSE; } @@ -533,7 +558,7 @@ BOOL PVideoInputDevice_V4L2::SetColourFo struct v4l2_streamparm streamParm; unsigned int fi_n = 0, fi_d = 0; streamParm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (::ioctl(videoFd, VIDIOC_G_PARM, &streamParm) == 0 && + if (v4l2_ioctl(videoFd, VIDIOC_G_PARM, &streamParm) == 0 && streamParm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) { fi_n = streamParm.parm.capture.timeperframe.numerator; fi_d = streamParm.parm.capture.timeperframe.denominator; @@ -542,7 +567,7 @@ BOOL PVideoInputDevice_V4L2::SetColourFo } // get the colour format - if (::ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { PTRACE(1,"PVidInDev\tG_FMT failed : " << ::strerror(errno)); return FALSE; } @@ -550,14 +575,14 @@ BOOL PVideoInputDevice_V4L2::SetColourFo videoFormat.fmt.pix.pixelformat = colourFormatTab[colourFormatIndex].code; // set the colour format - if (::ioctl(videoFd, VIDIOC_S_FMT, &videoFormat) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_S_FMT, &videoFormat) < 0) { PTRACE(1,"PVidInDev\tS_FMT failed : " << ::strerror(errno)); PTRACE(1,"\tused code of " << videoFormat.fmt.pix.pixelformat << " for palette: " << colourFormatTab[colourFormatIndex].colourFormat); return FALSE; } // get the colour format again to be careful about broken drivers - if (::ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { PTRACE(1,"PVidInDev\tG_FMT failed : " << ::strerror(errno)); return FALSE; } @@ -568,7 +593,7 @@ BOOL PVideoInputDevice_V4L2::SetColourFo } // reset the frame rate because it may have been overridden by the call to S_FMT - if (fi_n == 0 || fi_d == 0 || ::ioctl(videoFd, VIDIOC_S_PARM, &streamParm) < 0) { + if (fi_n == 0 || fi_d == 0 || v4l2_ioctl(videoFd, VIDIOC_S_PARM, &streamParm) < 0) { PTRACE(3,"PVidInDev\tunable to reset frame rate."); } else if (streamParm.parm.capture.timeperframe.numerator != fi_n || streamParm.parm.capture.timeperframe.denominator != fi_d) { @@ -600,7 +625,7 @@ BOOL PVideoInputDevice_V4L2::SetFrameRat videoStreamParm.parm.capture.timeperframe.denominator = (rate ? rate : 1); // set the stream parameters - if (::ioctl(videoFd, VIDIOC_S_PARM, &videoStreamParm) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_S_PARM, &videoStreamParm) < 0) { PTRACE(1,"PVidInDev\tS_PARM failed : "<< ::strerror(errno)); return TRUE; } @@ -628,12 +653,12 @@ BOOL PVideoInputDevice_V4L2::GetFrameSiz struct v4l2_format fmt; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (::ioctl(videoFd, VIDIOC_G_FMT, &fmt) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_G_FMT, &fmt) < 0) { return FALSE; } fmt.fmt.pix.width = fmt.fmt.pix.height = 10000; - if (::ioctl(videoFd, VIDIOC_TRY_FMT, &fmt) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_TRY_FMT, &fmt) < 0) { return FALSE; } maxWidth = fmt.fmt.pix.width; @@ -683,7 +708,7 @@ BOOL PVideoInputDevice_V4L2::SetMapping( reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; - if (::ioctl(videoFd, VIDIOC_REQBUFS, &reqbuf) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_REQBUFS, &reqbuf) < 0) { PTRACE(3,"PVidInDev\tREQBUFS failed : " << ::strerror(errno)); return FALSE; } @@ -703,12 +728,12 @@ BOOL PVideoInputDevice_V4L2::SetMapping( videoBufferCount = reqbuf.count; for (buf.index = 0; buf.index < videoBufferCount; buf.index++) { - if (::ioctl(videoFd, VIDIOC_QUERYBUF, &buf) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_QUERYBUF, &buf) < 0) { PTRACE(3,"PVidInDev\tQUERYBUF failed : " << ::strerror(errno)); return FALSE; } - if ((videoBuffer[buf.index] = (BYTE *)::mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, videoFd, buf.m.offset)) == MAP_FAILED) { + if ((videoBuffer[buf.index] = (BYTE *)v4l2_mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, videoFd, buf.m.offset)) == MAP_FAILED) { PTRACE(3,"PVidInDev\tmmap failed : " << ::strerror(errno)); return FALSE; } @@ -733,13 +758,13 @@ void PVideoInputDevice_V4L2::ClearMappin buf.memory = V4L2_MEMORY_MMAP; for (buf.index = 0; ; buf.index++) { - if (::ioctl(videoFd, VIDIOC_QUERYBUF, &buf) < 0) + if (v4l2_ioctl(videoFd, VIDIOC_QUERYBUF, &buf) < 0) break; #ifdef SOLARIS - ::munmap((char*)videoBuffer[buf.index], buf.length); + ::v4l2_munmap((char*)videoBuffer[buf.index], buf.length); #else - ::munmap(videoBuffer[buf.index], buf.length); + ::v4l2_munmap(videoBuffer[buf.index], buf.length); #endif } @@ -785,10 +810,10 @@ BOOL PVideoInputDevice_V4L2::GetFrameDat buf.memory = V4L2_MEMORY_MMAP; buf.index = currentvideoBuffer; - if (::ioctl(videoFd, VIDIOC_DQBUF, &buf) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_DQBUF, &buf) < 0) { // strace resistance if (errno == EINTR) { - if (::ioctl(videoFd, VIDIOC_DQBUF, &buf) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_DQBUF, &buf) < 0) { PTRACE(1,"PVidInDev\tDQBUF failed : " << ::strerror(errno)); return FALSE; } @@ -810,7 +835,7 @@ BOOL PVideoInputDevice_V4L2::GetFrameDat PTRACE(8,"PVidInDev\tget frame data of " << buf.bytesused << "bytes, fd=" << videoFd); // requeue the buffer - if (::ioctl(videoFd, VIDIOC_QBUF, &buf) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_QBUF, &buf) < 0) { PTRACE(1,"PVidInDev\tQBUF failed : " << ::strerror(errno)); } @@ -828,7 +853,7 @@ BOOL PVideoInputDevice_V4L2::NormalReadP ssize_t bytesRead; do - bytesRead = ::read(videoFd, buffer, frameBytes); + bytesRead = v4l2_read(videoFd, buffer, frameBytes); while (bytesRead < 0 && errno == EINTR && IsOpen()); if (bytesRead < 0) { @@ -860,14 +885,14 @@ BOOL PVideoInputDevice_V4L2::VerifyHardw streamParm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // get the frame size - if (::ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { PTRACE(1,"PVidInDev\tG_FMT failed : " << ::strerror(errno)); return FALSE; } // get the frame rate so we can preserve it throughout the S_FMT call // Sidenote: V4L2 gives us the frame interval, i.e. 1/fps. - if (::ioctl(videoFd, VIDIOC_G_PARM, &streamParm) == 0 && + if (v4l2_ioctl(videoFd, VIDIOC_G_PARM, &streamParm) == 0 && streamParm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) { fi_n = streamParm.parm.capture.timeperframe.numerator; fi_d = streamParm.parm.capture.timeperframe.denominator; @@ -879,14 +904,14 @@ BOOL PVideoInputDevice_V4L2::VerifyHardw videoFormat.fmt.pix.height = height; // set the frame size - if (::ioctl(videoFd, VIDIOC_S_FMT, &videoFormat) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_S_FMT, &videoFormat) < 0) { PTRACE(1,"PVidInDev\tS_FMT failed : " << ::strerror(errno)); PTRACE(1,"\tused frame size of " << videoFormat.fmt.pix.width << "x" << videoFormat.fmt.pix.height); return FALSE; } // get the frame size again to be careful about broken drivers - if (::ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { + if (v4l2_ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) { PTRACE(1,"PVidInDev\tG_FMT failed : " << ::strerror(errno)); return FALSE; } @@ -899,7 +924,7 @@ BOOL PVideoInputDevice_V4L2::VerifyHardw } // reset the frame rate because it may have been overridden by the call to S_FMT - if (fi_n == 0 || fi_d == 0 || ::ioctl(videoFd, VIDIOC_S_PARM, &streamParm) < 0) { + if (fi_n == 0 || fi_d == 0 || v4l2_ioctl(videoFd, VIDIOC_S_PARM, &streamParm) < 0) { PTRACE(3,"PVidInDev\tunable to reset frame rate."); } else if (streamParm.parm.capture.timeperframe.numerator != fi_n || streamParm.parm.capture.timeperframe.denominator != fi_d) { @@ -926,13 +951,13 @@ int PVideoInputDevice_V4L2::GetControlCo struct v4l2_queryctrl q; memset(&q, 0, sizeof(struct v4l2_queryctrl)); q.id = control; - if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0) + if (v4l2_ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0) return -1; struct v4l2_control c; memset(&c, 0, sizeof(struct v4l2_control)); c.id = control; - if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0) + if (v4l2_ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0) return -1; *value = ((c.value - q.minimum) * 65536) / ((q.maximum-q.minimum)); @@ -985,7 +1010,7 @@ BOOL PVideoInputDevice_V4L2::SetControlC struct v4l2_queryctrl q; memset(&q, 0, sizeof(struct v4l2_queryctrl)); q.id = control; - if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0) + if (v4l2_ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0) return FALSE; struct v4l2_control c; @@ -996,7 +1021,7 @@ BOOL PVideoInputDevice_V4L2::SetControlC else c.value = q.minimum + ((q.maximum-q.minimum) * newValue)/65535; - if (::ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0) + if (v4l2_ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0) return FALSE; return TRUE; diff -up pwlib-1.10.10/plugins/vidinput_v4l2/Makefile~ pwlib-1.10.10/plugins/vidinput_v4l2/Makefile --- pwlib-1.10.10/plugins/vidinput_v4l2/Makefile~ 2008-07-28 11:07:10.000000000 +0200 +++ pwlib-1.10.10/plugins/vidinput_v4l2/Makefile 2008-07-28 11:07:10.000000000 +0200 @@ -4,7 +4,7 @@ endif PLUGIN_NAME = v4l2 PLUGIN_FAMILY = device/videoinput -PLUGIN_LIBS = vidinput_names.cxx +PLUGIN_LIBS = vidinput_names.cxx -lv4l2 PLUGIN_SOURCES = vidinput_v4l2.cxx include ../../make/plugins.mak