Visual Servoing Platform  version 3.0.0
vpV4l2Grabber.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Framegrabber based on Video4Linux2 driver.
32  *
33  * Authors:
34  * Fabien Spindler
35  *
36  *****************************************************************************/
37 
44 #include <visp3/core/vpConfig.h>
45 
46 #ifdef VISP_HAVE_V4L2
47 
48 #include <stdio.h>
49 #include <unistd.h>
50 #include <stdlib.h>
51 #include <sys/time.h>
52 #include <sys/ioctl.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <fcntl.h>
56 #include <stdio.h>
57 #include <sys/mman.h>
58 #include <errno.h>
59 #include <iostream>
60 
61 #include <visp3/sensor/vpV4l2Grabber.h>
62 #include <visp3/core/vpFrameGrabberException.h>
63 //#include <visp3/io/vpImageIo.h>
64 #include <visp3/core/vpImageConvert.h>
65 
66 const unsigned int vpV4l2Grabber::DEFAULT_INPUT = 2;
67 const unsigned int vpV4l2Grabber::DEFAULT_SCALE = 2;
68 const __u32 vpV4l2Grabber::MAX_INPUTS = 16;
69 const __u32 vpV4l2Grabber::MAX_NORM = 16;
70 const __u32 vpV4l2Grabber::MAX_FORMAT = 32;
71 const unsigned int vpV4l2Grabber::MAX_CTRL = 32;
72 const unsigned int vpV4l2Grabber::MAX_BUFFERS = 32;
73 const unsigned int vpV4l2Grabber::FRAME_SIZE = 288;
74 #define vpCLEAR(x) memset (&(x), 0, sizeof (x))
75 
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),
118  m_input(vpV4l2Grabber::DEFAULT_INPUT),
119  m_framerate(vpV4l2Grabber::framerate_25fps),
120  m_frameformat(vpV4l2Grabber::V4L2_FRAME_FORMAT),
121  m_pixelformat(vpV4l2Grabber::V4L2_YUYV_FORMAT)
122 {
123  setDevice("/dev/video0");
124  setNBuffers(3);
129 
130  init = false;
131 }
132 
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),
177  m_input(vpV4l2Grabber::DEFAULT_INPUT),
178  m_framerate(vpV4l2Grabber::framerate_25fps),
179  m_frameformat(vpV4l2Grabber::V4L2_FRAME_FORMAT),
180  m_pixelformat(vpV4l2Grabber::V4L2_YUYV_FORMAT)
181 {
182  setDevice("/dev/video0");
183  setNBuffers(3);
188 
189  init = false;
190 }
191 
192 
223 vpV4l2Grabber::vpV4l2Grabber(unsigned input, unsigned scale)
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),
227  m_input(vpV4l2Grabber::DEFAULT_INPUT),
228  m_framerate(vpV4l2Grabber::framerate_25fps),
229  m_frameformat(vpV4l2Grabber::V4L2_FRAME_FORMAT),
230  m_pixelformat(vpV4l2Grabber::V4L2_YUYV_FORMAT)
231 {
232  setDevice("/dev/video0");
233  setNBuffers(3);
235  setInput(input);
236  setScale(scale);
237 
238  init = false;
239 }
240 
272 vpV4l2Grabber::vpV4l2Grabber(vpImage<unsigned char> &I, unsigned input, unsigned scale )
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),
276  m_input(vpV4l2Grabber::DEFAULT_INPUT),
277  m_framerate(vpV4l2Grabber::framerate_25fps),
278  m_frameformat(vpV4l2Grabber::V4L2_FRAME_FORMAT),
279  m_pixelformat(vpV4l2Grabber::V4L2_YUYV_FORMAT)
280 {
281  setDevice("/dev/video0");
282  setNBuffers(3);
284  setInput(input);
285  setScale(scale);
286 
287  init = false;
288 
289  open(I);
290 }
291 
324 vpV4l2Grabber::vpV4l2Grabber(vpImage<vpRGBa> &I, unsigned input, unsigned scale )
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),
328  m_input(vpV4l2Grabber::DEFAULT_INPUT),
329  m_framerate(vpV4l2Grabber::framerate_25fps),
330  m_frameformat(vpV4l2Grabber::V4L2_FRAME_FORMAT),
331  m_pixelformat(vpV4l2Grabber::V4L2_YUYV_FORMAT)
332 {
333  setDevice("/dev/video0");
334  setNBuffers(3);
336  setInput(input);
337  setScale(scale);
338 
339  init = false;
340 
341  open(I);
342 }
343 
350 {
351  close() ;
352 }
353 
357 void
358 vpV4l2Grabber::setInput(unsigned input)
359 {
360  this->m_input = input;
361 }
362 
375 void
376 vpV4l2Grabber::setScale(unsigned scale)
377 {
378  if ((scale <1) || (scale >16))
379  {
380  close();
381 
382  vpERROR_TRACE("Wrong scale %d, scale should be between 1 and 16",scale) ;
384  "Wrong scale") );
385  }
386 
387  setWidth(640/scale);
388  setHeight(480/scale);
389 }
390 
401 void
403 {
404  open();
405 
406  if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
407  {
408  std::cout << "Warning: cannot set input channel to " << m_input << std::endl;
409  }
410 
411  vpV4l2PixelFormatType req_pixelformat = getPixelFormat();
412 
413  try {
414  setFormat();
415 
416  startStreaming();
417  }
418  catch(...) {
419  if (m_verbose) {
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;
423  }
424 
425  // try to fing a compatible format
426  for (int format=0; format< (int)V4L2_MAX_FORMAT; format ++) {
427  if (format == req_pixelformat) {
428  continue;
429  }
430  try {
432  setFormat();
433  startStreaming();
434  if (m_verbose)
435  std::cout << "This format [" << m_pixelformat
436  << "] is compatible with camera" << std::endl;
437 
438  break;
439  }
440  catch (...) {
441  if (m_verbose)
442  std::cout << "This format [" << m_pixelformat
443  << "] is not compatible with camera" << std::endl;
444  if (format == (int)V4L2_MAX_FORMAT) {
445  std::cout << "No pixel format compatible with the camera was found" << std::endl;
446  close();
447 
449  "No pixel format compatible with the camera was found"));
450  }
451  }
452  }
453  }
454 
455  I.resize(height, width) ;
456 
457  init = true;
458 }
459 
469 void
471 {
472  open();
473 
474  if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &m_input) == -1 )
475  {
476  std::cout << "Warning: cannot set input channel to " << m_input << std::endl;
477  }
478 
479  vpV4l2PixelFormatType req_pixelformat = getPixelFormat();
480 
481  try {
482  setFormat();
483 
484  startStreaming();
485  }
486  catch(...) {
487  if (m_verbose) {
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;
491  }
492 
493  // try to fing a compatible format
494  for (int format=0; format< (int)V4L2_MAX_FORMAT; format ++) {
495  if (format == req_pixelformat) {
496  continue;
497  }
498  try {
500  setFormat();
501  startStreaming();
502  if (m_verbose)
503  std::cout << "This format [" << m_pixelformat
504  << "] is compatible with camera" << std::endl;
505 
506  break;
507  }
508  catch (...) {
509  if (m_verbose)
510  std::cout << "This format [" << m_pixelformat
511  << "] is not compatible with camera" << std::endl;
512 
513  }
514  }
515  }
516 
517  I.resize(height, width) ;
518 
519  init = true;
520 }
521 
522 
523 
534 void
536 {
537  struct timeval timestamp;
538 
539  acquire(I, timestamp);
540 }
541 
555 void
556 vpV4l2Grabber::acquire(vpImage<unsigned char> &I, struct timeval &timestamp)
557 {
558  if (init==false)
559  {
560  open(I);
561  }
562 
563  if (init==false)
564  {
565  close();
566 
568  "V4l2 frame grabber not initialized") );
569  }
570 
571  unsigned char *bitmap ;
572  bitmap = waiton(index_buffer, timestamp);
573 
574  if ((I.getWidth() != width)||(I.getHeight() != height))
575  I.resize(height, width) ;
576 
577  switch(m_pixelformat) {
578  case V4L2_GREY_FORMAT:
579  memcpy(I.bitmap, bitmap, height * width*sizeof(unsigned char));
580  break;
581  case V4L2_RGB24_FORMAT:
582  vpImageConvert::RGBToGrey((unsigned char *) bitmap, I.bitmap, width*height);
583 
584  break;
585  case V4L2_RGB32_FORMAT:
586  vpImageConvert::RGBaToGrey((unsigned char *) bitmap, I.bitmap, width*height);
587 
588  break;
589  case V4L2_BGR24_FORMAT:
590  vpImageConvert::BGRToGrey( (unsigned char *) bitmap, I.bitmap, width, height, false);
591 
592  break;
593  case V4L2_YUYV_FORMAT:
594  vpImageConvert::YUYVToGrey( (unsigned char *) bitmap, I.bitmap, width*height);
595 
596  break;
597  default:
598  std::cout << "V4L2 conversion not handled" << std::endl;
599  break;
600  }
601 
602  queueAll();
603 }
604 
615 void
617 {
618  struct timeval timestamp;
619 
620  acquire(I, timestamp);
621 }
622 
636 void
637 vpV4l2Grabber::acquire(vpImage<vpRGBa> &I, struct timeval &timestamp)
638 {
639  if (init==false)
640  {
641  open(I);
642  }
643 
644  if (init==false)
645  {
646  close();
647 
649  "V4l2 frame grabber not initialized") );
650  }
651 
652  unsigned char *bitmap ;
653  bitmap = waiton(index_buffer, timestamp);
654 
655  if ((I.getWidth() != width)||(I.getHeight() != height))
656  I.resize(height, width) ;
657 
658  // The framegrabber acquire aRGB format. We just shift the data from 1 byte all the data and initialize the last byte
659 
660  switch(m_pixelformat) {
661  case V4L2_GREY_FORMAT:
662  vpImageConvert::GreyToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width*height);
663  break;
664  case V4L2_RGB24_FORMAT:
665  vpImageConvert::RGBToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width*height);
666 
667  break;
668  case V4L2_RGB32_FORMAT:
669  // The framegrabber acquire aRGB format. We just shift the data
670  // from 1 byte all the data and initialize the last byte
671  memcpy(I.bitmap, bitmap + 1, height * width * sizeof(vpRGBa) - 1);
672  I[height-1][width-1].A = 0;
673  break;
674  case V4L2_BGR24_FORMAT:
675  vpImageConvert::BGRToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width, height, false);
676  break;
677  case V4L2_YUYV_FORMAT:
678  vpImageConvert::YUYVToRGBa( (unsigned char *) bitmap, (unsigned char *) I.bitmap, width, height);
679  break;
680  default:
681  std::cout << "V4l2 conversion not handled" << std::endl;
682  break;
683  }
684 
685  queueAll();
686 }
703 bool
705 {
706  if(field == 2) return 0; //top field
707  else if (field == 3) return 1; //bottom field;
708  else {
709  close();
710 
712  "V4l2 returns a bad frame field") );
713  return false;
714  }
715 }
730 void
732 {
733  this->m_framerate = framerate;
734 
735  if (framerate == vpV4l2Grabber::framerate_25fps)
736  setFrameFormat(V4L2_IMAGE_FORMAT);
737  else
738  setFrameFormat(V4L2_FRAME_FORMAT);
739 }
740 
753 {
754  return m_framerate;
755 }
756 
757 
761 void
763 {
764  stopStreaming();
765  streaming = false;
766 
767  if (fd >= 0){
768  //vpTRACE("v4l2_close()");
769  v4l2_close (fd);
770  fd = -1;
771  }
772 
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; }
779 }
780 
792 void
793 vpV4l2Grabber::open()
794 {
795  /* Open Video Device */
796  struct stat st;
797 
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") );
803 
804  }
805 
806  if (!S_ISCHR (st.st_mode)) {
807  fprintf (stderr, "%s is no device\n", device);
809  "No device") );
810 
811  }
812  fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
813  if (fd < 0) {
814  close();
815 
816  vpERROR_TRACE ("No video device \"%s\"\n", device);
818  "Can't access to video device") );
819 
820  }
821 
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; }
828 
829  inp = new struct v4l2_input [vpV4l2Grabber::MAX_INPUTS];
830  std = new struct v4l2_standard [vpV4l2Grabber::MAX_NORM];
831  fmt = new struct v4l2_fmtdesc [vpV4l2Grabber::MAX_FORMAT];
832  ctl = new struct v4l2_queryctrl [vpV4l2Grabber::MAX_CTRL*2];
833  buf_v4l2 = new struct v4l2_buffer [vpV4l2Grabber::MAX_BUFFERS];
834  buf_me = new struct ng_video_buf [vpV4l2Grabber::MAX_BUFFERS];
835 
836  /* Querry Video Device Capabilities */
837  if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
838  close();
839  fprintf (stderr, "%s is no V4L2 device\n", device);
841  "Is not a V4L2 device") );
842  }
843  if (m_verbose) {
844  fprintf(stdout, "v4l2 info:\n"
845  " device: %s\n"
846  " %s %d.%d.%d / %s @ %s\n",
847  device,
848  cap.driver,
849  (cap.version >> 16) & 0xff,
850  (cap.version >> 8) & 0xff,
851  cap.version & 0xff,
852  cap.card, cap.bus_info);
853  if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
854  fprintf(stdout, " Support overlay\n");
855  else
856  fprintf(stdout, " Does not support overlay\n");
857  if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
858  fprintf(stdout, " Support capture\n");
859  else
860  fprintf(stdout, " Does not support capture\n");
861  if (cap.capabilities & V4L2_CAP_TUNER)
862  fprintf(stdout, " Support tuning\n");
863  else
864  fprintf(stdout, " Does not support tuning\n");
865  if (cap.capabilities & V4L2_CAP_STREAMING)
866  fprintf(stdout, " Support streaming capture.\n");
867  else
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");
871  else
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");
875  else
876  fprintf(stdout, " Does not support time per frame field\n");
877  // Get framerate
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);
882  }
883  }
884 
885  getCapabilities();
886 }
887 
894 void
895 vpV4l2Grabber::getCapabilities()
896 {
897  for (__u32 ninputs = 0; ninputs < MAX_INPUTS; ninputs++) {
898  inp[ninputs].index = ninputs;
899  if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
900  break;
901  }
902  for (__u32 nstds = 0; nstds < MAX_NORM; nstds++) {
903  std[nstds].index = nstds;
904  if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &std[nstds]))
905  break;
906 
907  }
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]))
912  break;
913  }
914 
915  streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
916  if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
917  {
918  close();
919 
921  "Can't get video parameters") );
922  }
923 }
924 
938 void
939 vpV4l2Grabber::setFormat()
940 {
941  fmt_me.width = width;
942  fmt_me.height = height;
943  //fmt_me.bytesperline = width; // bad (normally width * depth / 8), but works
944  // because initialized later by an ioctl call to VIDIOC_S_FMT
945 
946  switch(m_pixelformat) {
947  case V4L2_GREY_FORMAT : fmt_me.pixelformat = V4L2_PIX_FMT_GREY;
948  if (m_verbose)
949  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
950  break;
951  case V4L2_RGB24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB24;
952  if (m_verbose)
953  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
954  break;
955  case V4L2_RGB32_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB32;
956  if (m_verbose)
957  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
958  break;
959  case V4L2_BGR24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_BGR24;
960  if (m_verbose)
961  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
962  break;
963  case V4L2_YUYV_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_YUYV;
964  if (m_verbose)
965  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
966  break;
967 
968  default:
969  close();
970 
972  "Bad format, probably do to a wrong scale"));
973  }
974 
975  /* Get Video Format */
976  vpCLEAR (fmt_v4l2);
977 
978  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
979 
980  if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
981  close();
982 
984  "Can't get video format") );
985  }
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;
989  //printf("1 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
990 
991 
992  switch (m_frameformat) {
993  case V4L2_FRAME_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_ALTERNATE;
994  if (m_verbose) {
995  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
996  }
997  break;
998  case V4L2_IMAGE_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_INTERLACED;
999  if (m_verbose) {
1000  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1001  }
1002  break;
1003  default:
1004  close();
1005 
1007  "Unrecognized frame format") );
1008  }
1009 
1010  //height and width of the captured image or frame
1011  if( m_frameformat == V4L2_FRAME_FORMAT && height > FRAME_SIZE )
1012  {
1013  height = FRAME_SIZE;
1014  }
1015  //printf("2 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1016 
1017  if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1019  "Can't set video format") );
1020  }
1021 
1022  if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1024  "Bad pixel format") );
1025  }
1026 
1027  /* Buggy driver paranoia. */
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;
1034 
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;
1038 
1039  if (m_verbose) {
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);
1048  }
1049 
1050 }
1059 void
1060 vpV4l2Grabber::startStreaming()
1061 {
1062  if (streaming == true) { // Acquisition in process.
1063  stopStreaming();
1064  streaming = false;
1065  }
1066 
1067  /* setup buffers */
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;
1072 
1073 
1074  if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1075  {
1076  if (EINVAL == errno) {
1077  fprintf (stderr, "%s does not support "
1078  "memory mapping\n", device);
1080  "Does not support memory mapping") );
1081  }
1083  "Can't require video buffers") );
1084  }
1085 
1086  for (unsigned i = 0; i < reqbufs.count; i++) {
1087  // Clear the buffer
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)
1094  {
1096  "Can't query video buffers") );
1097  }
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;
1100 
1101  // if (m_verbose)
1102  // std::cout << "1: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1103  // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1104  // << std::endl;
1105 
1106 
1107  buf_me[i].data = (unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1108  PROT_READ | PROT_WRITE,
1109  MAP_SHARED,
1110  fd, (off_t)buf_v4l2[i].m.offset);
1111 
1112  if(buf_me[i].data == MAP_FAILED)
1113  {
1115  "Can't map memory") );
1116  }
1117 
1118  buf_me[i].refcount = 0;
1119 
1120 // if (m_verbose)
1121 // {
1122 // std::cout << "2: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1123 // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1124 // << std::endl;
1125 // std::cout << "2: buf_me[" << i << "].size: " << buf_me[i].size << std::endl;
1126 // }
1127 
1128  if (m_verbose)
1129  printBufInfo(buf_v4l2[i]);
1130  }
1131 
1132  /* queue up all buffers */
1133  queueAll();
1134 
1135  /* Set video stream capture on */
1136  if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1137  {
1139  "Can't start streaming") );
1140  }
1141 
1142  streaming = true;
1143 }
1144 
1151 void
1152 vpV4l2Grabber::stopStreaming()
1153 {
1154  unsigned int i;
1155 
1156  //nothing to do if (fd < 0) or if (streaming == false)
1157  if ((fd >= 0) && (streaming == true)) {
1158 
1159  //vpTRACE(" Stop the streaming...");
1160  /* stop capture */
1161  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1162  if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1164  "Can't stop streaming") );
1165  }
1166  /* free buffers */
1167  for (i = 0; i < reqbufs.count; i++) {
1168  if (m_verbose)
1169  printBufInfo(buf_v4l2[i]);
1170  //vpTRACE("v4l2_munmap()");
1171 
1172  if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1174  "Can't unmap memory") );
1175  }
1176  }
1177  queue = 0;
1178  waiton_cpt = 0;
1179  streaming = false;
1180  }
1181 }
1182 
1196 unsigned char *
1197 vpV4l2Grabber::waiton(__u32 &index, struct timeval &timestamp)
1198 {
1199  struct v4l2_buffer buf;
1200  struct timeval tv;
1201  fd_set rdset;
1202 
1203  /* wait for the next frame */
1204  again:
1205 
1206  tv.tv_sec = 30;
1207  tv.tv_usec = 0;
1208  FD_ZERO(&rdset);
1209  FD_SET(static_cast<unsigned int>(fd), &rdset);
1210  switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1211  case -1:
1212  if (EINTR == errno)
1213  goto again;
1214  index = 0;
1216  "Can't access to the frame") );
1217  return NULL;
1218  case 0:
1219  index = 0;
1221  "Can't access to the frame: timeout") );
1222  return NULL;
1223  }
1224 
1225 
1226  /* get it */
1227  memset(&buf, 0, sizeof(buf));
1228  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1229  buf.memory = V4L2_MEMORY_MMAP; // Fabien manquait
1230  if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1231  index = 0;
1232  switch(errno)
1233  {
1234  case EAGAIN:
1236  "VIDIOC_DQBUF: EAGAIN") );
1237  break;
1238  case EINVAL:
1240  "VIDIOC_DQBUF: EINVAL") );
1241  break;
1242  case ENOMEM:
1244  "VIDIOC_DQBUF: ENOMEM") );
1245  break;
1246  default:
1248  "VIDIOC_DQBUF") );
1249  break;
1250  }
1251  return NULL;
1252  }
1253 
1254  waiton_cpt++;
1255  buf_v4l2[buf.index] = buf;
1256 
1257  index = buf.index;
1258 
1259  field = buf_v4l2[index].field;
1260 
1261  timestamp = buf_v4l2[index].timestamp;
1262 
1263  // if(m_verbose)
1264  // {
1265  // vpERROR_TRACE("field: %d\n", buf_v4l2[index].field);
1266 
1267  // vpERROR_TRACE("data adress : 0x%p\n", buf_me[buf.index].data);
1268  // }
1269  return buf_me[buf.index].data;
1270 }
1271 
1277 int
1278 vpV4l2Grabber::queueBuffer()
1279 {
1280  unsigned int frame = queue % reqbufs.count;
1281  int rc;
1282 
1283 
1284  if (0 != buf_me[frame].refcount) {
1285  if (0 != queue - waiton_cpt)
1286  return -1;
1287  fprintf(stderr,"v4l2: waiting for a free buffer..............\n");
1288  //ng_waiton_video_buf(h->buf_me+frame);
1289  std::cout << "Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1290  }
1291 
1292  // std::cout << "frame: " << frame << std::endl;
1293  rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1294  if (0 == rc)
1295  queue++;
1296  else
1297  {
1298  switch(errno)
1299  {
1300  case EAGAIN:
1302  "VIDIOC_QBUF: EAGAIN") );
1303  break;
1304  case EINVAL:
1306  "VIDIOC_QBUF: EINVAL") );
1307  break;
1308  case ENOMEM:
1310  "VIDIOC_QBUF: ENOMEM") );
1311  break;
1312  default:
1314  "VIDIOC_QBUF") );
1315  break;
1316  }
1317  }
1318  return rc;
1319 }
1320 
1326 void
1327 vpV4l2Grabber::queueAll()
1328 {
1329  for (;;) {
1330  if (queue - waiton_cpt >= reqbufs.count) {
1331  return;
1332  }
1333  if (0 != queueBuffer()) {
1334  return;
1335  }
1336  }
1337 }
1338 
1344 void
1345 vpV4l2Grabber::printBufInfo(struct v4l2_buffer buf)
1346 {
1347  char type[40];
1348 
1349  switch(buf.type) {
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;
1356  }
1357 
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);
1361 
1362 }
1363 
1364 #elif !defined(VISP_BUILD_SHARED_LIBS)
1365 // Work arround to avoid warning: libvisp_sensor.a(vpV4l2Grabber.cpp.o) has no symbols
1366 void dummy_vpV4l2Grabber() {};
1367 #endif
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
Definition: vpImage.h:161
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
Definition: vpImage.h:116
#define vpERROR_TRACE
Definition: vpDebug.h:391
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.
Definition: vpRGBa.h:64
virtual ~vpV4l2Grabber()
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.
Definition: vpImage.h:616
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.
25 frames per second
unsigned int getHeight() const
Definition: vpImage.h:152
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)