[libcamera-devel] [PATCH v2 6/6] libcamera: formats: Add additional data to PixelFormatInfo

Laurent Pinchart laurent.pinchart at ideasonboard.com
Thu Apr 30 05:07:23 CEST 2020


Add three additional fields to PixelFormatInfo to report the number of
bits per pixel, the colour encoding, and the data packing.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/libcamera/formats.cpp       | 127 ++++++++++++++++++++++++++++++++
 src/libcamera/include/formats.h |   9 +++
 2 files changed, 136 insertions(+)

diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp
index f6f8bc1202c2..331affe9fb25 100644
--- a/src/libcamera/formats.cpp
+++ b/src/libcamera/formats.cpp
@@ -121,6 +121,45 @@ const std::map<unsigned int, std::vector<SizeRange>> &ImageFormats::data() const
  *
  * \var PixelFormatInfo::v4l2Format
  * \brief The V4L2 pixel format corresponding to the PixelFormat
+ *
+ * \var PixelFormatInfo::bitsPerPixel
+ * \brief The average number of bits per pixel
+ *
+ * The number per pixel averages the total number of bits for all colour
+ * components over the whole image, excluding any padding bits or padding
+ * pixels.
+ *
+ * For formats that store pixels with bit padding within words, only the
+ * effective bits are taken into account. For instance, 12-bit Bayer data
+ * stored in two bytes per pixel report 12, not 16, in this field.
+ *
+ * Formats that don't have a fixed number of bits per pixel, such as compressed
+ * formats, report 0 in this field.
+ *
+ * \var PixelFormatInfo::colourEncoding
+ * \brief The colour encoding type
+ *
+ * \var PixelFormatInfo::packed
+ * \brief Tell if multiple pixels are packed in the same bytes
+ *
+ * Packed formats are defined as storing data from multiple pixels in the same
+ * bytes. For instance, 12-bit Bayer data with two pixels stored in three bytes
+ * is packed, while the same data stored with 4 bits of padding in two bytes
+ * per pixel is not packed.
+ */
+
+/**
+ * \enum PixelFormatInfo::ColourEncoding
+ * \brief The colour encoding type
+ *
+ * \var PixelFormatInfo::ColourEncodingRGB
+ * \brief RGB colour encoding
+ *
+ * \var PixelFormatInfo::ColourEncodingYUV
+ * \brief YUV colour encoding
+ *
+ * \var PixelFormatInfo::ColourEncodingRAW
+ * \brief RAW colour encoding
  */
 
 namespace {
@@ -130,156 +169,244 @@ const std::map<PixelFormat, PixelFormatInfo> pixelFormatInfo{
 	{ PixelFormat(DRM_FORMAT_BGR888), {
 		.format = PixelFormat(DRM_FORMAT_BGR888),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGB24),
+		.bitsPerPixel = 24,
+		.colourEncoding = PixelFormatInfo::ColourEncodingRGB,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_RGB888), {
 		.format = PixelFormat(DRM_FORMAT_RGB888),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGR24),
+		.bitsPerPixel = 24,
+		.colourEncoding = PixelFormatInfo::ColourEncodingRGB,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_ABGR8888), {
 		.format = PixelFormat(DRM_FORMAT_ABGR8888),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32),
+		.bitsPerPixel = 32,
+		.colourEncoding = PixelFormatInfo::ColourEncodingRGB,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_ARGB8888), {
 		.format = PixelFormat(DRM_FORMAT_ARGB8888),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32),
+		.bitsPerPixel = 32,
+		.colourEncoding = PixelFormatInfo::ColourEncodingRGB,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_BGRA8888), {
 		.format = PixelFormat(DRM_FORMAT_BGRA8888),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32),
+		.bitsPerPixel = 32,
+		.colourEncoding = PixelFormatInfo::ColourEncodingRGB,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_RGBA8888), {
 		.format = PixelFormat(DRM_FORMAT_RGBA8888),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32),
+		.bitsPerPixel = 32,
+		.colourEncoding = PixelFormatInfo::ColourEncodingRGB,
+		.packed = false,
 	} },
 
 	/* YUV packed formats. */
 	{ PixelFormat(DRM_FORMAT_YUYV), {
 		.format = PixelFormat(DRM_FORMAT_YUYV),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YUYV),
+		.bitsPerPixel = 16,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_YVYU), {
 		.format = PixelFormat(DRM_FORMAT_YVYU),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YVYU),
+		.bitsPerPixel = 16,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_UYVY), {
 		.format = PixelFormat(DRM_FORMAT_UYVY),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_UYVY),
+		.bitsPerPixel = 16,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_VYUY), {
 		.format = PixelFormat(DRM_FORMAT_VYUY),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_VYUY),
+		.bitsPerPixel = 16,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 
 	/* YUV planar formats. */
 	{ PixelFormat(DRM_FORMAT_NV16), {
 		.format = PixelFormat(DRM_FORMAT_NV16),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV16),
+		.bitsPerPixel = 16,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_NV61), {
 		.format = PixelFormat(DRM_FORMAT_NV61),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV61),
+		.bitsPerPixel = 16,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_NV12), {
 		.format = PixelFormat(DRM_FORMAT_NV12),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV12),
+		.bitsPerPixel = 12,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_NV21), {
 		.format = PixelFormat(DRM_FORMAT_NV21),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV21),
+		.bitsPerPixel = 12,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 
 	/* Greyscale formats. */
 	{ PixelFormat(DRM_FORMAT_R8), {
 		.format = PixelFormat(DRM_FORMAT_R8),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY),
+		.bitsPerPixel = 8,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 
 	/* Bayer formats. */
 	{ PixelFormat(DRM_FORMAT_SBGGR8), {
 		.format = PixelFormat(DRM_FORMAT_SBGGR8),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8),
+		.bitsPerPixel = 8,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGBRG8), {
 		.format = PixelFormat(DRM_FORMAT_SGBRG8),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8),
+		.bitsPerPixel = 8,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGRBG8), {
 		.format = PixelFormat(DRM_FORMAT_SGRBG8),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8),
+		.bitsPerPixel = 8,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SRGGB8), {
 		.format = PixelFormat(DRM_FORMAT_SRGGB8),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8),
+		.bitsPerPixel = 8,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SBGGR10), {
 		.format = PixelFormat(DRM_FORMAT_SBGGR10),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10),
+		.bitsPerPixel = 10,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGBRG10), {
 		.format = PixelFormat(DRM_FORMAT_SGBRG10),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10),
+		.bitsPerPixel = 10,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGRBG10), {
 		.format = PixelFormat(DRM_FORMAT_SGRBG10),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10),
+		.bitsPerPixel = 10,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SRGGB10), {
 		.format = PixelFormat(DRM_FORMAT_SRGGB10),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10),
+		.bitsPerPixel = 10,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P),
+		.bitsPerPixel = 10,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P),
+		.bitsPerPixel = 10,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P),
+		.bitsPerPixel = 10,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P),
+		.bitsPerPixel = 10,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SBGGR12), {
 		.format = PixelFormat(DRM_FORMAT_SBGGR12),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12),
+		.bitsPerPixel = 12,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGBRG12), {
 		.format = PixelFormat(DRM_FORMAT_SGBRG12),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12),
+		.bitsPerPixel = 12,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGRBG12), {
 		.format = PixelFormat(DRM_FORMAT_SGRBG12),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12),
+		.bitsPerPixel = 12,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SRGGB12), {
 		.format = PixelFormat(DRM_FORMAT_SRGGB12),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12),
+		.bitsPerPixel = 12,
+		.packed = false,
 	} },
 	{ PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P),
+		.bitsPerPixel = 12,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P),
+		.bitsPerPixel = 12,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P),
+		.bitsPerPixel = 12,
+		.packed = true,
 	} },
 	{ PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED), {
 		.format = PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P),
+		.bitsPerPixel = 12,
+		.packed = true,
 	} },
 
 	/* Compressed formats. */
 	{ PixelFormat(DRM_FORMAT_MJPEG), {
 		.format = PixelFormat(DRM_FORMAT_MJPEG),
 		.v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG),
+		.bitsPerPixel = 0,
+		.colourEncoding = PixelFormatInfo::ColourEncodingYUV,
+		.packed = false,
 	} },
 };
 
diff --git a/src/libcamera/include/formats.h b/src/libcamera/include/formats.h
index 560df07c4451..291a1108aa33 100644
--- a/src/libcamera/include/formats.h
+++ b/src/libcamera/include/formats.h
@@ -35,6 +35,12 @@ private:
 class PixelFormatInfo
 {
 public:
+	enum ColourEncoding {
+		ColourEncodingRGB,
+		ColourEncodingYUV,
+		ColourEncodingRAW,
+	};
+
 	bool isValid() const { return format.isValid(); }
 
 	static const PixelFormatInfo &info(const PixelFormat &format);
@@ -42,6 +48,9 @@ public:
 	/* \todo Add support for non-contiguous memory planes */
 	PixelFormat format;
 	V4L2PixelFormat v4l2Format;
+	unsigned int bitsPerPixel;
+	enum ColourEncoding colourEncoding;
+	bool packed;
 };
 
 } /* namespace libcamera */
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list