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 should 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;
622 "V4l2 frame grabber not initialized") );
625 unsigned char *bitmap ;
626 bitmap = waiton(index_buffer, timestamp);
631 switch(pixelformat) {
652 std::cout <<
"V4L2 conversion not handled" << std::endl;
672 struct timeval timestamp;
703 "V4l2 frame grabber not initialized") );
706 unsigned char *bitmap ;
707 bitmap = waiton(index_buffer, timestamp);
714 switch(pixelformat) {
726 I[height-1][
width-1].A = 0;
735 std::cout <<
"V4l2 conversion not handled" << std::endl;
760 if(field == 2)
return 0;
761 else if (field == 3)
return 1;
766 "V4l2 returns a bad frame field") );
787 this->framerate = framerate;
827 if (inp != NULL) {
delete [] inp; inp = NULL; }
828 if (
std != NULL) {
delete []
std;
std = NULL; }
829 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
830 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
831 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
832 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
847 vpV4l2Grabber::open()
852 if (-1 == stat (device, &st)) {
853 fprintf (stderr,
"Cannot identify '%s': %d, %s\n",
854 device, errno, strerror (errno));
856 "Cannot identify video device") );
860 if (!S_ISCHR (st.st_mode)) {
861 fprintf (stderr,
"%s is no device\n", device);
866 fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
872 "Can't access to video device") );
876 if (inp != NULL) {
delete [] inp; inp = NULL; }
877 if (
std != NULL) {
delete []
std;
std = NULL; }
878 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
879 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
880 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
881 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
891 if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
893 fprintf (stderr,
"%s is no V4L2 device\n", device);
895 "Is not a V4L2 device") );
898 fprintf(stdout,
"v4l2 info:\n"
900 " %s %d.%d.%d / %s @ %s\n",
903 (cap.version >> 16) & 0xff,
904 (cap.version >> 8) & 0xff,
906 cap.card, cap.bus_info);
907 if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
908 fprintf(stdout,
" Support overlay\n");
910 fprintf(stdout,
" Does not support overlay\n");
911 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
912 fprintf(stdout,
" Support capture\n");
914 fprintf(stdout,
" Does not support capture\n");
915 if (cap.capabilities & V4L2_CAP_TUNER)
916 fprintf(stdout,
" Support tuning\n");
918 fprintf(stdout,
" Does not support tuning\n");
919 if (cap.capabilities & V4L2_CAP_STREAMING)
920 fprintf(stdout,
" Support streaming capture.\n");
922 fprintf(stdout,
" Does not support streaming capture.\n");
923 if(cap.capabilities & V4L2_CAP_ASYNCIO)
924 fprintf(stdout,
" Support asynchronous I/O methods.\n");
926 fprintf(stdout,
" Does not support asynchronous I/O methods.\n");
939 vpV4l2Grabber::getCapabilities()
941 for (__u32 ninputs = 0; ninputs <
MAX_INPUTS; ninputs++) {
942 inp[ninputs].index = ninputs;
943 if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
946 for (__u32 nstds = 0; nstds <
MAX_NORM; nstds++) {
947 std[nstds].index = nstds;
948 if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &
std[nstds]))
952 for (__u32 nfmts = 0; nfmts <
MAX_FORMAT; nfmts++) {
953 fmt[nfmts].index = nfmts;
954 fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
955 if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
959 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
965 "Can't get video parameters") );
983 vpV4l2Grabber::setFormat()
985 fmt_me.width = _width;
986 fmt_me.height = _height;
990 switch(pixelformat) {
993 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
997 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
1001 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
1005 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
1009 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1016 "Bad format, probably do to a wrong scale"));
1022 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1024 if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1028 "Can't get video format") );
1030 fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
1031 fmt_v4l2.fmt.pix.width = fmt_me.width;
1032 fmt_v4l2.fmt.pix.height = fmt_me.height;
1036 switch (frameformat) {
1039 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1044 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1051 "Unrecognized frame format") );
1063 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1065 "Can't set video format") );
1068 if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1070 "Bad pixel format") );
1074 unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1075 if (fmt_v4l2.fmt.pix.bytesperline < min)
1076 fmt_v4l2.fmt.pix.bytesperline = min;
1077 min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1078 if (fmt_v4l2.fmt.pix.sizeimage < min)
1079 fmt_v4l2.fmt.pix.sizeimage = min;
1081 fmt_me.width = fmt_v4l2.fmt.pix.width;
1082 fmt_me.height = fmt_v4l2.fmt.pix.height;
1083 fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1086 fprintf(stdout,
"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1087 fmt_me.width, fmt_me.height,
1088 fmt_v4l2.fmt.pix.pixelformat & 0xff,
1089 (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1090 (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1091 (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1092 fmt_v4l2.fmt.pix.sizeimage,
1093 fmt_v4l2.fmt.pix.bytesperline);
1106 vpV4l2Grabber::startStreaming()
1108 if (streaming ==
true) {
1114 memset (&(reqbufs), 0,
sizeof (reqbufs));
1115 reqbufs.count = nbuffers;
1116 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1117 reqbufs.memory = V4L2_MEMORY_MMAP;
1120 if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1122 if (EINVAL == errno) {
1123 fprintf (stderr,
"%s does not support "
1124 "memory mapping\n", device);
1126 "Does not support memory mapping") );
1129 "Can't require video buffers") );
1132 for (
unsigned i = 0; i < reqbufs.count; i++) {
1134 memset (&(buf_v4l2[i]), 0,
sizeof (buf_v4l2[i]));
1135 buf_v4l2[i].index = i;
1136 buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1137 buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1138 buf_v4l2[i].length = 0;
1139 if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1142 "Can't query video buffers") );
1144 memcpy(&buf_me[i].fmt, &fmt_me,
sizeof(ng_video_fmt));
1145 buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1153 buf_me[i].data = (
unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1154 PROT_READ | PROT_WRITE,
1156 fd, (off_t)buf_v4l2[i].m.offset);
1158 if(buf_me[i].data == MAP_FAILED)
1161 "Can't map memory") );
1164 buf_me[i].refcount = 0;
1175 printBufInfo(buf_v4l2[i]);
1182 if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1185 "Can't start streaming") );
1198 vpV4l2Grabber::stopStreaming()
1203 if ((fd >= 0) && (streaming ==
true)) {
1207 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1208 if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1210 "Can't stop streaming") );
1213 for (i = 0; i < reqbufs.count; i++) {
1215 printBufInfo(buf_v4l2[i]);
1218 if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1220 "Can't unmap memory") );
1243 vpV4l2Grabber::waiton(__u32 &index,
struct timeval ×tamp)
1245 struct v4l2_buffer buf;
1255 FD_SET(static_cast<unsigned int>(fd), &rdset);
1256 switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1262 "Can't access to the frame") );
1267 "Can't access to the frame: timeout") );
1273 memset(&buf, 0,
sizeof(buf));
1274 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1275 buf.memory = V4L2_MEMORY_MMAP;
1276 if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1282 "VIDIOC_DQBUF: EAGAIN") );
1286 "VIDIOC_DQBUF: EINVAL") );
1290 "VIDIOC_DQBUF: ENOMEM") );
1301 buf_v4l2[buf.index] = buf;
1305 field = buf_v4l2[index].field;
1307 timestamp = buf_v4l2[index].timestamp;
1315 return buf_me[buf.index].data;
1324 vpV4l2Grabber::queueBuffer()
1326 unsigned int frame = queue % reqbufs.count;
1330 if (0 != buf_me[frame].refcount) {
1331 if (0 != queue - waiton_cpt)
1333 fprintf(stderr,
"v4l2: waiting for a free buffer..............\n");
1335 std::cout <<
"Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1339 rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1348 "VIDIOC_QBUF: EAGAIN") );
1352 "VIDIOC_QBUF: EINVAL") );
1356 "VIDIOC_QBUF: ENOMEM") );
1373 vpV4l2Grabber::queueAll()
1376 if (queue - waiton_cpt >= reqbufs.count) {
1379 if (0 != queueBuffer()) {
1391 vpV4l2Grabber::printBufInfo(
struct v4l2_buffer buf)
1396 case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type,
"video-cap");
break;
1397 case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type,
"video-over");
break;
1398 case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type,
"video-out");
break;
1399 case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type,
"vbi-cap");
break;
1400 case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type,
"vbi-out");
break;
1401 default: sprintf(type,
"unknown");
break;
1404 fprintf(stdout,
"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1405 buf.index, buf.type, buf.m.userptr, buf.m.offset,
1406 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)