libcamera: v4l2_device: Add enumeration of pixelformats and frame sizes
Add methods to enumerate pixelformats and frame sizes from a V4L2 device. The interface is similar to how V4L2Subdevice enumerates mbus codes and frame sizes. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
ce02ea29cd
commit
87e46f7f59
2 changed files with 119 additions and 0 deletions
|
@ -634,6 +634,33 @@ int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enumerate all pixel formats and frame sizes
|
||||
*
|
||||
* Enumerate all pixel formats and frame sizes supported by the video device.
|
||||
*
|
||||
* \return A list of the supported device formats
|
||||
*/
|
||||
ImageFormats V4L2Device::formats()
|
||||
{
|
||||
ImageFormats formats;
|
||||
|
||||
for (unsigned int pixelformat : enumPixelformats()) {
|
||||
std::vector<SizeRange> sizes = enumSizes(pixelformat);
|
||||
if (sizes.empty())
|
||||
return {};
|
||||
|
||||
if (formats.addFormat(pixelformat, sizes)) {
|
||||
LOG(V4L2, Error)
|
||||
<< "Could not add sizes for pixel format "
|
||||
<< pixelformat;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
int V4L2Device::requestBuffers(unsigned int count)
|
||||
{
|
||||
struct v4l2_requestbuffers rb = {};
|
||||
|
@ -763,6 +790,93 @@ int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex,
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> V4L2Device::enumPixelformats()
|
||||
{
|
||||
std::vector<unsigned int> formats;
|
||||
int ret;
|
||||
|
||||
for (unsigned int index = 0; ; index++) {
|
||||
struct v4l2_fmtdesc pixelformatEnum = {};
|
||||
pixelformatEnum.index = index;
|
||||
pixelformatEnum.type = bufferType_;
|
||||
|
||||
ret = ioctl(fd_, VIDIOC_ENUM_FMT, &pixelformatEnum);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
formats.push_back(pixelformatEnum.pixelformat);
|
||||
}
|
||||
|
||||
if (ret && errno != EINVAL) {
|
||||
ret = -errno;
|
||||
LOG(V4L2, Error)
|
||||
<< "Unable to enumerate pixel formats: "
|
||||
<< strerror(-ret);
|
||||
return {};
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
std::vector<SizeRange> V4L2Device::enumSizes(unsigned int pixelFormat)
|
||||
{
|
||||
std::vector<SizeRange> sizes;
|
||||
int ret;
|
||||
|
||||
for (unsigned int index = 0;; index++) {
|
||||
struct v4l2_frmsizeenum frameSize = {};
|
||||
frameSize.index = index;
|
||||
frameSize.pixel_format = pixelFormat;
|
||||
|
||||
ret = ioctl(fd_, VIDIOC_ENUM_FRAMESIZES, &frameSize);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (index != 0 &&
|
||||
frameSize.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||
LOG(V4L2, Error)
|
||||
<< "Non-zero index for non discrete type";
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (frameSize.type) {
|
||||
case V4L2_FRMSIZE_TYPE_DISCRETE:
|
||||
sizes.emplace_back(frameSize.discrete.width,
|
||||
frameSize.discrete.height);
|
||||
break;
|
||||
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
|
||||
sizes.emplace_back(frameSize.stepwise.min_width,
|
||||
frameSize.stepwise.min_height,
|
||||
frameSize.stepwise.max_width,
|
||||
frameSize.stepwise.max_height);
|
||||
break;
|
||||
case V4L2_FRMSIZE_TYPE_STEPWISE:
|
||||
sizes.emplace_back(frameSize.stepwise.min_width,
|
||||
frameSize.stepwise.min_height,
|
||||
frameSize.stepwise.max_width,
|
||||
frameSize.stepwise.max_height,
|
||||
frameSize.stepwise.step_width,
|
||||
frameSize.stepwise.step_height);
|
||||
break;
|
||||
default:
|
||||
LOG(V4L2, Error)
|
||||
<< "Unknown VIDIOC_ENUM_FRAMESIZES type "
|
||||
<< frameSize.type;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (ret && errno != EINVAL) {
|
||||
ret = -errno;
|
||||
LOG(V4L2, Error)
|
||||
<< "Unable to enumerate frame sizes: "
|
||||
<< strerror(-ret);
|
||||
return {};
|
||||
}
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Import the externally allocated \a pool of buffers
|
||||
* \param[in] pool BufferPool of buffers to import
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue