[libcamera-devel] [PATCH 4/4] v4l2: camera_proxy: Create format info array

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Jan 6 17:14:17 CET 2020


Create a PixelFormatInfo structure to store information about a format,
and add a global array of format info for all the formats currently
supported. Move the format helpers to use the information from the
array.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/v4l2/v4l2_camera_proxy.cpp | 180 +++++++++++++--------------------
 1 file changed, 70 insertions(+), 110 deletions(-)

diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index 6a222d702e13..b8c1a53af1c2 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -509,134 +509,94 @@ int V4L2CameraProxy::ioctl(unsigned long request, void *arg)
 	return ret;
 }
 
+struct PixelFormatPlaneInfo {
+	unsigned int bitsPerPixel;
+	unsigned int hSubSampling;
+	unsigned int vSubSampling;
+};
+
+struct PixelFormatInfo {
+	PixelFormat format;
+	uint32_t v4l2Format;
+	unsigned int numPlanes;
+	std::array<PixelFormatPlaneInfo, 3> planes;
+};
+
+namespace {
+
+constexpr std::array<PixelFormatInfo, 13> pixelFormatInfo = {{
+	/* RGB formats. */
+	{ DRM_FORMAT_RGB888,	V4L2_PIX_FMT_BGR24,	1, {{ { 24, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_BGR888,	V4L2_PIX_FMT_RGB24,	1, {{ { 24, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_BGRA8888,	V4L2_PIX_FMT_ARGB32,	1, {{ { 32, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	/* YUV packed formats. */
+	{ DRM_FORMAT_UYVY,	V4L2_PIX_FMT_UYVY,	1, {{ { 16, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_VYUY,	V4L2_PIX_FMT_VYUY,	1, {{ { 16, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_YUYV,	V4L2_PIX_FMT_YUYV,	1, {{ { 16, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_YVYU,	V4L2_PIX_FMT_YVYU,	1, {{ { 16, 1, 1 }, {  0, 0, 0 }, {  0, 0, 0 } }} },
+	/* YUY planar formats. */
+	{ DRM_FORMAT_NV12,	V4L2_PIX_FMT_NV12,	2, {{ {  8, 1, 1 }, { 16, 2, 2 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_NV21,	V4L2_PIX_FMT_NV21,	2, {{ {  8, 1, 1 }, { 16, 2, 2 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_NV16,	V4L2_PIX_FMT_NV16,	2, {{ {  8, 1, 1 }, { 16, 2, 1 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_NV61,	V4L2_PIX_FMT_NV61,	2, {{ {  8, 1, 1 }, { 16, 2, 1 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_NV24,	V4L2_PIX_FMT_NV24,	2, {{ {  8, 1, 1 }, { 16, 2, 1 }, {  0, 0, 0 } }} },
+	{ DRM_FORMAT_NV42,	V4L2_PIX_FMT_NV42,	2, {{ {  8, 1, 1 }, { 16, 1, 1 }, {  0, 0, 0 } }} },
+}};
+
+} /* namespace */
+
 /* \todo make libcamera export these */
 unsigned int V4L2CameraProxy::bplMultiplier(uint32_t format)
 {
-	switch (format) {
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV61:
-	case V4L2_PIX_FMT_NV24:
-	case V4L2_PIX_FMT_NV42:
-		return 1;
-	case V4L2_PIX_FMT_BGR24:
-	case V4L2_PIX_FMT_RGB24:
-		return 3;
-	case V4L2_PIX_FMT_ARGB32:
-		return 4;
-	case V4L2_PIX_FMT_VYUY:
-	case V4L2_PIX_FMT_YVYU:
-	case V4L2_PIX_FMT_UYVY:
-	case V4L2_PIX_FMT_YUYV:
-		return 2;
-	default:
+	auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
+				 [format](const PixelFormatInfo &info) {
+					 return info.v4l2Format == format;
+				 });
+	if (info == pixelFormatInfo.end())
 		return 0;
-	};
+
+	return info->planes[0].bitsPerPixel / 8;
 }
 
 unsigned int V4L2CameraProxy::imageSize(uint32_t format, unsigned int width,
 					unsigned int height)
 {
-	switch (format) {
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-		return width * height * 3 / 2;
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV61:
-		return width * height * 2;
-	case V4L2_PIX_FMT_NV24:
-	case V4L2_PIX_FMT_NV42:
-		return width * height * 3;
-	case V4L2_PIX_FMT_BGR24:
-	case V4L2_PIX_FMT_RGB24:
-		return width * height * 3;
-	case V4L2_PIX_FMT_ARGB32:
-		return width * height * 4;
-	case V4L2_PIX_FMT_VYUY:
-	case V4L2_PIX_FMT_YVYU:
-	case V4L2_PIX_FMT_UYVY:
-	case V4L2_PIX_FMT_YUYV:
-		return width * height * 2;
-	default:
+	auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
+				 [format](const PixelFormatInfo &info) {
+					 return info.v4l2Format == format;
+				 });
+	if (info == pixelFormatInfo.end())
 		return 0;
-	};
+
+	unsigned int multiplier = 0;
+	for (unsigned int i = 0; i < info->numPlanes; ++i)
+		multiplier += info->planes[i].bitsPerPixel
+			    / info->planes[i].hSubSampling
+			    / info->planes[i].vSubSampling;
+
+	return width * height * multiplier / 8;
 }
 
 PixelFormat V4L2CameraProxy::v4l2ToDrm(uint32_t format)
 {
-	switch (format) {
-	/* RGB formats. */
-	case V4L2_PIX_FMT_RGB24:
-		return DRM_FORMAT_BGR888;
-	case V4L2_PIX_FMT_BGR24:
-		return DRM_FORMAT_RGB888;
-	case V4L2_PIX_FMT_ARGB32:
-		return DRM_FORMAT_BGRA8888;
-
-	/* YUV packed formats. */
-	case V4L2_PIX_FMT_YUYV:
-		return DRM_FORMAT_YUYV;
-	case V4L2_PIX_FMT_YVYU:
-		return DRM_FORMAT_YVYU;
-	case V4L2_PIX_FMT_UYVY:
-		return DRM_FORMAT_UYVY;
-	case V4L2_PIX_FMT_VYUY:
-		return DRM_FORMAT_VYUY;
-
-	/* YUY planar formats. */
-	case V4L2_PIX_FMT_NV16:
-		return DRM_FORMAT_NV16;
-	case V4L2_PIX_FMT_NV61:
-		return DRM_FORMAT_NV61;
-	case V4L2_PIX_FMT_NV12:
-		return DRM_FORMAT_NV12;
-	case V4L2_PIX_FMT_NV21:
-		return DRM_FORMAT_NV21;
-	case V4L2_PIX_FMT_NV24:
-		return DRM_FORMAT_NV24;
-	case V4L2_PIX_FMT_NV42:
-		return DRM_FORMAT_NV42;
-	default:
+	auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
+				 [format](const PixelFormatInfo &info) {
+					 return info.v4l2Format == format;
+				 });
+	if (info == pixelFormatInfo.end())
 		return format;
-	};
+
+	return info->format;
 }
 
 uint32_t V4L2CameraProxy::drmToV4L2(PixelFormat format)
 {
-	switch (format) {
-	/* RGB formats. */
-	case DRM_FORMAT_BGR888:
-		return V4L2_PIX_FMT_RGB24;
-	case DRM_FORMAT_RGB888:
-		return V4L2_PIX_FMT_BGR24;
-	case DRM_FORMAT_BGRA8888:
-		return V4L2_PIX_FMT_ARGB32;
-
-	/* YUV packed formats. */
-	case DRM_FORMAT_YUYV:
-		return V4L2_PIX_FMT_YUYV;
-	case DRM_FORMAT_YVYU:
-		return V4L2_PIX_FMT_YVYU;
-	case DRM_FORMAT_UYVY:
-		return V4L2_PIX_FMT_UYVY;
-	case DRM_FORMAT_VYUY:
-		return V4L2_PIX_FMT_VYUY;
-
-	/* YUY planar formats. */
-	case DRM_FORMAT_NV16:
-		return V4L2_PIX_FMT_NV16;
-	case DRM_FORMAT_NV61:
-		return V4L2_PIX_FMT_NV61;
-	case DRM_FORMAT_NV12:
-		return V4L2_PIX_FMT_NV12;
-	case DRM_FORMAT_NV21:
-		return V4L2_PIX_FMT_NV21;
-	case DRM_FORMAT_NV24:
-		return V4L2_PIX_FMT_NV24;
-	case DRM_FORMAT_NV42:
-		return V4L2_PIX_FMT_NV42;
-	default:
+	auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(),
+				 [format](const PixelFormatInfo &info) {
+					 return info.format == format;
+				 });
+	if (info == pixelFormatInfo.end())
 		return format;
-	}
+
+	return info->v4l2Format;
 }
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list