ViSP  2.9.0
vpV4l2Grabber.cpp
1 /****************************************************************************
2  *
3  * $Id: vpV4l2Grabber.cpp 4656 2014-02-07 17:21:28Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Framegrabber based on Video4Linux2 driver.
36  *
37  * Authors:
38  * Fabien Spindler
39  *
40  *****************************************************************************/
41 
48 #include <visp/vpConfig.h>
49 
50 #ifdef VISP_HAVE_V4L2
51 
52 #include <stdio.h>
53 #include <unistd.h>
54 #include <stdlib.h>
55 #include <sys/time.h>
56 #include <sys/ioctl.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #include <fcntl.h>
60 #include <stdio.h>
61 #include <sys/mman.h>
62 #include <errno.h>
63 #include <iostream>
64 
65 #include <visp/vpV4l2Grabber.h>
66 #include <visp/vpFrameGrabberException.h>
67 #include <visp/vpImageIo.h>
68 
69 const unsigned int vpV4l2Grabber::DEFAULT_INPUT = 2;
70 const unsigned int vpV4l2Grabber::DEFAULT_SCALE = 2;
71 const __u32 vpV4l2Grabber::MAX_INPUTS = 16;
72 const __u32 vpV4l2Grabber::MAX_NORM = 16;
73 const __u32 vpV4l2Grabber::MAX_FORMAT = 32;
74 const unsigned int vpV4l2Grabber::MAX_CTRL = 32;
75 const unsigned int vpV4l2Grabber::MAX_BUFFERS = 32;
76 const unsigned int vpV4l2Grabber::FRAME_SIZE = 288;
77 #define vpCLEAR(x) memset (&(x), 0, sizeof (x))
78 
118 {
119  fd = -1;
120  streaming = false;
121  verbose = false;
122  field = 0;
123  width = 0;
124  height = 0;
125  queue = 0;
126  waiton_cpt= 0;
127  index_buffer = 0;
128 
129  inp = NULL;
130  std = NULL;
131  fmt = NULL;
132  ctl = NULL;
133  buf_v4l2 = NULL;
134  buf_me = NULL;
135 
136  setDevice("/dev/video0");
137  setNBuffers(3);
142 
143  init = false;
144 }
145 
187 {
188  fd = -1;
189  streaming = false;
190  this->verbose = verbose;
191  field = 0;
192  width = 0;
193  height = 0;
194  queue = 0;
195  waiton_cpt= 0;
196  index_buffer = 0;
197 
198  inp = NULL;
199  std = NULL;
200  fmt = NULL;
201  ctl = NULL;
202  buf_v4l2 = NULL;
203  buf_me = NULL;
204 
205  setDevice("/dev/video0");
206  setNBuffers(3);
211 
212  init = false;
213 }
214 
215 
246 vpV4l2Grabber::vpV4l2Grabber(unsigned input, unsigned scale)
247 {
248  fd = -1;
249  streaming = false;
250  verbose = false;
251  field = 0;
252  width = 0;
253  height = 0;
254  queue = 0;
255  waiton_cpt= 0;
256  index_buffer = 0;
257 
258  inp = NULL;
259  std = NULL;
260  fmt = NULL;
261  ctl = NULL;
262  buf_v4l2 = NULL;
263  buf_me = NULL;
264 
265  setDevice("/dev/video0");
266  setNBuffers(3);
268  setInput(input);
269  setScale(scale);
270 
271  init = false;
272 }
273 
306  unsigned input, unsigned scale )
307 {
308  fd = -1;
309  streaming = false;
310  verbose = false;
311  field = 0;
312  width = 0;
313  height = 0;
314  queue = 0;
315  waiton_cpt= 0;
316  index_buffer = 0;
317 
318  inp = NULL;
319  std = NULL;
320  fmt = NULL;
321  ctl = NULL;
322  buf_v4l2 = NULL;
323  buf_me = NULL;
324 
325  setDevice("/dev/video0");
326  setNBuffers(3);
328  setInput(input);
329  setScale(scale);
330 
331  init = false;
332 
333  open(I);
334 }
335 
368 vpV4l2Grabber::vpV4l2Grabber(vpImage<vpRGBa> &I, unsigned _input, unsigned _scale )
369 {
370  fd = -1;
371  streaming = false;
372  verbose = false;
373  field = 0;
374  width = 0;
375  height = 0;
376  queue = 0;
377  waiton_cpt= 0;
378  index_buffer = 0;
379 
380  inp = NULL;
381  std = NULL;
382  fmt = NULL;
383  ctl = NULL;
384  buf_v4l2 = NULL;
385  buf_me = NULL;
386 
387  setDevice("/dev/video0");
388  setNBuffers(3);
390  setInput(_input);
391  setScale(_scale);
392 
393  init = false;
394 
395  open(I);
396 }
397 
404 {
405  close() ;
406 }
407 
411 void
412 vpV4l2Grabber::setInput(unsigned input)
413 {
414  this->input = input;
415 }
416 
429 void
430 vpV4l2Grabber::setScale(unsigned scale)
431 {
432  if ((scale <1) || (scale >16))
433  {
434  close();
435 
436  vpERROR_TRACE("Wrong scale %d, scale should be between 1 and 16",scale) ;
438  "Wrong scale") );
439  }
440 
441  setWidth(640/scale);
442  setHeight(480/scale);
443 }
444 
455 void
457 {
458  open();
459 
460  if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &input) == -1 )
461  {
462  std::cout << "Warning: cannot set input channel to " << input << std::endl;
463  }
464 
465  vpV4l2PixelFormatType req_pixelformat = getPixelFormat();
466 
467  try {
468  setFormat();
469 
470  startStreaming();
471  }
472  catch(...) {
473  if (verbose) {
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;
477  }
478 
479  // try to fing a compatible format
480  for (int format=0; format< (int)V4L2_MAX_FORMAT; format ++) {
481  if (format == req_pixelformat) {
482  continue;
483  }
484  try {
486  setFormat();
487  startStreaming();
488  if (verbose)
489  std::cout << "This format [" << pixelformat
490  << "] is compatible with camera" << std::endl;
491 
492  break;
493  }
494  catch (...) {
495  if (verbose)
496  std::cout << "This format [" << pixelformat
497  << "] is not compatible with camera" << std::endl;
498  if (format == (int)V4L2_MAX_FORMAT) {
499  std::cout << "No pixel format compatible with the camera was found" << std::endl;
500  close();
501 
503  "No pixel format compatible with the camera was found"));
504  }
505  }
506  }
507  }
508 
509  I.resize(height, width) ;
510 
511  init = true;
512 }
513 
523 void
525 {
526  open();
527 
528  if( v4l2_ioctl (fd, VIDIOC_S_INPUT, &input) == -1 )
529  {
530  std::cout << "Warning: cannot set input channel to " << input << std::endl;
531  }
532 
533  vpV4l2PixelFormatType req_pixelformat = getPixelFormat();
534 
535  try {
536  setFormat();
537 
538  startStreaming();
539  }
540  catch(...) {
541  if (verbose) {
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;
545  }
546 
547  // try to fing a compatible format
548  for (int format=0; format< (int)V4L2_MAX_FORMAT; format ++) {
549  if (format == req_pixelformat) {
550  continue;
551  }
552  try {
554  setFormat();
555  startStreaming();
556  if (verbose)
557  std::cout << "This format [" << pixelformat
558  << "] is compatible with camera" << std::endl;
559 
560  break;
561  }
562  catch (...) {
563  if (verbose)
564  std::cout << "This format [" << pixelformat
565  << "] is not compatible with camera" << std::endl;
566 
567  }
568  }
569  }
570 
571  I.resize(height, width) ;
572 
573  init = true;
574 }
575 
576 
577 
588 void
590 {
591  struct timeval timestamp;
592 
593  acquire(I, timestamp);
594 }
595 
609 void
610 vpV4l2Grabber::acquire(vpImage<unsigned char> &I, struct timeval &timestamp)
611 {
612  if (init==false)
613  {
614  open(I);
615  }
616 
617  if (init==false)
618  {
619  close();
620 
622  "V4l2 frame grabber not initialized") );
623  }
624 
625  unsigned char *bitmap ;
626  bitmap = waiton(index_buffer, timestamp);
627 
628  if ((I.getWidth() != width)||(I.getHeight() != height))
629  I.resize(height, width) ;
630 
631  switch(pixelformat) {
632  case V4L2_GREY_FORMAT:
633  memcpy(I.bitmap, bitmap, height * width*sizeof(unsigned char));
634  break;
635  case V4L2_RGB24_FORMAT:
636  vpImageConvert::RGBToGrey((unsigned char *) bitmap, I.bitmap, width*height);
637 
638  break;
639  case V4L2_RGB32_FORMAT:
640  vpImageConvert::RGBaToGrey((unsigned char *) bitmap, I.bitmap, width*height);
641 
642  break;
643  case V4L2_BGR24_FORMAT:
644  vpImageConvert::BGRToGrey( (unsigned char *) bitmap, I.bitmap, width, height, false);
645 
646  break;
647  case V4L2_YUYV_FORMAT:
648  vpImageConvert::YUYVToGrey( (unsigned char *) bitmap, I.bitmap, width*height);
649 
650  break;
651  default:
652  std::cout << "V4L2 conversion not handled" << std::endl;
653  break;
654  }
655 
656  queueAll();
657 }
658 
669 void
671 {
672  struct timeval timestamp;
673 
674  acquire(I, timestamp);
675 }
676 
690 void
691 vpV4l2Grabber::acquire(vpImage<vpRGBa> &I, struct timeval &timestamp)
692 {
693  if (init==false)
694  {
695  open(I);
696  }
697 
698  if (init==false)
699  {
700  close();
701 
703  "V4l2 frame grabber not initialized") );
704  }
705 
706  unsigned char *bitmap ;
707  bitmap = waiton(index_buffer, timestamp);
708 
709  if ((I.getWidth() != width)||(I.getHeight() != height))
710  I.resize(height, width) ;
711 
712  // The framegrabber acquire aRGB format. We just shift the data from 1 byte all the data and initialize the last byte
713 
714  switch(pixelformat) {
715  case V4L2_GREY_FORMAT:
716  vpImageConvert::GreyToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width*height);
717  break;
718  case V4L2_RGB24_FORMAT:
719  vpImageConvert::RGBToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width*height);
720 
721  break;
722  case V4L2_RGB32_FORMAT:
723  // The framegrabber acquire aRGB format. We just shift the data
724  // from 1 byte all the data and initialize the last byte
725  memcpy(I.bitmap, bitmap + 1, height * width * sizeof(vpRGBa) - 1);
726  I[height-1][width-1].A = 0;
727  break;
728  case V4L2_BGR24_FORMAT:
729  vpImageConvert::BGRToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width, height, false);
730  break;
731  case V4L2_YUYV_FORMAT:
732  vpImageConvert::YUYVToRGBa( (unsigned char *) bitmap, (unsigned char *) I.bitmap, width, height);
733  break;
734  default:
735  std::cout << "V4l2 conversion not handled" << std::endl;
736  break;
737  }
738 
739  queueAll();
740 }
757 bool
759 {
760  if(field == 2) return 0; //top field
761  else if (field == 3) return 1; //bottom field;
762  else {
763  close();
764 
766  "V4l2 returns a bad frame field") );
767  return false;
768  }
769 }
784 void
786 {
787  this->framerate = framerate;
788 
789  if (framerate == vpV4l2Grabber::framerate_25fps)
790  setFrameFormat(V4L2_IMAGE_FORMAT);
791  else
792  setFrameFormat(V4L2_FRAME_FORMAT);
793 }
794 
807 {
808  return framerate;
809 }
810 
811 
815 void
817 {
818  stopStreaming();
819  streaming = false;
820 
821  if (fd >= 0){
822  //vpTRACE("v4l2_close()");
823  v4l2_close (fd);
824  fd = -1;
825  }
826 
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; }
833 }
834 
846 void
847 vpV4l2Grabber::open()
848 {
849  /* Open Video Device */
850  struct stat st;
851 
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") );
857 
858  }
859 
860  if (!S_ISCHR (st.st_mode)) {
861  fprintf (stderr, "%s is no device\n", device);
863  "No device") );
864 
865  }
866  fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
867  if (fd < 0) {
868  close();
869 
870  vpERROR_TRACE ("No video device \"%s\"\n", device);
872  "Can't access to video device") );
873 
874  }
875 
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; }
882 
883  inp = new struct v4l2_input [vpV4l2Grabber::MAX_INPUTS];
884  std = new struct v4l2_standard [vpV4l2Grabber::MAX_NORM];
885  fmt = new struct v4l2_fmtdesc [vpV4l2Grabber::MAX_FORMAT];
886  ctl = new struct v4l2_queryctrl [vpV4l2Grabber::MAX_CTRL*2];
887  buf_v4l2 = new struct v4l2_buffer [vpV4l2Grabber::MAX_BUFFERS];
888  buf_me = new struct ng_video_buf [vpV4l2Grabber::MAX_BUFFERS];
889 
890  /* Querry Video Device Capabilities */
891  if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
892  close();
893  fprintf (stderr, "%s is no V4L2 device\n", device);
895  "Is not a V4L2 device") );
896  }
897  if (verbose) {
898  fprintf(stdout, "v4l2 info:\n"
899  " device: %s\n"
900  " %s %d.%d.%d / %s @ %s\n",
901  device,
902  cap.driver,
903  (cap.version >> 16) & 0xff,
904  (cap.version >> 8) & 0xff,
905  cap.version & 0xff,
906  cap.card, cap.bus_info);
907  if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
908  fprintf(stdout, " Support overlay\n");
909  else
910  fprintf(stdout, " Does not support overlay\n");
911  if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
912  fprintf(stdout, " Support capture\n");
913  else
914  fprintf(stdout, " Does not support capture\n");
915  if (cap.capabilities & V4L2_CAP_TUNER)
916  fprintf(stdout, " Support tuning\n");
917  else
918  fprintf(stdout, " Does not support tuning\n");
919  if (cap.capabilities & V4L2_CAP_STREAMING)
920  fprintf(stdout, " Support streaming capture.\n");
921  else
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");
925  else
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");
929  else
930  fprintf(stdout, " Does not support time per frame field\n");
931  // Get framerate
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);
937  }
938  }
939 
940  getCapabilities();
941 }
942 
949 void
950 vpV4l2Grabber::getCapabilities()
951 {
952  for (__u32 ninputs = 0; ninputs < MAX_INPUTS; ninputs++) {
953  inp[ninputs].index = ninputs;
954  if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
955  break;
956  }
957  for (__u32 nstds = 0; nstds < MAX_NORM; nstds++) {
958  std[nstds].index = nstds;
959  if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &std[nstds]))
960  break;
961 
962  }
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]))
967  break;
968  }
969 
970  streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
971  if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
972  {
973  close();
974 
976  "Can't get video parameters") );
977  }
978 }
979 
993 void
994 vpV4l2Grabber::setFormat()
995 {
996  fmt_me.width = _width;
997  fmt_me.height = _height;
998  //fmt_me.bytesperline = _width; // bad (normally _width * depth / 8), but works
999  // because initialized later by an ioctl call to VIDIOC_S_FMT
1000 
1001  switch(pixelformat) {
1002  case V4L2_GREY_FORMAT : fmt_me.pixelformat = V4L2_PIX_FMT_GREY;
1003  if (verbose)
1004  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
1005  break;
1006  case V4L2_RGB24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB24;
1007  if (verbose)
1008  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
1009  break;
1010  case V4L2_RGB32_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB32;
1011  if (verbose)
1012  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
1013  break;
1014  case V4L2_BGR24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_BGR24;
1015  if (verbose)
1016  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
1017  break;
1018  case V4L2_YUYV_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_YUYV;
1019  if (verbose)
1020  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1021  break;
1022 
1023  default:
1024  close();
1025 
1027  "Bad format, probably do to a wrong scale"));
1028  }
1029 
1030  /* Get Video Format */
1031  vpCLEAR (fmt_v4l2);
1032 
1033  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1034 
1035  if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1036  close();
1037 
1039  "Can't get video format") );
1040  }
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;
1044  //printf("1 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1045 
1046 
1047  switch (frameformat) {
1048  case V4L2_FRAME_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_ALTERNATE;
1049  if (verbose) {
1050  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1051  }
1052  break;
1053  case V4L2_IMAGE_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_INTERLACED;
1054  if (verbose) {
1055  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1056  }
1057  break;
1058  default:
1059  close();
1060 
1062  "Unrecognized frame format") );
1063  }
1064 
1065  //height and width of the captured image or frame
1066  width = _width;
1067  height = _height;
1068  if( frameformat == V4L2_FRAME_FORMAT && height > FRAME_SIZE )
1069  {
1070  height = FRAME_SIZE;
1071  }
1072  //printf("2 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1073 
1074  if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1076  "Can't set video format") );
1077  }
1078 
1079  if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1081  "Bad pixel format") );
1082  }
1083 
1084  /* Buggy driver paranoia. */
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;
1091 
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;
1095 
1096  if (verbose) {
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);
1105  }
1106 
1107 }
1116 void
1117 vpV4l2Grabber::startStreaming()
1118 {
1119  if (streaming == true) { // Acquisition in process.
1120  stopStreaming();
1121  streaming = false;
1122  }
1123 
1124  /* setup buffers */
1125  memset (&(reqbufs), 0, sizeof (reqbufs));
1126  reqbufs.count = nbuffers;
1127  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1128  reqbufs.memory = V4L2_MEMORY_MMAP;
1129 
1130 
1131  if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1132  {
1133  if (EINVAL == errno) {
1134  fprintf (stderr, "%s does not support "
1135  "memory mapping\n", device);
1137  "Does not support memory mapping") );
1138  }
1140  "Can't require video buffers") );
1141  }
1142 
1143  for (unsigned i = 0; i < reqbufs.count; i++) {
1144  // Clear the buffer
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)
1151  {
1153  "Can't query video buffers") );
1154  }
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;
1157 
1158  // if (verbose)
1159  // std::cout << "1: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1160  // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1161  // << std::endl;
1162 
1163 
1164  buf_me[i].data = (unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1165  PROT_READ | PROT_WRITE,
1166  MAP_SHARED,
1167  fd, (off_t)buf_v4l2[i].m.offset);
1168 
1169  if(buf_me[i].data == MAP_FAILED)
1170  {
1172  "Can't map memory") );
1173  }
1174 
1175  buf_me[i].refcount = 0;
1176 
1177 // if (verbose)
1178 // {
1179 // std::cout << "2: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1180 // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1181 // << std::endl;
1182 // std::cout << "2: buf_me[" << i << "].size: " << buf_me[i].size << std::endl;
1183 // }
1184 
1185  if (verbose)
1186  printBufInfo(buf_v4l2[i]);
1187  }
1188 
1189  /* queue up all buffers */
1190  queueAll();
1191 
1192  /* Set video stream capture on */
1193  if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1194  {
1196  "Can't start streaming") );
1197  }
1198 
1199  streaming = true;
1200 }
1201 
1208 void
1209 vpV4l2Grabber::stopStreaming()
1210 {
1211  unsigned int i;
1212 
1213  //nothing to do if (fd < 0) or if (streaming == false)
1214  if ((fd >= 0) && (streaming == true)) {
1215 
1216  //vpTRACE(" Stop the streaming...");
1217  /* stop capture */
1218  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1219  if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1221  "Can't stop streaming") );
1222  }
1223  /* free buffers */
1224  for (i = 0; i < reqbufs.count; i++) {
1225  if (verbose)
1226  printBufInfo(buf_v4l2[i]);
1227  //vpTRACE("v4l2_munmap()");
1228 
1229  if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1231  "Can't unmap memory") );
1232  }
1233  }
1234  queue = 0;
1235  waiton_cpt = 0;
1236  streaming = false;
1237  }
1238 }
1239 
1253 unsigned char *
1254 vpV4l2Grabber::waiton(__u32 &index, struct timeval &timestamp)
1255 {
1256  struct v4l2_buffer buf;
1257  struct timeval tv;
1258  fd_set rdset;
1259 
1260  /* wait for the next frame */
1261  again:
1262 
1263  tv.tv_sec = 30;
1264  tv.tv_usec = 0;
1265  FD_ZERO(&rdset);
1266  FD_SET(static_cast<unsigned int>(fd), &rdset);
1267  switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1268  case -1:
1269  if (EINTR == errno)
1270  goto again;
1271  index = 0;
1273  "Can't access to the frame") );
1274  return NULL;
1275  case 0:
1276  index = 0;
1278  "Can't access to the frame: timeout") );
1279  return NULL;
1280  }
1281 
1282 
1283  /* get it */
1284  memset(&buf, 0, sizeof(buf));
1285  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1286  buf.memory = V4L2_MEMORY_MMAP; // Fabien manquait
1287  if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1288  index = 0;
1289  switch(errno)
1290  {
1291  case EAGAIN:
1293  "VIDIOC_DQBUF: EAGAIN") );
1294  break;
1295  case EINVAL:
1297  "VIDIOC_DQBUF: EINVAL") );
1298  break;
1299  case ENOMEM:
1301  "VIDIOC_DQBUF: ENOMEM") );
1302  break;
1303  default:
1305  "VIDIOC_DQBUF") );
1306  break;
1307  }
1308  return NULL;
1309  }
1310 
1311  waiton_cpt++;
1312  buf_v4l2[buf.index] = buf;
1313 
1314  index = buf.index;
1315 
1316  field = buf_v4l2[index].field;
1317 
1318  timestamp = buf_v4l2[index].timestamp;
1319 
1320  // if(verbose)
1321  // {
1322  // vpERROR_TRACE("field: %d\n", buf_v4l2[index].field);
1323 
1324  // vpERROR_TRACE("data adress : 0x%p\n", buf_me[buf.index].data);
1325  // }
1326  return buf_me[buf.index].data;
1327 }
1328 
1334 int
1335 vpV4l2Grabber::queueBuffer()
1336 {
1337  unsigned int frame = queue % reqbufs.count;
1338  int rc;
1339 
1340 
1341  if (0 != buf_me[frame].refcount) {
1342  if (0 != queue - waiton_cpt)
1343  return -1;
1344  fprintf(stderr,"v4l2: waiting for a free buffer..............\n");
1345  //ng_waiton_video_buf(h->buf_me+frame);
1346  std::cout << "Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1347  }
1348 
1349  // std::cout << "frame: " << frame << std::endl;
1350  rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1351  if (0 == rc)
1352  queue++;
1353  else
1354  {
1355  switch(errno)
1356  {
1357  case EAGAIN:
1359  "VIDIOC_QBUF: EAGAIN") );
1360  break;
1361  case EINVAL:
1363  "VIDIOC_QBUF: EINVAL") );
1364  break;
1365  case ENOMEM:
1367  "VIDIOC_QBUF: ENOMEM") );
1368  break;
1369  default:
1371  "VIDIOC_QBUF") );
1372  break;
1373  }
1374  }
1375  return rc;
1376 }
1377 
1383 void
1384 vpV4l2Grabber::queueAll()
1385 {
1386  for (;;) {
1387  if (queue - waiton_cpt >= reqbufs.count) {
1388  return;
1389  }
1390  if (0 != queueBuffer()) {
1391  return;
1392  }
1393  }
1394 }
1395 
1401 void
1402 vpV4l2Grabber::printBufInfo(struct v4l2_buffer buf)
1403 {
1404  char type[40];
1405 
1406  switch(buf.type) {
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;
1413  }
1414 
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);
1418 
1419 }
1420 #endif
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:159
#define vpERROR_TRACE
Definition: vpDebug.h:395
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
vpV4l2FramerateType getFramerate()
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
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.
Definition: vpRGBa.h:68
void setHeight(unsigned height)
virtual ~vpV4l2Grabber()
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
Definition: vpImage.h:532
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
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip)
unsigned int getHeight() const
Definition: vpImage.h:150
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)