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");
927 if(cap.capabilities & V4L2_CAP_TIMEPERFRAME)
928 fprintf(stdout,
" Support time per frame field\n");
930 fprintf(stdout,
" Does not support time per frame field\n");
932 struct v4l2_streamparm streamparm;
933 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
934 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) != -1) {
935 fprintf(stdout,
" Current acquisition framerate: %d fps\n",
936 streamparm.parm.output.timeperframe.denominator);
950 vpV4l2Grabber::getCapabilities()
952 for (__u32 ninputs = 0; ninputs <
MAX_INPUTS; ninputs++) {
953 inp[ninputs].index = ninputs;
954 if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
957 for (__u32 nstds = 0; nstds <
MAX_NORM; nstds++) {
958 std[nstds].index = nstds;
959 if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &
std[nstds]))
963 for (__u32 nfmts = 0; nfmts <
MAX_FORMAT; nfmts++) {
964 fmt[nfmts].index = nfmts;
965 fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
966 if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
970 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
971 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
976 "Can't get video parameters") );
994 vpV4l2Grabber::setFormat()
996 fmt_me.width = _width;
997 fmt_me.height = _height;
1001 switch(pixelformat) {
1004 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
1008 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
1012 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
1016 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
1020 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1027 "Bad format, probably do to a wrong scale"));
1033 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1035 if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1039 "Can't get video format") );
1041 fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
1042 fmt_v4l2.fmt.pix.width = fmt_me.width;
1043 fmt_v4l2.fmt.pix.height = fmt_me.height;
1047 switch (frameformat) {
1050 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1055 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1062 "Unrecognized frame format") );
1074 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1076 "Can't set video format") );
1079 if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1081 "Bad pixel format") );
1085 unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1086 if (fmt_v4l2.fmt.pix.bytesperline < min)
1087 fmt_v4l2.fmt.pix.bytesperline = min;
1088 min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1089 if (fmt_v4l2.fmt.pix.sizeimage < min)
1090 fmt_v4l2.fmt.pix.sizeimage = min;
1092 fmt_me.width = fmt_v4l2.fmt.pix.width;
1093 fmt_me.height = fmt_v4l2.fmt.pix.height;
1094 fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1097 fprintf(stdout,
"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1098 fmt_me.width, fmt_me.height,
1099 fmt_v4l2.fmt.pix.pixelformat & 0xff,
1100 (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1101 (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1102 (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1103 fmt_v4l2.fmt.pix.sizeimage,
1104 fmt_v4l2.fmt.pix.bytesperline);
1117 vpV4l2Grabber::startStreaming()
1119 if (streaming ==
true) {
1125 memset (&(reqbufs), 0,
sizeof (reqbufs));
1126 reqbufs.count = nbuffers;
1127 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1128 reqbufs.memory = V4L2_MEMORY_MMAP;
1131 if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1133 if (EINVAL == errno) {
1134 fprintf (stderr,
"%s does not support "
1135 "memory mapping\n", device);
1137 "Does not support memory mapping") );
1140 "Can't require video buffers") );
1143 for (
unsigned i = 0; i < reqbufs.count; i++) {
1145 memset (&(buf_v4l2[i]), 0,
sizeof (buf_v4l2[i]));
1146 buf_v4l2[i].index = i;
1147 buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1148 buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1149 buf_v4l2[i].length = 0;
1150 if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1153 "Can't query video buffers") );
1155 memcpy(&buf_me[i].fmt, &fmt_me,
sizeof(ng_video_fmt));
1156 buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1164 buf_me[i].data = (
unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1165 PROT_READ | PROT_WRITE,
1167 fd, (off_t)buf_v4l2[i].m.offset);
1169 if(buf_me[i].data == MAP_FAILED)
1172 "Can't map memory") );
1175 buf_me[i].refcount = 0;
1186 printBufInfo(buf_v4l2[i]);
1193 if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1196 "Can't start streaming") );
1209 vpV4l2Grabber::stopStreaming()
1214 if ((fd >= 0) && (streaming ==
true)) {
1218 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1219 if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1221 "Can't stop streaming") );
1224 for (i = 0; i < reqbufs.count; i++) {
1226 printBufInfo(buf_v4l2[i]);
1229 if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1231 "Can't unmap memory") );
1254 vpV4l2Grabber::waiton(__u32 &index,
struct timeval ×tamp)
1256 struct v4l2_buffer buf;
1266 FD_SET(static_cast<unsigned int>(fd), &rdset);
1267 switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1273 "Can't access to the frame") );
1278 "Can't access to the frame: timeout") );
1284 memset(&buf, 0,
sizeof(buf));
1285 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1286 buf.memory = V4L2_MEMORY_MMAP;
1287 if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1293 "VIDIOC_DQBUF: EAGAIN") );
1297 "VIDIOC_DQBUF: EINVAL") );
1301 "VIDIOC_DQBUF: ENOMEM") );
1312 buf_v4l2[buf.index] = buf;
1316 field = buf_v4l2[index].field;
1318 timestamp = buf_v4l2[index].timestamp;
1326 return buf_me[buf.index].data;
1335 vpV4l2Grabber::queueBuffer()
1337 unsigned int frame = queue % reqbufs.count;
1341 if (0 != buf_me[frame].refcount) {
1342 if (0 != queue - waiton_cpt)
1344 fprintf(stderr,
"v4l2: waiting for a free buffer..............\n");
1346 std::cout <<
"Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1350 rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1359 "VIDIOC_QBUF: EAGAIN") );
1363 "VIDIOC_QBUF: EINVAL") );
1367 "VIDIOC_QBUF: ENOMEM") );
1384 vpV4l2Grabber::queueAll()
1387 if (queue - waiton_cpt >= reqbufs.count) {
1390 if (0 != queueBuffer()) {
1402 vpV4l2Grabber::printBufInfo(
struct v4l2_buffer buf)
1407 case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type,
"video-cap");
break;
1408 case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type,
"video-over");
break;
1409 case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type,
"video-out");
break;
1410 case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type,
"vbi-cap");
break;
1411 case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type,
"vbi-out");
break;
1412 default: sprintf(type,
"unknown");
break;
1415 fprintf(stdout,
"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1416 buf.index, buf.type, buf.m.userptr, buf.m.offset,
1417 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 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
void resize(const unsigned int h, const unsigned int w)
set the size of the image
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)