From patchwork Fri Oct 23 10:58:24 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 28586 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 89F21C324C for ; Fri, 23 Oct 2026 11:00:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2230368FDB; Fri, 23 Oct 2026 13:00:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="u6ky2BRr"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2362068FB7 for ; Fri, 23 Oct 2026 13:00:11 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c30:59f6:be2b:2877:6bc4:392]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F07022830; Fri, 23 Oct 2026 12:58:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1792753082; bh=LI70pq+ztCKASZoW44bzJiJb8encCc7pCF6BKqntlK4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=u6ky2BRrVbyxp8YiJ/ONJLYNgnpxxUPd7gKh3/cOrC8RWhPRu4CGa0bGY53Jvc1BZ 9P2OQTKmqPuCToN4h0ZaiPUDcjCX8SA4FRReGAz0lDtGSSfillL+RSYCU7hZucMbln Kd4F8Dn3E8ZrxddSygKUKCUVUU92WLGZryCfhWbE= From: Jai Luthra Date: Fri, 23 Oct 2026 16:28:24 +0530 Subject: [PATCH WIP RFC 16/26] libcamera: v4l2_pixelformat: Add toNonGeneric() helper MIME-Version: 1.0 Message-Id: <20261023-b4-raw-model-v1-16-eadb9948901b@ideasonboard.com> References: <20261023-b4-raw-model-v1-0-eadb9948901b@ideasonboard.com> In-Reply-To: <20261023-b4-raw-model-v1-0-eadb9948901b@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart , Kieran Bingham , Sakari Ailus , Naushir Patuck , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7857; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=LI70pq+ztCKASZoW44bzJiJb8encCc7pCF6BKqntlK4=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBq2z3Sq2VlRPHwNC5SYjiinj7Ks54Rx2pBzeZyT Ks2sVYfnlqJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCats90gAKCRBD3pH5JJpx RT8eD/96OOeJy9NX+16xYk8J8kvboqH7Q8OIX/BiGHpn9NiygDsiSgWFv0fNWpjeByHc4m3oTMB ScC6/gr0Somozk+7orp5dz4TVfOJAR70mpsiTw1Zl1nJFkrkUQ5mO7/9ryiUb60+idl9QZ8WwsS L93PV/9gUFWDTQ8ebmPqK5ahBkADi1uudRUHl1+x988xlgUP6umhs+OoGTrWzl656FXGOLBKTRc 7H7rknUHcsnZ900cjZ4ulYa/yJv+CGGB4rM8t7uusuU1VqrBcwklQs/KpXAqwJveNfV8LpviuLo lc56iBXnLeSEozKy6j4BT18Qmz92Y6+sTWF5DSweHP90b3mihud5UF/sCDFJO7X/gZK3S4UEpkn PArsmhimgnOchm0QzMja9WBFkEJdj1bPdPnvzyBp0kyfZq0XbI0a3j+kOTbeDrWyn/dDEL/y86h ByX3XJvsf5iICt2G+TbrF8KufjOmInsZbiCaeBzNc0R4Sm/pzi3AL73lok0TOtZWhp3Jd3UQmcG miUhIb/q8KJ5H/vJNHL++WhhikPSB1b4+oMK8Xh6rV+WFA7l8mMsr41cq/4ROSxHHZUKSFykz6S xBtOPgve88JAgFefSUjWHZ97v7lMLEBtpCdZWXFt5ICYMxlSMTgdphs4+MicqMv1Ba0H/Cl5xwk Yxw1I7KZwVLjKLQ== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Many pipelines may not support the generic RAW format fourccs immediately. Add a toNonGeneric() helper that gives the bayer-order specific fourcc value given a PixelFormat and a ColorFilterArray. Signed-off-by: Jai Luthra --- include/libcamera/internal/v4l2_pixelformat.h | 3 + src/libcamera/v4l2_pixelformat.cpp | 127 ++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/include/libcamera/internal/v4l2_pixelformat.h b/include/libcamera/internal/v4l2_pixelformat.h index 543eb21b3c07..2e0991a59a6d 100644 --- a/include/libcamera/internal/v4l2_pixelformat.h +++ b/include/libcamera/internal/v4l2_pixelformat.h @@ -20,6 +20,8 @@ namespace libcamera { +class ColorFilterArray; + class V4L2PixelFormat { public: @@ -48,6 +50,7 @@ public: PixelFormat toPixelFormat(bool warn = true) const; static const std::vector & fromPixelFormat(const PixelFormat &pixelFormat); + bool toNonGeneric(const ColorFilterArray cfa); bool isGenericLineBasedMetadata() const; diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index d51987c5ad8a..ca479edb49c2 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -14,6 +14,7 @@ #include +#include #include #include @@ -245,6 +246,111 @@ const std::map vpf2pf{ { formats::MJPEG, "JPEG JFIF" } }, }; +struct FormatWithCfa { + V4L2PixelFormat pixfmt; + ColorFilterArray cfa; + + bool operator<(const FormatWithCfa &other) const + { + return std::tie(pixfmt, cfa.order) < + std::tie(other.pixfmt, other.cfa.order); + } +}; + +const std::map generic2specific { + /* 8-bit */ + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8) }, + /* 10-bit */ + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P) }, + /* 12-bit */ + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P) }, + /* 14-bit */ + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR14) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG14) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG14) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB14) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR14P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG14P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG14P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB14P) }, + /* 16-bit */ + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) }, + /* Monochrome */ + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::MONO }, + V4L2PixelFormat(V4L2_PIX_FMT_GREY) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::MONO }, + V4L2PixelFormat(V4L2_PIX_FMT_Y10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::MONO }, + V4L2PixelFormat(V4L2_PIX_FMT_Y10P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::MONO }, + V4L2PixelFormat(V4L2_PIX_FMT_Y12) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::MONO }, + V4L2PixelFormat(V4L2_PIX_FMT_Y12P) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::MONO }, + V4L2PixelFormat(V4L2_PIX_FMT_Y16) }, + /* IPU3 */ + { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::BGGR }, + V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::GBRG }, + V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::GRBG }, + V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) }, + { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::RGGB }, + V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) }, +}; + } /* namespace */ /** @@ -390,6 +496,27 @@ V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat) return info.v4l2Formats; } +/** + * \brief Convert a generic V4L2PixelFormat to a specific one given a color + * filter array pattern. + * \param[in] cfa Color filter array pattern + * + * If no specific variant is known for the combination, the format is left + * unmodified and false is returned. + * + * \return True if the format is converted, false otherwise + */ +bool V4L2PixelFormat::toNonGeneric(const ColorFilterArray cfa) +{ + const auto it = generic2specific.find({*this, cfa}); + if (it != generic2specific.end()) { + *this = it->second; + return true; + } + + return false; +} + /** * \brief Test if a V4L2PixelFormat is one of the line based generic metadata * formats