[libcamera-devel] [PATCH 2/4] libcamera: v4l2_pixelformat: Move DRM/V4L2 format conversion

Laurent Pinchart laurent.pinchart at ideasonboard.com
Thu Apr 30 02:52:24 CEST 2020


Move the DRM/V4L2 format conversion code from V4L2VideoDevice to
V4L2PixelFormat. This is a more natural home for the code.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/libcamera/include/v4l2_pixelformat.h     |   4 +
 src/libcamera/include/v4l2_videodevice.h     |   3 -
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp |   2 +-
 src/libcamera/v4l2_pixelformat.cpp           | 134 +++++++++++++++++
 src/libcamera/v4l2_videodevice.cpp           | 147 +------------------
 test/libtest/buffer_source.cpp               |   4 +-
 6 files changed, 143 insertions(+), 151 deletions(-)

diff --git a/src/libcamera/include/v4l2_pixelformat.h b/src/libcamera/include/v4l2_pixelformat.h
index 4d277569cb8c..0fe8a017de34 100644
--- a/src/libcamera/include/v4l2_pixelformat.h
+++ b/src/libcamera/include/v4l2_pixelformat.h
@@ -36,6 +36,10 @@ public:
 
 	std::string toString() const;
 
+	PixelFormat toPixelFormat() const;
+	static V4L2PixelFormat fromPixelFormat(const PixelFormat &pixelFormat,
+					       bool multiplanar);
+
 private:
 	uint32_t fourcc_;
 };
diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
index ff64bb357c7e..982fee6bf740 100644
--- a/src/libcamera/include/v4l2_videodevice.h
+++ b/src/libcamera/include/v4l2_videodevice.h
@@ -210,10 +210,7 @@ public:
 	static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
 					       const std::string &entity);
 
-	static PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc);
 	V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat);
-	static V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat,
-						 bool multiplanar);
 
 protected:
 	std::string logPrefix() const;
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 030ac6864752..455693264c2e 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -166,7 +166,7 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
 		       std::inserter(deviceFormats, deviceFormats.begin()),
 		       [&](const decltype(v4l2Formats)::value_type &format) {
 			       return decltype(deviceFormats)::value_type{
-				       data->video_->toPixelFormat(format.first),
+				       format.first.toPixelFormat(),
 				       format.second
 			       };
 		       });
diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp
index 57d65c380b0d..876f5de321f6 100644
--- a/src/libcamera/v4l2_pixelformat.cpp
+++ b/src/libcamera/v4l2_pixelformat.cpp
@@ -103,4 +103,138 @@ std::string V4L2PixelFormat::toString() const
 	return ss;
 }
 
+/**
+ * \brief Convert the V4L2 pixel format to the corresponding PixelFormat
+ * \return The PixelFormat corresponding to the V4L2 pixel format
+ */
+PixelFormat V4L2PixelFormat::toPixelFormat() const
+{
+	switch (fourcc_) {
+	/* RGB formats. */
+	case V4L2_PIX_FMT_RGB24:
+		return PixelFormat(DRM_FORMAT_BGR888);
+	case V4L2_PIX_FMT_BGR24:
+		return PixelFormat(DRM_FORMAT_RGB888);
+	case V4L2_PIX_FMT_RGBA32:
+		return PixelFormat(DRM_FORMAT_ABGR8888);
+	case V4L2_PIX_FMT_ABGR32:
+		return PixelFormat(DRM_FORMAT_ARGB8888);
+	case V4L2_PIX_FMT_ARGB32:
+		return PixelFormat(DRM_FORMAT_BGRA8888);
+	case V4L2_PIX_FMT_BGRA32:
+		return PixelFormat(DRM_FORMAT_RGBA8888);
+
+	/* YUV packed formats. */
+	case V4L2_PIX_FMT_YUYV:
+		return PixelFormat(DRM_FORMAT_YUYV);
+	case V4L2_PIX_FMT_YVYU:
+		return PixelFormat(DRM_FORMAT_YVYU);
+	case V4L2_PIX_FMT_UYVY:
+		return PixelFormat(DRM_FORMAT_UYVY);
+	case V4L2_PIX_FMT_VYUY:
+		return PixelFormat(DRM_FORMAT_VYUY);
+
+	/* YUY planar formats. */
+	case V4L2_PIX_FMT_NV16:
+	case V4L2_PIX_FMT_NV16M:
+		return PixelFormat(DRM_FORMAT_NV16);
+	case V4L2_PIX_FMT_NV61:
+	case V4L2_PIX_FMT_NV61M:
+		return PixelFormat(DRM_FORMAT_NV61);
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV12M:
+		return PixelFormat(DRM_FORMAT_NV12);
+	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV21M:
+		return PixelFormat(DRM_FORMAT_NV21);
+
+	/* Greyscale formats. */
+	case V4L2_PIX_FMT_GREY:
+		return PixelFormat(DRM_FORMAT_R8);
+
+	/* Compressed formats. */
+	case V4L2_PIX_FMT_MJPEG:
+		return PixelFormat(DRM_FORMAT_MJPEG);
+
+	/* V4L2 formats not yet supported by DRM. */
+	default:
+		LOG(V4L2, Warning)
+			<< "Unsupported V4L2 pixel format "
+			<< toString();
+		return PixelFormat();
+	}
+}
+
+/**
+ * \brief Convert \a pixelFormat to its corresponding V4L2PixelFormat
+ * \param[in] pixelFormat The PixelFormat to convert
+ * \param[in] multiplanar V4L2 Multiplanar API support flag
+ *
+ * Multiple V4L2 formats may exist for one PixelFormat when the format uses
+ * multiple planes, as V4L2 defines separate 4CCs for contiguous and separate
+ * planes formats. Set the \a multiplanar parameter to false to select a format
+ * with contiguous planes, or to true to select a format with non-contiguous
+ * planes.
+ *
+ * \return The V4L2PixelFormat corresponding to \a pixelFormat
+ */
+V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat,
+						 bool multiplanar)
+{
+	switch (pixelFormat) {
+	/* RGB formats. */
+	case DRM_FORMAT_BGR888:
+		return V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
+	case DRM_FORMAT_RGB888:
+		return V4L2PixelFormat(V4L2_PIX_FMT_BGR24);
+	case DRM_FORMAT_ABGR8888:
+		return V4L2PixelFormat(V4L2_PIX_FMT_RGBA32);
+	case DRM_FORMAT_ARGB8888:
+		return V4L2PixelFormat(V4L2_PIX_FMT_ABGR32);
+	case DRM_FORMAT_BGRA8888:
+		return V4L2PixelFormat(V4L2_PIX_FMT_ARGB32);
+	case DRM_FORMAT_RGBA8888:
+		return V4L2PixelFormat(V4L2_PIX_FMT_BGRA32);
+
+	/* YUV packed formats. */
+	case DRM_FORMAT_YUYV:
+		return V4L2PixelFormat(V4L2_PIX_FMT_YUYV);
+	case DRM_FORMAT_YVYU:
+		return V4L2PixelFormat(V4L2_PIX_FMT_YVYU);
+	case DRM_FORMAT_UYVY:
+		return V4L2PixelFormat(V4L2_PIX_FMT_UYVY);
+	case DRM_FORMAT_VYUY:
+		return V4L2PixelFormat(V4L2_PIX_FMT_VYUY);
+
+	/*
+	 * YUY planar formats.
+	 * \todo Add support for non-contiguous memory planes
+	 * \todo Select the format variant not only based on \a multiplanar but
+	 * also take into account the formats supported by the device.
+	 */
+	case DRM_FORMAT_NV16:
+		return V4L2PixelFormat(V4L2_PIX_FMT_NV16);
+	case DRM_FORMAT_NV61:
+		return V4L2PixelFormat(V4L2_PIX_FMT_NV61);
+	case DRM_FORMAT_NV12:
+		return V4L2PixelFormat(V4L2_PIX_FMT_NV12);
+	case DRM_FORMAT_NV21:
+		return V4L2PixelFormat(V4L2_PIX_FMT_NV21);
+
+	/* Greyscale formats. */
+	case DRM_FORMAT_R8:
+		return V4L2PixelFormat(V4L2_PIX_FMT_GREY);
+
+	/* Compressed formats. */
+	case DRM_FORMAT_MJPEG:
+		return V4L2PixelFormat(V4L2_PIX_FMT_MJPEG);
+
+	default:
+		LOG(V4L2, Warning)
+			<< "Unsupported pixel format "
+			<< pixelFormat.toString();
+		return V4L2PixelFormat();
+	}
+}
+
 } /* namespace libcamera */
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 21df4f524212..e95b0c01cc85 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -18,7 +18,6 @@
 #include <unistd.h>
 #include <vector>
 
-#include <linux/drm_fourcc.h>
 #include <linux/version.h>
 
 #include <libcamera/event_notifier.h>
@@ -1634,74 +1633,6 @@ V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media,
 	return new V4L2VideoDevice(mediaEntity);
 }
 
-/**
- * \brief Convert a \a v4l2Fourcc to the corresponding PixelFormat
- * \param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*)
- * \return The PixelFormat corresponding to \a v4l2Fourcc
- */
-PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)
-{
-	switch (v4l2Fourcc) {
-	/* RGB formats. */
-	case V4L2_PIX_FMT_RGB24:
-		return PixelFormat(DRM_FORMAT_BGR888);
-	case V4L2_PIX_FMT_BGR24:
-		return PixelFormat(DRM_FORMAT_RGB888);
-	case V4L2_PIX_FMT_RGBA32:
-		return PixelFormat(DRM_FORMAT_ABGR8888);
-	case V4L2_PIX_FMT_ABGR32:
-		return PixelFormat(DRM_FORMAT_ARGB8888);
-	case V4L2_PIX_FMT_ARGB32:
-		return PixelFormat(DRM_FORMAT_BGRA8888);
-	case V4L2_PIX_FMT_BGRA32:
-		return PixelFormat(DRM_FORMAT_RGBA8888);
-
-	/* YUV packed formats. */
-	case V4L2_PIX_FMT_YUYV:
-		return PixelFormat(DRM_FORMAT_YUYV);
-	case V4L2_PIX_FMT_YVYU:
-		return PixelFormat(DRM_FORMAT_YVYU);
-	case V4L2_PIX_FMT_UYVY:
-		return PixelFormat(DRM_FORMAT_UYVY);
-	case V4L2_PIX_FMT_VYUY:
-		return PixelFormat(DRM_FORMAT_VYUY);
-
-	/* YUY planar formats. */
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV16M:
-		return PixelFormat(DRM_FORMAT_NV16);
-	case V4L2_PIX_FMT_NV61:
-	case V4L2_PIX_FMT_NV61M:
-		return PixelFormat(DRM_FORMAT_NV61);
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV12M:
-		return PixelFormat(DRM_FORMAT_NV12);
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_NV21M:
-		return PixelFormat(DRM_FORMAT_NV21);
-
-	/* Greyscale formats. */
-	case V4L2_PIX_FMT_GREY:
-		return PixelFormat(DRM_FORMAT_R8);
-
-	/* Compressed formats. */
-	case V4L2_PIX_FMT_MJPEG:
-		return PixelFormat(DRM_FORMAT_MJPEG);
-
-	/* V4L2 formats not yet supported by DRM. */
-	default:
-		/*
-		 * \todo We can't use LOG() in a static method of a Loggable
-		 * class. Until we fix the logger, work around it.
-		 */
-		libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
-				LogWarning).stream()
-			<< "Unsupported V4L2 pixel format "
-			<< v4l2Fourcc.toString();
-		return PixelFormat();
-	}
-}
-
 /**
  * \brief Convert \a PixelFormat to its corresponding V4L2 FourCC
  * \param[in] pixelFormat The PixelFormat to convert
@@ -1715,82 +1646,8 @@ PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)
  */
 V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat)
 {
-	return toV4L2PixelFormat(pixelFormat, caps_.isMultiplanar());
-}
-
-/**
- * \brief Convert \a pixelFormat to its corresponding V4L2 FourCC
- * \param[in] pixelFormat The PixelFormat to convert
- * \param[in] multiplanar V4L2 Multiplanar API support flag
- *
- * Multiple V4L2 formats may exist for one PixelFormat when the format uses
- * multiple planes, as V4L2 defines separate 4CCs for contiguous and separate
- * planes formats. Set the \a multiplanar parameter to false to select a format
- * with contiguous planes, or to true to select a format with non-contiguous
- * planes.
- *
- * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
- */
-V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat,
-						   bool multiplanar)
-{
-	switch (pixelFormat) {
-	/* RGB formats. */
-	case DRM_FORMAT_BGR888:
-		return V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
-	case DRM_FORMAT_RGB888:
-		return V4L2PixelFormat(V4L2_PIX_FMT_BGR24);
-	case DRM_FORMAT_ABGR8888:
-		return V4L2PixelFormat(V4L2_PIX_FMT_RGBA32);
-	case DRM_FORMAT_ARGB8888:
-		return V4L2PixelFormat(V4L2_PIX_FMT_ABGR32);
-	case DRM_FORMAT_BGRA8888:
-		return V4L2PixelFormat(V4L2_PIX_FMT_ARGB32);
-	case DRM_FORMAT_RGBA8888:
-		return V4L2PixelFormat(V4L2_PIX_FMT_BGRA32);
-
-	/* YUV packed formats. */
-	case DRM_FORMAT_YUYV:
-		return V4L2PixelFormat(V4L2_PIX_FMT_YUYV);
-	case DRM_FORMAT_YVYU:
-		return V4L2PixelFormat(V4L2_PIX_FMT_YVYU);
-	case DRM_FORMAT_UYVY:
-		return V4L2PixelFormat(V4L2_PIX_FMT_UYVY);
-	case DRM_FORMAT_VYUY:
-		return V4L2PixelFormat(V4L2_PIX_FMT_VYUY);
-
-	/*
-	 * YUY planar formats.
-	 * \todo Add support for non-contiguous memory planes
-	 * \todo Select the format variant not only based on \a multiplanar but
-	 * also take into account the formats supported by the device.
-	 */
-	case DRM_FORMAT_NV16:
-		return V4L2PixelFormat(V4L2_PIX_FMT_NV16);
-	case DRM_FORMAT_NV61:
-		return V4L2PixelFormat(V4L2_PIX_FMT_NV61);
-	case DRM_FORMAT_NV12:
-		return V4L2PixelFormat(V4L2_PIX_FMT_NV12);
-	case DRM_FORMAT_NV21:
-		return V4L2PixelFormat(V4L2_PIX_FMT_NV21);
-
-	/* Greyscale formats. */
-	case DRM_FORMAT_R8:
-		return V4L2PixelFormat(V4L2_PIX_FMT_GREY);
-
-	/* Compressed formats. */
-	case DRM_FORMAT_MJPEG:
-		return V4L2PixelFormat(V4L2_PIX_FMT_MJPEG);
-	}
-
-	/*
-	 * \todo We can't use LOG() in a static method of a Loggable
-	 * class. Until we fix the logger, work around it.
-	 */
-	libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
-			LogWarning).stream()
-		<< "Unsupported V4L2 pixel format " << pixelFormat.toString();
-	return {};
+	return V4L2PixelFormat::fromPixelFormat(pixelFormat,
+						caps_.isMultiplanar());
 }
 
 /**
diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp
index dae3cb9f7a6c..d1dad2a0f8cf 100644
--- a/test/libtest/buffer_source.cpp
+++ b/test/libtest/buffer_source.cpp
@@ -70,8 +70,8 @@ int BufferSource::allocate(const StreamConfiguration &config)
 	}
 
 	format.size = config.size;
-	format.fourcc = V4L2VideoDevice::toV4L2PixelFormat(config.pixelFormat,
-							   false);
+	format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat,
+							 false);
 	if (video->setFormat(&format)) {
 		std::cout << "Failed to set format on output device" << std::endl;
 		return TestFail;
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list