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
43using std::cout;
44using std::endl;
45using 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
60namespace firevision {
61
62/// @cond INTERNALS
63class V4L2CameraData
64{
65public:
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 */
83V4L2Camera::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 */
364V4L2Camera::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
415void
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 */
452void
453V4L2Camera::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 */
472void
473V4L2Camera::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. */
533void
534V4L2Camera::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. */
568void
569V4L2Camera::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 */
610void
611V4L2Camera::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 */
779void
780V4L2Camera::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 */
810void
811V4L2Camera::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 */
863void
864V4L2Camera::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 */
902int
903V4L2Camera::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 */
945void
946V4L2Camera::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 */
997void
998V4L2Camera::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
1030void
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
1073void
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
1120void
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
1148bool
1150{
1151 return _started;
1152}
1153
1154void
1156{
1157 //LibLogger::log_debug("V4L2Cam", "flush()");
1158 /* not needed */
1159}
1160
1161void
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
1215unsigned char *
1217{
1218 //LibLogger::log_debug("V4L2Cam", "buffer()");
1219
1220 return (_current_buffer == -1 ? NULL : _frame_buffers[_current_buffer].buffer);
1221}
1222
1223unsigned int
1225{
1226 //LibLogger::log_debug("V4L2Cam", "buffer_size()");
1227
1228 return (_opened && (_current_buffer != -1) ? _frame_buffers[_current_buffer].size : 0);
1229}
1230
1231void
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
1269unsigned int
1271{
1272 //LibLogger::log_debug("V4L2Cam", "pixel_width()");
1273
1274 return _width;
1275}
1276
1277unsigned int
1279{
1280 //LibLogger::log_debug("V4L2Cam", "pixel_height()");
1281
1282 return _height;
1283}
1284
1285colorspace_t
1287{
1288 //LibLogger::log_debug("V4L2Cam", "colorspace()");
1289
1290 if (!_opened)
1291 return CS_UNKNOWN;
1292 else
1293 return _colorspace;
1294}
1295
1298{
1299 return _capture_time;
1300}
1301
1302void
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 */
1316bool
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 */
1326void
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 */
1339unsigned 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 */
1349void
1350V4L2Camera::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 */
1364unsigned 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 */
1374void
1375V4L2Camera::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 */
1385unsigned int
1387{
1388 return get_one_control("sharpness", V4L2_CID_SHARPNESS);
1389}
1390
1391/**
1392 * Set sharpness. Lower = blurrier picture
1393 * @param sharpness
1394 */
1395void
1396V4L2Camera::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
1402bool
1404{
1405 return get_one_control("AGC", V4L2_CID_AUTOGAIN);
1406}
1407
1408void
1410{
1411 LibLogger::log_debug("V4L2Cam", (enabled ? "enabling AGC" : "disabling AGC"));
1412 set_one_control("AGC", V4L2_CID_AUTOGAIN, (enabled ? 1 : 0));
1413}
1414
1415bool
1417{
1418 return get_one_control("AWB", V4L2_CID_AUTO_WHITE_BALANCE);
1419}
1420
1421void
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
1428unsigned int
1430{
1431 return get_one_control("exposure_auto", V4L2_CID_EXPOSURE_AUTO);
1432}
1433
1434void
1435V4L2Camera::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
1441int
1443{
1444 return get_one_control("red balance", V4L2_CID_RED_BALANCE);
1445}
1446
1447void
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
1454int
1456{
1457 return get_one_control("blue balance", V4L2_CID_BLUE_BALANCE);
1458}
1459
1460void
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
1467int
1469{
1470 throw NotImplementedException("No such method in the V4L2 standard");
1471}
1472
1473void
1475{
1476 throw NotImplementedException("No such method in the V4L2 standard");
1477}
1478
1479int
1481{
1482 throw NotImplementedException("No such method in the V4L2 standard");
1483}
1484
1485void
1487{
1488 throw NotImplementedException("No such method in the V4L2 standard");
1489}
1490
1491unsigned int
1493{
1494 return get_one_control("brightness", V4L2_CID_BRIGHTNESS);
1495}
1496
1497void
1498V4L2Camera::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
1504unsigned int
1506{
1507 return get_one_control("contrast", V4L2_CID_CONTRAST);
1508}
1509
1510void
1511V4L2Camera::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
1517unsigned int
1519{
1520 return get_one_control("saturation", V4L2_CID_SATURATION);
1521}
1522
1523void
1524V4L2Camera::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
1530int
1532{
1533 return get_one_control("hue", V4L2_CID_HUE);
1534}
1535
1536void
1538{
1539 LibLogger::log_debug("V4L2Cam", "Setting hue to %d", hue);
1540 set_one_control("hue", V4L2_CID_HUE, hue);
1541}
1542
1543unsigned int
1545{
1546 return get_one_control("exposure", V4L2_CID_EXPOSURE);
1547}
1548
1549void
1550V4L2Camera::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
1556unsigned int
1558{
1559 return get_one_control("gain", V4L2_CID_GAIN);
1560}
1561
1562void
1563V4L2Camera::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
1569const char *
1571{
1572 return _format;
1573}
1574
1575void
1576V4L2Camera::set_format(const char *format)
1577{
1578 strncpy(_format, format, 4);
1579 _format[4] = '\0';
1580 select_format();
1581}
1582
1583unsigned int
1585{
1586 return pixel_width();
1587}
1588
1589unsigned int
1591{
1592 return pixel_height();
1593}
1594
1595void
1596V4L2Camera::set_size(unsigned int width, unsigned int height)
1597{
1598 _width = width;
1599 _height = height;
1600 select_format();
1601}
1602
1603bool
1605{
1606 return (get_one_control("hflip", V4L2_CID_HFLIP) != 0);
1607}
1608
1609bool
1611{
1612 return (get_one_control("vflip", V4L2_CID_VFLIP) != 0);
1613}
1614
1615void
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
1623void
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 */
1634unsigned int
1636{
1637 return _fps;
1638}
1639
1640void
1641V4L2Camera::set_fps(unsigned int fps)
1642{
1643 _fps = fps;
1644 set_fps();
1645}
1646
1647unsigned int
1649{
1650 return get_one_control("lens x", V4L2_CID_PAN_RESET);
1651}
1652
1653unsigned int
1655{
1656 return get_one_control("lens y", V4L2_CID_TILT_RESET);
1657}
1658
1659void
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
1666void
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
1673void
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