25 #include <fvcams/v4l2.h> 27 #include <core/exception.h> 28 #include <core/exceptions/software.h> 29 #include <logging/liblogger.h> 30 #include <fvutils/system/camargp.h> 33 #include <sys/ioctl.h> 39 #include <linux/version.h> 53 # define v4l2_fd_open(fd, flags) (fd) 54 # define v4l2_close ::close 56 # define v4l2_ioctl ioctl 57 # define v4l2_read read 58 # define v4l2_mmap mmap 59 # define v4l2_munmap munmap 92 _opened = _started =
false;
93 _nao_hacks = _switch_u_v =
false;
94 _width = _height = _bytes_per_line = _fps = _buffers_length = 0;
96 _brightness.set = _contrast.set = _saturation.set = _hue.set =
97 _red_balance.set = _blue_balance.set = _exposure.set = _gain.set =
98 _lens_x.set = _lens_y.set =
false;
99 _aec = _awb = _agc = _h_flip = _v_flip = NOT_SET;
101 memset(_format, 0, 5);
102 _frame_buffers = NULL;
103 _capture_time = NULL;
104 _device_name = strdup(device_name);
105 _data =
new V4L2CameraData();
142 _opened = _started =
false;
144 _width = _height = _bytes_per_line = _buffers_length = 0;
145 _current_buffer = -1;
146 _frame_buffers = NULL;
147 _capture_time = NULL;
148 _data =
new V4L2CameraData();
150 if (cap->
has(
"device")) _device_name = strdup(cap->
get(
"device").c_str());
154 if (cap->
has(
"read_method"))
156 string rm = cap->
get(
"read_method");
157 if (rm.compare(
"READ") == 0) _read_method = READ;
158 else if (rm.compare(
"MMAP") == 0) _read_method = MMAP;
159 else if (rm.compare(
"UPTR") == 0) _read_method = UPTR;
160 else throw Exception(
"V4L2Cam: Invalid read method");
168 if (cap->
has(
"format"))
170 string fmt = cap->
get(
"format");
171 if (fmt.length() != 4)
throw Exception(
"V4L2Cam: Invalid format fourcc");
172 strncpy(_format, fmt.c_str(), 4);
177 memset(_format, 0, 5);
181 if (cap->
has(
"size"))
183 string size = cap->
get(
"size");
184 string::size_type pos;
185 if ((pos = size.find(
'x')) == string::npos)
throw Exception(
"V4L2Cam: invalid image size string");
186 if ((pos == (size.length() - 1)))
throw Exception(
"V4L2Cam: invalid image size string");
188 unsigned int mult = 1;
189 for (string::size_type i = pos - 1; i != string::npos; --i)
191 _width += (size.at(i) -
'0') * mult;
196 for (string::size_type i = size.length() - 1; i > pos; --i)
198 _height += (size.at(i) -
'0') * mult;
204 if (cap->
has(
"switch_u_v"))
206 _switch_u_v = (cap->
get(
"switch_u_v").compare(
"true") == 0);
216 if ((_fps = atoi(cap->
get(
"fps").c_str())) == 0)
throw Exception(
"V4L2Cam: invalid fps string");
226 _aec = (cap->
get(
"aec").compare(
"true") == 0 ? TRUE : FALSE);
236 _awb = (cap->
get(
"awb").compare(
"true") == 0 ? TRUE : FALSE);
246 _agc = (cap->
get(
"agc").compare(
"true") == 0 ? TRUE : FALSE);
254 if (cap->
has(
"h_flip"))
256 _h_flip = (cap->
get(
"h_flip").compare(
"true") == 0 ? TRUE : FALSE);
264 if (cap->
has(
"v_flip"))
266 _v_flip = (cap->
get(
"v_flip").compare(
"true") == 0 ? TRUE : FALSE);
274 if (cap->
has(
"brightness"))
276 _brightness.set =
true;
277 _brightness.value = atoi(cap->
get(
"brightness").c_str());
281 _brightness.set =
false;
285 if (cap->
has(
"contrast"))
287 _contrast.set =
true;
288 _contrast.value = atoi(cap->
get(
"contrast").c_str());
292 _contrast.set =
false;
296 if (cap->
has(
"saturation"))
298 _saturation.set =
true;
299 _saturation.value = atoi(cap->
get(
"saturation").c_str());
303 _saturation.set =
false;
310 _hue.value = atoi(cap->
get(
"hue").c_str());
318 if (cap->
has(
"red_balance"))
320 _red_balance.set =
true;
321 _red_balance.value = atoi(cap->
get(
"red_balance").c_str());
325 _red_balance.set =
false;
329 if (cap->
has(
"blue_balance"))
331 _blue_balance.set =
true;
332 _blue_balance.value = atoi(cap->
get(
"blue_balance").c_str());
336 _blue_balance.set =
false;
340 if (cap->
has(
"exposure"))
342 _exposure.set =
true;
343 _exposure.value = atoi(cap->
get(
"exposure").c_str());
347 _exposure.set =
false;
351 if (cap->
has(
"gain"))
354 _gain.value = atoi(cap->
get(
"gain").c_str());
362 if (cap->
has(
"lens_x"))
365 _lens_x.value = atoi(cap->
get(
"lens_x").c_str());
373 if (cap->
has(
"lens_y"))
376 _lens_y.value = atoi(cap->
get(
"lens_y").c_str());
395 _nao_hacks = _switch_u_v =
false;
396 _width = _height = _bytes_per_line = _buffers_length = _fps = 0;
397 _current_buffer = -1;
398 _brightness.set = _contrast.set = _saturation.set = _hue.set =
399 _red_balance.set = _blue_balance.set = _exposure.set = _gain.set =
400 _lens_x.set = _lens_y.set =
false;
401 _aec = _awb = _agc = _h_flip = _v_flip = NOT_SET;
403 memset(_format, 0, 5);
404 _frame_buffers = NULL;
405 _capture_time = NULL;
406 _device_name = strdup(device_name);
407 _data =
new V4L2CameraData();
412 if (v4l2_ioctl(_dev, VIDIOC_QUERYCAP, &_data->caps))
415 throw Exception(
"V4L2Cam: Could not get capabilities - probably not a v4l2 device");
424 if (_started) stop();
425 if (_opened) close();
434 if (_started) stop();
437 _dev = ::open(_device_name, O_RDWR);
438 int libv4l2_fd = v4l2_fd_open(_dev, 0);
439 if (libv4l2_fd != -1) _dev = libv4l2_fd;
446 if (_dev < 0)
throw Exception(
"V4L2Cam: Could not open device");
451 if (v4l2_ioctl(_dev, VIDIOC_QUERYCAP, &_data->caps))
454 throw Exception(
"V4L2Cam: Could not get capabilities - probably not a v4l2 device");
466 V4L2Camera::post_open()
469 select_read_method();
498 V4L2Camera::select_read_method()
501 if (!(_data->caps.capabilities &
502 (_read_method == READ ? V4L2_CAP_READWRITE : V4L2_CAP_STREAMING)))
505 _read_method = (_read_method == READ ? MMAP : READ);
506 if (!(_data->caps.capabilities &
507 (_read_method == READ ? V4L2_CAP_READWRITE : V4L2_CAP_STREAMING)))
510 throw Exception(
"V4L2Cam: Neither read() nor streaming IO supported");
514 if (_read_method != READ)
516 v4l2_requestbuffers buf;
519 for (
int i = 0; i < 2; ++i)
521 if (_read_method == MMAP)
523 _buffers_length = MMAP_NUM_BUFFERS;
524 buf.count = _buffers_length;
525 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
526 buf.memory = V4L2_MEMORY_MMAP;
532 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
533 buf.memory = V4L2_MEMORY_USERPTR;
536 if (v4l2_ioctl(_dev, VIDIOC_REQBUFS, &buf))
541 throw Exception(
"V4L2Cam: REQBUFS query failed");
548 throw Exception(
"V4L2Cam: Neither memory mapped nor user pointer IO supported");
552 _read_method = (_read_method == MMAP ? UPTR : MMAP);
557 if ((_read_method == MMAP) && (buf.count < _buffers_length))
560 throw Exception(
"V4L2Cam: Not enough memory for the buffers");
571 switch (_read_method)
574 LibLogger::log_debug(
"V4L2Cam",
"Using read() method");
578 LibLogger::log_debug(
"V4L2Cam",
"Using memory mapping method");
582 LibLogger::log_debug(
"V4L2Cam",
"Using user pointer method");
584 throw Exception(
"V4L2Cam: user pointer method not supported yet");
598 V4L2Camera::select_format()
600 bool preferred_found =
false;
601 v4l2_fmtdesc format_desc;
603 char fourcc[5] =
" ";
605 if (strcmp(_format,
""))
608 memset(&format_desc, 0,
sizeof(format_desc));
609 format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
610 for (format_desc.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUM_FMT, &format_desc) == 0; format_desc.index++)
612 fourcc[0] =
static_cast<char>(format_desc.pixelformat & 0xFF);
613 fourcc[1] =
static_cast<char>((format_desc.pixelformat >> 8) & 0xFF);
614 fourcc[2] =
static_cast<char>((format_desc.pixelformat >> 16) & 0xFF);
615 fourcc[3] =
static_cast<char>((format_desc.pixelformat >> 24) & 0xFF);
617 if (strcmp(_format, fourcc) == 0)
619 preferred_found =
true;
625 if (!preferred_found)
629 memset(&format_desc, 0,
sizeof(format_desc));
630 format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
631 format_desc.index = 0;
632 if (v4l2_ioctl(_dev, VIDIOC_ENUM_FMT, &format_desc))
635 throw Exception(
"V4L2Cam: No image format found");
638 fourcc[0] =
static_cast<char>(format_desc.pixelformat & 0xFF);
639 fourcc[1] =
static_cast<char>((format_desc.pixelformat >> 8) & 0xFF);
640 fourcc[2] =
static_cast<char>((format_desc.pixelformat >> 16) & 0xFF);
641 fourcc[3] =
static_cast<char>((format_desc.pixelformat >> 24) & 0xFF);
646 memset(&format, 0,
sizeof(format));
647 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
648 if (v4l2_ioctl(_dev, VIDIOC_G_FMT, &format))
651 throw Exception(
"V4L2Cam: Format query failed");
656 format.fmt.pix.pixelformat = v4l2_fourcc(fourcc[0], fourcc[1], fourcc[2], fourcc[3]);
657 format.fmt.pix.field = V4L2_FIELD_ANY;
659 format.fmt.pix.width = _width;
661 format.fmt.pix.height = _height;
663 if (v4l2_ioctl(_dev, VIDIOC_S_FMT, &format))
669 LibLogger::log_warn(
"V4L2Cam",
"Format setting failed (driver sucks) - %d: %s", errno, strerror(errno));
670 LibLogger::log_info(
"V4L2Cam",
"Trying workaround");
674 if (v4l2_ioctl(_dev, VIDIOC_G_STD, &std))
677 throw Exception(
"V4L2Cam: Standard query (workaround) failed");
680 if ((_width == 320) && (_height == 240))
690 if (v4l2_ioctl(_dev, VIDIOC_S_STD, &std))
693 throw Exception(
"V4L2Cam: Standard setting (workaround) failed");
696 format.fmt.pix.width = _width;
697 format.fmt.pix.height = _height;
698 format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
699 format.fmt.pix.field = V4L2_FIELD_ANY;
701 if (v4l2_ioctl(_dev, VIDIOC_S_FMT, &format))
704 throw Exception(
"V4L2Cam: Format setting (workaround) failed");
707 if (_switch_u_v) _colorspace = YVY2;
711 _format[0] =
static_cast<char>(format.fmt.pix.pixelformat & 0xFF);
712 _format[1] =
static_cast<char>((format.fmt.pix.pixelformat >> 8) & 0xFF);
713 _format[2] =
static_cast<char>((format.fmt.pix.pixelformat >> 16) & 0xFF);
714 _format[3] =
static_cast<char>((format.fmt.pix.pixelformat >> 24) & 0xFF);
716 if (!_nao_hacks || !_switch_u_v)
718 if (strcmp(_format,
"RGB3") == 0) _colorspace = RGB;
719 else if (strcmp(_format,
"Y41P") == 0) _colorspace = YUV411_PACKED;
720 else if (strcmp(_format,
"411P") == 0) _colorspace = YUV411_PLANAR;
721 else if (strcmp(_format,
"YUYV") == 0) _colorspace = YUY2;
722 else if (strcmp(_format,
"BGR3") == 0) _colorspace = BGR;
723 else if (strcmp(_format,
"UYVY") == 0) _colorspace = YUV422_PACKED;
724 else if (strcmp(_format,
"422P") == 0) _colorspace = YUV422_PLANAR;
725 else if (strcmp(_format,
"GREY") == 0) _colorspace = GRAY8;
726 else if (strcmp(_format,
"RGB4") == 0) _colorspace = RGB_WITH_ALPHA;
727 else if (strcmp(_format,
"BGR4") == 0) _colorspace = BGR_WITH_ALPHA;
728 else if (strcmp(_format,
"BA81") == 0) _colorspace = BAYER_MOSAIC_BGGR;
729 else if (strcmp(_format,
"Y16 ") == 0) _colorspace = MONO16;
730 else _colorspace = CS_UNKNOWN;
735 _width = format.fmt.pix.width;
736 _height = format.fmt.pix.height;
739 _bytes_per_line = format.fmt.pix.bytesperline;
742 if (_bytes_per_line == 0)
744 LibLogger::log_warn(
"V4L2Cam",
"bytesperline is 0 (driver sucks)");
745 _bytes_per_line = colorspace_buffer_size(_colorspace, _width, _height) / _height;
748 LibLogger::log_debug(
"V4L2Cam",
"w%d h%d bpl%d cs%d fmt%s", _width, _height, _bytes_per_line, _colorspace, _format);
755 V4L2Camera::set_fps()
757 v4l2_streamparm param;
758 param.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
759 if (v4l2_ioctl(_dev, VIDIOC_G_PARM, ¶m))
762 throw Exception(
"V4L2Cam: Streaming parameter query failed");
765 if (!(param.parm.capture.capability & V4L2_CAP_TIMEPERFRAME))
767 LibLogger::log_warn(
"V4L2Cam",
"FPS change not supported");
771 param.parm.capture.timeperframe.numerator = 1;
772 param.parm.capture.timeperframe.denominator = _fps;
773 if (v4l2_ioctl(_dev, VIDIOC_S_PARM, ¶m))
776 throw Exception(
"V4L2Cam: Streaming parameter setting failed");
780 LibLogger::log_debug(
"V4L2Cam",
"FPS set - %d/%d",
781 param.parm.capture.timeperframe.numerator,
782 param.parm.capture.timeperframe.denominator);
790 V4L2Camera::set_controls()
792 if (_aec != NOT_SET) set_auto_exposure(_aec == TRUE);
793 if (_awb != NOT_SET) set_auto_white_balance(_awb == TRUE);
794 if (_agc != NOT_SET) set_auto_gain(_agc == TRUE);
796 if (_h_flip != NOT_SET) set_horiz_mirror(_h_flip == TRUE);
797 if (_v_flip != NOT_SET) set_vert_mirror(_v_flip == TRUE);
799 if (_brightness.set) set_brightness(_brightness.value);
800 if (_contrast.set) set_contrast(_contrast.value);
801 if (_saturation.set) set_saturation(_saturation.value);
802 if (_hue.set) set_hue(_hue.value);
803 if (_red_balance.set) set_red_balance(_red_balance.value);
804 if (_blue_balance.set) set_blue_balance(_blue_balance.value);
805 if (_exposure.set) set_exposure(_exposure.value);
806 if (_gain.set) set_gain(_gain.value);
807 if (_lens_x.set) set_lens_x_corr(_lens_x.value);
808 if (_lens_y.set) set_lens_y_corr(_lens_y.value);
820 v4l2_queryctrl queryctrl;
821 v4l2_control control;
823 memset(&queryctrl, 0,
sizeof(queryctrl));
826 if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl))
830 LibLogger::log_error(
"V4L2Cam",
"Control %s not supported", ctrl);
835 throw Exception(
"V4L2Cam: %s Control query failed", ctrl);
837 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
839 LibLogger::log_error(
"V4L2Cam",
"Control %s disabled", ctrl);
843 memset(&control, 0,
sizeof(control));
845 control.value = value;
847 if (v4l2_ioctl(_dev, VIDIOC_S_CTRL, &control))
850 throw Exception(
"V4L2Cam: %s Control setting failed", ctrl);
863 v4l2_queryctrl queryctrl;
864 v4l2_control control;
866 memset(&queryctrl, 0,
sizeof(queryctrl));
869 if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl))
873 LibLogger::log_error(
"V4L2Cam",
"Control %s not supported", ctrl);
878 throw Exception(
"V4L2Cam: %s Control query failed", ctrl);
880 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
882 LibLogger::log_error(
"V4L2Cam",
"Control %s disabled", ctrl);
886 memset(&control, 0,
sizeof(control));
889 if (v4l2_ioctl(_dev, VIDIOC_G_CTRL, &control))
892 throw Exception(
"V4L2Cam: %s Control value reading failed", ctrl);
895 return control.value;
908 V4L2Camera::create_buffer()
910 _frame_buffers =
new FrameBuffer[_buffers_length];
912 switch (_read_method)
916 _frame_buffers[0].size = _bytes_per_line * _height;
917 _frame_buffers[0].buffer =
static_cast<unsigned char *
>(malloc(_frame_buffers[0].size));
918 if (_frame_buffers[0].buffer == NULL)
921 throw Exception(
"V4L2Cam: Out of memory");
928 for (
unsigned int i = 0; i < _buffers_length; ++i)
933 memset(&buffer, 0,
sizeof (buffer));
934 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
935 buffer.memory = V4L2_MEMORY_MMAP;
938 if (v4l2_ioctl(_dev, VIDIOC_QUERYBUF, &buffer))
941 throw Exception(
"V4L2Cam: Buffer query failed");
944 _frame_buffers[i].size = buffer.length;
945 _frame_buffers[i].buffer =
static_cast<unsigned char *
>(
946 v4l2_mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, _dev, buffer.m.offset)
948 if (_frame_buffers[i].buffer == MAP_FAILED)
951 throw Exception(
"V4L2Cam: Memory mapping failed");
968 V4L2Camera::reset_cropping()
970 v4l2_cropcap cropcap;
973 memset(&cropcap, 0,
sizeof(cropcap));
974 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
976 if (v4l2_ioctl(_dev, VIDIOC_CROPCAP, &cropcap))
978 LibLogger::log_warn(
"V4L2Cam",
"cropcap query failed (driver sucks) - %d: %s", errno, strerror(errno));
981 memset(&crop, 0,
sizeof(crop));
982 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
983 crop.c = cropcap.defrect;
986 if (v4l2_ioctl(_dev, VIDIOC_S_CROP, &crop) && errno != EINVAL)
988 LibLogger::log_warn(
"V4L2Cam",
"cropping query failed (driver sucks) - %d: %s", errno, strerror(errno));
997 if (_started) stop();
1001 switch (_read_method)
1005 free(_frame_buffers[0].buffer);
1011 for (
unsigned int i = 0; i < _buffers_length; ++i)
1013 v4l2_munmap(_frame_buffers[i].buffer, _frame_buffers[i].size);
1022 delete[] _frame_buffers;
1023 _frame_buffers = NULL;
1024 _current_buffer = -1;
1036 delete _capture_time;
1046 if (!_opened)
throw Exception(
"VL42Cam: Camera not opened");
1048 if (_started) stop();
1050 switch (_read_method)
1059 for (
unsigned int i = 0; i < _buffers_length; ++i)
1062 memset(&buffer, 0,
sizeof(buffer));
1063 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1064 buffer.memory = V4L2_MEMORY_MMAP;
1067 if (v4l2_ioctl(_dev, VIDIOC_QBUF, &buffer))
1070 throw Exception(
"V4L2Cam: Enqueuing buffer failed");
1075 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1076 if (v4l2_ioctl(_dev, VIDIOC_STREAMON, &type))
1079 throw Exception(
"V4L2Cam: Starting stream failed");
1098 if (!_started)
return;
1100 switch (_read_method)
1110 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1111 if (v4l2_ioctl(_dev, VIDIOC_STREAMOFF, &type))
1114 throw Exception(
"V4L2Cam: Stopping stream failed");
1120 _current_buffer = -1;
1144 if (!_started)
return;
1146 switch (_read_method)
1150 _current_buffer = 0;
1152 if (v4l2_read(_dev, _frame_buffers[_current_buffer].buffer, _frame_buffers[_current_buffer].size) == -1)
1155 LibLogger::log_warn(
"V4L2Cam",
"read() failed with code %d: %s", errno, strerror(errno));
1162 _capture_time->stamp();
1176 memset(&buffer, 0,
sizeof(buffer));
1177 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1178 buffer.memory = V4L2_MEMORY_MMAP;
1180 if (v4l2_ioctl(_dev, VIDIOC_DQBUF, &buffer))
1184 throw Exception(
"V4L2Cam: Dequeuing buffer failed");
1187 _current_buffer = buffer.index;
1191 _capture_time->set_time(&buffer.timestamp);
1211 return (_current_buffer == -1 ? NULL : _frame_buffers[_current_buffer].buffer);
1219 return (_opened && (_current_buffer != -1) ? _frame_buffers[_current_buffer].size : 0);
1227 if (!_opened)
return;
1229 switch (_read_method)
1239 memset(&buffer, 0,
sizeof(buffer));
1240 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1241 buffer.memory = V4L2_MEMORY_MMAP;
1242 buffer.index = _current_buffer;
1245 if (v4l2_ioctl(_dev, VIDIOC_QBUF, &buffer))
1247 int errno_save = errno;
1249 throw Exception(errno_save,
"V4L2Cam: Enqueuing buffer failed");
1259 _current_buffer = -1;
1292 return _capture_time;
1309 return get_one_control(
"AGC", V4L2_CID_AUTOGAIN);
1315 LibLogger::log_debug(
"V4L2Cam", (enabled ?
"enabling AGC" :
"disabling AGC"));
1316 set_one_control(
"AGC", V4L2_CID_AUTOGAIN, (enabled ? 1 : 0));
1322 return get_one_control(
"AWB", V4L2_CID_AUTO_WHITE_BALANCE);
1328 LibLogger::log_debug(
"V4L2Cam", (enabled ?
"enabling AWB" :
"disabling AWB"));
1329 set_one_control(
"AWB", V4L2_CID_AUTO_WHITE_BALANCE, (enabled ? 1 : 0));
1347 return get_one_control(
"red balance", V4L2_CID_RED_BALANCE);
1353 LibLogger::log_debug(
"V4L2Cam",
"Setting red balance to %d", red_balance);
1354 set_one_control(
"red balance", V4L2_CID_RED_BALANCE, red_balance);
1360 return get_one_control(
"blue balance", V4L2_CID_BLUE_BALANCE);
1366 LibLogger::log_debug(
"V4L2Cam",
"Setting blue balance to %d", blue_balance);
1367 set_one_control(
"blue balance", V4L2_CID_BLUE_BALANCE, blue_balance);
1397 return get_one_control(
"brightness", V4L2_CID_BRIGHTNESS);
1403 LibLogger::log_debug(
"V4L2Cam",
"Setting brighness to %d", brightness);
1404 set_one_control(
"brightness", V4L2_CID_BRIGHTNESS, brightness);
1410 return get_one_control(
"contrast", V4L2_CID_CONTRAST);
1416 LibLogger::log_debug(
"V4L2Cam",
"Setting contrast to %d", contrast);
1417 set_one_control(
"contrast", V4L2_CID_CONTRAST, contrast);
1423 return get_one_control(
"saturation", V4L2_CID_SATURATION);
1429 LibLogger::log_debug(
"V4L2Cam",
"Setting saturation to %d", saturation);
1430 set_one_control(
"saturation", V4L2_CID_SATURATION, saturation);
1436 return get_one_control(
"hue", V4L2_CID_HUE);
1442 LibLogger::log_debug(
"V4L2Cam",
"Setting hue to %d", hue);
1443 set_one_control(
"hue", V4L2_CID_HUE, hue);
1449 return get_one_control(
"exposure", V4L2_CID_EXPOSURE);
1455 LibLogger::log_debug(
"V4L2Cam",
"Setting exposure to %d", exposure);
1456 set_one_control(
"exposure", V4L2_CID_EXPOSURE, exposure);
1462 return get_one_control(
"gain", V4L2_CID_GAIN);
1468 LibLogger::log_debug(
"V4L2Cam",
"Setting gain to %u", gain);
1469 set_one_control(
"gain", V4L2_CID_GAIN, gain);
1482 strncpy(_format, format, 4);
1490 return pixel_width();
1496 return pixel_height();
1501 unsigned int height)
1511 return (get_one_control(
"hflip", V4L2_CID_HFLIP) != 0);
1517 return (get_one_control(
"vflip", V4L2_CID_VFLIP) != 0);
1523 LibLogger::log_debug(
"V4L2Cam", (enabled ?
"enabling horizontal flip" :
"disabling horizontal flip"));
1524 set_one_control(
"hflip", V4L2_CID_HFLIP, (enabled ? 1 : 0));
1530 LibLogger::log_debug(
"V4L2Cam", (enabled ?
"enabling vertical flip" :
"disabling vertical flip"));
1531 set_one_control(
"vflip", V4L2_CID_VFLIP, (enabled ? 1 : 0));
1545 V4L2Camera::set_fps(
unsigned int fps)
1554 return get_one_control(
"lens x", V4L2_CID_PAN_RESET);
1560 return get_one_control(
"lens y", V4L2_CID_TILT_RESET);
1566 LibLogger::log_debug(
"V4L2Cam",
"Setting horizontal lens correction to %d", x_corr);
1567 set_one_control(
"lens x", V4L2_CID_PAN_RESET, x_corr);
1573 LibLogger::log_debug(
"V4L2Cam",
"Setting vertical lens correction to %d", y_corr);
1574 set_one_control(
"lens x", V4L2_CID_TILT_RESET, y_corr);
1583 "==========================================================================" 1584 << endl << _device_name <<
" (" << _data->caps.card <<
") - " << _data->caps.bus_info
1585 << endl <<
"Driver: " << _data->caps.driver <<
" (ver " <<
1586 ((_data->caps.version >> 16) & 0xFF) <<
"." <<
1587 ((_data->caps.version >> 8) & 0xFF) <<
"." <<
1588 (_data->caps.version & 0xFF) <<
")" << endl <<
1589 "--------------------------------------------------------------------------" 1593 cout <<
"Capabilities:" << endl;
1594 if (_data->caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)
1595 cout <<
" + Video capture interface supported" << endl;
1596 if (_data->caps.capabilities & V4L2_CAP_VIDEO_OUTPUT)
1597 cout <<
" + Video output interface supported" << endl;
1598 if (_data->caps.capabilities & V4L2_CAP_VIDEO_OVERLAY)
1599 cout <<
" + Video overlay interface supported" << endl;
1600 if (_data->caps.capabilities & V4L2_CAP_VBI_CAPTURE)
1601 cout <<
" + Raw VBI capture interface supported" << endl;
1602 if (_data->caps.capabilities & V4L2_CAP_VBI_OUTPUT)
1603 cout <<
" + Raw VBI output interface supported" << endl;
1604 if (_data->caps.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE)
1605 cout <<
" + Sliced VBI capture interface supported" << endl;
1606 if (_data->caps.capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
1607 cout <<
" + Sliced VBI output interface supported" << endl;
1608 if (_data->caps.capabilities & V4L2_CAP_RDS_CAPTURE)
1609 cout <<
" + RDS_CAPTURE set" << endl;
1613 if (_data->caps.capabilities & V4L2_CAP_TUNER)
1614 cout <<
" + Has some sort of tuner" << endl;
1615 if (_data->caps.capabilities & V4L2_CAP_AUDIO)
1616 cout <<
" + Has audio inputs or outputs" << endl;
1617 if (_data->caps.capabilities & V4L2_CAP_RADIO)
1618 cout <<
" + Has a radio receiver" << endl;
1619 if (_data->caps.capabilities & V4L2_CAP_READWRITE)
1620 cout <<
" + read() and write() IO supported" << endl;
1621 if (_data->caps.capabilities & V4L2_CAP_ASYNCIO)
1622 cout <<
" + asynchronous IO supported" << endl;
1623 if (_data->caps.capabilities & V4L2_CAP_STREAMING)
1624 cout <<
" + streaming IO supported" << endl;
1625 if (_data->caps.capabilities & V4L2_CAP_TIMEPERFRAME)
1626 cout <<
" + timeperframe field is supported" << endl;
1630 cout <<
"Inputs:" << endl;
1632 memset(&input, 0,
sizeof(input));
1634 for (input.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMINPUT, &input) == 0; input.index++)
1636 cout <<
"Input " << input.index <<
": " << input.name << endl;
1638 cout <<
" |- Type: ";
1641 case V4L2_INPUT_TYPE_TUNER:
1645 case V4L2_INPUT_TYPE_CAMERA:
1654 cout <<
" |- Supported standards:";
1657 cout <<
" Unknown" << endl;
1663 v4l2_standard standard;
1664 memset (&standard, 0,
sizeof(standard));
1667 for (standard.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMSTD, &standard) == 0; standard.index++)
1669 if (standard.id & input.std) cout <<
" + " << standard.name << endl;
1673 if (input.index == 0) cout <<
"None" << endl;
1677 cout <<
"Outputs:" << endl;
1679 memset (&output, 0,
sizeof(output));
1681 for (output.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMOUTPUT, &output) == 0; output.index++)
1683 cout <<
" + Output " << output.index <<
": " << output.name << endl;
1685 cout <<
" |- Type: ";
1686 switch (output.type)
1688 case V4L2_OUTPUT_TYPE_MODULATOR:
1689 cout <<
"TV Modulator";
1692 case V4L2_OUTPUT_TYPE_ANALOG:
1693 cout <<
"Analog output";
1701 cout <<
" |- Supported standards:";
1702 if (output.std == 0)
1704 cout <<
" Unknown" << endl;
1710 v4l2_standard standard;
1711 memset (&standard, 0,
sizeof (standard));
1714 for (standard.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUMSTD, &standard) == 0; standard.index++)
1716 if (standard.id & output.std) cout <<
" + " << standard.name << endl;
1720 if (output.index == 0) cout <<
"None" << endl;
1724 cout <<
"Formats:" << endl;
1725 v4l2_fmtdesc format_desc;
1726 memset(&format_desc, 0,
sizeof(format_desc));
1727 format_desc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1729 char fourcc[5] =
" ";
1730 for (format_desc.index = 0; v4l2_ioctl(_dev, VIDIOC_ENUM_FMT, &format_desc) == 0; format_desc.index++)
1732 fourcc[0] =
static_cast<char>(format_desc.pixelformat & 0xFF);
1733 fourcc[1] =
static_cast<char>((format_desc.pixelformat >> 8) & 0xFF);
1734 fourcc[2] =
static_cast<char>((format_desc.pixelformat >> 16) & 0xFF);
1735 fourcc[3] =
static_cast<char>((format_desc.pixelformat >> 24) & 0xFF);
1737 colorspace_t cs = CS_UNKNOWN;
1738 if (strcmp(fourcc,
"RGB3") == 0) cs = RGB;
1739 else if (strcmp(fourcc,
"Y41P") == 0) cs = YUV411_PACKED;
1740 else if (strcmp(fourcc,
"411P") == 0) cs = YUV411_PLANAR;
1741 else if (strcmp(fourcc,
"YUYV") == 0) cs = YUY2;
1742 else if (strcmp(fourcc,
"BGR3") == 0) cs = BGR;
1743 else if (strcmp(fourcc,
"UYVY") == 0) cs = YUV422_PACKED;
1744 else if (strcmp(fourcc,
"422P") == 0) cs = YUV422_PLANAR;
1745 else if (strcmp(fourcc,
"GREY") == 0) cs = GRAY8;
1746 else if (strcmp(fourcc,
"RGB4") == 0) cs = RGB_WITH_ALPHA;
1747 else if (strcmp(fourcc,
"BGR4") == 0) cs = BGR_WITH_ALPHA;
1748 else if (strcmp(fourcc,
"BA81") == 0) cs = BAYER_MOSAIC_BGGR;
1749 else if (strcmp(fourcc,
"Y16 ") == 0) cs = MONO16;
1751 cout <<
" + Format " << format_desc.index <<
": " << fourcc <<
1752 " (" << format_desc.description <<
")";
1753 if (format_desc.flags & V4L2_FMT_FLAG_COMPRESSED) cout <<
" [Compressed]";
1754 cout << endl <<
" |- Colorspace: " << colorspace_to_string(cs) << endl;
1760 memset(&format, 0,
sizeof(format));
1761 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1762 if (v4l2_ioctl(_dev, VIDIOC_G_FMT, &format))
throw Exception(
"V4L2Cam: Format query failed");
1763 fourcc[0] =
static_cast<char>(format.fmt.pix.pixelformat & 0xFF);
1764 fourcc[1] =
static_cast<char>((format.fmt.pix.pixelformat >> 8) & 0xFF);
1765 fourcc[2] =
static_cast<char>((format.fmt.pix.pixelformat >> 16) & 0xFF);
1766 fourcc[3] =
static_cast<char>((format.fmt.pix.pixelformat >> 24) & 0xFF);
1768 cout <<
" Current Format:" << endl <<
1769 " " << format.fmt.pix.width <<
"x" << format.fmt.pix.height <<
1770 " (" << fourcc <<
")" << endl <<
1771 " " << format.fmt.pix.bytesperline <<
" bytes per line" << endl <<
1772 " Total size: " << format.fmt.pix.sizeimage << endl;
1775 cout <<
"Controls:" << endl;
1776 v4l2_queryctrl queryctrl;
1777 v4l2_querymenu querymenu;
1779 memset(&queryctrl, 0,
sizeof(queryctrl));
1781 for (queryctrl.id = V4L2_CID_BASE; queryctrl.id < V4L2_CID_LASTP1;
1784 if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl))
1786 if (errno == EINVAL)
continue;
1788 cout <<
"Control query failed" << endl;
1791 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
1793 cout <<
" + " << queryctrl.name <<
" [" <<
1794 (queryctrl.id - V4L2_CID_BASE) <<
"] (";
1795 switch (queryctrl.type)
1797 case V4L2_CTRL_TYPE_INTEGER:
1798 cout <<
"int [" << queryctrl.minimum <<
"-" << queryctrl.maximum <<
1799 " /" << queryctrl.step <<
" def " << queryctrl.default_value <<
1803 case V4L2_CTRL_TYPE_MENU:
1804 cout <<
"menu [def " << queryctrl.default_value <<
"]";
1807 case V4L2_CTRL_TYPE_BOOLEAN:
1808 cout <<
"bool [def " << queryctrl.default_value <<
"]";
1811 case V4L2_CTRL_TYPE_BUTTON:
1815 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) 1816 case V4L2_CTRL_TYPE_INTEGER64:
1820 case V4L2_CTRL_TYPE_CTRL_CLASS:
1821 cout <<
"ctrl_class";
1824 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) 1825 case V4L2_CTRL_TYPE_STRING:
1829 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,41) 1830 case V4L2_CTRL_TYPE_BITMASK:
1835 cout <<
")" << endl;
1837 if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
1839 cout <<
" |- Menu items:" << endl;
1841 memset(&querymenu, 0,
sizeof(querymenu));
1842 querymenu.id = queryctrl.id;
1844 for (querymenu.index = queryctrl.minimum;
1845 querymenu.index <= static_cast<unsigned long int>(queryctrl.maximum);
1848 if (v4l2_ioctl(_dev, VIDIOC_QUERYMENU, &querymenu))
1850 cout <<
"Getting menu items failed" << endl;
1853 cout <<
" | + " << querymenu.name << endl;
1857 if (queryctrl.id == V4L2_CID_BASE) cout <<
"None" << endl;
1861 cout <<
"Private Controls:" << endl;
1862 for (queryctrl.id = V4L2_CID_PRIVATE_BASE; ; queryctrl.id++)
1864 if (v4l2_ioctl(_dev, VIDIOC_QUERYCTRL, &queryctrl))
1866 if (errno == EINVAL)
break;
1868 cout <<
"Private Control query failed" << endl;
1872 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
1874 cout <<
" + " << queryctrl.name <<
" [" <<
1875 (queryctrl.id - V4L2_CID_PRIVATE_BASE) <<
"] (";
1876 switch (queryctrl.type)
1878 case V4L2_CTRL_TYPE_INTEGER:
1879 cout <<
"int [" << queryctrl.minimum <<
"-" << queryctrl.maximum <<
1880 " /" << queryctrl.step <<
" def " << queryctrl.default_value <<
1884 case V4L2_CTRL_TYPE_MENU:
1885 cout <<
"menu [def " << queryctrl.default_value <<
"]";
1888 case V4L2_CTRL_TYPE_BOOLEAN:
1889 cout <<
"bool [def " << queryctrl.default_value <<
"]";
1892 case V4L2_CTRL_TYPE_BUTTON:
1896 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) 1897 case V4L2_CTRL_TYPE_INTEGER64:
1901 case V4L2_CTRL_TYPE_CTRL_CLASS:
1902 cout <<
"ctrl_class";
1905 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) 1906 case V4L2_CTRL_TYPE_STRING:
1910 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,41) 1911 case V4L2_CTRL_TYPE_BITMASK:
1916 cout <<
")" << endl;
1918 if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
1920 cout <<
" |- Menu items:" << endl;
1922 memset(&querymenu, 0,
sizeof(querymenu));
1923 querymenu.id = queryctrl.id;
1925 for (querymenu.index = queryctrl.minimum;
1926 querymenu.index <= static_cast<unsigned long int>(queryctrl.maximum);
1929 if (v4l2_ioctl(_dev, VIDIOC_QUERYMENU, &querymenu))
1931 cout <<
"Getting menu items failed" << endl;
1934 cout <<
" | + " << querymenu.name << endl;
1938 if (queryctrl.id == V4L2_CID_PRIVATE_BASE) cout <<
"None" << endl;
1941 "==========================================================================" virtual fawkes::Time * capture_time()
Get the Time of the last successfully captured image.
std::string get(std::string s) const
Get the value of the given parameter.
virtual void set_lens_y_corr(unsigned int y_corr)
Set lens y correction.
virtual void set_brightness(unsigned int brightness)
Set new brightness.
virtual void close()
Close camera.
virtual void stop()
Stop image transfer from the camera.
virtual unsigned int lens_y_corr()
Get current lens y correction.
virtual void set_auto_exposure(bool enabled)
Enable/disable auto exposure.
virtual void print_info()
Print out camera information.
virtual bool auto_gain()
Return whether auto gain is enabled.
Called method has not been implemented.
virtual bool horiz_mirror()
Return whether the camera image is horizontally mirrored.
virtual const char * format()
Get the image format the camera currently uses.
virtual void set_horiz_mirror(bool enabled)
Set whether the camera should mirror images horizontally.
virtual void set_auto_white_balance(bool enabled)
Enable/disable auto white balance.
A class for handling time.
virtual void set_hue(int hue)
Set new hue.
virtual colorspace_t colorspace()
Colorspace of returned image.
virtual void set_format(const char *format)
Set the image format the camera should use.
virtual int v_balance()
Get current v balance.
virtual void set_auto_gain(bool enabled)
Enable/disable auto gain.
virtual int u_balance()
Get current u balance.
virtual unsigned int brightness()
Get current brightness.
virtual void set_size(unsigned int width, unsigned int height)
Set the image size the camera should use.
virtual unsigned int buffer_size()
Size of buffer.
virtual void set_lens_x_corr(unsigned int x_corr)
Set lens x correction.
virtual int red_balance()
Get current red balance.
V4L2Camera(const char *device_name="/dev/video0")
Constructor.
virtual unsigned int contrast()
Get current contrast.
Base class for exceptions in Fawkes.
virtual unsigned int pixel_width()
Width of image in pixels.
virtual unsigned char * buffer()
Get access to current image buffer.
virtual void set_contrast(unsigned int contrast)
Set new contrast.
virtual bool ready()
Camera is ready for taking pictures.
virtual unsigned int fps()
Get the number of frames per second that have been requested from the camera.
virtual ~V4L2Camera()
Destructor.
virtual unsigned int height()
Get the current height of the image.
virtual unsigned int exposure()
Get current exposure.
virtual bool vert_mirror()
Return whether the camera image is vertically mirrored.
virtual void set_one_control(const char *ctrl, unsigned int id, int value)
Set one Camera control value.
virtual bool auto_exposure()
Return whether auto exposure is enabled.
virtual int get_one_control(const char *ctrl, unsigned int id)
Get one Camera control value.
virtual void set_exposure(unsigned int exposure)
Set new exposure.
virtual void set_saturation(unsigned int saturation)
Set new saturation.
virtual void set_vert_mirror(bool enabled)
Set whether the camera should mirror images vertically.
virtual void set_blue_balance(int blue_balance)
Set blue balance.
virtual void open()
Open the camera.
virtual void set_red_balance(int red_balance)
Set red balance.
virtual void capture()
Capture an image.
virtual unsigned int width()
Get the current width of the image.
virtual void dispose_buffer()
Dispose current buffer.
virtual int hue()
Get current hue.
virtual unsigned int gain()
Get current gain.
virtual void set_gain(unsigned int gain)
Set new gain.
virtual int blue_balance()
Get current blue balance.
virtual void set_u_balance(int u_balance)
Set u balance.
virtual bool auto_white_balance()
Return whether auto white balance is enabled.
virtual unsigned int saturation()
Get current saturation.
virtual void start()
Start image transfer from the camera.
virtual void flush()
Flush image queue.
virtual void set_image_number(unsigned int n)
Set image number to retrieve.
Expected parameter is missing.
virtual void set_v_balance(int v_balance)
Set v balance.
bool has(std::string s) const
Check if an parameter was given.
virtual unsigned int pixel_height()
Height of image in pixels.
virtual unsigned int lens_x_corr()
Get current lens x correction.