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))
118 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
119 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
120 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
177 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
178 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
179 waiton_cpt(0), index_buffer(0), m_verbose(verbose), m_nbuffers(3), field(0), streaming(false),
227 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
228 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
229 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
276 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
277 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
278 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
328 : fd(-1), device(), cap(), streamparm(), inp(NULL),
std(NULL), fmt(NULL), ctl(NULL),
329 fps(0), fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), queue(0),
330 waiton_cpt(0), index_buffer(0), m_verbose(false), m_nbuffers(3), field(0), streaming(false),
363 this->m_input = input;
381 if ((scale <1) || (scale >16))
385 vpERROR_TRACE(
"Wrong scale %d, scale should be between 1 and 16",scale) ;
409 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
411 std::cout <<
"Warning: cannot set input channel to " << m_input << std::endl;
423 std::cout <<
"Requested pixel format [" << req_pixelformat
424 <<
"] not compatible with camera" << std::endl;
425 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
430 if (format == req_pixelformat) {
438 std::cout <<
"This format [" << m_pixelformat
439 <<
"] is compatible with camera" << std::endl;
445 std::cout <<
"This format [" << m_pixelformat
446 <<
"] is not compatible with camera" << std::endl;
448 std::cout <<
"No pixel format compatible with the camera was found" << std::endl;
452 "No pixel format compatible with the camera was found"));
477 if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
479 std::cout <<
"Warning: cannot set input channel to " << m_input << std::endl;
491 std::cout <<
"Requested pixel format [" << m_pixelformat
492 <<
"] not compatible with camera" << std::endl;
493 std::cout <<
"Try to found a compatible pixel format..." << std::endl;
498 if (format == req_pixelformat) {
506 std::cout <<
"This format [" << m_pixelformat
507 <<
"] is compatible with camera" << std::endl;
513 std::cout <<
"This format [" << m_pixelformat
514 <<
"] is not compatible with camera" << std::endl;
540 struct timeval timestamp;
571 "V4l2 frame grabber not initialized") );
574 unsigned char *bitmap ;
575 bitmap = waiton(index_buffer, timestamp);
580 switch(m_pixelformat) {
601 std::cout <<
"V4L2 conversion not handled" << std::endl;
621 struct timeval timestamp;
652 "V4l2 frame grabber not initialized") );
655 unsigned char *bitmap ;
656 bitmap = waiton(index_buffer, timestamp);
663 switch(m_pixelformat) {
675 I[height-1][
width-1].A = 0;
684 std::cout <<
"V4l2 conversion not handled" << std::endl;
709 if(field == 2)
return 0;
710 else if (field == 3)
return 1;
715 "V4l2 returns a bad frame field") );
736 this->m_framerate = framerate;
776 if (inp != NULL) {
delete [] inp; inp = NULL; }
777 if (
std != NULL) {
delete []
std;
std = NULL; }
778 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
779 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
780 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
781 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
796 vpV4l2Grabber::open()
801 if (-1 == stat (device, &st)) {
802 fprintf (stderr,
"Cannot identify '%s': %d, %s\n",
803 device, errno, strerror (errno));
805 "Cannot identify video device") );
809 if (!S_ISCHR (st.st_mode)) {
810 fprintf (stderr,
"%s is no device\n", device);
815 fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
821 "Can't access to video device") );
825 if (inp != NULL) {
delete [] inp; inp = NULL; }
826 if (
std != NULL) {
delete []
std;
std = NULL; }
827 if (fmt != NULL) {
delete [] fmt; fmt = NULL; }
828 if (ctl != NULL) {
delete [] ctl; ctl = NULL; }
829 if (buf_v4l2 != NULL) {
delete [] buf_v4l2; buf_v4l2 = NULL; }
830 if (buf_me != NULL) {
delete [] buf_me; buf_me = NULL; }
840 if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
842 fprintf (stderr,
"%s is no V4L2 device\n", device);
844 "Is not a V4L2 device") );
847 fprintf(stdout,
"v4l2 info:\n"
849 " %s %d.%d.%d / %s @ %s\n",
852 (cap.version >> 16) & 0xff,
853 (cap.version >> 8) & 0xff,
855 cap.card, cap.bus_info);
856 if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
857 fprintf(stdout,
" Support overlay\n");
859 fprintf(stdout,
" Does not support overlay\n");
860 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
861 fprintf(stdout,
" Support capture\n");
863 fprintf(stdout,
" Does not support capture\n");
864 if (cap.capabilities & V4L2_CAP_TUNER)
865 fprintf(stdout,
" Support tuning\n");
867 fprintf(stdout,
" Does not support tuning\n");
868 if (cap.capabilities & V4L2_CAP_STREAMING)
869 fprintf(stdout,
" Support streaming capture.\n");
871 fprintf(stdout,
" Does not support streaming capture\n");
872 if(cap.capabilities & V4L2_CAP_ASYNCIO)
873 fprintf(stdout,
" Support asynchronous I/O methods\n");
875 fprintf(stdout,
" Does not support asynchronous I/O methods\n");
876 if(cap.capabilities & V4L2_CAP_TIMEPERFRAME)
877 fprintf(stdout,
" Support time per frame field\n");
879 fprintf(stdout,
" Does not support time per frame field\n");
881 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
882 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) != -1) {
883 fprintf(stdout,
" Current acquisition framerate: %d fps\n",
884 streamparm.parm.output.timeperframe.denominator);
898 vpV4l2Grabber::getCapabilities()
900 for (__u32 ninputs = 0; ninputs <
MAX_INPUTS; ninputs++) {
901 inp[ninputs].index = ninputs;
902 if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
905 for (__u32 nstds = 0; nstds <
MAX_NORM; nstds++) {
906 std[nstds].index = nstds;
907 if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &
std[nstds]))
911 for (__u32 nfmts = 0; nfmts <
MAX_FORMAT; nfmts++) {
912 fmt[nfmts].index = nfmts;
913 fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
914 if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
918 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
919 if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
924 "Can't get video parameters") );
942 vpV4l2Grabber::setFormat()
944 fmt_me.width =
width;
949 switch(m_pixelformat) {
952 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
956 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
960 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
964 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
968 fprintf(stdout,
"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
975 "Bad format, probably do to a wrong scale"));
981 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
983 if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
987 "Can't get video format") );
989 fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
990 fmt_v4l2.fmt.pix.width = fmt_me.width;
991 fmt_v4l2.fmt.pix.height = fmt_me.height;
995 switch (m_frameformat) {
998 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1003 fprintf(stdout,
"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1010 "Unrecognized frame format") );
1020 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1022 "Can't set video format") );
1025 if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1027 "Bad pixel format") );
1031 unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1032 if (fmt_v4l2.fmt.pix.bytesperline < min)
1033 fmt_v4l2.fmt.pix.bytesperline = min;
1034 min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1035 if (fmt_v4l2.fmt.pix.sizeimage < min)
1036 fmt_v4l2.fmt.pix.sizeimage = min;
1038 fmt_me.width = fmt_v4l2.fmt.pix.width;
1039 fmt_me.height = fmt_v4l2.fmt.pix.height;
1040 fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1043 fprintf(stdout,
"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1044 fmt_me.width, fmt_me.height,
1045 fmt_v4l2.fmt.pix.pixelformat & 0xff,
1046 (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1047 (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1048 (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1049 fmt_v4l2.fmt.pix.sizeimage,
1050 fmt_v4l2.fmt.pix.bytesperline);
1063 vpV4l2Grabber::startStreaming()
1065 if (streaming ==
true) {
1071 memset (&(reqbufs), 0,
sizeof (reqbufs));
1072 reqbufs.count = m_nbuffers;
1073 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1074 reqbufs.memory = V4L2_MEMORY_MMAP;
1077 if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1079 if (EINVAL == errno) {
1080 fprintf (stderr,
"%s does not support "
1081 "memory mapping\n", device);
1083 "Does not support memory mapping") );
1086 "Can't require video buffers") );
1089 for (
unsigned i = 0; i < reqbufs.count; i++) {
1091 memset (&(buf_v4l2[i]), 0,
sizeof (buf_v4l2[i]));
1092 buf_v4l2[i].index = i;
1093 buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1094 buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1095 buf_v4l2[i].length = 0;
1096 if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1099 "Can't query video buffers") );
1101 memcpy(&buf_me[i].fmt, &fmt_me,
sizeof(ng_video_fmt));
1102 buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1110 buf_me[i].data = (
unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1111 PROT_READ | PROT_WRITE,
1113 fd, (off_t)buf_v4l2[i].m.offset);
1115 if(buf_me[i].data == MAP_FAILED)
1118 "Can't map memory") );
1121 buf_me[i].refcount = 0;
1132 printBufInfo(buf_v4l2[i]);
1139 if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1142 "Can't start streaming") );
1155 vpV4l2Grabber::stopStreaming()
1160 if ((fd >= 0) && (streaming ==
true)) {
1164 fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1165 if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1167 "Can't stop streaming") );
1170 for (i = 0; i < reqbufs.count; i++) {
1172 printBufInfo(buf_v4l2[i]);
1175 if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1177 "Can't unmap memory") );
1200 vpV4l2Grabber::waiton(__u32 &index,
struct timeval ×tamp)
1202 struct v4l2_buffer buf;
1212 FD_SET(static_cast<unsigned int>(fd), &rdset);
1213 switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1219 "Can't access to the frame") );
1224 "Can't access to the frame: timeout") );
1230 memset(&buf, 0,
sizeof(buf));
1231 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1232 buf.memory = V4L2_MEMORY_MMAP;
1233 if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1239 "VIDIOC_DQBUF: EAGAIN") );
1243 "VIDIOC_DQBUF: EINVAL") );
1247 "VIDIOC_DQBUF: ENOMEM") );
1258 buf_v4l2[buf.index] = buf;
1262 field = buf_v4l2[index].field;
1264 timestamp = buf_v4l2[index].timestamp;
1272 return buf_me[buf.index].data;
1281 vpV4l2Grabber::queueBuffer()
1283 unsigned int frame = queue % reqbufs.count;
1287 if (0 != buf_me[frame].refcount) {
1288 if (0 != queue - waiton_cpt)
1290 fprintf(stderr,
"v4l2: waiting for a free buffer..............\n");
1292 std::cout <<
"Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1296 rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1305 "VIDIOC_QBUF: EAGAIN") );
1309 "VIDIOC_QBUF: EINVAL") );
1313 "VIDIOC_QBUF: ENOMEM") );
1330 vpV4l2Grabber::queueAll()
1333 if (queue - waiton_cpt >= reqbufs.count) {
1336 if (0 != queueBuffer()) {
1348 vpV4l2Grabber::printBufInfo(
struct v4l2_buffer buf)
1353 case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type,
"video-cap");
break;
1354 case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type,
"video-over");
break;
1355 case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type,
"video-out");
break;
1356 case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type,
"vbi-cap");
break;
1357 case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type,
"vbi-out");
break;
1358 default: sprintf(type,
"unknown");
break;
1361 fprintf(stdout,
"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1362 buf.index, buf.type, buf.m.userptr, buf.m.offset,
1363 buf.length, buf.length, buf.bytesused);
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)