Fawkes API  Fawkes Development Version
v4l2.cpp
1 
2 /***************************************************************************
3  * v4l2.cpp - Video4Linux 2 camera access
4  *
5  * Created: Sat Jul 5 20:40:20 2008
6  * Copyright 2008 Tobias Kellner
7  * 2010-2014 Tim Niemueller
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <core/exception.h>
25 #include <core/exceptions/software.h>
26 #include <fvcams/v4l2.h>
27 #include <fvutils/system/camargp.h>
28 #include <linux/version.h>
29 #include <logging/liblogger.h>
30 #include <sys/ioctl.h>
31 #include <sys/mman.h>
32 
33 #include <cerrno>
34 #include <cstdlib>
35 #include <cstring>
36 #include <fcntl.h>
37 #include <iostream>
38 
39 using fawkes::Exception;
40 using fawkes::LibLogger;
43 using std::cout;
44 using std::endl;
45 using std::string;
46 
47 #ifdef HAVE_LIBV4L2
48 # include <libv4l2.h>
49 #else
50 # include <unistd.h>
51 # define v4l2_fd_open(fd, flags) (fd)
52 # define v4l2_close ::close
53 # define v4l2_dup dup
54 # define v4l2_ioctl ioctl
55 # define v4l2_read read
56 # define v4l2_mmap mmap
57 # define v4l2_munmap munmap
58 #endif
59 
60 namespace firevision {
61 
62 /// @cond INTERNALS
63 class V4L2CameraData
64 {
65 public:
66  v4l2_capability caps; //< Device capabilites
67 };
68 
69 /// @endcond
70 
71 /** @class V4L2Camera <fvcams/v4l2.h>
72  * Video4Linux 2 camera access implementation.
73  *
74  * @todo UPTR method
75  * @todo v4l2_pix_format.field
76  * @author Tobias Kellner
77  * @author Tim Niemueller
78  */
79 
80 /** Constructor.
81  * @param device_name device file name (e.g. /dev/video0)
82  */
83 V4L2Camera::V4L2Camera(const char *device_name)
84 {
85  _opened = _started = false;
86  _nao_hacks = _switch_u_v = false;
87  _width = _height = _bytes_per_line = _fps = _buffers_length = 0;
88  _current_buffer = -1;
89  _standard = NULL;
90  _input = NULL;
91  _brightness.set = _contrast.set = _saturation.set = _hue.set = _red_balance.set =
92  _blue_balance.set = _exposure.set = _gain.set = _lens_x.set = _lens_y.set = false;
93  _awb = _agc = _h_flip = _v_flip = NOT_SET;
94  _exposure_auto_priority = NOT_SET;
95  _exposure_auto.set = false;
96  _white_balance_temperature.set = false;
97  _exposure_absolute.set = false;
98  _white_balance_temperature.set = false;
99  _sharpness.set = false;
100  _read_method = MMAP;
101  memset(_format, 0, 5);
102  _frame_buffers = NULL;
103  _capture_time = NULL;
104  _device_name = strdup(device_name);
105  _data = new V4L2CameraData();
106 }
107 
108 /** Constructor.
109  * Initialize camera with parameters from camera argument parser.
110  * Supported arguments:
111  * *Required:
112  * - device=DEV, device file, for example /dev/video0 (required)
113  * *Optional:
114  * - read_method=METHOD, preferred read method
115  * READ: read()
116  * MMAP: memory mapping
117  * UPTR: user pointer
118  * - standard=std, set video standard, e.g. PAL or NTSC
119  * - input=inp, set video input, e.g. S-Video
120  * - format=FOURCC, preferred format
121  * - size=WIDTHxHEIGHT, preferred image size
122  * - switch_u_v=true/false, switch U and V channels
123  * - fps=FPS, frames per second
124  * - aec=true/false, Auto Exposition enabled [warning: only valid on nao]
125  * - awb=true/false, Auto White Balance enabled
126  * - agc=true/false, Auto Gain enabled
127  * - h_flip=true/false, Horizontal mirror
128  * - v_flip=true/false, Vertical mirror
129  * - brightness=BRIGHT, Brightness [0-255] (def. 128)
130  * - contrast=CONTR, Contrast [0-127] (def. 64)
131  * - saturation=SAT, Saturation [0-256] (def. 128)
132  * - hue=HUE, Hue [-180-180] (def. 0)
133  * - red_balance=RB, Red Balance [0-255] (def. 128)
134  * - blue_balance=BB, Blue Balance [0-255] (def. 128)
135  * - exposure=EXP, Exposure [0-65535] (def. 60)
136  * - gain=GAIN, Gain [0-255] (def. 0)
137  * - lens_x=CORR, Lens Correction X [0-255] (def. 0)
138  * - lens_y=CORR, Lens Correction Y [0-255] (def. 0)
139  * @param cap camera argument parser
140  */
142 {
143  _opened = _started = false;
144  _nao_hacks = false;
145  _width = _height = _bytes_per_line = _buffers_length = 0;
146  _current_buffer = -1;
147  _frame_buffers = NULL;
148  _capture_time = NULL;
149  _standard = NULL;
150  _input = NULL;
151  _data = new V4L2CameraData();
152 
153  if (cap->has("device"))
154  _device_name = strdup(cap->get("device").c_str());
155  else
156  throw MissingParameterException("V4L2Cam: Missing device");
157 
158  if (cap->has("nao")) {
159  _nao_hacks = true;
160  }
161 
162  if (cap->has("read_method")) {
163  string rm = cap->get("read_method");
164  if (rm.compare("READ") == 0)
165  _read_method = READ;
166  else if (rm.compare("MMAP") == 0)
167  _read_method = MMAP;
168  else if (rm.compare("UPTR") == 0)
169  _read_method = UPTR;
170  else
171  throw Exception("V4L2Cam: Invalid read method");
172  } else {
173  _read_method = MMAP;
174  }
175 
176  if (cap->has("format")) {
177  string fmt = cap->get("format");
178  if (fmt.length() != 4)
179  throw Exception("V4L2Cam: Invalid format fourcc");
180  strncpy(_format, fmt.c_str(), 4);
181  _format[4] = '\0';
182  } else {
183  memset(_format, 0, 5);
184  }
185 
186  if (cap->has("standard")) {
187  _standard = strdup(cap->get("standard").c_str());
188  }
189 
190  if (cap->has("input")) {
191  _input = strdup(cap->get("input").c_str());
192  }
193 
194  if (cap->has("size")) {
195  string size = cap->get("size");
196  string::size_type pos;
197  if ((pos = size.find('x')) == string::npos)
198  throw Exception("V4L2Cam: invalid image size string");
199  if (pos == (size.length() - 1))
200  throw Exception("V4L2Cam: invalid image size string");
201 
202  unsigned int mult = 1;
203  for (string::size_type i = pos - 1; i != string::npos; --i) {
204  _width += (size.at(i) - '0') * mult;
205  mult *= 10;
206  }
207 
208  mult = 1;
209  for (string::size_type i = size.length() - 1; i > pos; --i) {
210  _height += (size.at(i) - '0') * mult;
211  mult *= 10;
212  }
213  }
214 
215  if (cap->has("switch_u_v")) {
216  _switch_u_v = (cap->get("switch_u_v").compare("true") == 0);
217  } else {
218  _switch_u_v = false;
219  }
220 
221  if (cap->has("fps")) {
222  if ((_fps = atoi(cap->get("fps").c_str())) == 0)
223  throw Exception("V4L2Cam: invalid fps string");
224  } else {
225  _fps = 0;
226  }
227 
228  if (cap->has("awb")) {
229  _awb = (cap->get("awb").compare("true") == 0 ? TRUE : FALSE);
230  } else {
231  _awb = NOT_SET;
232  }
233 
234  if (cap->has("agc")) {
235  _agc = (cap->get("agc").compare("true") == 0 ? TRUE : FALSE);
236  } else {
237  _agc = NOT_SET;
238  }
239 
240  if (cap->has("h_flip")) {
241  _h_flip = (cap->get("h_flip").compare("true") == 0 ? TRUE : FALSE);
242  } else {
243  _h_flip = NOT_SET;
244  }
245 
246  if (cap->has("v_flip")) {
247  _v_flip = (cap->get("v_flip").compare("true") == 0 ? TRUE : FALSE);
248  } else {
249  _v_flip = NOT_SET;
250  }
251 
252  if (cap->has("brightness")) {
253  _brightness.set = true;
254  _brightness.value = atoi(cap->get("brightness").c_str());
255  } else {
256  _brightness.set = false;
257  }
258 
259  if (cap->has("contrast")) {
260  _contrast.set = true;
261  _contrast.value = atoi(cap->get("contrast").c_str());
262  } else {
263  _contrast.set = false;
264  }
265 
266  if (cap->has("saturation")) {
267  _saturation.set = true;
268  _saturation.value = atoi(cap->get("saturation").c_str());
269  } else {
270  _saturation.set = false;
271  }
272 
273  if (cap->has("hue")) {
274  _hue.set = true;
275  _hue.value = atoi(cap->get("hue").c_str());
276  } else {
277  _hue.set = false;
278  }
279 
280  if (cap->has("red_balance")) {
281  _red_balance.set = true;
282  _red_balance.value = atoi(cap->get("red_balance").c_str());
283  } else {
284  _red_balance.set = false;
285  }
286 
287  if (cap->has("blue_balance")) {
288  _blue_balance.set = true;
289  _blue_balance.value = atoi(cap->get("blue_balance").c_str());
290  } else {
291  _blue_balance.set = false;
292  }
293 
294  if (cap->has("exposure")) {
295  _exposure.set = true;
296  _exposure.value = atoi(cap->get("exposure").c_str());
297  } else {
298  _exposure.set = false;
299  }
300 
301  if (cap->has("gain")) {
302  _gain.set = true;
303  _gain.value = atoi(cap->get("gain").c_str());
304  } else {
305  _gain.set = false;
306  }
307 
308  if (cap->has("lens_x")) {
309  _lens_x.set = true;
310  _lens_x.value = atoi(cap->get("lens_x").c_str());
311  } else {
312  _lens_x.set = false;
313  }
314 
315  if (cap->has("lens_y")) {
316  _lens_y.set = true;
317  _lens_y.value = atoi(cap->get("lens_y").c_str());
318  } else {
319  _lens_y.set = false;
320  }
321 
322  if (cap->has("exposure_auto_priority")) {
323  _exposure_auto_priority =
324  (cap->get("exposure_auto_priority").compare("true") == 0 ? TRUE : FALSE);
325  } else {
326  _exposure_auto_priority = NOT_SET;
327  }
328 
329  if (cap->has("exposure_auto")) {
330  _exposure_auto.set = true;
331  _exposure_auto.value = atoi(cap->get("exposure_auto").c_str());
332  } else {
333  _exposure_auto.set = false;
334  }
335 
336  if (cap->has("exposure_absolute")) {
337  _exposure_absolute.set = true;
338  _exposure_absolute.value = atoi(cap->get("exposure_absolute").c_str());
339  } else {
340  _exposure_absolute.set = false;
341  }
342 
343  if (cap->has("white_balance_temperature")) {
344  _white_balance_temperature.set = true;
345  _white_balance_temperature.value = atoi(cap->get("white_balance_temperature").c_str());
346  } else {
347  _white_balance_temperature.set = false;
348  }
349 
350  if (cap->has("sharpness")) {
351  _sharpness.set = true;
352  _sharpness.value = atoi(cap->get("sharpness").c_str());
353  } else {
354  _sharpness.set = false;
355  }
356 }
357 
358 /** Protected Constructor.
359  * Gets called from V4LCamera, when the device has already been opened
360  * and determined to be a V4L2 device.
361  * @param device_name device file name (e.g. /dev/video0)
362  * @param dev file descriptor of the opened device
363  */
364 V4L2Camera::V4L2Camera(const char *device_name, int dev)
365 {
366  _opened = true;
367  _started = false;
368  _nao_hacks = _switch_u_v = false;
369  _width = _height = _bytes_per_line = _buffers_length = _fps = 0;
370  _current_buffer = -1;
371  _brightness.set = _contrast.set = _saturation.set = _hue.set = _red_balance.set =
372  _blue_balance.set = _exposure.set = _gain.set = _lens_x.set = _lens_y.set = false;
373  _awb = _agc = _h_flip = _v_flip = NOT_SET;
374  _exposure_auto_priority = NOT_SET;
375  _white_balance_temperature.set = false;
376  _exposure_auto.set = false;
377  _exposure_absolute.set = false;
378  _sharpness.set = false;
379  _read_method = UPTR;
380  memset(_format, 0, 5);
381  _frame_buffers = NULL;
382  _capture_time = NULL;
383  _device_name = strdup(device_name);
384  _standard = NULL;
385  _input = NULL;
386  _data = new V4L2CameraData();
387 
388  _dev = dev;
389 
390  // getting capabilities
391  if (v4l2_ioctl(_dev, VIDIOC_QUERYCAP, &_data->caps)) {
392  close();
393  throw Exception("V4L2Cam: Could not get capabilities - probably not a v4l2 device");
394  }
395 
396  post_open();
397 }
398 
399 /** Destructor. */
401 {
402  if (_started)
403  stop();
404  if (_opened)
405  close();
406 
407  free(_device_name);
408  if (_standard)
409  free(_standard);
410  if (_input)
411  free(_input);
412  delete _data;
413 }
414 
415 void
417 {
418  if (_started)
419  stop();
420  if (_opened)
421  close();
422 
423  _dev = ::open(_device_name, O_RDWR);
424  int libv4l2_fd = v4l2_fd_open(_dev, 0);
425  if (libv4l2_fd != -1)
426  _dev = libv4l2_fd;
427  /* Note the v4l2_xxx functions are designed so that if they get passed an
428  unknown fd, the will behave exactly as their regular xxx counterparts, so
429  if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom
430  cam format to normal formats conversion). Chances are big we will still
431  fail then though, as normally v4l2_fd_open only fails if the device is not
432  a v4l2 device. */
433  if (_dev < 0)
434  throw Exception("V4L2Cam: Could not open device");
435 
436  _opened = true;
437 
438  // getting capabilities
439  if (v4l2_ioctl(_dev, VIDIOC_QUERYCAP, &_data->caps)) {
440  close();
441  throw Exception("V4L2Cam: Could not get capabilities - probably not a v4l2 device");
442  }
443 
444  post_open();
445 }
446 
447 /**
448  * Post-open() operations.
449  * Precondition: _dev (file desc) and _data->caps (capabilities) are set.
450  * @param dev file descriptor of the opened device
451  */
452 void
453 V4L2Camera::post_open()
454 {
455  select_standard();
456  select_input();
457  select_read_method();
458  select_format();
459  if (_fps)
460  set_fps();
461  set_controls();
462  create_buffer();
463  reset_cropping();
464 }
465 
466 /**
467  * Find suitable reading method.
468  * The one set in _read_method is preferred.
469  * Postconditions:
470  * - _read_method and _buffers_length are set
471  */
472 void
473 V4L2Camera::select_read_method()
474 {
475  /* try preferred method */
476  if (!(_data->caps.capabilities
477  & (_read_method == READ ? V4L2_CAP_READWRITE : V4L2_CAP_STREAMING))) {
478  /* preferred read method not supported - try next */
479  _read_method = (_read_method == READ ? MMAP : READ);
480  if (!(_data->caps.capabilities
481  & (_read_method == READ ? V4L2_CAP_READWRITE : V4L2_CAP_STREAMING))) {
482  close();
483  throw Exception("V4L2Cam: Neither read() nor streaming IO supported");
484  }
485  }
486 
487  if (_read_method != READ) {
488  v4l2_requestbuffers buf;
489 
490  /* Streaming IO - Try 1st method, and if that fails 2nd */
491  if (_read_method == MMAP) {
492  _buffers_length = MMAP_NUM_BUFFERS;
493  buf.count = _buffers_length;
494  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
495  buf.memory = V4L2_MEMORY_MMAP;
496  } else if (_read_method == UPTR) {
497  _buffers_length = 0;
498  buf.count = 0;
499  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
500  buf.memory = V4L2_MEMORY_USERPTR;
501  }
502 
503  if (v4l2_ioctl(_dev, VIDIOC_REQBUFS, &buf)) {
504  close();
505  throw Exception("V4L2Cam: REQBUFS query failed");
506  }
507 
508  if (_read_method == MMAP) {
509  if (buf.count < _buffers_length) {
510  close();
511  throw Exception("V4L2Cam: Not enough memory for the buffers");
512  }
513  }
514  } else {
515  /* Read IO */
516  _buffers_length = 1;
517  }
518 
519  switch (_read_method) {
520  case READ: LibLogger::log_debug("V4L2Cam", "Using read() method"); break;
521 
522  case MMAP: LibLogger::log_debug("V4L2Cam", "Using memory mapping method"); break;
523 
524  case UPTR:
525  LibLogger::log_debug("V4L2Cam", "Using user pointer method");
526  //TODO
527  throw Exception("V4L2Cam: user pointer method not supported yet");
528  break;
529  }
530 }
531 
532 /** Set requested video standard. */
533 void
534 V4L2Camera::select_standard()
535 {
536  // No video standard setting requested? Return!
537  if (!_standard)
538  return;
539 
540  v4l2_standard std;
541  bool found = false;
542  memset(&std, 0, sizeof(std));
543  for (std.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMSTD, &std) == 0; std.index++) {
544  if (strcmp(_standard, (const char *)std.name) == 0) {
545  found = true;
546  break;
547  }
548  }
549 
550  if (!found) {
551  throw Exception("Requested standard %s is not supported by the device", _standard);
552  }
553 
554  v4l2_std_id current_std_id;
555  if (v4l2_ioctl(_dev, VIDIOC_G_STD, &current_std_id) != 0) {
556  throw Exception("Failed to read current standard");
557  }
558  if (std.id != current_std_id) {
559  // Set it
560  v4l2_std_id set_std_id = std.id;
561  if (v4l2_ioctl(_dev, VIDIOC_S_STD, &set_std_id) != 0) {
562  throw Exception(errno, "Failed to set standard %s", _standard);
563  }
564  }
565 }
566 
567 /** Set requested video input. */
568 void
569 V4L2Camera::select_input()
570 {
571  // No video input setting requested? Return!
572  if (!_input)
573  return;
574 
575  v4l2_input inp;
576  bool found = false;
577  memset(&inp, 0, sizeof(inp));
578  for (inp.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMINPUT, &inp) == 0; inp.index++) {
579  if (strcmp(_input, (const char *)inp.name) == 0) {
580  found = true;
581  break;
582  }
583  }
584 
585  if (!found) {
586  throw Exception("Requested input %s is not supported by the device", _input);
587  }
588 
589  int current_inp_ind;
590  if (v4l2_ioctl(_dev, VIDIOC_G_INPUT, &current_inp_ind) != 0) {
591  throw Exception("Failed to read current input index");
592  }
593  if ((int)inp.index != current_inp_ind) {
594  // Set it
595  int set_inp_ind = inp.index;
596  if (v4l2_ioctl(_dev, VIDIOC_S_INPUT, &set_inp_ind) != 0) {
597  throw Exception(errno, "Failed to set input %s", _input);
598  }
599  }
600 }
601 
602 /**
603  * Find suitable image format.
604  * The one set in _format (if any) is preferred.
605  * Postconditions:
606  * - _format is set (and selected)
607  * - _colorspace is set accordingly
608  * - _width, _height, and _bytes_per_line are set
609  */
610 void
611 V4L2Camera::select_format()
612 {
613  bool preferred_found = false;
614  v4l2_fmtdesc format_desc;
615 
616  char fourcc[5] = " ";
617 
618 #ifdef HAVE_LIBV4L2
619  if (strcmp(_format, "") == 0) {
620  // no format setup, use YU12 by default when compiled with libv4l
621  strcpy(_format, "YU12");
622  }
623 #endif
624 
625  if (strcmp(_format, "")) {
626  /* Try to select preferred format */
627  memset(&format_desc, 0, sizeof(format_desc));
628  format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
629  for (format_desc.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUM_FMT, &format_desc) == 0;
630  format_desc.index++) {
631  fourcc[0] = static_cast<char>(format_desc.pixelformat & 0xFF);
632  fourcc[1] = static_cast<char>((format_desc.pixelformat >> 8) & 0xFF);
633  fourcc[2] = static_cast<char>((format_desc.pixelformat >> 16) & 0xFF);
634  fourcc[3] = static_cast<char>((format_desc.pixelformat >> 24) & 0xFF);
635 
636  if (strcmp(_format, fourcc) == 0) {
637  preferred_found = true;
638  break;
639  }
640  }
641  }
642 
643  if (!preferred_found) {
644  /* Preferred format not found (or none selected)
645  -> just take first available format */
646  memset(&format_desc, 0, sizeof(format_desc));
647  format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
648  format_desc.index = 0;
649  if (v4l2_ioctl(_dev, VIDIOC_ENUM_FMT, &format_desc)) {
650  close();
651  throw Exception("V4L2Cam: No image format found");
652  }
653 
654  fourcc[0] = static_cast<char>(format_desc.pixelformat & 0xFF);
655  fourcc[1] = static_cast<char>((format_desc.pixelformat >> 8) & 0xFF);
656  fourcc[2] = static_cast<char>((format_desc.pixelformat >> 16) & 0xFF);
657  fourcc[3] = static_cast<char>((format_desc.pixelformat >> 24) & 0xFF);
658  }
659 
660  /* Now set this format */
661  v4l2_format format;
662  memset(&format, 0, sizeof(format));
663  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
664  if (v4l2_ioctl(_dev, VIDIOC_G_FMT, &format)) {
665  close();
666  throw Exception("V4L2Cam: Format query failed");
667  }
668 
669  //LibLogger::log_debug("V4L2Cam", "setting %dx%d (%s) - type %d", _width, _height, fourcc, format.type);
670 
671  format.fmt.pix.pixelformat = v4l2_fourcc(fourcc[0], fourcc[1], fourcc[2], fourcc[3]);
672  format.fmt.pix.field = V4L2_FIELD_ANY;
673  if (_width)
674  format.fmt.pix.width = _width;
675  if (_height)
676  format.fmt.pix.height = _height;
677 
678  int s_fmt_rv = v4l2_ioctl(_dev, VIDIOC_S_FMT, &format);
679  if (s_fmt_rv != 0 && errno != EBUSY && _nao_hacks) {
680  //throw Exception(errno, "Failed to set video format");
681  //}
682 
683  // Nao workaround (Hack alert)
684  LibLogger::log_warn("V4L2Cam",
685  "Format setting failed (driver sucks) - %d: %s",
686  errno,
687  strerror(errno));
688  LibLogger::log_info("V4L2Cam", "Trying workaround");
689 
690  v4l2_std_id std;
691  if (v4l2_ioctl(_dev, VIDIOC_G_STD, &std)) {
692  close();
693  throw Exception("V4L2Cam: Standard query (workaround) failed");
694  }
695 
696  if ((_width == 320) && (_height == 240)) {
697  std = 0x04000000UL; // QVGA
698  } else {
699  std = 0x08000000UL; // VGA
700  _width = 640;
701  _height = 480;
702  }
703  if (v4l2_ioctl(_dev, VIDIOC_S_STD, &std)) {
704  close();
705  throw Exception("V4L2Cam: Standard setting (workaround) failed");
706  }
707 
708  format.fmt.pix.width = _width;
709  format.fmt.pix.height = _height;
710  format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
711  format.fmt.pix.field = V4L2_FIELD_ANY;
712 
713  if (v4l2_ioctl(_dev, VIDIOC_S_FMT, &format)) {
714  close();
715  throw Exception("V4L2Cam: Format setting (workaround) failed");
716  }
717 
718  if (_switch_u_v)
719  _colorspace = YVY2;
720  }
721 
722  /* ...and store final values */
723  _format[0] = static_cast<char>(format.fmt.pix.pixelformat & 0xFF);
724  _format[1] = static_cast<char>((format.fmt.pix.pixelformat >> 8) & 0xFF);
725  _format[2] = static_cast<char>((format.fmt.pix.pixelformat >> 16) & 0xFF);
726  _format[3] = static_cast<char>((format.fmt.pix.pixelformat >> 24) & 0xFF);
727 
728  if (!_nao_hacks || !_switch_u_v) {
729  if (strcmp(_format, "RGB3") == 0)
730  _colorspace = RGB;
731  else if (strcmp(_format, "Y41P") == 0)
732  _colorspace = YUV411_PACKED; //different byte ordering
733  else if (strcmp(_format, "411P") == 0)
734  _colorspace = YUV411_PLANAR;
735  else if (strcmp(_format, "YUYV") == 0)
736  _colorspace = YUY2;
737  else if (strcmp(_format, "BGR3") == 0)
738  _colorspace = BGR;
739  else if (strcmp(_format, "UYVY") == 0)
740  _colorspace = YUV422_PACKED;
741  else if (strcmp(_format, "422P") == 0)
742  _colorspace = YUV422_PLANAR;
743  else if (strcmp(_format, "GREY") == 0)
744  _colorspace = GRAY8;
745  else if (strcmp(_format, "RGB4") == 0)
746  _colorspace = RGB_WITH_ALPHA;
747  else if (strcmp(_format, "BGR4") == 0)
748  _colorspace = BGR_WITH_ALPHA;
749  else if (strcmp(_format, "BA81") == 0)
750  _colorspace = BAYER_MOSAIC_BGGR;
751  else if (strcmp(_format, "Y16 ") == 0)
752  _colorspace = MONO16;
753  else if (strcmp(_format, "YU12") == 0)
754  _colorspace = YUV420_PLANAR;
755  else
756  _colorspace = CS_UNKNOWN;
757  }
758 
759  if (!_nao_hacks) {
760  _width = format.fmt.pix.width;
761  _height = format.fmt.pix.height;
762  }
763 
764  _bytes_per_line = format.fmt.pix.bytesperline;
765 
766  /* Hack for bad drivers */
767  if (_bytes_per_line == 0) {
768  LibLogger::log_warn("V4L2Cam", "bytesperline is 0 (driver sucks)");
769  _bytes_per_line = colorspace_buffer_size(_colorspace, _width, _height) / _height;
770  }
771 
772  LibLogger::log_debug(
773  "V4L2Cam", "w%d h%d bpl%d cs%d fmt%s", _width, _height, _bytes_per_line, _colorspace, _format);
774 }
775 
776 /**
777  * Set desired FPS count.
778  */
779 void
780 V4L2Camera::set_fps()
781 {
782  v4l2_streamparm param;
783  param.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
784  if (v4l2_ioctl(_dev, VIDIOC_G_PARM, &param)) {
785  close();
786  throw Exception("V4L2Cam: Streaming parameter query failed");
787  }
788 
789  if (!(param.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) {
790  LibLogger::log_warn("V4L2Cam", "FPS change not supported");
791  return;
792  }
793 
794  param.parm.capture.timeperframe.numerator = 1;
795  param.parm.capture.timeperframe.denominator = _fps;
796  if (v4l2_ioctl(_dev, VIDIOC_S_PARM, &param)) {
797  close();
798  throw Exception("V4L2Cam: Streaming parameter setting failed");
799  } else {
800  LibLogger::log_debug("V4L2Cam",
801  "FPS set - %d/%d",
802  param.parm.capture.timeperframe.numerator,
803  param.parm.capture.timeperframe.denominator);
804  }
805 }
806 
807 /**
808  * Set Camera controls.
809  */
810 void
811 V4L2Camera::set_controls()
812 {
813  if (_exposure_auto_priority != NOT_SET)
814  set_exposure_auto_priority(_exposure_auto_priority == TRUE);
815  if (_exposure_auto.set)
816  set_exposure_auto(_exposure_auto.value);
817 
818  if (_awb != NOT_SET)
819  set_auto_white_balance(_awb == TRUE);
820  if (_agc != NOT_SET)
821  set_auto_gain(_agc == TRUE);
822 
823  if (_h_flip != NOT_SET)
824  set_horiz_mirror(_h_flip == TRUE);
825  if (_v_flip != NOT_SET)
826  set_vert_mirror(_v_flip == TRUE);
827 
828  if (_brightness.set)
829  set_brightness(_brightness.value);
830  if (_contrast.set)
831  set_contrast(_contrast.value);
832  if (_saturation.set)
833  set_saturation(_saturation.value);
834  if (_hue.set)
835  set_hue(_hue.value);
836  if (_red_balance.set)
837  set_red_balance(_red_balance.value);
838  if (_blue_balance.set)
839  set_blue_balance(_blue_balance.value);
840  if (_exposure.set)
841  set_exposure(_exposure.value);
842  if (_gain.set)
843  set_gain(_gain.value);
844  if (_lens_x.set)
845  set_lens_x_corr(_lens_x.value);
846  if (_lens_y.set)
847  set_lens_y_corr(_lens_y.value);
848 
849  if (_exposure_absolute.set)
850  set_exposure_absolute(_exposure_absolute.value);
851  if (_white_balance_temperature.set)
852  set_white_balance_temperature(_white_balance_temperature.value);
853  if (_sharpness.set)
854  set_sharpness(_sharpness.value);
855 }
856 
857 /**
858  * Set one Camera control value.
859  * @param ctrl name of the value
860  * @param id ID of the value
861  * @param value value to set
862  */
863 void
864 V4L2Camera::set_one_control(const char *ctrl, unsigned int id, int value)
865 {
866  v4l2_queryctrl queryctrl;
867  v4l2_control control;
868 
869  memset(&queryctrl, 0, sizeof(queryctrl));
870  queryctrl.id = id;
871 
872  if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl)) {
873  if (errno == EINVAL) {
874  LibLogger::log_error("V4L2Cam", "Control %s not supported", ctrl);
875  return;
876  }
877 
878  close();
879  throw Exception("V4L2Cam: %s Control query failed", ctrl);
880  }
881  if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
882  LibLogger::log_error("V4L2Cam", "Control %s disabled", ctrl);
883  return;
884  }
885 
886  memset(&control, 0, sizeof(control));
887  control.id = id;
888  control.value = value;
889 
890  if (v4l2_ioctl(_dev, VIDIOC_S_CTRL, &control)) {
891  close();
892  throw Exception("V4L2Cam: %s Control setting failed", ctrl);
893  }
894 }
895 
896 /**
897  * Get one Camera control value.
898  * @param ctrl name of the value
899  * @param id ID of the value
900  * @return current value
901  */
902 int
903 V4L2Camera::get_one_control(const char *ctrl, unsigned int id)
904 {
905  v4l2_queryctrl queryctrl;
906  v4l2_control control;
907 
908  memset(&queryctrl, 0, sizeof(queryctrl));
909  queryctrl.id = id;
910 
911  if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl)) {
912  if (errno == EINVAL) {
913  LibLogger::log_error("V4L2Cam", "Control %s not supported", ctrl);
914  return 0;
915  }
916 
917  close();
918  throw Exception("V4L2Cam: %s Control query failed", ctrl);
919  }
920  if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
921  LibLogger::log_error("V4L2Cam", "Control %s disabled", ctrl);
922  return 0;
923  }
924 
925  memset(&control, 0, sizeof(control));
926  control.id = id;
927 
928  if (v4l2_ioctl(_dev, VIDIOC_G_CTRL, &control)) {
929  close();
930  throw Exception("V4L2Cam: %s Control value reading failed", ctrl);
931  }
932 
933  return control.value;
934 }
935 
936 /**
937  * Create a buffer for image transfer.
938  * Preconditions:
939  * - _read_method is set
940  * - _height and _bytes_per_line are set
941  * - _buffers_length is set
942  * Postconditions:
943  * - _frame_buffers is set up
944  */
945 void
946 V4L2Camera::create_buffer()
947 {
948  _frame_buffers = new FrameBuffer[_buffers_length];
949 
950  switch (_read_method) {
951  case READ: {
952  _frame_buffers[0].size = _bytes_per_line * _height;
953  _frame_buffers[0].buffer = static_cast<unsigned char *>(malloc(_frame_buffers[0].size));
954  if (_frame_buffers[0].buffer == NULL) {
955  close();
956  throw Exception("V4L2Cam: Out of memory");
957  }
958  break;
959  }
960 
961  case MMAP: {
962  for (unsigned int i = 0; i < _buffers_length; ++i) {
963  /* Query status of buffer */
964  v4l2_buffer buffer;
965 
966  memset(&buffer, 0, sizeof(buffer));
967  buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
968  buffer.memory = V4L2_MEMORY_MMAP;
969  buffer.index = i;
970 
971  if (v4l2_ioctl(_dev, VIDIOC_QUERYBUF, &buffer)) {
972  close();
973  throw Exception("V4L2Cam: Buffer query failed");
974  }
975 
976  _frame_buffers[i].size = buffer.length;
977  _frame_buffers[i].buffer = static_cast<unsigned char *>(
978  v4l2_mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, _dev, buffer.m.offset));
979  if (_frame_buffers[i].buffer == MAP_FAILED) {
980  close();
981  throw Exception("V4L2Cam: Memory mapping failed");
982  }
983  }
984 
985  break;
986  }
987 
988  case UPTR:
989  /* not supported yet */
990  break;
991  }
992 }
993 
994 /**
995  * Reset cropping parameters.
996  */
997 void
998 V4L2Camera::reset_cropping()
999 {
1000  v4l2_cropcap cropcap;
1001  v4l2_crop crop;
1002 
1003  memset(&cropcap, 0, sizeof(cropcap));
1004  cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1005 
1006  if (v4l2_ioctl(_dev, VIDIOC_CROPCAP, &cropcap)) {
1007  if (errno == ENOTTY) {
1008  // simply not suppored
1009  return;
1010  }
1011  LibLogger::log_warn("V4L2Cam",
1012  "cropcap query failed (driver sucks) - %d: %s",
1013  errno,
1014  strerror(errno));
1015  }
1016 
1017  memset(&crop, 0, sizeof(crop));
1018  crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1019  crop.c = cropcap.defrect;
1020 
1021  /* Ignore if cropping is not supported (EINVAL). */
1022  if (v4l2_ioctl(_dev, VIDIOC_S_CROP, &crop) && errno != EINVAL) {
1023  LibLogger::log_warn("V4L2Cam",
1024  "cropping query failed (driver sucks) - %d: %s",
1025  errno,
1026  strerror(errno));
1027  }
1028 }
1029 
1030 void
1032 {
1033  //LibLogger::log_debug("V4L2Cam", "close()");
1034 
1035  if (_started)
1036  stop();
1037 
1038  if (_frame_buffers) {
1039  switch (_read_method) {
1040  case READ: {
1041  free(_frame_buffers[0].buffer);
1042  break;
1043  }
1044 
1045  case MMAP: {
1046  for (unsigned int i = 0; i < _buffers_length; ++i) {
1047  v4l2_munmap(_frame_buffers[i].buffer, _frame_buffers[i].size);
1048  }
1049  break;
1050  }
1051 
1052  case UPTR:
1053  /* not supported yet */
1054  break;
1055  }
1056  delete[] _frame_buffers;
1057  _frame_buffers = NULL;
1058  _current_buffer = -1;
1059  }
1060 
1061  if (_opened) {
1062  v4l2_close(_dev);
1063  _opened = false;
1064  _dev = 0;
1065  }
1066 
1067  if (_capture_time) {
1068  delete _capture_time;
1069  _capture_time = 0;
1070  }
1071 }
1072 
1073 void
1075 {
1076  if (!_opened)
1077  throw Exception("VL42Cam: Camera not opened");
1078 
1079  if (_started)
1080  stop();
1081 
1082  switch (_read_method) {
1083  case READ:
1084  /* nothing to do here */
1085  break;
1086 
1087  case MMAP: {
1088  // enqueue buffers
1089  for (unsigned int i = 0; i < _buffers_length; ++i) {
1090  v4l2_buffer buffer;
1091  memset(&buffer, 0, sizeof(buffer));
1092  buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1093  buffer.memory = V4L2_MEMORY_MMAP;
1094  buffer.index = i;
1095 
1096  if (v4l2_ioctl(_dev, VIDIOC_QBUF, &buffer)) {
1097  close();
1098  throw Exception("V4L2Cam: Enqueuing buffer failed");
1099  }
1100  }
1101 
1102  // start streaming
1103  int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1104  if (v4l2_ioctl(_dev, VIDIOC_STREAMON, &type)) {
1105  close();
1106  throw Exception("V4L2Cam: Starting stream failed");
1107  }
1108  break;
1109  }
1110 
1111  case UPTR:
1112  /* not supported yet */
1113  break;
1114  }
1115 
1116  //LibLogger::log_debug("V4L2Cam", "start() complete");
1117  _started = true;
1118 }
1119 
1120 void
1122 {
1123  //LibLogger::log_debug("V4L2Cam", "stop()");
1124 
1125  if (!_started)
1126  return;
1127 
1128  switch (_read_method) {
1129  case READ:
1130  // nothing to do here
1131  break;
1132 
1133  case MMAP:
1134  case UPTR: {
1135  // stop streaming
1136  int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1137  if (v4l2_ioctl(_dev, VIDIOC_STREAMOFF, &type)) {
1138  throw Exception("V4L2Cam: Stopping stream failed");
1139  }
1140  break;
1141  }
1142  }
1143 
1144  _current_buffer = -1;
1145  _started = false;
1146 }
1147 
1148 bool
1150 {
1151  return _started;
1152 }
1153 
1154 void
1156 {
1157  //LibLogger::log_debug("V4L2Cam", "flush()");
1158  /* not needed */
1159 }
1160 
1161 void
1163 {
1164  if (!_started)
1165  return;
1166 
1167  switch (_read_method) {
1168  case READ: {
1169  _current_buffer = 0;
1170  if (v4l2_read(_dev,
1171  _frame_buffers[_current_buffer].buffer,
1172  _frame_buffers[_current_buffer].size)
1173  == -1) {
1174  LibLogger::log_warn("V4L2Cam", "read() failed with code %d: %s", errno, strerror(errno));
1175  }
1176 
1177  //No timestamping support here - just take current system time
1178  if (_capture_time) {
1179  _capture_time->stamp();
1180  } else {
1181  _capture_time = new fawkes::Time();
1182  }
1183 
1184  break;
1185  }
1186 
1187  case MMAP: {
1188  // dequeue buffer
1189  v4l2_buffer buffer;
1190  memset(&buffer, 0, sizeof(buffer));
1191  buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1192  buffer.memory = V4L2_MEMORY_MMAP;
1193 
1194  if (v4l2_ioctl(_dev, VIDIOC_DQBUF, &buffer)) {
1195  close();
1196  throw Exception("V4L2Cam: Dequeuing buffer failed");
1197  }
1198 
1199  _current_buffer = buffer.index;
1200 
1201  if (_capture_time) {
1202  _capture_time->set_time(&buffer.timestamp);
1203  } else {
1204  _capture_time = new fawkes::Time(&buffer.timestamp);
1205  }
1206  break;
1207  }
1208 
1209  case UPTR:
1210  /* not supported yet */
1211  break;
1212  }
1213 }
1214 
1215 unsigned char *
1217 {
1218  //LibLogger::log_debug("V4L2Cam", "buffer()");
1219 
1220  return (_current_buffer == -1 ? NULL : _frame_buffers[_current_buffer].buffer);
1221 }
1222 
1223 unsigned int
1225 {
1226  //LibLogger::log_debug("V4L2Cam", "buffer_size()");
1227 
1228  return (_opened && (_current_buffer != -1) ? _frame_buffers[_current_buffer].size : 0);
1229 }
1230 
1231 void
1233 {
1234  //LibLogger::log_debug("V4L2Cam", "dispose_buffer()");
1235 
1236  if (!_opened)
1237  return;
1238 
1239  switch (_read_method) {
1240  case READ:
1241  /* nothing to do here */
1242  break;
1243 
1244  case MMAP: {
1245  /* enqueue next buffer */
1246  v4l2_buffer buffer;
1247  memset(&buffer, 0, sizeof(buffer));
1248  buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1249  buffer.memory = V4L2_MEMORY_MMAP;
1250  buffer.index = _current_buffer;
1251 
1252  //TODO: Test if the next buffer is also the latest buffer (VIDIOC_QUERYBUF)
1253  if (v4l2_ioctl(_dev, VIDIOC_QBUF, &buffer)) {
1254  int errno_save = errno;
1255  close();
1256  throw Exception(errno_save, "V4L2Cam: Enqueuing buffer failed");
1257  }
1258  break;
1259  }
1260 
1261  case UPTR:
1262  /* not supported yet */
1263  break;
1264  }
1265 
1266  _current_buffer = -1;
1267 }
1268 
1269 unsigned int
1271 {
1272  //LibLogger::log_debug("V4L2Cam", "pixel_width()");
1273 
1274  return _width;
1275 }
1276 
1277 unsigned int
1279 {
1280  //LibLogger::log_debug("V4L2Cam", "pixel_height()");
1281 
1282  return _height;
1283 }
1284 
1285 colorspace_t
1287 {
1288  //LibLogger::log_debug("V4L2Cam", "colorspace()");
1289 
1290  if (!_opened)
1291  return CS_UNKNOWN;
1292  else
1293  return _colorspace;
1294 }
1295 
1296 fawkes::Time *
1298 {
1299  return _capture_time;
1300 }
1301 
1302 void
1304 {
1305  //LibLogger::log_debug("V4L2Cam", "set_image_number(%d)", n);
1306 
1307  /* not needed */
1308 }
1309 
1310 /* --- CameraControls --- */
1311 
1312 /**
1313  * Get exposure_auto_priority V4L2 control
1314  * @return whether auto exposure gets priority
1315  */
1316 bool
1318 {
1319  return get_one_control("exposure_auto_priority", V4L2_CID_EXPOSURE_AUTO_PRIORITY);
1320 }
1321 
1322 /**
1323  * Set exposure_auto_priority V4L2 control
1324  * @param enabled
1325  */
1326 void
1328 {
1329  LibLogger::log_debug("V4L2Cam",
1330  (enabled ? "enabling exposure_auto_priority"
1331  : "disabling exposure_auto_priority"));
1332  set_one_control("AGC", V4L2_CID_EXPOSURE_AUTO_PRIORITY, (enabled ? 1 : 0));
1333 }
1334 
1335 /**
1336  * Get absolute white balance setting
1337  * @return white balance temperature
1338  */
1339 unsigned int
1341 {
1342  return get_one_control("white_balance_temperature", V4L2_CID_WHITE_BALANCE_TEMPERATURE);
1343 }
1344 
1345 /**
1346  * Set white balance
1347  * @param white_balance_temperature
1348  */
1349 void
1350 V4L2Camera::set_white_balance_temperature(unsigned int white_balance_temperature)
1351 {
1352  LibLogger::log_debug("V4L2Cam",
1353  "setting white_balance_temperature to %d",
1355  set_one_control("white_balance_temperature",
1356  V4L2_CID_WHITE_BALANCE_TEMPERATURE,
1358 }
1359 
1360 /**
1361  * Get absolute exposure time
1362  * @return exposure time value
1363  */
1364 unsigned int
1366 {
1367  return get_one_control("exposure_absolute", V4L2_CID_EXPOSURE_ABSOLUTE);
1368 }
1369 
1370 /**
1371  * set absolute exposure time (1/s)
1372  * @param exposure_absolute
1373  */
1374 void
1375 V4L2Camera::set_exposure_absolute(unsigned int exposure_absolute)
1376 {
1377  LibLogger::log_debug("V4L2Cam", "setting exposure_absolute to %d", exposure_absolute);
1378  set_one_control("exposure_absolute", V4L2_CID_EXPOSURE_ABSOLUTE, exposure_absolute);
1379 }
1380 
1381 /**
1382  * Get sharpness value
1383  * @return V4L2 sharpness setting
1384  */
1385 unsigned int
1387 {
1388  return get_one_control("sharpness", V4L2_CID_SHARPNESS);
1389 }
1390 
1391 /**
1392  * Set sharpness. Lower = blurrier picture
1393  * @param sharpness
1394  */
1395 void
1396 V4L2Camera::set_sharpness(unsigned int sharpness)
1397 {
1398  LibLogger::log_debug("V4L2Cam", "setting sharpness to %d", sharpness);
1399  set_one_control("sharpness", V4L2_CID_SHARPNESS, sharpness);
1400 }
1401 
1402 bool
1404 {
1405  return get_one_control("AGC", V4L2_CID_AUTOGAIN);
1406 }
1407 
1408 void
1410 {
1411  LibLogger::log_debug("V4L2Cam", (enabled ? "enabling AGC" : "disabling AGC"));
1412  set_one_control("AGC", V4L2_CID_AUTOGAIN, (enabled ? 1 : 0));
1413 }
1414 
1415 bool
1417 {
1418  return get_one_control("AWB", V4L2_CID_AUTO_WHITE_BALANCE);
1419 }
1420 
1421 void
1423 {
1424  LibLogger::log_debug("V4L2Cam", (enabled ? "enabling AWB" : "disabling AWB"));
1425  set_one_control("AWB", V4L2_CID_AUTO_WHITE_BALANCE, (enabled ? 1 : 0));
1426 }
1427 
1428 unsigned int
1430 {
1431  return get_one_control("exposure_auto", V4L2_CID_EXPOSURE_AUTO);
1432 }
1433 
1434 void
1435 V4L2Camera::set_exposure_auto(unsigned int exposure_auto)
1436 {
1437  LibLogger::log_debug("V4L2Cam", "setting exposure_auto to %d", exposure_auto);
1438  set_one_control("exposure_auto", V4L2_CID_EXPOSURE_AUTO, exposure_auto);
1439 }
1440 
1441 int
1443 {
1444  return get_one_control("red balance", V4L2_CID_RED_BALANCE);
1445 }
1446 
1447 void
1449 {
1450  LibLogger::log_debug("V4L2Cam", "Setting red balance to %d", red_balance);
1451  set_one_control("red balance", V4L2_CID_RED_BALANCE, red_balance);
1452 }
1453 
1454 int
1456 {
1457  return get_one_control("blue balance", V4L2_CID_BLUE_BALANCE);
1458 }
1459 
1460 void
1462 {
1463  LibLogger::log_debug("V4L2Cam", "Setting blue balance to %d", blue_balance);
1464  set_one_control("blue balance", V4L2_CID_BLUE_BALANCE, blue_balance);
1465 }
1466 
1467 int
1469 {
1470  throw NotImplementedException("No such method in the V4L2 standard");
1471 }
1472 
1473 void
1475 {
1476  throw NotImplementedException("No such method in the V4L2 standard");
1477 }
1478 
1479 int
1481 {
1482  throw NotImplementedException("No such method in the V4L2 standard");
1483 }
1484 
1485 void
1487 {
1488  throw NotImplementedException("No such method in the V4L2 standard");
1489 }
1490 
1491 unsigned int
1493 {
1494  return get_one_control("brightness", V4L2_CID_BRIGHTNESS);
1495 }
1496 
1497 void
1498 V4L2Camera::set_brightness(unsigned int brightness)
1499 {
1500  LibLogger::log_debug("V4L2Cam", "Setting brighness to %d", brightness);
1501  set_one_control("brightness", V4L2_CID_BRIGHTNESS, brightness);
1502 }
1503 
1504 unsigned int
1506 {
1507  return get_one_control("contrast", V4L2_CID_CONTRAST);
1508 }
1509 
1510 void
1511 V4L2Camera::set_contrast(unsigned int contrast)
1512 {
1513  LibLogger::log_debug("V4L2Cam", "Setting contrast to %d", contrast);
1514  set_one_control("contrast", V4L2_CID_CONTRAST, contrast);
1515 }
1516 
1517 unsigned int
1519 {
1520  return get_one_control("saturation", V4L2_CID_SATURATION);
1521 }
1522 
1523 void
1524 V4L2Camera::set_saturation(unsigned int saturation)
1525 {
1526  LibLogger::log_debug("V4L2Cam", "Setting saturation to %d", saturation);
1527  set_one_control("saturation", V4L2_CID_SATURATION, saturation);
1528 }
1529 
1530 int
1532 {
1533  return get_one_control("hue", V4L2_CID_HUE);
1534 }
1535 
1536 void
1538 {
1539  LibLogger::log_debug("V4L2Cam", "Setting hue to %d", hue);
1540  set_one_control("hue", V4L2_CID_HUE, hue);
1541 }
1542 
1543 unsigned int
1545 {
1546  return get_one_control("exposure", V4L2_CID_EXPOSURE);
1547 }
1548 
1549 void
1550 V4L2Camera::set_exposure(unsigned int exposure)
1551 {
1552  LibLogger::log_debug("V4L2Cam", "Setting exposure to %d", exposure);
1553  set_one_control("exposure", V4L2_CID_EXPOSURE, exposure);
1554 }
1555 
1556 unsigned int
1558 {
1559  return get_one_control("gain", V4L2_CID_GAIN);
1560 }
1561 
1562 void
1563 V4L2Camera::set_gain(unsigned int gain)
1564 {
1565  LibLogger::log_debug("V4L2Cam", "Setting gain to %u", gain);
1566  set_one_control("gain", V4L2_CID_GAIN, gain);
1567 }
1568 
1569 const char *
1571 {
1572  return _format;
1573 }
1574 
1575 void
1576 V4L2Camera::set_format(const char *format)
1577 {
1578  strncpy(_format, format, 4);
1579  _format[4] = '\0';
1580  select_format();
1581 }
1582 
1583 unsigned int
1585 {
1586  return pixel_width();
1587 }
1588 
1589 unsigned int
1591 {
1592  return pixel_height();
1593 }
1594 
1595 void
1596 V4L2Camera::set_size(unsigned int width, unsigned int height)
1597 {
1598  _width = width;
1599  _height = height;
1600  select_format();
1601 }
1602 
1603 bool
1605 {
1606  return (get_one_control("hflip", V4L2_CID_HFLIP) != 0);
1607 }
1608 
1609 bool
1611 {
1612  return (get_one_control("vflip", V4L2_CID_VFLIP) != 0);
1613 }
1614 
1615 void
1617 {
1618  LibLogger::log_debug("V4L2Cam",
1619  (enabled ? "enabling horizontal flip" : "disabling horizontal flip"));
1620  set_one_control("hflip", V4L2_CID_HFLIP, (enabled ? 1 : 0));
1621 }
1622 
1623 void
1625 {
1626  LibLogger::log_debug("V4L2Cam", (enabled ? "enabling vertical flip" : "disabling vertical flip"));
1627  set_one_control("vflip", V4L2_CID_VFLIP, (enabled ? 1 : 0));
1628 }
1629 
1630 /** Get the number of frames per second that have been requested from the camera.
1631  * A return value of 0 means that fps haven't been set yet through the camera.
1632  * @return the currently requested fps or 0 if not set yet
1633  */
1634 unsigned int
1636 {
1637  return _fps;
1638 }
1639 
1640 void
1641 V4L2Camera::set_fps(unsigned int fps)
1642 {
1643  _fps = fps;
1644  set_fps();
1645 }
1646 
1647 unsigned int
1649 {
1650  return get_one_control("lens x", V4L2_CID_PAN_RESET);
1651 }
1652 
1653 unsigned int
1655 {
1656  return get_one_control("lens y", V4L2_CID_TILT_RESET);
1657 }
1658 
1659 void
1660 V4L2Camera::set_lens_x_corr(unsigned int x_corr)
1661 {
1662  LibLogger::log_debug("V4L2Cam", "Setting horizontal lens correction to %d", x_corr);
1663  set_one_control("lens x", V4L2_CID_PAN_RESET, x_corr);
1664 }
1665 
1666 void
1667 V4L2Camera::set_lens_y_corr(unsigned int y_corr)
1668 {
1669  LibLogger::log_debug("V4L2Cam", "Setting vertical lens correction to %d", y_corr);
1670  set_one_control("lens x", V4L2_CID_TILT_RESET, y_corr);
1671 }
1672 
1673 void
1675 {
1676  /* General capabilities */
1677  cout << "==========================================================================" << endl
1678  << _device_name << " (" << _data->caps.card << ") - " << _data->caps.bus_info << endl
1679  << "Driver: " << _data->caps.driver << " (ver " << ((_data->caps.version >> 16) & 0xFF)
1680  << "." << ((_data->caps.version >> 8) & 0xFF) << "." << (_data->caps.version & 0xFF) << ")"
1681  << endl
1682  << "--------------------------------------------------------------------------" << endl;
1683 
1684  /* General capabilities */
1685  cout << "Capabilities:" << endl;
1686  if (_data->caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)
1687  cout << " + Video capture interface supported" << endl;
1688  if (_data->caps.capabilities & V4L2_CAP_VIDEO_OUTPUT)
1689  cout << " + Video output interface supported" << endl;
1690  if (_data->caps.capabilities & V4L2_CAP_VIDEO_OVERLAY)
1691  cout << " + Video overlay interface supported" << endl;
1692  if (_data->caps.capabilities & V4L2_CAP_VBI_CAPTURE)
1693  cout << " + Raw VBI capture interface supported" << endl;
1694  if (_data->caps.capabilities & V4L2_CAP_VBI_OUTPUT)
1695  cout << " + Raw VBI output interface supported" << endl;
1696  if (_data->caps.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE)
1697  cout << " + Sliced VBI capture interface supported" << endl;
1698  if (_data->caps.capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
1699  cout << " + Sliced VBI output interface supported" << endl;
1700  if (_data->caps.capabilities & V4L2_CAP_RDS_CAPTURE)
1701  cout << " + RDS_CAPTURE set" << endl;
1702  /* Not included in Nao's version
1703  if (caps.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
1704  cout << " + Video output overlay interface supported" << endl; */
1705  if (_data->caps.capabilities & V4L2_CAP_TUNER)
1706  cout << " + Has some sort of tuner" << endl;
1707  if (_data->caps.capabilities & V4L2_CAP_AUDIO)
1708  cout << " + Has audio inputs or outputs" << endl;
1709  if (_data->caps.capabilities & V4L2_CAP_RADIO)
1710  cout << " + Has a radio receiver" << endl;
1711  if (_data->caps.capabilities & V4L2_CAP_READWRITE)
1712  cout << " + read() and write() IO supported" << endl;
1713  if (_data->caps.capabilities & V4L2_CAP_ASYNCIO)
1714  cout << " + asynchronous IO supported" << endl;
1715  if (_data->caps.capabilities & V4L2_CAP_STREAMING)
1716  cout << " + streaming IO supported" << endl;
1717  if (_data->caps.capabilities & V4L2_CAP_TIMEPERFRAME)
1718  cout << " + timeperframe field is supported" << endl;
1719  cout << endl;
1720 
1721  /* Inputs */
1722  cout << "Inputs:" << endl;
1723  v4l2_input input;
1724  memset(&input, 0, sizeof(input));
1725 
1726  for (input.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMINPUT, &input) == 0; input.index++) {
1727  cout << "Input " << input.index << ": " << input.name << endl;
1728 
1729  cout << " |- Type: ";
1730  switch (input.type) {
1731  case V4L2_INPUT_TYPE_TUNER: cout << "Tuner"; break;
1732 
1733  case V4L2_INPUT_TYPE_CAMERA: cout << "Camera"; break;
1734 
1735  default: cout << "Unknown";
1736  }
1737  cout << endl;
1738 
1739  cout << " |- Supported standards:";
1740  if (input.std == 0) {
1741  cout << " Unknown" << endl;
1742  } else {
1743  cout << endl;
1744 
1745  v4l2_standard standard;
1746  memset(&standard, 0, sizeof(standard));
1747  standard.index = 0;
1748 
1749  for (standard.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMSTD, &standard) == 0; standard.index++) {
1750  if (standard.id & input.std)
1751  cout << " + " << standard.name << endl;
1752  }
1753  }
1754  }
1755  if (input.index == 0)
1756  cout << "None" << endl;
1757  cout << endl;
1758 
1759  /* Outputs */
1760  cout << "Outputs:" << endl;
1761  v4l2_output output;
1762  memset(&output, 0, sizeof(output));
1763 
1764  for (output.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMOUTPUT, &output) == 0; output.index++) {
1765  cout << " + Output " << output.index << ": " << output.name << endl;
1766 
1767  cout << " |- Type: ";
1768  switch (output.type) {
1769  case V4L2_OUTPUT_TYPE_MODULATOR: cout << "TV Modulator"; break;
1770 
1771  case V4L2_OUTPUT_TYPE_ANALOG: cout << "Analog output"; break;
1772 
1773  default: cout << "Unknown";
1774  }
1775  cout << endl;
1776 
1777  cout << " |- Supported standards:";
1778  if (output.std == 0) {
1779  cout << " Unknown" << endl;
1780  } else {
1781  cout << endl;
1782 
1783  v4l2_standard standard;
1784  memset(&standard, 0, sizeof(standard));
1785  standard.index = 0;
1786 
1787  for (standard.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMSTD, &standard) == 0; standard.index++) {
1788  if (standard.id & output.std)
1789  cout << " + " << standard.name << endl;
1790  }
1791  }
1792  }
1793  if (output.index == 0)
1794  cout << "None" << endl;
1795  cout << endl;
1796 
1797  /* Supported formats */
1798  cout << "Formats:" << endl;
1799  v4l2_fmtdesc format_desc;
1800  memset(&format_desc, 0, sizeof(format_desc));
1801  format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1802 
1803  char fourcc[5] = " ";
1804  for (format_desc.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUM_FMT, &format_desc) == 0;
1805  format_desc.index++) {
1806  fourcc[0] = static_cast<char>(format_desc.pixelformat & 0xFF);
1807  fourcc[1] = static_cast<char>((format_desc.pixelformat >> 8) & 0xFF);
1808  fourcc[2] = static_cast<char>((format_desc.pixelformat >> 16) & 0xFF);
1809  fourcc[3] = static_cast<char>((format_desc.pixelformat >> 24) & 0xFF);
1810 
1811  colorspace_t cs = CS_UNKNOWN;
1812  if (strcmp(fourcc, "RGB3") == 0)
1813  cs = RGB;
1814  else if (strcmp(fourcc, "Y41P") == 0)
1815  cs = YUV411_PACKED; //different byte ordering
1816  else if (strcmp(fourcc, "411P") == 0)
1817  cs = YUV411_PLANAR;
1818  else if (strcmp(fourcc, "YUYV") == 0)
1819  cs = YUY2;
1820  else if (strcmp(fourcc, "BGR3") == 0)
1821  cs = BGR;
1822  else if (strcmp(fourcc, "UYVY") == 0)
1823  cs = YUV422_PACKED;
1824  else if (strcmp(fourcc, "422P") == 0)
1825  cs = YUV422_PLANAR;
1826  else if (strcmp(fourcc, "GREY") == 0)
1827  cs = GRAY8;
1828  else if (strcmp(fourcc, "RGB4") == 0)
1829  cs = RGB_WITH_ALPHA;
1830  else if (strcmp(fourcc, "BGR4") == 0)
1831  cs = BGR_WITH_ALPHA;
1832  else if (strcmp(fourcc, "BA81") == 0)
1833  cs = BAYER_MOSAIC_BGGR;
1834  else if (strcmp(fourcc, "Y16 ") == 0)
1835  cs = MONO16;
1836 
1837  cout << " + Format " << format_desc.index << ": " << fourcc << " (" << format_desc.description
1838  << ")";
1839  if (format_desc.flags & V4L2_FMT_FLAG_COMPRESSED)
1840  cout << " [Compressed]";
1841  cout << endl << " |- Colorspace: " << colorspace_to_string(cs) << endl;
1842  }
1843  cout << endl;
1844 
1845  /* Current Format */
1846  v4l2_format format;
1847  memset(&format, 0, sizeof(format));
1848  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1849  if (v4l2_ioctl(_dev, VIDIOC_G_FMT, &format))
1850  throw Exception("V4L2Cam: Format query failed");
1851  fourcc[0] = static_cast<char>(format.fmt.pix.pixelformat & 0xFF);
1852  fourcc[1] = static_cast<char>((format.fmt.pix.pixelformat >> 8) & 0xFF);
1853  fourcc[2] = static_cast<char>((format.fmt.pix.pixelformat >> 16) & 0xFF);
1854  fourcc[3] = static_cast<char>((format.fmt.pix.pixelformat >> 24) & 0xFF);
1855 
1856  cout << " Current Format:" << endl
1857  << " " << format.fmt.pix.width << "x" << format.fmt.pix.height << " (" << fourcc << ")"
1858  << endl
1859  << " " << format.fmt.pix.bytesperline << " bytes per line" << endl
1860  << " Total size: " << format.fmt.pix.sizeimage << endl;
1861 
1862  /* Supported Controls */
1863  cout << "Controls:" << endl;
1864  v4l2_queryctrl queryctrl;
1865  v4l2_querymenu querymenu;
1866 
1867  memset(&queryctrl, 0, sizeof(queryctrl));
1868 
1869  for (queryctrl.id = V4L2_CID_BASE; queryctrl.id < V4L2_CID_LASTP1; queryctrl.id++) {
1870  if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl)) {
1871  if (errno == EINVAL)
1872  continue;
1873 
1874  cout << "Control query failed" << endl;
1875  return;
1876  }
1877  if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
1878  continue;
1879 
1880  cout << " + " << queryctrl.name << " [" << (queryctrl.id - V4L2_CID_BASE) << "] (";
1881  switch (queryctrl.type) {
1882  case V4L2_CTRL_TYPE_INTEGER:
1883  cout << "int [" << queryctrl.minimum << "-" << queryctrl.maximum << " /" << queryctrl.step
1884  << " def " << queryctrl.default_value << "]";
1885  break;
1886 
1887  case V4L2_CTRL_TYPE_MENU: cout << "menu [def " << queryctrl.default_value << "]"; break;
1888 
1889  case V4L2_CTRL_TYPE_BOOLEAN: cout << "bool [def " << queryctrl.default_value << "]"; break;
1890 
1891  case V4L2_CTRL_TYPE_BUTTON: cout << "button"; break;
1892 
1893 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
1894  case V4L2_CTRL_TYPE_INTEGER64: cout << "int64"; break;
1895 
1896  case V4L2_CTRL_TYPE_CTRL_CLASS: cout << "ctrl_class"; break;
1897 #endif
1898 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1899  case V4L2_CTRL_TYPE_STRING: cout << "string"; break;
1900 #endif
1901 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 41)
1902  case V4L2_CTRL_TYPE_BITMASK: cout << "bitmask"; break;
1903 #endif
1904  }
1905  cout << ")" << endl;
1906 
1907  if (queryctrl.type == V4L2_CTRL_TYPE_MENU) {
1908  cout << " |- Menu items:" << endl;
1909 
1910  memset(&querymenu, 0, sizeof(querymenu));
1911  querymenu.id = queryctrl.id;
1912 
1913  for (querymenu.index = queryctrl.minimum;
1914  querymenu.index <= static_cast<unsigned long int>(queryctrl.maximum);
1915  querymenu.index++) {
1916  if (v4l2_ioctl(_dev, VIDIOC_QUERYMENU, &querymenu)) {
1917  cout << "Getting menu items failed" << endl;
1918  return;
1919  }
1920  cout << " | + " << querymenu.name << endl;
1921  }
1922  }
1923  }
1924  if (queryctrl.id == V4L2_CID_BASE)
1925  cout << "None" << endl;
1926  cout << endl;
1927 
1928  /* Supported Private Controls */
1929  cout << "Private Controls:" << endl;
1930  for (queryctrl.id = V4L2_CID_PRIVATE_BASE;; queryctrl.id++) {
1931  if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl)) {
1932  if (errno == EINVAL)
1933  break;
1934 
1935  cout << "Private Control query failed" << endl;
1936  return;
1937  }
1938 
1939  if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
1940  continue;
1941 
1942  cout << " + " << queryctrl.name << " [" << (queryctrl.id - V4L2_CID_PRIVATE_BASE) << "] (";
1943  switch (queryctrl.type) {
1944  case V4L2_CTRL_TYPE_INTEGER:
1945  cout << "int [" << queryctrl.minimum << "-" << queryctrl.maximum << " /" << queryctrl.step
1946  << " def " << queryctrl.default_value << "]";
1947  break;
1948 
1949  case V4L2_CTRL_TYPE_MENU: cout << "menu [def " << queryctrl.default_value << "]"; break;
1950 
1951  case V4L2_CTRL_TYPE_BOOLEAN: cout << "bool [def " << queryctrl.default_value << "]"; break;
1952 
1953  case V4L2_CTRL_TYPE_BUTTON: cout << "button"; break;
1954 
1955 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
1956  case V4L2_CTRL_TYPE_INTEGER64: cout << "int64"; break;
1957 
1958  case V4L2_CTRL_TYPE_CTRL_CLASS: cout << "ctrl_class"; break;
1959 #endif
1960 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1961  case V4L2_CTRL_TYPE_STRING: cout << "string"; break;
1962 #endif
1963 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 41)
1964  case V4L2_CTRL_TYPE_BITMASK: cout << "bitmask"; break;
1965 #endif
1966  }
1967  cout << ")" << endl;
1968 
1969  if (queryctrl.type == V4L2_CTRL_TYPE_MENU) {
1970  cout << " |- Menu items:" << endl;
1971 
1972  memset(&querymenu, 0, sizeof(querymenu));
1973  querymenu.id = queryctrl.id;
1974 
1975  for (querymenu.index = queryctrl.minimum;
1976  querymenu.index <= static_cast<unsigned long int>(queryctrl.maximum);
1977  querymenu.index++) {
1978  if (v4l2_ioctl(_dev, VIDIOC_QUERYMENU, &querymenu)) {
1979  cout << "Getting menu items failed" << endl;
1980  return;
1981  }
1982  cout << " | + " << querymenu.name << endl;
1983  }
1984  }
1985  }
1986  if (queryctrl.id == V4L2_CID_PRIVATE_BASE)
1987  cout << "None" << endl;
1988 
1989  cout << "==========================================================================" << endl;
1990 }
1991 
1992 } // end namespace firevision
Base class for exceptions in Fawkes.
Definition: exception.h:36
Library logger.
Definition: liblogger.h:39
Expected parameter is missing.
Definition: software.h:74
Called method has not been implemented.
Definition: software.h:105
A class for handling time.
Definition: time.h:93
Time & stamp()
Set this time to the current time.
Definition: time.cpp:704
void set_time(const timeval *tv)
Sets the time.
Definition: time.cpp:246
Camera argument parser.
Definition: camargp.h:36
bool has(std::string s) const
Check if an parameter was given.
Definition: camargp.cpp:145
std::string get(std::string s) const
Get the value of the given parameter.
Definition: camargp.cpp:156
virtual void size(unsigned int &width, unsigned int &height)
Get the current image size.
Definition: image.cpp:89
virtual void set_fps(unsigned int fps)
Set the number of frames per second the camera tries to deliver.
Definition: v4l2.cpp:1641
virtual void close()
Close camera.
Definition: v4l2.cpp:1031
virtual void set_exposure_absolute(unsigned int exposure_absolute)
set absolute exposure time (1/s)
Definition: v4l2.cpp:1375
virtual void stop()
Stop image transfer from the camera.
Definition: v4l2.cpp:1121
virtual unsigned int exposure_absolute()
Get absolute exposure time.
Definition: v4l2.cpp:1365
virtual void set_one_control(const char *ctrl, unsigned int id, int value)
Set one Camera control value.
Definition: v4l2.cpp:864
virtual void set_contrast(unsigned int contrast)
Set new contrast.
Definition: v4l2.cpp:1511
virtual unsigned int pixel_width()
Width of image in pixels.
Definition: v4l2.cpp:1270
virtual int red_balance()
Get current red balance.
Definition: v4l2.cpp:1442
virtual unsigned int pixel_height()
Height of image in pixels.
Definition: v4l2.cpp:1278
virtual void set_exposure(unsigned int exposure)
Set new exposure.
Definition: v4l2.cpp:1550
virtual bool exposure_auto_priority()
Get exposure_auto_priority V4L2 control.
Definition: v4l2.cpp:1317
virtual void set_gain(unsigned int gain)
Set new gain.
Definition: v4l2.cpp:1563
virtual void set_red_balance(int red_balance)
Set red balance.
Definition: v4l2.cpp:1448
virtual unsigned int buffer_size()
Size of buffer.
Definition: v4l2.cpp:1224
virtual unsigned int contrast()
Get current contrast.
Definition: v4l2.cpp:1505
virtual ~V4L2Camera()
Destructor.
Definition: v4l2.cpp:400
virtual void set_blue_balance(int blue_balance)
Set blue balance.
Definition: v4l2.cpp:1461
virtual void dispose_buffer()
Dispose current buffer.
Definition: v4l2.cpp:1232
virtual void set_image_number(unsigned int n)
Set image number to retrieve.
Definition: v4l2.cpp:1303
virtual void capture()
Capture an image.
Definition: v4l2.cpp:1162
virtual void set_size(unsigned int width, unsigned int height)
Set the image size the camera should use.
Definition: v4l2.cpp:1596
virtual void set_hue(int hue)
Set new hue.
Definition: v4l2.cpp:1537
virtual const char * format()
Get the image format the camera currently uses.
Definition: v4l2.cpp:1570
virtual unsigned int brightness()
Get current brightness.
Definition: v4l2.cpp:1492
char * _device_name
Device name.
Definition: v4l2.h:140
virtual unsigned int exposure()
Get current exposure.
Definition: v4l2.cpp:1544
virtual void set_white_balance_temperature(unsigned int white_balance_temperature)
Set white balance.
Definition: v4l2.cpp:1350
virtual bool horiz_mirror()
Return whether the camera image is horizontally mirrored.
Definition: v4l2.cpp:1604
virtual colorspace_t colorspace()
Colorspace of returned image.
Definition: v4l2.cpp:1286
virtual bool ready()
Camera is ready for taking pictures.
Definition: v4l2.cpp:1149
virtual void set_brightness(unsigned int brightness)
Set new brightness.
Definition: v4l2.cpp:1498
virtual unsigned int lens_y_corr()
Get current lens y correction.
Definition: v4l2.cpp:1654
virtual unsigned int fps()
Get the number of frames per second that have been requested from the camera.
Definition: v4l2.cpp:1635
virtual void flush()
Flush image queue.
Definition: v4l2.cpp:1155
virtual unsigned char * buffer()
Get access to current image buffer.
Definition: v4l2.cpp:1216
virtual void start()
Start image transfer from the camera.
Definition: v4l2.cpp:1074
virtual void set_lens_x_corr(unsigned int x_corr)
Set lens x correction.
Definition: v4l2.cpp:1660
virtual unsigned int height()
Get the current height of the image.
Definition: v4l2.cpp:1590
virtual void set_u_balance(int u_balance)
Set u balance.
Definition: v4l2.cpp:1474
virtual unsigned int gain()
Get current gain.
Definition: v4l2.cpp:1557
virtual void print_info()
Print out camera information.
Definition: v4l2.cpp:1674
virtual void set_auto_white_balance(bool enabled)
Enable/disable auto white balance.
Definition: v4l2.cpp:1422
virtual fawkes::Time * capture_time()
Get the Time of the last successfully captured image.
Definition: v4l2.cpp:1297
virtual void set_exposure_auto(unsigned int exposure_auto)
Enable/disable auto exposure.
Definition: v4l2.cpp:1435
virtual void set_v_balance(int v_balance)
Set v balance.
Definition: v4l2.cpp:1486
virtual bool auto_gain()
Return whether auto gain is enabled.
Definition: v4l2.cpp:1403
virtual void set_format(const char *format)
Set the image format the camera should use.
Definition: v4l2.cpp:1576
virtual unsigned int exposure_auto()
Return whether auto exposure is enabled.
Definition: v4l2.cpp:1429
virtual void set_exposure_auto_priority(bool enabled)
Set exposure_auto_priority V4L2 control.
Definition: v4l2.cpp:1327
virtual unsigned int width()
Get the current width of the image.
Definition: v4l2.cpp:1584
virtual unsigned int lens_x_corr()
Get current lens x correction.
Definition: v4l2.cpp:1648
virtual void set_saturation(unsigned int saturation)
Set new saturation.
Definition: v4l2.cpp:1524
virtual unsigned int saturation()
Get current saturation.
Definition: v4l2.cpp:1518
virtual unsigned int sharpness()
Get sharpness value.
Definition: v4l2.cpp:1386
V4L2Camera(const char *device_name="/dev/video0")
Constructor.
Definition: v4l2.cpp:83
virtual int v_balance()
Get current v balance.
Definition: v4l2.cpp:1480
virtual bool auto_white_balance()
Return whether auto white balance is enabled.
Definition: v4l2.cpp:1416
virtual int blue_balance()
Get current blue balance.
Definition: v4l2.cpp:1455
virtual void set_vert_mirror(bool enabled)
Set whether the camera should mirror images vertically.
Definition: v4l2.cpp:1624
virtual void open()
Open the camera.
Definition: v4l2.cpp:416
virtual int get_one_control(const char *ctrl, unsigned int id)
Get one Camera control value.
Definition: v4l2.cpp:903
virtual void set_sharpness(unsigned int sharpness)
Set sharpness.
Definition: v4l2.cpp:1396
virtual int u_balance()
Get current u balance.
Definition: v4l2.cpp:1468
virtual bool vert_mirror()
Return whether the camera image is vertically mirrored.
Definition: v4l2.cpp:1610
virtual unsigned int white_balance_temperature()
Get absolute white balance setting.
Definition: v4l2.cpp:1340
virtual void set_horiz_mirror(bool enabled)
Set whether the camera should mirror images horizontally.
Definition: v4l2.cpp:1616
virtual void set_auto_gain(bool enabled)
Enable/disable auto gain.
Definition: v4l2.cpp:1409
virtual void set_lens_y_corr(unsigned int y_corr)
Set lens y correction.
Definition: v4l2.cpp:1667
virtual int hue()
Get current hue.
Definition: v4l2.cpp:1531