[libcamera-devel] [PATCH v5 4/8] libcamera: Allow Bayer pixel formats to be transformed

David Plowman david.plowman at raspberrypi.com
Sat Aug 29 13:54:25 CEST 2020


Add a transform method to the V4L2PixelFormat class which allows Bayer
formats to be re-ordered into a different Bayer order when horizontal
or vertical flips are requested from the sensor.

Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
---
 include/libcamera/internal/v4l2_pixelformat.h |  3 +
 src/libcamera/v4l2_pixelformat.cpp            | 94 ++++++++++++++++++-
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/include/libcamera/internal/v4l2_pixelformat.h b/include/libcamera/internal/v4l2_pixelformat.h
index 9bfd81a..cddac86 100644
--- a/include/libcamera/internal/v4l2_pixelformat.h
+++ b/include/libcamera/internal/v4l2_pixelformat.h
@@ -14,6 +14,7 @@
 #include <linux/videodev2.h>
 
 #include <libcamera/pixel_format.h>
+#include <libcamera/transform.h>
 
 namespace libcamera {
 
@@ -40,6 +41,8 @@ public:
 	static V4L2PixelFormat fromPixelFormat(const PixelFormat &pixelFormat,
 					       bool multiplanar);
 
+	V4L2PixelFormat transform(Transform t) const;
+
 private:
 	uint32_t fourcc_;
 };
diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp
index 30c94bb..28bcd51 100644
--- a/src/libcamera/v4l2_pixelformat.cpp
+++ b/src/libcamera/v4l2_pixelformat.cpp
@@ -101,6 +101,62 @@ const std::map<V4L2PixelFormat, PixelFormat> vpf2pf{
 	{ V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), formats::MJPEG },
 };
 
+/* Table giving the result of applying an hflip to each Bayer pixel format. */
+const std::map<V4L2PixelFormat, V4L2PixelFormat> hflipTable{
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) },
+};
+
+/* Table giving the result of applying a vflip to each Bayer pixel format. */
+const std::map<V4L2PixelFormat, V4L2PixelFormat> vflipTable{
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16), V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16), V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16), V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16) },
+	{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16), V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) },
+};
+
 } /* namespace */
 
 /**
@@ -113,7 +169,7 @@ const std::map<V4L2PixelFormat, PixelFormat> vpf2pf{
 
 /**
  * \fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc)
- * \brief Construct a V4L2PixelFormat from a FourCC value
+p * \brief Construct a V4L2PixelFormat from a FourCC value
  * \param[in] fourcc The pixel format FourCC numerical value
  */
 
@@ -205,4 +261,40 @@ V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat,
 	return info.v4l2Format;
 }
 
+/**
+ * \brief Transform a Bayer V4L2PixelFormat.
+ * \param[in] t The Transform to be applied to the pixel format.
+ *
+ * Some sensors that produce Bayer V4L2PixelFormats may change their Bayer
+ * order when the V4L2_CID_HFLIP or V4L2_CID_VFLIP controls are applied to the
+ * device. For such sensors, this function computes the new V4L2PixelFormat
+ * for the transformed Bayer order.
+ *
+ * Transposes are ignored as sensors do not implement them.
+ *
+ * \return The Bayer V4L2PixelFormat resulting from applying transform \a t
+ * to the given V4L2PixelFormat.
+ */
+V4L2PixelFormat V4L2PixelFormat::transform(Transform t) const
+{
+	V4L2PixelFormat result = *this;
+
+	if (!!(t & Transform::HFlip)) {
+		const auto iter = hflipTable.find(*this);
+		if (iter == hflipTable.end()) {
+			LOG(V4L2, Warning)
+				<< "Cannot transpose V4L2 pixel format "
+				<< toString();
+			return V4L2PixelFormat();
+		}
+		result = iter->second;
+	}
+
+	/* This will be found as the tables have the same keys. */
+	if (!!(t & Transform::VFlip))
+		result = vflipTable.find(result)->second;
+
+	return result;
+}
+
 } /* namespace libcamera */
-- 
2.20.1



More information about the libcamera-devel mailing list