summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-03-13 03:38:00 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-05-10 23:58:34 +0300
commitcd6addc31b72059dbbb1319afeebbc4d0908c064 (patch)
treecc7340ed0aaed14440b09d0b8246be8256873685 /src
parent972bb30c4b2fdd50f8fc02683130fd45b0d793f6 (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/include/v4l2_videodevice.h4
-rw-r--r--src/libcamera/v4l2_videodevice.cpp16
2 files changed, 15 insertions, 5 deletions
diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
index 982fee6b..94565b97 100644
--- a/src/libcamera/include/v4l2_videodevice.h
+++ b/src/libcamera/include/v4l2_videodevice.h
@@ -187,7 +187,7 @@ public:
int getFormat(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);
@@ -225,7 +225,7 @@ private:
int getFormatSingleplane(V4L2DeviceFormat *format);
int setFormatSingleplane(V4L2DeviceFormat *format);
- std::vector<V4L2PixelFormat> enumPixelformats();
+ std::vector<V4L2PixelFormat> enumPixelformats(uint32_t code);
std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
int requestBuffers(unsigned int count, enum v4l2_memory memoryType);
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index e95b0c01..4b9f8b5c 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -917,16 +917,19 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
/**
* \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.
+ * 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
*/
-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;
- for (V4L2PixelFormat pixelFormat : enumPixelformats()) {
+ for (V4L2PixelFormat pixelFormat : enumPixelformats(code)) {
std::vector<SizeRange> sizes = enumSizes(pixelFormat);
if (sizes.empty())
return {};
@@ -944,15 +947,22 @@ std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats()
return formats;
}
-std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats()
+std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats(uint32_t code)
{
std::vector<V4L2PixelFormat> formats;
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++) {
struct v4l2_fmtdesc pixelformatEnum = {};
pixelformatEnum.index = index;
pixelformatEnum.type = bufferType_;
+ pixelformatEnum.mbus_code = code;
ret = ioctl(VIDIOC_ENUM_FMT, &pixelformatEnum);
if (ret)