libcamera: v4l2_videodevice: Support filtering formats by media bus code

Add support for the recent V4L2 extension to VIDIOC_ENUM_FMT that allows
filtering pixel formats by media bus codes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Laurent Pinchart 2020-03-13 03:38:00 +02:00
parent 972bb30c4b
commit cd6addc31b
2 changed files with 15 additions and 5 deletions

View file

@ -187,7 +187,7 @@ public:
int getFormat(V4L2DeviceFormat *format); int getFormat(V4L2DeviceFormat *format);
int setFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format);
std::map<V4L2PixelFormat, std::vector<SizeRange>> formats(); std::map<V4L2PixelFormat, std::vector<SizeRange>> formats(uint32_t code = 0);
int setSelection(unsigned int target, Rectangle *rect); int setSelection(unsigned int target, Rectangle *rect);
@ -225,7 +225,7 @@ private:
int getFormatSingleplane(V4L2DeviceFormat *format); int getFormatSingleplane(V4L2DeviceFormat *format);
int setFormatSingleplane(V4L2DeviceFormat *format); int setFormatSingleplane(V4L2DeviceFormat *format);
std::vector<V4L2PixelFormat> enumPixelformats(); std::vector<V4L2PixelFormat> enumPixelformats(uint32_t code);
std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat); std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
int requestBuffers(unsigned int count, enum v4l2_memory memoryType); int requestBuffers(unsigned int count, enum v4l2_memory memoryType);

View file

@ -917,16 +917,19 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
/** /**
* \brief Enumerate all pixel formats and frame sizes * \brief Enumerate all pixel formats and frame sizes
* \param[in] code Restrict formats to this media bus code.
* *
* Enumerate all pixel formats and frame sizes supported by the video device. * Enumerate all pixel formats and frame sizes supported by the video device.
* If the \a code argument is not zero, only formats compatible with that media
* bus code will be enumerated.
* *
* \return A list of the supported video device formats * \return A list of the supported video device formats
*/ */
std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats() std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats(uint32_t code)
{ {
std::map<V4L2PixelFormat, std::vector<SizeRange>> formats; std::map<V4L2PixelFormat, std::vector<SizeRange>> formats;
for (V4L2PixelFormat pixelFormat : enumPixelformats()) { for (V4L2PixelFormat pixelFormat : enumPixelformats(code)) {
std::vector<SizeRange> sizes = enumSizes(pixelFormat); std::vector<SizeRange> sizes = enumSizes(pixelFormat);
if (sizes.empty()) if (sizes.empty())
return {}; return {};
@ -944,15 +947,22 @@ std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats()
return formats; return formats;
} }
std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats() std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats(uint32_t code)
{ {
std::vector<V4L2PixelFormat> formats; std::vector<V4L2PixelFormat> formats;
int ret; int ret;
if (code && !(caps_.device_caps() & V4L2_CAP_IO_MC)) {
LOG(V4L2, Error)
<< "Media bus code filtering not supported by the device";
return {};
}
for (unsigned int index = 0; ; index++) { for (unsigned int index = 0; ; index++) {
struct v4l2_fmtdesc pixelformatEnum = {}; struct v4l2_fmtdesc pixelformatEnum = {};
pixelformatEnum.index = index; pixelformatEnum.index = index;
pixelformatEnum.type = bufferType_; pixelformatEnum.type = bufferType_;
pixelformatEnum.mbus_code = code;
ret = ioctl(VIDIOC_ENUM_FMT, &pixelformatEnum); ret = ioctl(VIDIOC_ENUM_FMT, &pixelformatEnum);
if (ret) if (ret)