44 #include <visp3/core/vpConfig.h>
52 #include <sys/ioctl.h>
53 #include <sys/types.h>
61 #include <visp3/sensor/vpV4l2Grabber.h>
62 #include <visp3/core/vpFrameGrabberException.h>
64 #include <visp3/core/vpImageConvert.h>
65 #include <visp3/core/vpImageTools.h>
75 #define vpCLEAR(x) memset (&(x), 0, sizeof (x))
150 : fd(-1), device(), cap(), streamparm(), inp(NULL), std(NULL), fmt(NULL), ctl(NULL),
151 fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
152 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
209 : fd(-1), device(), cap(), streamparm(), inp(NULL), std(NULL), fmt(NULL), ctl(NULL),
210 fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
211 waiton_cpt(0), index_buffer(0), m_verbose(verbose), m_nbuffers(3), field(0), streaming(false),
259 : fd(-1), device(), cap(), streamparm(), inp(NULL), std(NULL), fmt(NULL), ctl(NULL),
260 fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
261 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
308 : fd(-1), device(), cap(), streamparm(), inp(NULL), std(NULL), fmt(NULL), ctl(NULL),
309 fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
310 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
360 : fd(-1), device(), cap(), streamparm(), inp(NULL), std(NULL), fmt(NULL), ctl(NULL),
361 fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
362 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
395 this->m_input = input;
413 if ((scale <1) || (scale >16))
417 vpERROR_TRACE(
"Wrong scale %d, scale should be between 1 and 16",scale) ;
441 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
443 std::cout <<
"Warning: cannot set input channel to " << m_input << std::endl;
455 std::cout <<
"Requested pixel format [" << req_pixelformat
456 <<
"] not compatible with camera" << std::endl;
457 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
462 if (format == req_pixelformat) {
470 std::cout <<
"This format [" << m_pixelformat
471 <<
"] is compatible with camera" << std::endl;
477 std::cout <<
"This format [" << m_pixelformat
478 <<
"] is not compatible with camera" << std::endl;
480 std::cout <<
"No pixel format compatible with the camera was found" << std::endl;
484 "No pixel format compatible with the camera was found"));
509 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
511 std::cout <<
"Warning: cannot set input channel to " << m_input << std::endl;
523 std::cout <<
"Requested pixel format [" << m_pixelformat
524 <<
"] not compatible with camera" << std::endl;
525 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
530 if (format == req_pixelformat) {
538 std::cout <<
"This format [" << m_pixelformat
539 <<
"] is compatible with camera" << std::endl;
545 std::cout <<
"This format [" << m_pixelformat
546 <<
"] is not compatible with camera" << std::endl;
570 struct timeval timestamp;
590 struct timeval timestamp;
625 "V4l2 frame grabber not initialized") );
628 unsigned char *bitmap ;
629 bitmap = waiton(index_buffer, timestamp);
635 switch(m_pixelformat) {
680 std::cout <<
"V4L2 conversion not handled" << std::endl;
700 struct timeval timestamp;
720 struct timeval timestamp;
755 "V4l2 frame grabber not initialized") );
758 unsigned char *bitmap ;
759 bitmap = waiton(index_buffer, timestamp);
768 switch(m_pixelformat) {
789 I[height-1][
width-1].A = 0;
792 for(
unsigned int i=0; i<I.
getHeight(); i++) {
817 std::cout <<
"V4l2 conversion not handled" << std::endl;
842 if(field == 2)
return 0;
843 else if (field == 3)
return 1;
848 "V4l2 returns a bad frame field") );
869 this->m_framerate = framerate;
909 if (inp != NULL) {
delete [] inp; inp = NULL; }
910 if (std != NULL) {
delete [] std; std = NULL; }
911 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
912 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
913 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
914 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
929 vpV4l2Grabber::open()
934 if (-1 == stat (device, &st)) {
935 fprintf (stderr,
"Cannot identify '%s': %d, %s\n",
936 device, errno, strerror (errno));
938 "Cannot identify video device") );
942 if (!S_ISCHR (st.st_mode)) {
943 fprintf (stderr,
"%s is no device\n", device);
948 fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
954 "Can't access to video device") );
958 if (inp != NULL) {
delete [] inp; inp = NULL; }
959 if (std != NULL) {
delete [] std; std = NULL; }
960 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
961 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
962 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
963 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
973 if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
975 fprintf (stderr,
"%s is no V4L2 device\n", device);
977 "Is not a V4L2 device") );
980 fprintf(stdout,
"v4l2 info:\n"
982 " %s %d.%d.%d / %s @ %s\n",
985 (cap.version >> 16) & 0xff,
986 (cap.version >> 8) & 0xff,
988 cap.card, cap.bus_info);
989 if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
990 fprintf(stdout,
" Support overlay\n");
992 fprintf(stdout,
" Does not support overlay\n");
993 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
994 fprintf(stdout,
" Support capture\n");
996 fprintf(stdout,
" Does not support capture\n");
997 if (cap.capabilities & V4L2_CAP_TUNER)
998 fprintf(stdout,
" Support tuning\n");
1000 fprintf(stdout,
" Does not support tuning\n");
1001 if (cap.capabilities & V4L2_CAP_STREAMING)
1002 fprintf(stdout,
" Support streaming capture.\n");
1004 fprintf(stdout,
" Does not support streaming capture\n");
1005 if(cap.capabilities & V4L2_CAP_ASYNCIO)
1006 fprintf(stdout,
" Support asynchronous I/O methods\n");
1008 fprintf(stdout,
" Does not support asynchronous I/O methods\n");
1009 if(cap.capabilities & V4L2_CAP_TIMEPERFRAME)
1010 fprintf(stdout,
" Support time per frame field\n");
1012 fprintf(stdout,
" Does not support time per frame field\n");
1014 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1015 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) != -1) {
1016 fprintf(stdout,
" Current acquisition framerate: %d fps\n",
1017 streamparm.parm.output.timeperframe.denominator);
1031 vpV4l2Grabber::getCapabilities()
1033 for (__u32 ninputs = 0; ninputs <
MAX_INPUTS; ninputs++) {
1034 inp[ninputs].index = ninputs;
1035 if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
1038 for (__u32 nstds = 0; nstds <
MAX_NORM; nstds++) {
1039 std[nstds].index = nstds;
1040 if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &std[nstds]))
1044 for (__u32 nfmts = 0; nfmts <
MAX_FORMAT; nfmts++) {
1045 fmt[nfmts].index = nfmts;
1046 fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1047 if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
1051 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1052 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
1057 "Can't get video parameters") );
1075 vpV4l2Grabber::setFormat()
1077 fmt_me.width =
width;
1082 switch(m_pixelformat) {
1085 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
1089 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
1093 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
1097 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
1101 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1108 "Bad format, probably do to a wrong scale"));
1114 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1116 if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1120 "Can't get video format") );
1122 fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
1123 fmt_v4l2.fmt.pix.width = fmt_me.width;
1124 fmt_v4l2.fmt.pix.height = fmt_me.height;
1128 switch (m_frameformat) {
1131 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1136 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1143 "Unrecognized frame format") );
1153 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1155 "Can't set video format") );
1158 if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1160 "Bad pixel format") );
1164 unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1165 if (fmt_v4l2.fmt.pix.bytesperline < min)
1166 fmt_v4l2.fmt.pix.bytesperline = min;
1167 min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1168 if (fmt_v4l2.fmt.pix.sizeimage < min)
1169 fmt_v4l2.fmt.pix.sizeimage = min;
1171 fmt_me.width = fmt_v4l2.fmt.pix.width;
1172 fmt_me.height = fmt_v4l2.fmt.pix.height;
1173 fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1176 fprintf(stdout,
"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1177 fmt_me.width, fmt_me.height,
1178 fmt_v4l2.fmt.pix.pixelformat & 0xff,
1179 (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1180 (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1181 (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1182 fmt_v4l2.fmt.pix.sizeimage,
1183 fmt_v4l2.fmt.pix.bytesperline);
1196 vpV4l2Grabber::startStreaming()
1198 if (streaming ==
true) {
1204 memset (&(reqbufs), 0,
sizeof (reqbufs));
1205 reqbufs.count = m_nbuffers;
1206 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1207 reqbufs.memory = V4L2_MEMORY_MMAP;
1210 if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1212 if (EINVAL == errno) {
1213 fprintf (stderr,
"%s does not support "
1214 "memory mapping\n", device);
1216 "Does not support memory mapping") );
1219 "Can't require video buffers") );
1222 for (
unsigned i = 0; i < reqbufs.count; i++) {
1224 memset (&(buf_v4l2[i]), 0,
sizeof (buf_v4l2[i]));
1225 buf_v4l2[i].index = i;
1226 buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1227 buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1228 buf_v4l2[i].length = 0;
1229 if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1232 "Can't query video buffers") );
1234 memcpy(&buf_me[i].fmt, &fmt_me,
sizeof(ng_video_fmt));
1235 buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1243 buf_me[i].data = (
unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1244 PROT_READ | PROT_WRITE,
1246 fd, (off_t)buf_v4l2[i].m.offset);
1248 if(buf_me[i].data == MAP_FAILED)
1251 "Can't map memory") );
1254 buf_me[i].refcount = 0;
1265 printBufInfo(buf_v4l2[i]);
1272 if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1275 "Can't start streaming") );
1288 vpV4l2Grabber::stopStreaming()
1291 if ((fd >= 0) && (streaming ==
true)) {
1295 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1296 if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1298 "Can't stop streaming") );
1301 for (
unsigned int i = 0; i < reqbufs.count; i++) {
1303 printBufInfo(buf_v4l2[i]);
1306 if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1308 "Can't unmap memory") );
1331 vpV4l2Grabber::waiton(__u32 &index,
struct timeval ×tamp)
1333 struct v4l2_buffer buf;
1343 FD_SET(static_cast<unsigned int>(fd), &rdset);
1344 switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1350 "Can't access to the frame") );
1355 "Can't access to the frame: timeout") );
1361 memset(&buf, 0,
sizeof(buf));
1362 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1363 buf.memory = V4L2_MEMORY_MMAP;
1364 if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1370 "VIDIOC_DQBUF: EAGAIN") );
1374 "VIDIOC_DQBUF: EINVAL") );
1378 "VIDIOC_DQBUF: ENOMEM") );
1389 buf_v4l2[buf.index] = buf;
1393 field = buf_v4l2[index].field;
1395 timestamp = buf_v4l2[index].timestamp;
1403 return buf_me[buf.index].data;
1412 vpV4l2Grabber::queueBuffer()
1414 unsigned int frame = queue % reqbufs.count;
1418 if (0 != buf_me[frame].refcount) {
1419 if (0 != queue - waiton_cpt)
1421 fprintf(stderr,
"v4l2: waiting for a free buffer..............\n");
1423 std::cout <<
"Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1427 rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1436 "VIDIOC_QBUF: EAGAIN") );
1440 "VIDIOC_QBUF: EINVAL") );
1444 "VIDIOC_QBUF: ENOMEM") );
1461 vpV4l2Grabber::queueAll()
1464 if (queue - waiton_cpt >= reqbufs.count) {
1467 if (0 != queueBuffer()) {
1479 vpV4l2Grabber::printBufInfo(
struct v4l2_buffer buf)
1484 case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type,
"video-cap");
break;
1485 case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type,
"video-over");
break;
1486 case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type,
"video-out");
break;
1487 case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type,
"vbi-cap");
break;
1488 case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type,
"vbi-out");
break;
1489 default: sprintf(type,
"unknown");
break;
1492 fprintf(stdout,
"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1493 buf.index, buf.type, buf.m.userptr, buf.m.offset,
1494 buf.length, buf.length, buf.bytesused);
1542 #elif !defined(VISP_BUILD_SHARED_LIBS)
1544 void dummy_vpV4l2Grabber() {};
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static const unsigned int MAX_CTRL
void acquire(vpImage< unsigned char > &I)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
void open(vpImage< unsigned char > &I)
static const __u32 MAX_FORMAT
unsigned int getWidth() const
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
vpV4l2FramerateType getFramerate()
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
Type * bitmap
points toward the bitmap
void setDevice(const std::string &devname)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
vpV4l2PixelFormatType getPixelFormat()
static const unsigned int DEFAULT_INPUT
Error that can be emited by the vpFrameGrabber class and its derivates.
vpV4l2Grabber & operator>>(vpImage< unsigned char > &I)
static const unsigned int FRAME_SIZE
void setHeight(unsigned h)
unsigned int height
Number of rows in the image.
static void YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
static const __u32 MAX_INPUTS
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
void setWidth(unsigned w)
static const __u32 MAX_NORM
void setScale(unsigned scale=vpV4l2Grabber::DEFAULT_SCALE)
void setInput(unsigned input=vpV4l2Grabber::DEFAULT_INPUT)
bool init
Set to true if the frame grabber has been initialized.
Class that is a wrapper over the Video4Linux2 (V4L2) driver.
unsigned int getHeight() const
Defines a rectangle in the plane.
void setNBuffers(unsigned nbuffers)
unsigned int width
Number of columns in the image.
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
void setPixelFormat(vpV4l2PixelFormatType pixelformat)
static const unsigned int DEFAULT_SCALE
static const unsigned int MAX_BUFFERS
void setFramerate(vpV4l2FramerateType framerate)