1 /**************************************************************************** 2 * 3 * ViSP, open source Visual Servoing Platform software. 4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved. 5 * 6 * This software is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * See the file LICENSE.txt at the root directory of this source 11 * distribution for additional information about the GNU GPL. 12 * 13 * For using ViSP with software that can not be combined with the GNU 14 * GPL, please contact Inria about acquiring a ViSP Professional 15 * Edition License. 16 * 17 * See http://visp.inria.fr for more information. 18 * 19 * This software was developed at: 20 * Inria Rennes - Bretagne Atlantique 21 * Campus Universitaire de Beaulieu 22 * 35042 Rennes Cedex 23 * France 24 * 25 * If you have questions regarding the use of this file, please contact 26 * Inria at visp@inria.fr 27 * 28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 30 * 31 * Description: 32 * Video for linux two framegrabber. 33 * 34 * Authors: 35 * Fabien Spindler 36 * 37 *****************************************************************************/ 38 39 /*! 40 \file vpV4l2Grabber.h 41 \brief class for the Video For Linux 2 video device framegrabbing. 42 \ingroup libdevice 43 */ 44 45 #ifndef vpV4l2Grabber_hh 46 #define vpV4l2Grabber_hh 47 48 #include <visp3/core/vpConfig.h> 49 50 #ifdef VISP_HAVE_V4L2 51 52 #include <libv4l2.h> // Video For Linux Two interface 53 #include <linux/videodev2.h> // Video For Linux Two interface 54 55 #include <visp3/core/vpFrameGrabber.h> 56 #include <visp3/core/vpImage.h> 57 #include <visp3/core/vpRGBa.h> 58 #include <visp3/core/vpRect.h> 59 60 /*! 61 \class vpV4l2Grabber 62 63 \ingroup group_sensor_camera 64 65 \brief Class that is a wrapper over the Video4Linux2 (V4L2) driver. 66 67 Thus to be enabled, this class needs the optional V4L2 3rd party. 68 Installation instruction are provided here https://visp.inria.fr/3rd_v4l2. 69 70 Information about Video4Linux can be found on 71 http://linuxtv.org/v4lwiki/index.php/Main_Page 72 73 This class was tested with a Pinnacle PCTV Studio/Rave board but 74 also with the following webcams (Logitech QuickCam Vision Pro 9000, 75 Logitech QuickCam Orbit AF, Logitech QuickCam IM (V-USB39), Dell latitude 76 E6400 internal webcam). 77 78 If the grabbing fail with a webcam, it means probably that you don't 79 have the read/write permission on the /dev/video%%d device. You can 80 set the right permissions by "sudo chmod a+rw /dev/video*". 81 82 If the grabbing fails when the camera is attached to a bttv PCI 83 card, it means potentially that you have not configured the linux 84 bttv kernel module according to your board. 85 86 For that, depending on your linux distribution check the card id in 87 - /usr/share/doc/kernel-doc-2.4.20/video4linux/bttv/CARDLIST 88 - or 89 /usr/share/doc/kernel-doc-2.6.20/Documentation/video4linux/CARDLIST.bttv 90 91 For example, the card id of a Pinnacle PCTV Studio/Rave board is 39. 92 Once this id is determined, you have to set the bttv driver with, by adding 93 \verbatim 94 options bttv card=39 95 \endverbatim 96 in one of theses files : 97 - /etc/modules.conf 98 - or /etc/modprobe.conf 99 100 This first example available in tutorial-grabber-v4l2.cpp shows how to grab 101 and display images from an usb camera. 102 \include tutorial-grabber-v4l2.cpp 103 104 This other example shows how to use this grabber with an analogic camera 105 attached to a bttv PCI card. 106 \code 107 #include <visp3/io/vpImageIo.h> 108 #include <visp3/sensor/vpV4l2Grabber.h> 109 110 int main() 111 { 112 #if defined(VISP_HAVE_V4L2) 113 vpImage<unsigned char> I; 114 vpV4l2Grabber g; 115 g.setInput(2); // Input 2 on the board 116 g.setFramerate(vpV4l2Grabber::framerate_25fps); // 25 fps 117 g.setWidth(768); // Acquired images are 768 width 118 g.setHeight(576); // Acquired images are 576 height 119 g.setNBuffers(3); // 3 ring buffers to ensure real-time acquisition 120 g.open(I); // Open the grabber 121 122 g.acquire(I); // Acquire a 768x576 grey image 123 vpImageIo::write(I, "image.pgm"); // Save the image on the disk 124 #endif 125 } 126 \endcode 127 128 129 \author Fabien Spindler (Fabien.Spindler@irisa.fr), Irisa / Inria Rennes 130 131 132 \sa vpFrameGrabber 133 */ 134 class VISP_EXPORT vpV4l2Grabber : public vpFrameGrabber 135 { 136 public: 137 static const unsigned int DEFAULT_INPUT; 138 static const unsigned int DEFAULT_SCALE; 139 static const __u32 MAX_INPUTS; 140 static const __u32 MAX_NORM; 141 static const __u32 MAX_FORMAT; 142 static const unsigned int MAX_CTRL; 143 static const unsigned int MAX_BUFFERS; 144 static const unsigned int FRAME_SIZE; 145 146 /*! \enum vpV4l2FramerateType 147 Frame rate type for capture. 148 */ 149 typedef enum { 150 framerate_50fps, //!< 50 frames per second 151 framerate_25fps //!< 25 frames per second 152 } vpV4l2FramerateType; 153 154 /*! \enum vpV4l2FrameFormatType 155 Frame format type for capture. 156 */ 157 typedef enum { 158 V4L2_FRAME_FORMAT, /*!< a field only */ 159 V4L2_IMAGE_FORMAT /*!< an interlaced image */ 160 } vpV4l2FrameFormatType; 161 162 /*! \enum vpV4l2PixelFormatType 163 Pixel format type for capture. 164 */ 165 typedef enum { 166 V4L2_GREY_FORMAT, /*!< 8 Greyscale */ 167 V4L2_RGB24_FORMAT, /*!< 24 RGB-8-8-8 */ 168 V4L2_RGB32_FORMAT, /*!< 32 RGB-8-8-8-8 */ 169 V4L2_BGR24_FORMAT, /*!< 24 BGR-8-8-8 */ 170 V4L2_YUYV_FORMAT, /*!< 16 YUYV 4:2:2 */ 171 V4L2_MAX_FORMAT 172 } vpV4l2PixelFormatType; 173 174 #ifndef DOXYGEN_SHOULD_SKIP_THIS 175 struct ng_video_fmt { 176 unsigned int pixelformat; /* VIDEO_* */ 177 unsigned int width; 178 unsigned int height; 179 unsigned int bytesperline; /* zero for compressed formats */ 180 }; 181 182 struct ng_video_buf { 183 struct ng_video_fmt fmt; 184 size_t size; 185 unsigned char *data; 186 int refcount; 187 }; 188 #endif 189 190 // private: 191 //#ifndef DOXYGEN_SHOULD_SKIP_THIS 192 // vpV4l2Grabber(const vpV4l2Grabber &) 193 // : fd(-1), device(), cap(), streamparm(), inp(NULL), std(NULL), 194 // fmt(NULL), ctl(NULL), 195 // fmt_v4l2(), fmt_me(), reqbufs(), buf_v4l2(NULL), buf_me(NULL), 196 // queue(0), waiton_cpt(0), index_buffer(0), m_verbose(false), 197 // m_nbuffers(3), field(0), streaming(false), 198 // m_input(vpV4l2Grabber::DEFAULT_INPUT), 199 // m_framerate(vpV4l2Grabber::framerate_25fps), 200 // m_frameformat(vpV4l2Grabber::V4L2_FRAME_FORMAT), 201 // m_pixelformat(vpV4l2Grabber::V4L2_YUYV_FORMAT) 202 // { 203 // throw vpException(vpException::functionNotImplementedError,"Not 204 // implemented!"); 205 // } 206 // vpV4l2Grabber &operator=(const vpV4l2Grabber &){ 207 // throw vpException(vpException::functionNotImplementedError,"Not 208 // implemented!"); return *this; 209 // } 210 //#endif 211 212 public: 213 vpV4l2Grabber(); 214 explicit vpV4l2Grabber(bool verbose); 215 vpV4l2Grabber(unsigned input, unsigned scale = vpV4l2Grabber::DEFAULT_SCALE); 216 vpV4l2Grabber(vpImage<unsigned char> &I, unsigned input, unsigned scale = vpV4l2Grabber::DEFAULT_SCALE); 217 vpV4l2Grabber(vpImage<vpRGBa> &I, unsigned input, unsigned scale = vpV4l2Grabber::DEFAULT_SCALE); 218 virtual ~vpV4l2Grabber(); 219 220 public: 221 void open(vpImage<unsigned char> &I); 222 void open(vpImage<vpRGBa> &I); 223 224 void acquire(vpImage<unsigned char> &I); 225 void acquire(vpImage<unsigned char> &I, const vpRect &roi); 226 void acquire(vpImage<unsigned char> &I, struct timeval ×tamp, const vpRect &roi = vpRect()); 227 void acquire(vpImage<vpRGBa> &I); 228 void acquire(vpImage<vpRGBa> &I, const vpRect &roi); 229 void acquire(vpImage<vpRGBa> &I, struct timeval ×tamp, const vpRect &roi = vpRect()); 230 bool getField(); 231 vpV4l2FramerateType getFramerate(); 232 /*! 233 234 Get the pixel format used for capture. 235 236 \return Camera pixel format coding. 237 238 */ getPixelFormat()239 inline vpV4l2PixelFormatType getPixelFormat() { return (this->m_pixelformat); } 240 241 vpV4l2Grabber &operator>>(vpImage<unsigned char> &I); 242 vpV4l2Grabber &operator>>(vpImage<vpRGBa> &I); 243 244 /*! 245 Activates the verbose mode to print additional information on stdout. 246 \param verbose : If true activates the verbose mode. 247 */ setVerboseMode(bool verbose)248 void setVerboseMode(bool verbose) { this->m_verbose = verbose; }; 249 void setFramerate(vpV4l2FramerateType framerate); 250 251 void setInput(unsigned input = vpV4l2Grabber::DEFAULT_INPUT); 252 253 /*! 254 Set image width to acquire. 255 256 */ setWidth(unsigned w)257 inline void setWidth(unsigned w) { this->width = w; } 258 /*! 259 Set image height to acquire. 260 261 */ setHeight(unsigned h)262 inline void setHeight(unsigned h) { this->height = h; } 263 264 void setScale(unsigned scale = vpV4l2Grabber::DEFAULT_SCALE); 265 266 /*! 267 268 Set the number of buffers required for streaming data. 269 270 For non real-time applications the number of buffers should be set to 1. For 271 real-time applications to reach 25 fps or 50 fps a good compromise is to set 272 the number of buffers to 3. 273 274 \param nbuffers : Number of ring buffers. 275 276 */ setNBuffers(unsigned nbuffers)277 inline void setNBuffers(unsigned nbuffers) { this->m_nbuffers = nbuffers; } 278 279 /*! 280 Set the device name. 281 282 \param devname : Device name (like /dev/video0). 283 284 */ setDevice(const std::string & devname)285 inline void setDevice(const std::string &devname) { sprintf(device, "%s", devname.c_str()); } 286 /*! 287 288 Set the pixel format for capture.`If the specified pixel format is 289 out of range, we set the V4L2_RGB24_FORMAT. 290 291 \param pixelformat : Camera pixel format coding. 292 293 */ setPixelFormat(vpV4l2PixelFormatType pixelformat)294 inline void setPixelFormat(vpV4l2PixelFormatType pixelformat) 295 { 296 this->m_pixelformat = pixelformat; 297 if (this->m_pixelformat >= V4L2_MAX_FORMAT) 298 this->m_pixelformat = V4L2_RGB24_FORMAT; 299 } 300 301 void close(); 302 303 private: 304 void setFormat(); 305 /*! 306 Set the frame format. 307 308 \param frameformat : 309 - vpV4l2Grabber::V4L2_FRAME_FORMAT: capture alternate fields (or frames), 310 - vpV4l2Grabber::V4L2_IMAGE_FORMAT: capture interlaced images. 311 */ setFrameFormat(vpV4l2FrameFormatType frameformat)312 inline void setFrameFormat(vpV4l2FrameFormatType frameformat) { this->m_frameformat = frameformat; } 313 void open(); 314 void getCapabilities(); 315 void startStreaming(); 316 void stopStreaming(); 317 unsigned char *waiton(__u32 &index, struct timeval ×tamp); 318 int queueBuffer(); 319 void queueAll(); 320 void printBufInfo(struct v4l2_buffer buf); 321 322 int fd; 323 char device[FILENAME_MAX]; 324 /* device descriptions */ 325 struct v4l2_capability cap; 326 struct v4l2_streamparm streamparm; 327 struct v4l2_input *inp; //[vpV4l2Grabber::MAX_INPUTS]; 328 struct v4l2_standard *std; //[vpV4l2Grabber::MAX_NORM]; 329 struct v4l2_fmtdesc *fmt; //[vpV4l2Grabber::MAX_FORMAT]; 330 struct v4l2_queryctrl *ctl; //[vpV4l2Grabber::MAX_CTRL*2]; 331 332 /* capture */ 333 struct v4l2_format fmt_v4l2; 334 struct ng_video_fmt fmt_me; 335 struct v4l2_requestbuffers reqbufs; 336 struct v4l2_buffer *buf_v4l2; //[vpV4l2Grabber::MAX_BUFFERS]; 337 struct ng_video_buf *buf_me; //[vpV4l2Grabber::MAX_BUFFERS]; 338 unsigned int queue; 339 unsigned int waiton_cpt; 340 __u32 index_buffer; //!< index of the buffer in use 341 342 bool m_verbose; 343 unsigned m_nbuffers; 344 unsigned int field; 345 bool streaming; 346 347 unsigned m_input; 348 vpV4l2FramerateType m_framerate; 349 vpV4l2FrameFormatType m_frameformat; 350 vpV4l2PixelFormatType m_pixelformat; 351 }; 352 353 #endif 354 #endif 355