p26001-store-acs-soc-fw-app/video/v4l2/InputFormat.cpp
2026-09-28 21:33:04 +08:00

83 lines
2.7 KiB
C++

/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "InputFormat.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <Poco/Exception.h>
#include <Poco/Format.h>
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);
}
}
}