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>
74 #define vpCLEAR(x) memset (&(x), 0, sizeof (x))
115 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
116 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
117 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
174 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
175 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
176 waiton_cpt(0), index_buffer(0), m_verbose(verbose), m_nbuffers(3), field(0), streaming(false),
224 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
225 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
226 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
273 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
274 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
275 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
325 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
326 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
327 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
360 this->m_input = input;
378 if ((scale <1) || (scale >16))
382 vpERROR_TRACE(
"Wrong scale %d, scale should be between 1 and 16",scale) ;
406 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
408 std::cout <<
"Warning: cannot set input channel to " << m_input << std::endl;
420 std::cout <<
"Requested pixel format [" << req_pixelformat
421 <<
"] not compatible with camera" << std::endl;
422 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
427 if (format == req_pixelformat) {
435 std::cout <<
"This format [" << m_pixelformat
436 <<
"] is compatible with camera" << std::endl;
442 std::cout <<
"This format [" << m_pixelformat
443 <<
"] is not compatible with camera" << std::endl;
445 std::cout <<
"No pixel format compatible with the camera was found" << std::endl;
449 "No pixel format compatible with the camera was found"));
474 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
476 std::cout <<
"Warning: cannot set input channel to " << m_input << std::endl;
488 std::cout <<
"Requested pixel format [" << m_pixelformat
489 <<
"] not compatible with camera" << std::endl;
490 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
495 if (format == req_pixelformat) {
503 std::cout <<
"This format [" << m_pixelformat
504 <<
"] is compatible with camera" << std::endl;
510 std::cout <<
"This format [" << m_pixelformat
511 <<
"] is not compatible with camera" << std::endl;
537 struct timeval timestamp;
568 "V4l2 frame grabber not initialized") );
571 unsigned char *bitmap ;
572 bitmap = waiton(index_buffer, timestamp);
577 switch(m_pixelformat) {
598 std::cout <<
"V4L2 conversion not handled" << std::endl;
618 struct timeval timestamp;
649 "V4l2 frame grabber not initialized") );
652 unsigned char *bitmap ;
653 bitmap = waiton(index_buffer, timestamp);
660 switch(m_pixelformat) {
672 I[height-1][
width-1].A = 0;
681 std::cout <<
"V4l2 conversion not handled" << std::endl;
706 if(field == 2)
return 0;
707 else if (field == 3)
return 1;
712 "V4l2 returns a bad frame field") );
733 this->m_framerate = framerate;
773 if (inp != NULL) {
delete [] inp; inp = NULL; }
774 if (
std != NULL) {
delete []
std;
std = NULL; }
775 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
776 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
777 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
778 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
793 vpV4l2Grabber::open()
798 if (-1 == stat (device, &st)) {
799 fprintf (stderr,
"Cannot identify '%s': %d, %s\n",
800 device, errno, strerror (errno));
802 "Cannot identify video device") );
806 if (!S_ISCHR (st.st_mode)) {
807 fprintf (stderr,
"%s is no device\n", device);
812 fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
818 "Can't access to video device") );
822 if (inp != NULL) {
delete [] inp; inp = NULL; }
823 if (
std != NULL) {
delete []
std;
std = NULL; }
824 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
825 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
826 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
827 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
837 if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
839 fprintf (stderr,
"%s is no V4L2 device\n", device);
841 "Is not a V4L2 device") );
844 fprintf(stdout,
"v4l2 info:\n"
846 " %s %d.%d.%d / %s @ %s\n",
849 (cap.version >> 16) & 0xff,
850 (cap.version >> 8) & 0xff,
852 cap.card, cap.bus_info);
853 if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
854 fprintf(stdout,
" Support overlay\n");
856 fprintf(stdout,
" Does not support overlay\n");
857 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
858 fprintf(stdout,
" Support capture\n");
860 fprintf(stdout,
" Does not support capture\n");
861 if (cap.capabilities & V4L2_CAP_TUNER)
862 fprintf(stdout,
" Support tuning\n");
864 fprintf(stdout,
" Does not support tuning\n");
865 if (cap.capabilities & V4L2_CAP_STREAMING)
866 fprintf(stdout,
" Support streaming capture.\n");
868 fprintf(stdout,
" Does not support streaming capture\n");
869 if(cap.capabilities & V4L2_CAP_ASYNCIO)
870 fprintf(stdout,
" Support asynchronous I/O methods\n");
872 fprintf(stdout,
" Does not support asynchronous I/O methods\n");
873 if(cap.capabilities & V4L2_CAP_TIMEPERFRAME)
874 fprintf(stdout,
" Support time per frame field\n");
876 fprintf(stdout,
" Does not support time per frame field\n");
878 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
879 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) != -1) {
880 fprintf(stdout,
" Current acquisition framerate: %d fps\n",
881 streamparm.parm.output.timeperframe.denominator);
895 vpV4l2Grabber::getCapabilities()
897 for (__u32 ninputs = 0; ninputs <
MAX_INPUTS; ninputs++) {
898 inp[ninputs].index = ninputs;
899 if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
902 for (__u32 nstds = 0; nstds <
MAX_NORM; nstds++) {
903 std[nstds].index = nstds;
904 if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &
std[nstds]))
908 for (__u32 nfmts = 0; nfmts <
MAX_FORMAT; nfmts++) {
909 fmt[nfmts].index = nfmts;
910 fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
911 if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
915 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
916 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
921 "Can't get video parameters") );
939 vpV4l2Grabber::setFormat()
941 fmt_me.width =
width;
946 switch(m_pixelformat) {
949 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
953 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
957 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
961 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
965 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
972 "Bad format, probably do to a wrong scale"));
978 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
980 if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
984 "Can't get video format") );
986 fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
987 fmt_v4l2.fmt.pix.width = fmt_me.width;
988 fmt_v4l2.fmt.pix.height = fmt_me.height;
992 switch (m_frameformat) {
995 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1000 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1007 "Unrecognized frame format") );
1017 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1019 "Can't set video format") );
1022 if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1024 "Bad pixel format") );
1028 unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1029 if (fmt_v4l2.fmt.pix.bytesperline < min)
1030 fmt_v4l2.fmt.pix.bytesperline = min;
1031 min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1032 if (fmt_v4l2.fmt.pix.sizeimage < min)
1033 fmt_v4l2.fmt.pix.sizeimage = min;
1035 fmt_me.width = fmt_v4l2.fmt.pix.width;
1036 fmt_me.height = fmt_v4l2.fmt.pix.height;
1037 fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1040 fprintf(stdout,
"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1041 fmt_me.width, fmt_me.height,
1042 fmt_v4l2.fmt.pix.pixelformat & 0xff,
1043 (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1044 (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1045 (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1046 fmt_v4l2.fmt.pix.sizeimage,
1047 fmt_v4l2.fmt.pix.bytesperline);
1060 vpV4l2Grabber::startStreaming()
1062 if (streaming ==
true) {
1068 memset (&(reqbufs), 0,
sizeof (reqbufs));
1069 reqbufs.count = m_nbuffers;
1070 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1071 reqbufs.memory = V4L2_MEMORY_MMAP;
1074 if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1076 if (EINVAL == errno) {
1077 fprintf (stderr,
"%s does not support "
1078 "memory mapping\n", device);
1080 "Does not support memory mapping") );
1083 "Can't require video buffers") );
1086 for (
unsigned i = 0; i < reqbufs.count; i++) {
1088 memset (&(buf_v4l2[i]), 0,
sizeof (buf_v4l2[i]));
1089 buf_v4l2[i].index = i;
1090 buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1091 buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1092 buf_v4l2[i].length = 0;
1093 if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1096 "Can't query video buffers") );
1098 memcpy(&buf_me[i].fmt, &fmt_me,
sizeof(ng_video_fmt));
1099 buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1107 buf_me[i].data = (
unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1108 PROT_READ | PROT_WRITE,
1110 fd, (off_t)buf_v4l2[i].m.offset);
1112 if(buf_me[i].data == MAP_FAILED)
1115 "Can't map memory") );
1118 buf_me[i].refcount = 0;
1129 printBufInfo(buf_v4l2[i]);
1136 if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1139 "Can't start streaming") );
1152 vpV4l2Grabber::stopStreaming()
1157 if ((fd >= 0) && (streaming ==
true)) {
1161 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1162 if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1164 "Can't stop streaming") );
1167 for (i = 0; i < reqbufs.count; i++) {
1169 printBufInfo(buf_v4l2[i]);
1172 if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1174 "Can't unmap memory") );
1197 vpV4l2Grabber::waiton(__u32 &index,
struct timeval ×tamp)
1199 struct v4l2_buffer buf;
1209 FD_SET(static_cast<unsigned int>(fd), &rdset);
1210 switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1216 "Can't access to the frame") );
1221 "Can't access to the frame: timeout") );
1227 memset(&buf, 0,
sizeof(buf));
1228 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1229 buf.memory = V4L2_MEMORY_MMAP;
1230 if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1236 "VIDIOC_DQBUF: EAGAIN") );
1240 "VIDIOC_DQBUF: EINVAL") );
1244 "VIDIOC_DQBUF: ENOMEM") );
1255 buf_v4l2[buf.index] = buf;
1259 field = buf_v4l2[index].field;
1261 timestamp = buf_v4l2[index].timestamp;
1269 return buf_me[buf.index].data;
1278 vpV4l2Grabber::queueBuffer()
1280 unsigned int frame = queue % reqbufs.count;
1284 if (0 != buf_me[frame].refcount) {
1285 if (0 != queue - waiton_cpt)
1287 fprintf(stderr,
"v4l2: waiting for a free buffer..............\n");
1289 std::cout <<
"Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1293 rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1302 "VIDIOC_QBUF: EAGAIN") );
1306 "VIDIOC_QBUF: EINVAL") );
1310 "VIDIOC_QBUF: ENOMEM") );
1327 vpV4l2Grabber::queueAll()
1330 if (queue - waiton_cpt >= reqbufs.count) {
1333 if (0 != queueBuffer()) {
1345 vpV4l2Grabber::printBufInfo(
struct v4l2_buffer buf)
1350 case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type,
"video-cap");
break;
1351 case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type,
"video-over");
break;
1352 case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type,
"video-out");
break;
1353 case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type,
"vbi-cap");
break;
1354 case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type,
"vbi-out");
break;
1355 default: sprintf(type,
"unknown");
break;
1358 fprintf(stdout,
"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1359 buf.index, buf.type, buf.m.userptr, buf.m.offset,
1360 buf.length, buf.length, buf.bytesused);
1364 #elif !defined(VISP_BUILD_SHARED_LIBS)
1366 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.
Class that defines a RGB 32 bits structure.
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)
set the size of the image without initializing it.
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 for the Video4Linux2 video device.
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 const unsigned int DEFAULT_SCALE
static const unsigned int MAX_BUFFERS
void setFramerate(vpV4l2FramerateType framerate)