ViSP  2.8.0
vpV4l2Grabber.cpp
1 /****************************************************************************
2  *
3  * $Id: vpV4l2Grabber.cpp 4317 2013-07-17 09:40:17Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 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  }
928 
929  getCapabilities();
930 }
931 
938 void
939 vpV4l2Grabber::getCapabilities()
940 {
941  for (__u32 ninputs = 0; ninputs < MAX_INPUTS; ninputs++) {
942  inp[ninputs].index = ninputs;
943  if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
944  break;
945  }
946  for (__u32 nstds = 0; nstds < MAX_NORM; nstds++) {
947  std[nstds].index = nstds;
948  if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &std[nstds]))
949  break;
950 
951  }
952  for (__u32 nfmts = 0; nfmts < MAX_FORMAT; nfmts++) {
953  fmt[nfmts].index = nfmts;
954  fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
955  if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
956  break;
957  }
958 
959  streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960  if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
961  {
962  close();
963 
965  "Can't get video parameters") );
966  }
967 }
968 
982 void
983 vpV4l2Grabber::setFormat()
984 {
985  fmt_me.width = _width;
986  fmt_me.height = _height;
987  //fmt_me.bytesperline = _width; // bad (normally _width * depth / 8), but works
988  // because initialized later by an ioctl call to VIDIOC_S_FMT
989 
990  switch(pixelformat) {
991  case V4L2_GREY_FORMAT : fmt_me.pixelformat = V4L2_PIX_FMT_GREY;
992  if (verbose)
993  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
994  break;
995  case V4L2_RGB24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB24;
996  if (verbose)
997  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
998  break;
999  case V4L2_RGB32_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB32;
1000  if (verbose)
1001  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
1002  break;
1003  case V4L2_BGR24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_BGR24;
1004  if (verbose)
1005  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
1006  break;
1007  case V4L2_YUYV_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_YUYV;
1008  if (verbose)
1009  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1010  break;
1011 
1012  default:
1013  close();
1014 
1016  "Bad format, probably do to a wrong scale"));
1017  }
1018 
1019  /* Get Video Format */
1020  vpCLEAR (fmt_v4l2);
1021 
1022  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1023 
1024  if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1025  close();
1026 
1028  "Can't get video format") );
1029  }
1030  fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
1031  fmt_v4l2.fmt.pix.width = fmt_me.width;
1032  fmt_v4l2.fmt.pix.height = fmt_me.height;
1033  //printf("1 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1034 
1035 
1036  switch (frameformat) {
1037  case V4L2_FRAME_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_ALTERNATE;
1038  if (verbose) {
1039  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1040  }
1041  break;
1042  case V4L2_IMAGE_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_INTERLACED;
1043  if (verbose) {
1044  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1045  }
1046  break;
1047  default:
1048  close();
1049 
1051  "Unrecognized frame format") );
1052  }
1053 
1054  //height and width of the captured image or frame
1055  width = _width;
1056  height = _height;
1057  if( frameformat == V4L2_FRAME_FORMAT && height > FRAME_SIZE )
1058  {
1059  height = FRAME_SIZE;
1060  }
1061  //printf("2 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1062 
1063  if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1065  "Can't set video format") );
1066  }
1067 
1068  if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1070  "Bad pixel format") );
1071  }
1072 
1073  /* Buggy driver paranoia. */
1074  unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1075  if (fmt_v4l2.fmt.pix.bytesperline < min)
1076  fmt_v4l2.fmt.pix.bytesperline = min;
1077  min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1078  if (fmt_v4l2.fmt.pix.sizeimage < min)
1079  fmt_v4l2.fmt.pix.sizeimage = min;
1080 
1081  fmt_me.width = fmt_v4l2.fmt.pix.width;
1082  fmt_me.height = fmt_v4l2.fmt.pix.height;
1083  fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1084 
1085  if (verbose) {
1086  fprintf(stdout,"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1087  fmt_me.width, fmt_me.height,
1088  fmt_v4l2.fmt.pix.pixelformat & 0xff,
1089  (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1090  (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1091  (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1092  fmt_v4l2.fmt.pix.sizeimage,
1093  fmt_v4l2.fmt.pix.bytesperline);
1094  }
1095 
1096 }
1105 void
1106 vpV4l2Grabber::startStreaming()
1107 {
1108  if (streaming == true) { // Acquisition in process.
1109  stopStreaming();
1110  streaming = false;
1111  }
1112 
1113  /* setup buffers */
1114  memset (&(reqbufs), 0, sizeof (reqbufs));
1115  reqbufs.count = nbuffers;
1116  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1117  reqbufs.memory = V4L2_MEMORY_MMAP;
1118 
1119 
1120  if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1121  {
1122  if (EINVAL == errno) {
1123  fprintf (stderr, "%s does not support "
1124  "memory mapping\n", device);
1126  "Does not support memory mapping") );
1127  }
1129  "Can't require video buffers") );
1130  }
1131 
1132  for (unsigned i = 0; i < reqbufs.count; i++) {
1133  // Clear the buffer
1134  memset (&(buf_v4l2[i]), 0, sizeof (buf_v4l2[i]));
1135  buf_v4l2[i].index = i;
1136  buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1137  buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1138  buf_v4l2[i].length = 0;
1139  if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1140  {
1142  "Can't query video buffers") );
1143  }
1144  memcpy(&buf_me[i].fmt, &fmt_me, sizeof(ng_video_fmt));
1145  buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1146 
1147  // if (verbose)
1148  // std::cout << "1: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1149  // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1150  // << std::endl;
1151 
1152 
1153  buf_me[i].data = (unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1154  PROT_READ | PROT_WRITE,
1155  MAP_SHARED,
1156  fd, (off_t)buf_v4l2[i].m.offset);
1157 
1158  if(buf_me[i].data == MAP_FAILED)
1159  {
1161  "Can't map memory") );
1162  }
1163 
1164  buf_me[i].refcount = 0;
1165 
1166 // if (verbose)
1167 // {
1168 // std::cout << "2: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1169 // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1170 // << std::endl;
1171 // std::cout << "2: buf_me[" << i << "].size: " << buf_me[i].size << std::endl;
1172 // }
1173 
1174  if (verbose)
1175  printBufInfo(buf_v4l2[i]);
1176  }
1177 
1178  /* queue up all buffers */
1179  queueAll();
1180 
1181  /* Set video stream capture on */
1182  if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1183  {
1185  "Can't start streaming") );
1186  }
1187 
1188  streaming = true;
1189 }
1190 
1197 void
1198 vpV4l2Grabber::stopStreaming()
1199 {
1200  unsigned int i;
1201 
1202  //nothing to do if (fd < 0) or if (streaming == false)
1203  if ((fd >= 0) && (streaming == true)) {
1204 
1205  //vpTRACE(" Stop the streaming...");
1206  /* stop capture */
1207  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1208  if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1210  "Can't stop streaming") );
1211  }
1212  /* free buffers */
1213  for (i = 0; i < reqbufs.count; i++) {
1214  if (verbose)
1215  printBufInfo(buf_v4l2[i]);
1216  //vpTRACE("v4l2_munmap()");
1217 
1218  if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1220  "Can't unmap memory") );
1221  }
1222  }
1223  queue = 0;
1224  waiton_cpt = 0;
1225  streaming = false;
1226  }
1227 }
1228 
1242 unsigned char *
1243 vpV4l2Grabber::waiton(__u32 &index, struct timeval &timestamp)
1244 {
1245  struct v4l2_buffer buf;
1246  struct timeval tv;
1247  fd_set rdset;
1248 
1249  /* wait for the next frame */
1250  again:
1251 
1252  tv.tv_sec = 30;
1253  tv.tv_usec = 0;
1254  FD_ZERO(&rdset);
1255  FD_SET(static_cast<unsigned int>(fd), &rdset);
1256  switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1257  case -1:
1258  if (EINTR == errno)
1259  goto again;
1260  index = 0;
1262  "Can't access to the frame") );
1263  return NULL;
1264  case 0:
1265  index = 0;
1267  "Can't access to the frame: timeout") );
1268  return NULL;
1269  }
1270 
1271 
1272  /* get it */
1273  memset(&buf, 0, sizeof(buf));
1274  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1275  buf.memory = V4L2_MEMORY_MMAP; // Fabien manquait
1276  if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1277  index = 0;
1278  switch(errno)
1279  {
1280  case EAGAIN:
1282  "VIDIOC_DQBUF: EAGAIN") );
1283  break;
1284  case EINVAL:
1286  "VIDIOC_DQBUF: EINVAL") );
1287  break;
1288  case ENOMEM:
1290  "VIDIOC_DQBUF: ENOMEM") );
1291  break;
1292  default:
1294  "VIDIOC_DQBUF") );
1295  break;
1296  }
1297  return NULL;
1298  }
1299 
1300  waiton_cpt++;
1301  buf_v4l2[buf.index] = buf;
1302 
1303  index = buf.index;
1304 
1305  field = buf_v4l2[index].field;
1306 
1307  timestamp = buf_v4l2[index].timestamp;
1308 
1309  // if(verbose)
1310  // {
1311  // vpERROR_TRACE("field: %d\n", buf_v4l2[index].field);
1312 
1313  // vpERROR_TRACE("data adress : 0x%p\n", buf_me[buf.index].data);
1314  // }
1315  return buf_me[buf.index].data;
1316 }
1317 
1323 int
1324 vpV4l2Grabber::queueBuffer()
1325 {
1326  unsigned int frame = queue % reqbufs.count;
1327  int rc;
1328 
1329 
1330  if (0 != buf_me[frame].refcount) {
1331  if (0 != queue - waiton_cpt)
1332  return -1;
1333  fprintf(stderr,"v4l2: waiting for a free buffer..............\n");
1334  //ng_waiton_video_buf(h->buf_me+frame);
1335  std::cout << "Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1336  }
1337 
1338  // std::cout << "frame: " << frame << std::endl;
1339  rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1340  if (0 == rc)
1341  queue++;
1342  else
1343  {
1344  switch(errno)
1345  {
1346  case EAGAIN:
1348  "VIDIOC_QBUF: EAGAIN") );
1349  break;
1350  case EINVAL:
1352  "VIDIOC_QBUF: EINVAL") );
1353  break;
1354  case ENOMEM:
1356  "VIDIOC_QBUF: ENOMEM") );
1357  break;
1358  default:
1360  "VIDIOC_QBUF") );
1361  break;
1362  }
1363  }
1364  return rc;
1365 }
1366 
1372 void
1373 vpV4l2Grabber::queueAll()
1374 {
1375  for (;;) {
1376  if (queue - waiton_cpt >= reqbufs.count) {
1377  return;
1378  }
1379  if (0 != queueBuffer()) {
1380  return;
1381  }
1382  }
1383 }
1384 
1390 void
1391 vpV4l2Grabber::printBufInfo(struct v4l2_buffer buf)
1392 {
1393  char type[40];
1394 
1395  switch(buf.type) {
1396  case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type, "video-cap"); break;
1397  case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type, "video-over"); break;
1398  case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type, "video-out"); break;
1399  case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type, "vbi-cap"); break;
1400  case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type, "vbi-out"); break;
1401  default: sprintf(type, "unknown"); break;
1402  }
1403 
1404  fprintf(stdout,"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1405  buf.index, buf.type, buf.m.userptr, buf.m.offset,
1406  buf.length, buf.length, buf.bytesused);
1407 
1408 }
1409 #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:379
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 resize(const unsigned int height, const unsigned int width)
set the size of the image
Definition: vpImage.h:535
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
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)