ViSP  2.6.2
vpV4l2Grabber.cpp
1 /****************************************************************************
2  *
3  * $Id: vpV4l2Grabber.cpp 3726 2012-05-11 17:39:07Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 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 shoud 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 
613  if (init==false)
614  {
615  close();
616 
618  "V4l2 frame grabber not initialized") );
619  }
620 
621  unsigned char *bitmap ;
622  bitmap = waiton(index_buffer, timestamp);
623 
624  if ((I.getWidth() != width)||(I.getHeight() != height))
625  I.resize(height, width) ;
626 
627  switch(pixelformat) {
628  case V4L2_GREY_FORMAT:
629  memcpy(I.bitmap, bitmap, height * width*sizeof(unsigned char));
630  break;
631  case V4L2_RGB24_FORMAT:
632  vpImageConvert::RGBToGrey((unsigned char *) bitmap, I.bitmap, width*height);
633 
634  break;
635  case V4L2_RGB32_FORMAT:
636  vpImageConvert::RGBaToGrey((unsigned char *) bitmap, I.bitmap, width*height);
637 
638  break;
639  case V4L2_BGR24_FORMAT:
640  vpImageConvert::BGRToGrey( (unsigned char *) bitmap, I.bitmap, width, height, false);
641 
642  break;
643  case V4L2_YUYV_FORMAT:
644  vpImageConvert::YUYVToGrey( (unsigned char *) bitmap, I.bitmap, width*height);
645 
646  break;
647  default:
648  std::cout << "V4L2 conversion not handled" << std::endl;
649  break;
650  }
651 
652  queueAll();
653 }
654 
665 void
667 {
668  struct timeval timestamp;
669 
670  acquire(I, timestamp);
671 }
672 
686 void
687 vpV4l2Grabber::acquire(vpImage<vpRGBa> &I, struct timeval &timestamp)
688 {
689 
690  if (init==false)
691  {
692  close();
693 
695  "V4l2 frame grabber not initialized") );
696  }
697 
698  unsigned char *bitmap ;
699  bitmap = waiton(index_buffer, timestamp);
700 
701  if ((I.getWidth() != width)||(I.getHeight() != height))
702  I.resize(height, width) ;
703 
704  // The framegrabber acquire aRGB format. We just shift the data from 1 byte all the data and initialize the last byte
705 
706  switch(pixelformat) {
707  case V4L2_GREY_FORMAT:
708  vpImageConvert::GreyToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width*height);
709  break;
710  case V4L2_RGB24_FORMAT:
711  vpImageConvert::RGBToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width*height);
712 
713  break;
714  case V4L2_RGB32_FORMAT:
715  // The framegrabber acquire aRGB format. We just shift the data
716  // from 1 byte all the data and initialize the last byte
717  memcpy(I.bitmap, bitmap + 1, height * width * sizeof(vpRGBa) - 1);
718  I[height-1][width-1].A = 0;
719  break;
720  case V4L2_BGR24_FORMAT:
721  vpImageConvert::BGRToRGBa((unsigned char *) bitmap, (unsigned char *) I.bitmap, width, height, false);
722  break;
723  case V4L2_YUYV_FORMAT:
724  vpImageConvert::YUYVToRGBa( (unsigned char *) bitmap, (unsigned char *) I.bitmap, width, height);
725  break;
726  default:
727  std::cout << "V4l2 conversion not handled" << std::endl;
728  break;
729  }
730 
731  queueAll();
732 }
749 bool
751 {
752  if(field == 2) return 0; //top field
753  else if (field == 3) return 1; //bottom field;
754  else {
755  close();
756 
758  "V4l2 returns a bad frame field") );
759  return false;
760  }
761 }
776 void
778 {
779  this->framerate = framerate;
780 
781  if (framerate == vpV4l2Grabber::framerate_25fps)
782  setFrameFormat(V4L2_IMAGE_FORMAT);
783  else
784  setFrameFormat(V4L2_FRAME_FORMAT);
785 }
786 
799 {
800  return framerate;
801 }
802 
803 
807 void
809 {
810  stopStreaming();
811  streaming = false;
812 
813  if (fd >= 0){
814  //vpTRACE("v4l2_close()");
815  v4l2_close (fd);
816  fd = -1;
817  }
818 
819  if (inp != NULL) { delete [] inp; inp = NULL; }
820  if (std != NULL) { delete [] std; std = NULL; }
821  if (fmt != NULL) { delete [] fmt; fmt = NULL; }
822  if (ctl != NULL) { delete [] ctl; ctl = NULL; }
823  if (buf_v4l2 != NULL) { delete [] buf_v4l2; buf_v4l2 = NULL; }
824  if (buf_me != NULL) { delete [] buf_me; buf_me = NULL; }
825 }
826 
838 void
839 vpV4l2Grabber::open()
840 {
841  /* Open Video Device */
842  struct stat st;
843 
844  if (-1 == stat (device, &st)) {
845  fprintf (stderr, "Cannot identify '%s': %d, %s\n",
846  device, errno, strerror (errno));
848  "Cannot identify video device") );
849 
850  }
851 
852  if (!S_ISCHR (st.st_mode)) {
853  fprintf (stderr, "%s is no device\n", device);
855  "No device") );
856 
857  }
858  fd = v4l2_open (device, O_RDWR | O_NONBLOCK, 0);
859  if (fd < 0) {
860  close();
861 
862  vpERROR_TRACE ("No video device \"%s\"\n", device);
864  "Can't access to video device") );
865 
866  }
867 
868  if (inp != NULL) { delete [] inp; inp = NULL; }
869  if (std != NULL) { delete [] std; std = NULL; }
870  if (fmt != NULL) { delete [] fmt; fmt = NULL; }
871  if (ctl != NULL) { delete [] ctl; ctl = NULL; }
872  if (buf_v4l2 != NULL) { delete [] buf_v4l2; buf_v4l2 = NULL; }
873  if (buf_me != NULL) { delete [] buf_me; buf_me = NULL; }
874 
875  inp = new struct v4l2_input [vpV4l2Grabber::MAX_INPUTS];
876  std = new struct v4l2_standard [vpV4l2Grabber::MAX_NORM];
877  fmt = new struct v4l2_fmtdesc [vpV4l2Grabber::MAX_FORMAT];
878  ctl = new struct v4l2_queryctrl [vpV4l2Grabber::MAX_CTRL*2];
879  buf_v4l2 = new struct v4l2_buffer [vpV4l2Grabber::MAX_BUFFERS];
880  buf_me = new struct ng_video_buf [vpV4l2Grabber::MAX_BUFFERS];
881 
882  /* Querry Video Device Capabilities */
883  if ( v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) == -1 ) {
884  close();
885  fprintf (stderr, "%s is no V4L2 device\n", device);
887  "Is not a V4L2 device") );
888  }
889  if (verbose) {
890  fprintf(stdout, "v4l2 info:\n"
891  " device: %s\n"
892  " %s %d.%d.%d / %s @ %s\n",
893  device,
894  cap.driver,
895  (cap.version >> 16) & 0xff,
896  (cap.version >> 8) & 0xff,
897  cap.version & 0xff,
898  cap.card, cap.bus_info);
899  if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
900  fprintf(stdout, " Support overlay\n");
901  else
902  fprintf(stdout, " Does not support overlay\n");
903  if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
904  fprintf(stdout, " Support capture\n");
905  else
906  fprintf(stdout, " Does not support capture\n");
907  if (cap.capabilities & V4L2_CAP_TUNER)
908  fprintf(stdout, " Support tuning\n");
909  else
910  fprintf(stdout, " Does not support tuning\n");
911  if (cap.capabilities & V4L2_CAP_STREAMING)
912  fprintf(stdout, " Support streaming capture.\n");
913  else
914  fprintf(stdout, " Does not support streaming capture.\n");
915  if(cap.capabilities & V4L2_CAP_ASYNCIO)
916  fprintf(stdout, " Support asynchronous I/O methods.\n");
917  else
918  fprintf(stdout, " Does not support asynchronous I/O methods.\n");
919  }
920 
921  getCapabilities();
922 }
923 
930 void
931 vpV4l2Grabber::getCapabilities()
932 {
933  for (__u32 ninputs = 0; ninputs < MAX_INPUTS; ninputs++) {
934  inp[ninputs].index = ninputs;
935  if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &inp[ninputs]))
936  break;
937  }
938  for (__u32 nstds = 0; nstds < MAX_NORM; nstds++) {
939  std[nstds].index = nstds;
940  if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &std[nstds]))
941  break;
942 
943  }
944  for (__u32 nfmts = 0; nfmts < MAX_FORMAT; nfmts++) {
945  fmt[nfmts].index = nfmts;
946  fmt[nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
947  if (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt[nfmts]))
948  break;
949  }
950 
951  streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
952  if (v4l2_ioctl(fd, VIDIOC_G_PARM, &streamparm) == -1)
953  {
954  close();
955 
957  "Can't get video parameters") );
958  }
959 }
960 
974 void
975 vpV4l2Grabber::setFormat()
976 {
977  fmt_me.width = _width;
978  fmt_me.height = _height;
979  //fmt_me.bytesperline = _width; // bad (normally _width * depth / 8), but works
980  // because initialized later by an ioctl call to VIDIOC_S_FMT
981 
982  switch(pixelformat) {
983  case V4L2_GREY_FORMAT : fmt_me.pixelformat = V4L2_PIX_FMT_GREY;
984  if (verbose)
985  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_GREY)\n");
986  break;
987  case V4L2_RGB24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB24;
988  if (verbose)
989  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB24)\n");
990  break;
991  case V4L2_RGB32_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_RGB32;
992  if (verbose)
993  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_RGB32)\n");
994  break;
995  case V4L2_BGR24_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_BGR24;
996  if (verbose)
997  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_BGR24)\n");
998  break;
999  case V4L2_YUYV_FORMAT: fmt_me.pixelformat = V4L2_PIX_FMT_YUYV;
1000  if (verbose)
1001  fprintf(stdout,"v4l2: new capture params (V4L2_PIX_FMT_YUYV)\n");
1002  break;
1003 
1004  default:
1005  close();
1006 
1008  "Bad format, probably do to a wrong scale"));
1009  }
1010 
1011  /* Get Video Format */
1012  vpCLEAR (fmt_v4l2);
1013 
1014  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1015 
1016  if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt_v4l2) == -1 ) {
1017  close();
1018 
1020  "Can't get video format") );
1021  }
1022  fmt_v4l2.fmt.pix.pixelformat = fmt_me.pixelformat;
1023  fmt_v4l2.fmt.pix.width = fmt_me.width;
1024  fmt_v4l2.fmt.pix.height = fmt_me.height;
1025  //printf("1 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1026 
1027 
1028  switch (frameformat) {
1029  case V4L2_FRAME_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_ALTERNATE;
1030  if (verbose) {
1031  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_ALTERNATE)\n");
1032  }
1033  break;
1034  case V4L2_IMAGE_FORMAT: fmt_v4l2.fmt.pix.field = V4L2_FIELD_INTERLACED;
1035  if (verbose) {
1036  fprintf(stdout,"v4l2: new capture params (V4L2_FIELD_INTERLACED)\n");
1037  }
1038  break;
1039  default:
1040  close();
1041 
1043  "Unrecognized frame format") );
1044  }
1045 
1046  //height and width of the captured image or frame
1047  width = _width;
1048  height = _height;
1049  if( frameformat == V4L2_FRAME_FORMAT && height > FRAME_SIZE )
1050  {
1051  height = FRAME_SIZE;
1052  }
1053  //printf("2 - w: %d h: %d\n", fmt_v4l2.fmt.pix.width, fmt_v4l2.fmt.pix.height);
1054 
1055  if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt_v4l2) == -1) {
1057  "Can't set video format") );
1058  }
1059 
1060  if (fmt_v4l2.fmt.pix.pixelformat != fmt_me.pixelformat) {
1062  "Bad pixel format") );
1063  }
1064 
1065  /* Buggy driver paranoia. */
1066  unsigned int min = fmt_v4l2.fmt.pix.width * 2;
1067  if (fmt_v4l2.fmt.pix.bytesperline < min)
1068  fmt_v4l2.fmt.pix.bytesperline = min;
1069  min = fmt_v4l2.fmt.pix.bytesperline * fmt_v4l2.fmt.pix.height;
1070  if (fmt_v4l2.fmt.pix.sizeimage < min)
1071  fmt_v4l2.fmt.pix.sizeimage = min;
1072 
1073  fmt_me.width = fmt_v4l2.fmt.pix.width;
1074  fmt_me.height = fmt_v4l2.fmt.pix.height;
1075  fmt_me.bytesperline = fmt_v4l2.fmt.pix.bytesperline;
1076 
1077  if (verbose) {
1078  fprintf(stdout,"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte, %d bytes per line)\n",
1079  fmt_me.width, fmt_me.height,
1080  fmt_v4l2.fmt.pix.pixelformat & 0xff,
1081  (fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff,
1082  (fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,
1083  (fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,
1084  fmt_v4l2.fmt.pix.sizeimage,
1085  fmt_v4l2.fmt.pix.bytesperline);
1086  }
1087 
1088 }
1097 void
1098 vpV4l2Grabber::startStreaming()
1099 {
1100  if (streaming == true) { // Acquisition in process.
1101  stopStreaming();
1102  streaming = false;
1103  }
1104 
1105  /* setup buffers */
1106  memset (&(reqbufs), 0, sizeof (reqbufs));
1107  reqbufs.count = nbuffers;
1108  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1109  reqbufs.memory = V4L2_MEMORY_MMAP;
1110 
1111 
1112  if (v4l2_ioctl(fd, VIDIOC_REQBUFS, &reqbufs) == -1)
1113  {
1114  if (EINVAL == errno) {
1115  fprintf (stderr, "%s does not support "
1116  "memory mapping\n", device);
1118  "Does not support memory mapping") );
1119  }
1121  "Can't require video buffers") );
1122  }
1123 
1124  for (unsigned i = 0; i < reqbufs.count; i++) {
1125  // Clear the buffer
1126  memset (&(buf_v4l2[i]), 0, sizeof (buf_v4l2[i]));
1127  buf_v4l2[i].index = i;
1128  buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1129  buf_v4l2[i].memory = V4L2_MEMORY_MMAP;
1130  buf_v4l2[i].length = 0;
1131  if (v4l2_ioctl(fd, VIDIOC_QUERYBUF, &buf_v4l2[i]) == -1)
1132  {
1134  "Can't query video buffers") );
1135  }
1136  memcpy(&buf_me[i].fmt, &fmt_me, sizeof(ng_video_fmt));
1137  buf_me[i].size = buf_me[i].fmt.bytesperline * buf_me[i].fmt.height;
1138 
1139  // if (verbose)
1140  // std::cout << "1: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1141  // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1142  // << std::endl;
1143 
1144 
1145  buf_me[i].data = (unsigned char *) v4l2_mmap(NULL, buf_v4l2[i].length,
1146  PROT_READ | PROT_WRITE,
1147  MAP_SHARED,
1148  fd, (off_t)buf_v4l2[i].m.offset);
1149 
1150  if(buf_me[i].data == MAP_FAILED)
1151  {
1153  "Can't map memory") );
1154  }
1155 
1156  buf_me[i].refcount = 0;
1157 
1158 // if (verbose)
1159 // {
1160 // std::cout << "2: buf_v4l2[" << i << "].length: " << buf_v4l2[i].length
1161 // << " buf_v4l2[" << i << "].offset: " << buf_v4l2[i].m.offset
1162 // << std::endl;
1163 // std::cout << "2: buf_me[" << i << "].size: " << buf_me[i].size << std::endl;
1164 // }
1165 
1166  if (verbose)
1167  printBufInfo(buf_v4l2[i]);
1168  }
1169 
1170  /* queue up all buffers */
1171  queueAll();
1172 
1173  /* Set video stream capture on */
1174  if (v4l2_ioctl(fd, VIDIOC_STREAMON, &fmt_v4l2.type)<0)
1175  {
1177  "Can't start streaming") );
1178  }
1179 
1180  streaming = true;
1181 }
1182 
1189 void
1190 vpV4l2Grabber::stopStreaming()
1191 {
1192  unsigned int i;
1193 
1194  //nothing to do if (fd < 0) or if (streaming == false)
1195  if ((fd >= 0) && (streaming == true)) {
1196 
1197  //vpTRACE(" Stop the streaming...");
1198  /* stop capture */
1199  fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1200  if (v4l2_ioctl(fd, VIDIOC_STREAMOFF,&fmt_v4l2.type)) {
1202  "Can't stop streaming") );
1203  }
1204  /* free buffers */
1205  for (i = 0; i < reqbufs.count; i++) {
1206  if (verbose)
1207  printBufInfo(buf_v4l2[i]);
1208  //vpTRACE("v4l2_munmap()");
1209 
1210  if (-1 == v4l2_munmap(buf_me[i].data, buf_me[i].size)) {
1212  "Can't unmap memory") );
1213  }
1214  }
1215  queue = 0;
1216  waiton_cpt = 0;
1217  streaming = false;
1218  }
1219 }
1220 
1234 unsigned char *
1235 vpV4l2Grabber::waiton(__u32 &index, struct timeval &timestamp)
1236 {
1237  struct v4l2_buffer buf;
1238  struct timeval tv;
1239  fd_set rdset;
1240 
1241  /* wait for the next frame */
1242  again:
1243 
1244  tv.tv_sec = 30;
1245  tv.tv_usec = 0;
1246  FD_ZERO(&rdset);
1247  FD_SET(static_cast<unsigned int>(fd), &rdset);
1248  switch (select(fd + 1, &rdset, NULL, NULL, &tv)) {
1249  case -1:
1250  if (EINTR == errno)
1251  goto again;
1252  index = 0;
1254  "Can't access to the frame") );
1255  return NULL;
1256  case 0:
1257  index = 0;
1259  "Can't access to the frame: timeout") );
1260  return NULL;
1261  }
1262 
1263 
1264  /* get it */
1265  memset(&buf, 0, sizeof(buf));
1266  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1267  buf.memory = V4L2_MEMORY_MMAP; // Fabien manquait
1268  if (-1 == v4l2_ioctl(fd,VIDIOC_DQBUF, &buf)) {
1269  index = 0;
1270  switch(errno)
1271  {
1272  case EAGAIN:
1274  "VIDIOC_DQBUF: EAGAIN") );
1275  break;
1276  case EINVAL:
1278  "VIDIOC_DQBUF: EINVAL") );
1279  break;
1280  case ENOMEM:
1282  "VIDIOC_DQBUF: ENOMEM") );
1283  break;
1284  default:
1286  "VIDIOC_DQBUF") );
1287  break;
1288  }
1289  return NULL;
1290  }
1291 
1292  waiton_cpt++;
1293  buf_v4l2[buf.index] = buf;
1294 
1295  index = buf.index;
1296 
1297  field = buf_v4l2[index].field;
1298 
1299  timestamp = buf_v4l2[index].timestamp;
1300 
1301  // if(verbose)
1302  // {
1303  // vpERROR_TRACE("field: %d\n", buf_v4l2[index].field);
1304 
1305  // vpERROR_TRACE("data adress : 0x%p\n", buf_me[buf.index].data);
1306  // }
1307  return buf_me[buf.index].data;
1308 }
1309 
1315 int
1316 vpV4l2Grabber::queueBuffer()
1317 {
1318  unsigned int frame = queue % reqbufs.count;
1319  int rc;
1320 
1321 
1322  if (0 != buf_me[frame].refcount) {
1323  if (0 != queue - waiton_cpt)
1324  return -1;
1325  fprintf(stderr,"v4l2: waiting for a free buffer..............\n");
1326  //ng_waiton_video_buf(h->buf_me+frame);
1327  std::cout << "Normalement call ng_waiton_video_buf(buf_me+frame); --------\n";
1328  }
1329 
1330  // std::cout << "frame: " << frame << std::endl;
1331  rc = v4l2_ioctl(fd, VIDIOC_QBUF, &buf_v4l2[frame]);
1332  if (0 == rc)
1333  queue++;
1334  else
1335  {
1336  switch(errno)
1337  {
1338  case EAGAIN:
1340  "VIDIOC_QBUF: EAGAIN") );
1341  break;
1342  case EINVAL:
1344  "VIDIOC_QBUF: EINVAL") );
1345  break;
1346  case ENOMEM:
1348  "VIDIOC_QBUF: ENOMEM") );
1349  break;
1350  default:
1352  "VIDIOC_QBUF") );
1353  break;
1354  }
1355  }
1356  return rc;
1357 }
1358 
1364 void
1365 vpV4l2Grabber::queueAll()
1366 {
1367  for (;;) {
1368  if (queue - waiton_cpt >= reqbufs.count) {
1369  return;
1370  }
1371  if (0 != queueBuffer()) {
1372  return;
1373  }
1374  }
1375 }
1376 
1382 void
1383 vpV4l2Grabber::printBufInfo(struct v4l2_buffer buf)
1384 {
1385  char type[40];
1386 
1387  switch(buf.type) {
1388  case V4L2_BUF_TYPE_VIDEO_CAPTURE: sprintf(type, "video-cap"); break;
1389  case V4L2_BUF_TYPE_VIDEO_OVERLAY: sprintf(type, "video-over"); break;
1390  case V4L2_BUF_TYPE_VIDEO_OUTPUT: sprintf(type, "video-out"); break;
1391  case V4L2_BUF_TYPE_VBI_CAPTURE: sprintf(type, "vbi-cap"); break;
1392  case V4L2_BUF_TYPE_VBI_OUTPUT: sprintf(type, "vbi-out"); break;
1393  default: sprintf(type, "unknown"); break;
1394  }
1395 
1396  fprintf(stdout,"v4l2: buf %d: %d ad: 0x%lx offset 0x%x+%d (=0x%x),used %d\n",
1397  buf.index, buf.type, buf.m.userptr, buf.m.offset,
1398  buf.length, buf.length, buf.bytesused);
1399 
1400 }
1401 #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:154
#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:115
void resize(const unsigned int height, const unsigned int width)
set the size of the image
Definition: vpImage.h:530
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:145
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)