48 #include <visp/vpConfig.h>
56 #include <sys/ioctl.h>
57 #include <sys/types.h>
65 #include <visp/vpV4l2Grabber.h>
66 #include <visp/vpFrameGrabberException.h>
67 #include <visp/vpImageIo.h>
77 #define vpCLEAR(x) memset (&(x), 0, sizeof (x))
190 this->verbose = verbose;
306 unsigned input,
unsigned scale )
432 if ((scale <1) || (scale >16))
436 vpERROR_TRACE(
"Wrong scale %d, scale shoud be between 1 and 16",scale) ;
460 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &input) == -1 )
462 std::cout <<
"Warning: cannot set input channel to " << input << std::endl;
474 std::cout <<
"Requested pixel format [" << req_pixelformat
475 <<
"] not compatible with camera" << std::endl;
476 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
481 if (format == req_pixelformat) {
489 std::cout <<
"This format [" << pixelformat
490 <<
"] is compatible with camera" << std::endl;
496 std::cout <<
"This format [" << pixelformat
497 <<
"] is not compatible with camera" << std::endl;
499 std::cout <<
"No pixel format compatible with the camera was found" << std::endl;
503 "No pixel format compatible with the camera was found"));
528 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &input) == -1 )
530 std::cout <<
"Warning: cannot set input channel to " << input << std::endl;
542 std::cout <<
"Requested pixel format [" << pixelformat
543 <<
"] not compatible with camera" << std::endl;
544 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
549 if (format == req_pixelformat) {
557 std::cout <<
"This format [" << pixelformat
558 <<
"] is compatible with camera" << std::endl;
564 std::cout <<
"This format [" << pixelformat
565 <<
"] is not compatible with camera" << std::endl;
591 struct timeval timestamp;
618 "V4l2 frame grabber not initialized") );
621 unsigned char *bitmap ;
622 bitmap = waiton(index_buffer, timestamp);
627 switch(pixelformat) {
648 std::cout <<
"V4L2 conversion not handled" << std::endl;
668 struct timeval timestamp;
695 "V4l2 frame grabber not initialized") );
698 unsigned char *bitmap ;
699 bitmap = waiton(index_buffer, timestamp);
706 switch(pixelformat) {
718 I[height-1][
width-1].A = 0;
727 std::cout <<
"V4l2 conversion not handled" << std::endl;
752 if(field == 2)
return 0;
753 else if (field == 3)
return 1;
758 "V4l2 returns a bad frame field") );
779 this->framerate = framerate;
819 if (inp != NULL) {
delete [] inp; inp = NULL; }
820 if (
std != NULL) {
delete []
std;
std = NULL; }
821 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
822 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
823 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
824 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
839 vpV4l2Grabber::open()
844 if (-1 == stat (device, &st)) {
845 fprintf (stderr,
"Cannot identify '%s': %d, %s\n",
846 device, errno, strerror (errno));
848 "Cannot identify video device") );
852 if (!S_ISCHR (st.st_mode)) {
853 fprintf (stderr,
"%s is no device\n", device);
858 fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
864 "Can't access to video device") );
868 if (inp != NULL) {
delete [] inp; inp = NULL; }
869 if (
std != NULL) {
delete []
std;
std = NULL; }
870 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
871 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
872 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
873 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
883 if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
885 fprintf (stderr,
"%s is no V4L2 device\n", device);
887 "Is not a V4L2 device") );
890 fprintf(stdout,
"v4l2 info:\n"
892 " %s %d.%d.%d / %s @ %s\n",
895 (cap.version >> 16) & 0xff,
896 (cap.version >> 8) & 0xff,
898 cap.card, cap.bus_info);
899 if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
900 fprintf(stdout,
" Support overlay\n");
902 fprintf(stdout,
" Does not support overlay\n");
903 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
904 fprintf(stdout,
" Support capture\n");
906 fprintf(stdout,
" Does not support capture\n");
907 if (cap.capabilities & V4L2_CAP_TUNER)
908 fprintf(stdout,
" Support tuning\n");
910 fprintf(stdout,
" Does not support tuning\n");
911 if (cap.capabilities & V4L2_CAP_STREAMING)
912 fprintf(stdout,
" Support streaming capture.\n");
914 fprintf(stdout,
" Does not support streaming capture.\n");
915 if(cap.capabilities & V4L2_CAP_ASYNCIO)
916 fprintf(stdout,
" Support asynchronous I/O methods.\n");
918 fprintf(stdout,
" Does not support asynchronous I/O methods.\n");
931 vpV4l2Grabber::getCapabilities()
933 for (__u32 ninputs = 0; ninputs <
MAX_INPUTS; ninputs++) {
934 inp[ninputs].index = ninputs;
935 if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
938 for (__u32 nstds = 0; nstds <
MAX_NORM; nstds++) {
939 std[nstds].index = nstds;
940 if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &
std[nstds]))
944 for (__u32 nfmts = 0; nfmts <
MAX_FORMAT; nfmts++) {
945 fmt[nfmts].index = nfmts;
946 fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
947 if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
951 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
952 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
957 "Can't get video parameters") );
975 vpV4l2Grabber::setFormat()
977 fmt_me.width = _width;
978 fmt_me.height = _height;
982 switch(pixelformat) {
985 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
989 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
993 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
997 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
1001 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1008 "Bad format, probably do to a wrong scale"));
1014 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1016 if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1020 "Can't get video format") );
1022 fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
1023 fmt_v4l2.fmt.pix.width = fmt_me.width;
1024 fmt_v4l2.fmt.pix.height = fmt_me.height;
1028 switch (frameformat) {
1031 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1036 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1043 "Unrecognized frame format") );
1055 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1057 "Can't set video format") );
1060 if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1062 "Bad pixel format") );
1066 unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1067 if (fmt_v4l2.fmt.pix.bytesperline < min)
1068 fmt_v4l2.fmt.pix.bytesperline = min;
1069 min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1070 if (fmt_v4l2.fmt.pix.sizeimage < min)
1071 fmt_v4l2.fmt.pix.sizeimage = min;
1073 fmt_me.width = fmt_v4l2.fmt.pix.width;
1074 fmt_me.height = fmt_v4l2.fmt.pix.height;
1075 fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1078 fprintf(stdout,
"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1079 fmt_me.width, fmt_me.height,
1080 fmt_v4l2.fmt.pix.pixelformat & 0xff,
1081 (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1082 (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1083 (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1084 fmt_v4l2.fmt.pix.sizeimage,
1085 fmt_v4l2.fmt.pix.bytesperline);
1098 vpV4l2Grabber::startStreaming()
1100 if (streaming ==
true) {
1106 memset (&(reqbufs), 0,
sizeof (reqbufs));
1107 reqbufs.count = nbuffers;
1108 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1109 reqbufs.memory = V4L2_MEMORY_MMAP;
1112 if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1114 if (EINVAL == errno) {
1115 fprintf (stderr,
"%s does not support "
1116 "memory mapping\n", device);
1118 "Does not support memory mapping") );
1121 "Can't require video buffers") );
1124 for (
unsigned i = 0; i < reqbufs.count; i++) {
1126 memset (&(buf_v4l2[i]), 0,
sizeof (buf_v4l2[i]));
1127 buf_v4l2[i].index = i;
1128 buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1129 buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1130 buf_v4l2[i].length = 0;
1131 if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1134 "Can't query video buffers") );
1136 memcpy(&buf_me[i].fmt, &fmt_me,
sizeof(ng_video_fmt));
1137 buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1145 buf_me[i].data = (
unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1146 PROT_READ | PROT_WRITE,
1148 fd, (off_t)buf_v4l2[i].m.offset);
1150 if(buf_me[i].data == MAP_FAILED)
1153 "Can't map memory") );
1156 buf_me[i].refcount = 0;
1167 printBufInfo(buf_v4l2[i]);
1174 if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1177 "Can't start streaming") );
1190 vpV4l2Grabber::stopStreaming()
1195 if ((fd >= 0) && (streaming ==
true)) {
1199 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1200 if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1202 "Can't stop streaming") );
1205 for (i = 0; i < reqbufs.count; i++) {
1207 printBufInfo(buf_v4l2[i]);
1210 if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1212 "Can't unmap memory") );
1235 vpV4l2Grabber::waiton(__u32 &index,
struct timeval ×tamp)
1237 struct v4l2_buffer buf;
1247 FD_SET(static_cast<unsigned int>(fd), &rdset);
1248 switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1254 "Can't access to the frame") );
1259 "Can't access to the frame: timeout") );
1265 memset(&buf, 0,
sizeof(buf));
1266 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1267 buf.memory = V4L2_MEMORY_MMAP;
1268 if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1274 "VIDIOC_DQBUF: EAGAIN") );
1278 "VIDIOC_DQBUF: EINVAL") );
1282 "VIDIOC_DQBUF: ENOMEM") );
1293 buf_v4l2[buf.index] = buf;
1297 field = buf_v4l2[index].field;
1299 timestamp = buf_v4l2[index].timestamp;
1307 return buf_me[buf.index].data;
1316 vpV4l2Grabber::queueBuffer()
1318 unsigned int frame = queue % reqbufs.count;
1322 if (0 != buf_me[frame].refcount) {
1323 if (0 != queue - waiton_cpt)
1325 fprintf(stderr,
"v4l2: waiting for a free buffer..............\n");
1327 std::cout <<
"Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1331 rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1340 "VIDIOC_QBUF: EAGAIN") );
1344 "VIDIOC_QBUF: EINVAL") );
1348 "VIDIOC_QBUF: ENOMEM") );
1365 vpV4l2Grabber::queueAll()
1368 if (queue - waiton_cpt >= reqbufs.count) {
1371 if (0 != queueBuffer()) {
1383 vpV4l2Grabber::printBufInfo(
struct v4l2_buffer buf)
1388 case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type,
"video-cap");
break;
1389 case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type,
"video-over");
break;
1390 case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type,
"video-out");
break;
1391 case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type,
"vbi-cap");
break;
1392 case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type,
"vbi-out");
break;
1393 default: sprintf(type,
"unknown");
break;
1396 fprintf(stdout,
"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1397 buf.index, buf.type, buf.m.userptr, buf.m.offset,
1398 buf.length, buf.length, buf.bytesused);
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()
Type * bitmap
points toward the bitmap
void resize(const unsigned int height, const unsigned int width)
set the size of the image
void setWidth(unsigned width)
void setDevice(const char *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.
Class that defines a RGB 32 bits structure.
void setHeight(unsigned height)
static const unsigned int FRAME_SIZE
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
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 for the Video4Linux2 video device.
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip)
unsigned int getHeight() const
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 void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip)
static const unsigned int DEFAULT_SCALE
static const unsigned int MAX_BUFFERS
void setFramerate(vpV4l2FramerateType framerate)