/* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "InputFormat.h" #include #include #include #include #include #include #include #include #include namespace Video { namespace V4L2 { /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ void InputFormat::enumerate(const std::string& deviceName, InputFormat::Collection& c) { int fd = open(deviceName.c_str(), O_RDWR); if (fd < 0) throw Poco::InvalidAccessException(Poco::format("Video::V4l2::InputFormat: Open %s FAIL: %d", deviceName, fd)); struct v4l2_fmtdesc fmt; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.index = 0; while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == 0) { InputFormat format; format.pixelFormat = fmt.pixelformat; format.description = (char*)fmt.description; struct v4l2_frmsizeenum frmsize; frmsize.index = 0; frmsize.pixel_format = fmt.pixelformat; while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0) { switch (frmsize.type) { case V4L2_FRMSIZE_TYPE_DISCRETE: { struct v4l2_frmivalenum frameinterval; frameinterval.width = frmsize.discrete.width; frameinterval.height = frmsize.discrete.height; frameinterval.pixel_format = fmt.pixelformat; frameinterval.type = V4L2_FRMIVAL_TYPE_DISCRETE; frameinterval.index = 0; while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frameinterval) == 0) { InputFormat::Resolution resolution; resolution.width = frameinterval.width; resolution.height = frameinterval.height; resolution.fps = frameinterval.discrete.denominator / frameinterval.discrete.numerator; format.resolutions.push_back(resolution); frameinterval.index++; } } break; } frmsize.index++; } format.resolutions.sort([](auto& a, auto& b) { return a.width * a.height > b.width * b.height; }); c.push_back(format); fmt.index++; } close(fd); } } }