[libcamera-devel,v5,2/6] libcamera: v4l2_videodevice: Support filtering formats by media bus code

Message ID 20200510115810.21938-3-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • Simple pipeline handler
Related show

Commit Message

Laurent Pinchart May 10, 2020, 11:58 a.m. UTC
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>
---
 src/libcamera/include/v4l2_videodevice.h |  4 ++--
 src/libcamera/v4l2_videodevice.cpp       | 16 +++++++++++++---
 2 files changed, 15 insertions(+), 5 deletions(-)

Patch

diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
index 982fee6bf740..94565b97b6b1 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 e95b0c01cc85..4b9f8b5c0413 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)