summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2022-07-15 13:47:01 +0200
committerJacopo Mondi <jacopo@jmondi.org>2022-07-23 11:41:20 +0200
commit15a5ab99aea0f87c86a5e45401fc2641e813ff3e (patch)
treeba0884ba49aea3241f79a18e46e5a286790590c4 /src
parent0f1d5cc15b88bb9cbc759a77186c891c6481d7b2 (diff)
libcamera: v4l2_videodevice: Match formats supported by the device
Now that V4L2PixelFormat::fromPixelFormat() returns a list of formats to chose from by checking which ones are actually supported by the video device. The first format found to match one of the device supported ones is returned. As V4L2VideoDevice::toV4L2PixelFormat() is a const function which uses other functions of the class, those functions has to be made const as well. In particular: - enumPixelformats() and enumSizes() do not modify the class state and can safely be made const. - formats() uses the above functions and does not itself modify the class state and can be made const - add a const version of V4L2Device::ioctl() to be used by the now const functions Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/v4l2_device.cpp15
-rw-r--r--src/libcamera/v4l2_videodevice.cpp31
2 files changed, 39 insertions, 7 deletions
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 3fc8438f..59f92403 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -460,6 +460,21 @@ int V4L2Device::ioctl(unsigned long request, void *argp)
}
/**
+ * \copydoc ioctl()
+ */
+int V4L2Device::ioctl(unsigned long request, void *argp) const
+{
+ /*
+ * Printing out an error message is usually better performed
+ * in the caller, which can provide more context.
+ */
+ if (::ioctl(fd_.get(), request, argp) < 0)
+ return -errno;
+
+ return 0;
+}
+
+/**
* \fn V4L2Device::deviceNode()
* \brief Retrieve the device node path
* \return The device node path
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 43c3d0f6..a3242ba7 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -1045,7 +1045,7 @@ int V4L2VideoDevice::trySetFormatSingleplane(V4L2DeviceFormat *format, bool set)
*
* \return A list of the supported video device formats
*/
-V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code)
+V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code) const
{
Formats formats;
@@ -1067,7 +1067,7 @@ V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code)
return formats;
}
-std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats(uint32_t code)
+std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats(uint32_t code) const
{
std::vector<V4L2PixelFormat> formats;
int ret;
@@ -1101,7 +1101,7 @@ std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats(uint32_t code)
return formats;
}
-std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat)
+std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat) const
{
std::vector<SizeRange> sizes;
int ret;
@@ -1990,20 +1990,37 @@ V4L2VideoDevice::fromEntityName(const MediaDevice *media,
}
/**
- * \brief Convert \a PixelFormat to its corresponding V4L2 FourCC
+ * \brief Convert \a PixelFormat to one of the device supported V4L2 FourCC
* \param[in] pixelFormat The PixelFormat to convert
*
+ * Convert a\ pixelformat to a V4L2 FourCC that is known to be supported by
+ * the video device.
+ *
* For multiplanar formats, the V4L2 format variant (contiguous or
* non-contiguous planes) is selected automatically based on the capabilities
* of the video device. If the video device supports the V4L2 multiplanar API,
* non-contiguous formats are preferred.
*
- * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
+ * \return The V4L2PixelFormat corresponding to \a pixelFormat or an invalid
+ * PixelFormat if \a pixelFormat is not supported by the video device
*/
V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat) const
{
- return V4L2PixelFormat::fromPixelFormat(pixelFormat,
- caps_.isMultiplanar())[0];
+ std::vector<V4L2PixelFormat> deviceFormats = enumPixelformats(0);
+ std::vector<V4L2PixelFormat> v4l2PixelFormats =
+ V4L2PixelFormat::fromPixelFormat(pixelFormat, caps_.isMultiplanar());
+
+ for (const V4L2PixelFormat &v4l2Format : v4l2PixelFormats) {
+ auto it = std::find_if(deviceFormats.begin(), deviceFormats.end(),
+ [&v4l2Format](const V4L2PixelFormat &deviceFormat) {
+ return v4l2Format == deviceFormat;
+ });
+
+ if (it != deviceFormats.end())
+ return v4l2Format;
+ }
+
+ return {};
}
/**