From patchwork Fri Mar 15 00:16:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19720 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 0D9C2BD160 for ; Fri, 15 Mar 2024 00:16:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A285162C87; Fri, 15 Mar 2024 01:16:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cEFuFG7h"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7430162973 for ; Fri, 15 Mar 2024 01:16:17 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 75174667 for ; Fri, 15 Mar 2024 01:15:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461753; bh=ETHXVVQLCpZSOkVJlTt0QkZn7HotTnX9JWslsfe15ic=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cEFuFG7hQ+actwiJ1ta6v6p3ofu9wearwxSjeySGDwO7T4eT3mFHU/hnHj0s+QSCr sJARrjIU4il357X+wQGWFW0rX6c5Uqazcx8LaeW6Uow3LP0S7lXwJBoHbwo3lDUr7U j6wbctUXJh0iLRd0dJjyYA0w6c6WJ0Sxv+at29oI= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 01/14] libcamera: v4l2_subdevice: Rename V4L2SubdeviceFormatInfo Date: Fri, 15 Mar 2024 02:16:00 +0200 Message-ID: <20240315001613.2033-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The V4L2SubdeviceFormatInfo structure contains information about a media bus format, not a V4L2 subdevice format. Rename it to MediaBusFormatInfo to clarify its purpose. Rename the formatInfoMap map accordingly. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/libcamera/v4l2_subdevice.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 9b118063e696..b6a25e25230b 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -39,24 +39,24 @@ LOG_DECLARE_CATEGORY(V4L2) namespace { /* - * \struct V4L2SubdeviceFormatInfo + * \struct MediaBusFormatInfo * \brief Information about media bus formats * \param bitsPerPixel Bits per pixel * \param name Name of MBUS format * \param colourEncoding Type of colour encoding */ -struct V4L2SubdeviceFormatInfo { +struct MediaBusFormatInfo { unsigned int bitsPerPixel; const char *name; PixelFormatInfo::ColourEncoding colourEncoding; }; /* - * \var formatInfoMap - * \brief A map that associates V4L2SubdeviceFormatInfo struct to V4L2 media + * \var mediaBusFormatInfo + * \brief A map that associates MediaBusFormatInfo struct to V4L2 media * bus codes */ -const std::map formatInfoMap = { +const std::map mediaBusFormatInfo = { /* This table is sorted to match the order in linux/media-bus-format.h */ { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { 16, "RGB444_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRGB } }, { MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, { 16, "RGB444_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRGB } }, @@ -241,8 +241,8 @@ const std::string V4L2SubdeviceFormat::toString() const */ uint8_t V4L2SubdeviceFormat::bitsPerPixel() const { - const auto it = formatInfoMap.find(mbus_code); - if (it == formatInfoMap.end()) { + const auto it = mediaBusFormatInfo.find(mbus_code); + if (it == mediaBusFormatInfo.end()) { LOG(V4L2, Error) << "No information available for format '" << *this << "'"; return 0; @@ -262,9 +262,9 @@ std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f) { out << f.size << "-"; - const auto it = formatInfoMap.find(f.mbus_code); + const auto it = mediaBusFormatInfo.find(f.mbus_code); - if (it == formatInfoMap.end()) + if (it == mediaBusFormatInfo.end()) out << utils::hex(f.mbus_code, 4); else out << it->second.name; @@ -515,8 +515,8 @@ std::optional V4L2Subdevice::toColorSpace(const v4l2_mbus_framefmt & return std::nullopt; PixelFormatInfo::ColourEncoding colourEncoding; - auto iter = formatInfoMap.find(format.code); - if (iter != formatInfoMap.end()) { + auto iter = mediaBusFormatInfo.find(format.code); + if (iter != mediaBusFormatInfo.end()) { colourEncoding = iter->second.colourEncoding; } else { LOG(V4L2, Warning) From patchwork Fri Mar 15 00:16:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19721 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 9E0B0BD160 for ; Fri, 15 Mar 2024 00:16:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D83F562C8F; Fri, 15 Mar 2024 01:16:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="N4WflZxx"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B95C662C87 for ; Fri, 15 Mar 2024 01:16:18 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 048D9A9A for ; Fri, 15 Mar 2024 01:15:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461755; bh=O5W3bY3Vh6hz/tvYEQHmjOSEbqPM1HlROqc2RgAtKEc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=N4WflZxxW99TBPXSpwm8bmoa5a4Fr/YDgaTvMQZGaBf6YGVkAprs9L8VmwJmNrCAP 6h4rORL7MmfWApOfuklSG29fCJ/gxCTEKX9R21XVMKMh9tR28fbC/vGPAP7iBG+hu8 3vo4+qEYTOcGqqP8oxXhGKK2Q2o+bMnFdu5V5new= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 02/14] libcamera: v4l2_subdevice: Add code member to MediaBusFormatInfo Date: Fri, 15 Mar 2024 02:16:01 +0200 Message-ID: <20240315001613.2033-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" To prepare for exposing the MediaBusFormatInfo structure as an internal API, add a code member to the structure to store the media bus code. This makes MediaBusFormatInfo usable standalone, without having to externally associate the code related to the info. The entries in the mediaBusFormatInfo map are becoming too long, so split them on multiple lines. While at it, swap the order of the members to match the PixelFormatInfo class for consistency. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- Changes since combined RFC: - Rebase on addition oa 14-bit bayer formats --- src/libcamera/v4l2_subdevice.cpp | 582 ++++++++++++++++++++++++++----- 1 file changed, 497 insertions(+), 85 deletions(-) diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index b6a25e25230b..1286e7c385c4 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -41,13 +41,15 @@ namespace { /* * \struct MediaBusFormatInfo * \brief Information about media bus formats - * \param bitsPerPixel Bits per pixel * \param name Name of MBUS format + * \param code The media bus format code + * \param bitsPerPixel Bits per pixel * \param colourEncoding Type of colour encoding */ struct MediaBusFormatInfo { - unsigned int bitsPerPixel; const char *name; + uint32_t code; + unsigned int bitsPerPixel; PixelFormatInfo::ColourEncoding colourEncoding; }; @@ -56,91 +58,501 @@ struct MediaBusFormatInfo { * \brief A map that associates MediaBusFormatInfo struct to V4L2 media * bus codes */ -const std::map mediaBusFormatInfo = { +const std::map mediaBusFormatInfo{ /* This table is sorted to match the order in linux/media-bus-format.h */ - { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { 16, "RGB444_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, { 16, "RGB444_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, { 16, "RGB555_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, { 16, "RGB555_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB565_1X16, { 16, "RGB565_1X16", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_BGR565_2X8_BE, { 16, "BGR565_2X8_BE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_BGR565_2X8_LE, { 16, "BGR565_2X8_LE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB565_2X8_BE, { 16, "RGB565_2X8_BE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB565_2X8_LE, { 16, "RGB565_2X8_LE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB666_1X18, { 18, "RGB666_1X18", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_BGR888_1X24, { 24, "BGR888_1X24", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB888_1X24, { 24, "RGB888_1X24", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB888_2X12_BE, { 24, "RGB888_2X12_BE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_RGB888_2X12_LE, { 24, "RGB888_2X12_LE", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_ARGB8888_1X32, { 32, "ARGB8888_1X32", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_Y8_1X8, { 8, "Y8_1X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UV8_1X8, { 8, "UV8_1X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY8_1_5X8, { 12, "UYVY8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY8_1_5X8, { 12, "VYUY8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV8_1_5X8, { 12, "YUYV8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU8_1_5X8, { 12, "YVYU8_1_5X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY8_2X8, { 16, "UYVY8_2X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY8_2X8, { 16, "VYUY8_2X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV8_2X8, { 16, "YUYV8_2X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU8_2X8, { 16, "YVYU8_2X8", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_Y10_1X10, { 10, "Y10_1X10", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY10_2X10, { 20, "UYVY10_2X10", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY10_2X10, { 20, "VYUY10_2X10", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV10_2X10, { 20, "YUYV10_2X10", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU10_2X10, { 20, "YVYU10_2X10", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_Y12_1X12, { 12, "Y12_1X12", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_Y16_1X16, { 16, "Y16_1X16", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY8_1X16, { 16, "UYVY8_1X16", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY8_1X16, { 16, "VYUY8_1X16", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV8_1X16, { 16, "YUYV8_1X16", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU8_1X16, { 16, "YVYU8_1X16", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YDYUYDYV8_1X16, { 16, "YDYUYDYV8_1X16", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY10_1X20, { 20, "UYVY10_1X20", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY10_1X20, { 20, "VYUY10_1X20", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV10_1X20, { 20, "YUYV10_1X20", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU10_1X20, { 20, "YVYU10_1X20", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUV8_1X24, { 24, "YUV8_1X24", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUV10_1X30, { 30, "YUV10_1X30", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_AYUV8_1X32, { 32, "AYUV8_1X32", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY12_2X12, { 24, "UYVY12_2X12", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY12_2X12, { 24, "VYUY12_2X12", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV12_2X12, { 24, "YUYV12_2X12", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU12_2X12, { 24, "YVYU12_2X12", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_UYVY12_1X24, { 24, "UYVY12_1X24", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_VYUY12_1X24, { 24, "VYUY12_1X24", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YUYV12_1X24, { 24, "YUYV12_1X24", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_YVYU12_1X24, { 24, "YVYU12_1X24", PixelFormatInfo::ColourEncodingYUV } }, - { MEDIA_BUS_FMT_SBGGR8_1X8, { 8, "SBGGR8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGBRG8_1X8, { 8, "SGBRG8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGRBG8_1X8, { 8, "SGRBG8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SRGGB8_1X8, { 8, "SRGGB8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, { 8, "SBGGR10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, { 8, "SGBRG10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, { 8, "SGRBG10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, { 8, "SRGGB10_ALAW8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, { 8, "SBGGR10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, { 8, "SGBRG10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, { 8, "SGRBG10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, { 8, "SRGGB10_DPCM8_1X8", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, { 16, "SBGGR10_2X8_PADHI_BE", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, { 16, "SBGGR10_2X8_PADHI_LE", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, { 16, "SBGGR10_2X8_PADLO_BE", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, { 16, "SBGGR10_2X8_PADLO_LE", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR10_1X10, { 10, "SBGGR10_1X10", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGBRG10_1X10, { 10, "SGBRG10_1X10", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGRBG10_1X10, { 10, "SGRBG10_1X10", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SRGGB10_1X10, { 10, "SRGGB10_1X10", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR12_1X12, { 12, "SBGGR12_1X12", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGBRG12_1X12, { 12, "SGBRG12_1X12", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGRBG12_1X12, { 12, "SGRBG12_1X12", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SRGGB12_1X12, { 12, "SRGGB12_1X12", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SBGGR14_1X14, { 14, "SBGGR14_1X14", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGBRG14_1X14, { 14, "SGBRG14_1X14", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SGRBG14_1X14, { 14, "SGRBG14_1X14", PixelFormatInfo::ColourEncodingRAW } }, - { MEDIA_BUS_FMT_SRGGB14_1X14, { 14, "SRGGB14_1X14", PixelFormatInfo::ColourEncodingRAW } }, + { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { + .name = "RGB444_2X8_PADHI_BE", + .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, { + .name = "RGB444_2X8_PADHI_LE", + .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, { + .name = "RGB555_2X8_PADHI_BE", + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, { + .name = "RGB555_2X8_PADHI_LE", + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB565_1X16, { + .name = "RGB565_1X16", + .code = MEDIA_BUS_FMT_RGB565_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_BGR565_2X8_BE, { + .name = "BGR565_2X8_BE", + .code = MEDIA_BUS_FMT_BGR565_2X8_BE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_BGR565_2X8_LE, { + .name = "BGR565_2X8_LE", + .code = MEDIA_BUS_FMT_BGR565_2X8_LE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB565_2X8_BE, { + .name = "RGB565_2X8_BE", + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB565_2X8_LE, { + .name = "RGB565_2X8_LE", + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB666_1X18, { + .name = "RGB666_1X18", + .code = MEDIA_BUS_FMT_RGB666_1X18, + .bitsPerPixel = 18, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_BGR888_1X24, { + .name = "BGR888_1X24", + .code = MEDIA_BUS_FMT_BGR888_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB888_1X24, { + .name = "RGB888_1X24", + .code = MEDIA_BUS_FMT_RGB888_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB888_2X12_BE, { + .name = "RGB888_2X12_BE", + .code = MEDIA_BUS_FMT_RGB888_2X12_BE, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_RGB888_2X12_LE, { + .name = "RGB888_2X12_LE", + .code = MEDIA_BUS_FMT_RGB888_2X12_LE, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_ARGB8888_1X32, { + .name = "ARGB8888_1X32", + .code = MEDIA_BUS_FMT_ARGB8888_1X32, + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_Y8_1X8, { + .name = "Y8_1X8", + .code = MEDIA_BUS_FMT_Y8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UV8_1X8, { + .name = "UV8_1X8", + .code = MEDIA_BUS_FMT_UV8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY8_1_5X8, { + .name = "UYVY8_1_5X8", + .code = MEDIA_BUS_FMT_UYVY8_1_5X8, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY8_1_5X8, { + .name = "VYUY8_1_5X8", + .code = MEDIA_BUS_FMT_VYUY8_1_5X8, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV8_1_5X8, { + .name = "YUYV8_1_5X8", + .code = MEDIA_BUS_FMT_YUYV8_1_5X8, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU8_1_5X8, { + .name = "YVYU8_1_5X8", + .code = MEDIA_BUS_FMT_YVYU8_1_5X8, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY8_2X8, { + .name = "UYVY8_2X8", + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY8_2X8, { + .name = "VYUY8_2X8", + .code = MEDIA_BUS_FMT_VYUY8_2X8, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV8_2X8, { + .name = "YUYV8_2X8", + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU8_2X8, { + .name = "YVYU8_2X8", + .code = MEDIA_BUS_FMT_YVYU8_2X8, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_Y10_1X10, { + .name = "Y10_1X10", + .code = MEDIA_BUS_FMT_Y10_1X10, + .bitsPerPixel = 10, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY10_2X10, { + .name = "UYVY10_2X10", + .code = MEDIA_BUS_FMT_UYVY10_2X10, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY10_2X10, { + .name = "VYUY10_2X10", + .code = MEDIA_BUS_FMT_VYUY10_2X10, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV10_2X10, { + .name = "YUYV10_2X10", + .code = MEDIA_BUS_FMT_YUYV10_2X10, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU10_2X10, { + .name = "YVYU10_2X10", + .code = MEDIA_BUS_FMT_YVYU10_2X10, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_Y12_1X12, { + .name = "Y12_1X12", + .code = MEDIA_BUS_FMT_Y12_1X12, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_Y16_1X16, { + .name = "Y16_1X16", + .code = MEDIA_BUS_FMT_Y16_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY8_1X16, { + .name = "UYVY8_1X16", + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY8_1X16, { + .name = "VYUY8_1X16", + .code = MEDIA_BUS_FMT_VYUY8_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV8_1X16, { + .name = "YUYV8_1X16", + .code = MEDIA_BUS_FMT_YUYV8_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU8_1X16, { + .name = "YVYU8_1X16", + .code = MEDIA_BUS_FMT_YVYU8_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YDYUYDYV8_1X16, { + .name = "YDYUYDYV8_1X16", + .code = MEDIA_BUS_FMT_YDYUYDYV8_1X16, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY10_1X20, { + .name = "UYVY10_1X20", + .code = MEDIA_BUS_FMT_UYVY10_1X20, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY10_1X20, { + .name = "VYUY10_1X20", + .code = MEDIA_BUS_FMT_VYUY10_1X20, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV10_1X20, { + .name = "YUYV10_1X20", + .code = MEDIA_BUS_FMT_YUYV10_1X20, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU10_1X20, { + .name = "YVYU10_1X20", + .code = MEDIA_BUS_FMT_YVYU10_1X20, + .bitsPerPixel = 20, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUV8_1X24, { + .name = "YUV8_1X24", + .code = MEDIA_BUS_FMT_YUV8_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUV10_1X30, { + .name = "YUV10_1X30", + .code = MEDIA_BUS_FMT_YUV10_1X30, + .bitsPerPixel = 30, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_AYUV8_1X32, { + .name = "AYUV8_1X32", + .code = MEDIA_BUS_FMT_AYUV8_1X32, + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY12_2X12, { + .name = "UYVY12_2X12", + .code = MEDIA_BUS_FMT_UYVY12_2X12, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY12_2X12, { + .name = "VYUY12_2X12", + .code = MEDIA_BUS_FMT_VYUY12_2X12, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV12_2X12, { + .name = "YUYV12_2X12", + .code = MEDIA_BUS_FMT_YUYV12_2X12, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU12_2X12, { + .name = "YVYU12_2X12", + .code = MEDIA_BUS_FMT_YVYU12_2X12, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_UYVY12_1X24, { + .name = "UYVY12_1X24", + .code = MEDIA_BUS_FMT_UYVY12_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_VYUY12_1X24, { + .name = "VYUY12_1X24", + .code = MEDIA_BUS_FMT_VYUY12_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YUYV12_1X24, { + .name = "YUYV12_1X24", + .code = MEDIA_BUS_FMT_YUYV12_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_YVYU12_1X24, { + .name = "YVYU12_1X24", + .code = MEDIA_BUS_FMT_YVYU12_1X24, + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, + { MEDIA_BUS_FMT_SBGGR8_1X8, { + .name = "SBGGR8_1X8", + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGBRG8_1X8, { + .name = "SGBRG8_1X8", + .code = MEDIA_BUS_FMT_SGBRG8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGRBG8_1X8, { + .name = "SGRBG8_1X8", + .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SRGGB8_1X8, { + .name = "SRGGB8_1X8", + .code = MEDIA_BUS_FMT_SRGGB8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, { + .name = "SBGGR10_ALAW8_1X8", + .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, { + .name = "SGBRG10_ALAW8_1X8", + .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, { + .name = "SGRBG10_ALAW8_1X8", + .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, { + .name = "SRGGB10_ALAW8_1X8", + .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, { + .name = "SBGGR10_DPCM8_1X8", + .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, { + .name = "SGBRG10_DPCM8_1X8", + .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, { + .name = "SGRBG10_DPCM8_1X8", + .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, { + .name = "SRGGB10_DPCM8_1X8", + .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, { + .name = "SBGGR10_2X8_PADHI_BE", + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, { + .name = "SBGGR10_2X8_PADHI_LE", + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, { + .name = "SBGGR10_2X8_PADLO_BE", + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, { + .name = "SBGGR10_2X8_PADLO_LE", + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR10_1X10, { + .name = "SBGGR10_1X10", + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .bitsPerPixel = 10, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGBRG10_1X10, { + .name = "SGBRG10_1X10", + .code = MEDIA_BUS_FMT_SGBRG10_1X10, + .bitsPerPixel = 10, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGRBG10_1X10, { + .name = "SGRBG10_1X10", + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .bitsPerPixel = 10, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SRGGB10_1X10, { + .name = "SRGGB10_1X10", + .code = MEDIA_BUS_FMT_SRGGB10_1X10, + .bitsPerPixel = 10, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR12_1X12, { + .name = "SBGGR12_1X12", + .code = MEDIA_BUS_FMT_SBGGR12_1X12, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGBRG12_1X12, { + .name = "SGBRG12_1X12", + .code = MEDIA_BUS_FMT_SGBRG12_1X12, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGRBG12_1X12, { + .name = "SGRBG12_1X12", + .code = MEDIA_BUS_FMT_SGRBG12_1X12, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SRGGB12_1X12, { + .name = "SRGGB12_1X12", + .code = MEDIA_BUS_FMT_SRGGB12_1X12, + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SBGGR14_1X14, { + .name = "SBGGR14_1X14", + .code = MEDIA_BUS_FMT_SBGGR14_1X14, + .bitsPerPixel = 14, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGBRG14_1X14, { + .name = "SGBRG14_1X14", + .code = MEDIA_BUS_FMT_SGBRG14_1X14, + .bitsPerPixel = 14, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SGRBG14_1X14, { + .name = "SGRBG14_1X14", + .code = MEDIA_BUS_FMT_SGRBG14_1X14, + .bitsPerPixel = 14, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, + { MEDIA_BUS_FMT_SRGGB14_1X14, { + .name = "SRGGB14_1X14", + .code = MEDIA_BUS_FMT_SRGGB14_1X14, + .bitsPerPixel = 14, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, /* \todo Clarify colour encoding for HSV formats */ - { MEDIA_BUS_FMT_AHSV8888_1X32, { 32, "AHSV8888_1X32", PixelFormatInfo::ColourEncodingRGB } }, - { MEDIA_BUS_FMT_JPEG_1X8, { 8, "JPEG_1X8", PixelFormatInfo::ColourEncodingYUV } }, + { MEDIA_BUS_FMT_AHSV8888_1X32, { + .name = "AHSV8888_1X32", + .code = MEDIA_BUS_FMT_AHSV8888_1X32, + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + } }, + { MEDIA_BUS_FMT_JPEG_1X8, { + .name = "JPEG_1X8", + .code = MEDIA_BUS_FMT_JPEG_1X8, + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + } }, }; } /* namespace */ From patchwork Fri Mar 15 00:16:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19722 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 0D138BD160 for ; Fri, 15 Mar 2024 00:16:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8D8CB62C9E; Fri, 15 Mar 2024 01:16:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TdUqXDJM"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EA9F62C94 for ; Fri, 15 Mar 2024 01:16:20 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9BDBF667 for ; Fri, 15 Mar 2024 01:15:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461756; bh=X7huh+woFiV06sZwTs3RKrbSgRRFY5NTwl60CrvcKNs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TdUqXDJM1RpuxEraVxoj/jNYPXd57KWk0vbb+PfDmJOImdc8h81tRhDgPBi6g5VIJ OiUTR980+lssSEOpqWGhA0Kkx9QaIwJXtQrTeagCfg44xekv0yjLPcdGpN1v7gOjv9 Gwnhn9QDO18aU+jyCT/xarTfkMGugwEfCGGZHngY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 03/14] libcamera: v4l2_subdevice: Expose media bus format info as internal API Date: Fri, 15 Mar 2024 02:16:02 +0200 Message-ID: <20240315001613.2033-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The V4L2SubdeviceFormatInfo structure, internal to the v4l2_subdevice.cpp compilation unit, contains information about media bus formats that will be useful in other parts of libcamera. To prepare for this, expose the structure in the v4l2_subdevice.h header and turn it into a class with a similar design as PixelFormatInfo. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- Changes since v1: - Improve MediaBusFormatInfo::code documentation --- include/libcamera/internal/v4l2_subdevice.h | 13 +++ src/libcamera/v4l2_subdevice.cpp | 94 ++++++++++++++------- 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 17db311bcfb3..a4df9ddfd322 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -29,6 +29,19 @@ namespace libcamera { class MediaDevice; +class MediaBusFormatInfo +{ +public: + bool isValid() const { return code != 0; } + + static const MediaBusFormatInfo &info(uint32_t code); + + const char *name; + uint32_t code; + unsigned int bitsPerPixel; + PixelFormatInfo::ColourEncoding colourEncoding; +}; + struct V4L2SubdeviceCapability final : v4l2_subdev_capability { bool isReadOnly() const { diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 1286e7c385c4..4918e28e5f18 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -36,28 +36,40 @@ namespace libcamera { LOG_DECLARE_CATEGORY(V4L2) +/** + * \class MediaBusFormatInfo + * \brief Information about media bus formats + * + * The MediaBusFormatInfo class groups together information describing a media + * bus format. It facilitates handling of media bus formats by providing data + * commonly used in pipeline handlers. + * + * \var MediaBusFormatInfo::name + * \brief The format name as a human-readable string, used as the text + * representation of the format + * + * \var MediaBusFormatInfo::code + * \brief The media bus format code described by this instance (MEDIA_BUS_FMT_*) + * + * \var MediaBusFormatInfo::bitsPerPixel + * \brief The average number of bits per pixel + * + * The number of bits 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 transmit multiple or fractional pixels per sample, the + * value will differ from the bus width. + * + * Formats that don't have a fixed number of bits per pixel, such as compressed + * formats, report 0 in this field. + * + * \var MediaBusFormatInfo::colourEncoding + * \brief The colour encoding type + */ + namespace { -/* - * \struct MediaBusFormatInfo - * \brief Information about media bus formats - * \param name Name of MBUS format - * \param code The media bus format code - * \param bitsPerPixel Bits per pixel - * \param colourEncoding Type of colour encoding - */ -struct MediaBusFormatInfo { - const char *name; - uint32_t code; - unsigned int bitsPerPixel; - PixelFormatInfo::ColourEncoding colourEncoding; -}; - -/* - * \var mediaBusFormatInfo - * \brief A map that associates MediaBusFormatInfo struct to V4L2 media - * bus codes - */ const std::map mediaBusFormatInfo{ /* This table is sorted to match the order in linux/media-bus-format.h */ { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { @@ -557,6 +569,33 @@ const std::map mediaBusFormatInfo{ } /* namespace */ +/** + * \fn bool MediaBusFormatInfo::isValid() const + * \brief Check if the media bus format info is valid + * \return True if the media bus format info is valid, false otherwise + */ + +/** + * \brief Retrieve information about a media bus format + * \param[in] code The media bus format code + * \return The MediaBusFormatInfo describing the \a code if known, or an invalid + * MediaBusFormatInfo otherwise + */ +const MediaBusFormatInfo &MediaBusFormatInfo::info(uint32_t code) +{ + static const MediaBusFormatInfo invalid{}; + + const auto it = mediaBusFormatInfo.find(code); + if (it == mediaBusFormatInfo.end()) { + LOG(V4L2, Warning) + << "Unsupported media bus format " + << utils::hex(code, 4); + return invalid; + } + + return it->second; +} + /** * \struct V4L2SubdeviceCapability * \brief struct v4l2_subdev_capability object wrapper and helpers @@ -653,14 +692,7 @@ const std::string V4L2SubdeviceFormat::toString() const */ uint8_t V4L2SubdeviceFormat::bitsPerPixel() const { - const auto it = mediaBusFormatInfo.find(mbus_code); - if (it == mediaBusFormatInfo.end()) { - LOG(V4L2, Error) << "No information available for format '" - << *this << "'"; - return 0; - } - - return it->second.bitsPerPixel; + return MediaBusFormatInfo::info(mbus_code).bitsPerPixel; } /** @@ -927,9 +959,9 @@ std::optional V4L2Subdevice::toColorSpace(const v4l2_mbus_framefmt & return std::nullopt; PixelFormatInfo::ColourEncoding colourEncoding; - auto iter = mediaBusFormatInfo.find(format.code); - if (iter != mediaBusFormatInfo.end()) { - colourEncoding = iter->second.colourEncoding; + const MediaBusFormatInfo &info = MediaBusFormatInfo::info(format.code); + if (info.isValid()) { + colourEncoding = info.colourEncoding; } else { LOG(V4L2, Warning) << "Unknown subdev format " From patchwork Fri Mar 15 00:16:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19723 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 E258EBD160 for ; Fri, 15 Mar 2024 00:16:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2D94862CA1; Fri, 15 Mar 2024 01:16:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="QW40vPD4"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C7EF462C8C for ; Fri, 15 Mar 2024 01:16:21 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 166F2A9A for ; Fri, 15 Mar 2024 01:15:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461758; bh=Wz+YFZB5rN//JLGNWEd1WiJSeIzLBy8sI5Y5yvF0VHQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=QW40vPD4nN5YOL1joUXtcPrdPojrVLUv4VPT0mo8YHZ+W+StBrw7VlEGM7/2iTsqQ bB61AoDGUpeEgVzI45dp5CvCXSNIJx60tJqn6+4H9yeiRuPAvk7E/9NoI+556zWbrj 1K4Q9FwrwcLjArQVOZ9eBQeT6pVfPOheLrwZMcZQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 04/14] libcamera: v4l2_subdevice: Extend MediaBusFormatInfo with metadata formats Date: Fri, 15 Mar 2024 02:16:03 +0200 Message-ID: <20240315001613.2033-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" Not all media bus formats describe image formats. Extend the MediaBusFormatInfo class with a type member to indicate if the format corresponds to image data or metadata, and add the (only) metatdata format supported by the kernel to the known mediaBusFormatInfo. The kernel doesn't (yet) have any metadata format specific to sensor embedded data. This is being addressed in the V4L2 API. In preparation for embedded data support, already introduce the EmbeddedData type here. Corresponding formats will be added when available. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- Changes since combined RFC: - Rebase on addition oa 14-bit bayer formats --- include/libcamera/internal/v4l2_subdevice.h | 7 ++ src/libcamera/v4l2_subdevice.cpp | 110 +++++++++++++++++++- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index a4df9ddfd322..c9aa90e00ec8 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -32,12 +32,19 @@ class MediaDevice; class MediaBusFormatInfo { public: + enum class Type { + Image, + Metadata, + EmbeddedData, + }; + bool isValid() const { return code != 0; } static const MediaBusFormatInfo &info(uint32_t code); const char *name; uint32_t code; + Type type; unsigned int bitsPerPixel; PixelFormatInfo::ColourEncoding colourEncoding; }; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 4918e28e5f18..a508cef4dcbb 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -51,6 +51,9 @@ LOG_DECLARE_CATEGORY(V4L2) * \var MediaBusFormatInfo::code * \brief The media bus format code described by this instance (MEDIA_BUS_FMT_*) * + * \var MediaBusFormatInfo::type + * \brief The media bus format type + * * \var MediaBusFormatInfo::bitsPerPixel * \brief The average number of bits per pixel * @@ -62,10 +65,26 @@ LOG_DECLARE_CATEGORY(V4L2) * value will differ from the bus width. * * Formats that don't have a fixed number of bits per pixel, such as compressed - * formats, report 0 in this field. + * formats, or device-specific embedded data formats, report 0 in this field. * * \var MediaBusFormatInfo::colourEncoding * \brief The colour encoding type + * + * This field is valid for Type::Image formats only. + */ + +/** + * \enum MediaBusFormatInfo::Type + * \brief The format type + * + * \var MediaBusFormatInfo::Type::Image + * \brief The format describes image data + * + * \var MediaBusFormatInfo::Type::Metadata + * \brief The format describes generic metadata + * + * \var MediaBusFormatInfo::Type::EmbeddedData + * \brief The format describes sensor embedded data */ namespace { @@ -75,480 +94,560 @@ const std::map mediaBusFormatInfo{ { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { .name = "RGB444_2X8_PADHI_BE", .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, { .name = "RGB444_2X8_PADHI_LE", .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, { .name = "RGB555_2X8_PADHI_BE", .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, { .name = "RGB555_2X8_PADHI_LE", .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB565_1X16, { .name = "RGB565_1X16", .code = MEDIA_BUS_FMT_RGB565_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_BGR565_2X8_BE, { .name = "BGR565_2X8_BE", .code = MEDIA_BUS_FMT_BGR565_2X8_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_BGR565_2X8_LE, { .name = "BGR565_2X8_LE", .code = MEDIA_BUS_FMT_BGR565_2X8_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB565_2X8_BE, { .name = "RGB565_2X8_BE", .code = MEDIA_BUS_FMT_RGB565_2X8_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB565_2X8_LE, { .name = "RGB565_2X8_LE", .code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB666_1X18, { .name = "RGB666_1X18", .code = MEDIA_BUS_FMT_RGB666_1X18, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 18, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_BGR888_1X24, { .name = "BGR888_1X24", .code = MEDIA_BUS_FMT_BGR888_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB888_1X24, { .name = "RGB888_1X24", .code = MEDIA_BUS_FMT_RGB888_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB888_2X12_BE, { .name = "RGB888_2X12_BE", .code = MEDIA_BUS_FMT_RGB888_2X12_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_RGB888_2X12_LE, { .name = "RGB888_2X12_LE", .code = MEDIA_BUS_FMT_RGB888_2X12_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_ARGB8888_1X32, { .name = "ARGB8888_1X32", .code = MEDIA_BUS_FMT_ARGB8888_1X32, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_Y8_1X8, { .name = "Y8_1X8", .code = MEDIA_BUS_FMT_Y8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UV8_1X8, { .name = "UV8_1X8", .code = MEDIA_BUS_FMT_UV8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY8_1_5X8, { .name = "UYVY8_1_5X8", .code = MEDIA_BUS_FMT_UYVY8_1_5X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY8_1_5X8, { .name = "VYUY8_1_5X8", .code = MEDIA_BUS_FMT_VYUY8_1_5X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV8_1_5X8, { .name = "YUYV8_1_5X8", .code = MEDIA_BUS_FMT_YUYV8_1_5X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU8_1_5X8, { .name = "YVYU8_1_5X8", .code = MEDIA_BUS_FMT_YVYU8_1_5X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY8_2X8, { .name = "UYVY8_2X8", .code = MEDIA_BUS_FMT_UYVY8_2X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY8_2X8, { .name = "VYUY8_2X8", .code = MEDIA_BUS_FMT_VYUY8_2X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV8_2X8, { .name = "YUYV8_2X8", .code = MEDIA_BUS_FMT_YUYV8_2X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU8_2X8, { .name = "YVYU8_2X8", .code = MEDIA_BUS_FMT_YVYU8_2X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_Y10_1X10, { .name = "Y10_1X10", .code = MEDIA_BUS_FMT_Y10_1X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY10_2X10, { .name = "UYVY10_2X10", .code = MEDIA_BUS_FMT_UYVY10_2X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY10_2X10, { .name = "VYUY10_2X10", .code = MEDIA_BUS_FMT_VYUY10_2X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV10_2X10, { .name = "YUYV10_2X10", .code = MEDIA_BUS_FMT_YUYV10_2X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU10_2X10, { .name = "YVYU10_2X10", .code = MEDIA_BUS_FMT_YVYU10_2X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_Y12_1X12, { .name = "Y12_1X12", .code = MEDIA_BUS_FMT_Y12_1X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_Y16_1X16, { .name = "Y16_1X16", .code = MEDIA_BUS_FMT_Y16_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY8_1X16, { .name = "UYVY8_1X16", .code = MEDIA_BUS_FMT_UYVY8_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY8_1X16, { .name = "VYUY8_1X16", .code = MEDIA_BUS_FMT_VYUY8_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV8_1X16, { .name = "YUYV8_1X16", .code = MEDIA_BUS_FMT_YUYV8_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU8_1X16, { .name = "YVYU8_1X16", .code = MEDIA_BUS_FMT_YVYU8_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YDYUYDYV8_1X16, { .name = "YDYUYDYV8_1X16", .code = MEDIA_BUS_FMT_YDYUYDYV8_1X16, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY10_1X20, { .name = "UYVY10_1X20", .code = MEDIA_BUS_FMT_UYVY10_1X20, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY10_1X20, { .name = "VYUY10_1X20", .code = MEDIA_BUS_FMT_VYUY10_1X20, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV10_1X20, { .name = "YUYV10_1X20", .code = MEDIA_BUS_FMT_YUYV10_1X20, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU10_1X20, { .name = "YVYU10_1X20", .code = MEDIA_BUS_FMT_YVYU10_1X20, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 20, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUV8_1X24, { .name = "YUV8_1X24", .code = MEDIA_BUS_FMT_YUV8_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUV10_1X30, { .name = "YUV10_1X30", .code = MEDIA_BUS_FMT_YUV10_1X30, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 30, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_AYUV8_1X32, { .name = "AYUV8_1X32", .code = MEDIA_BUS_FMT_AYUV8_1X32, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY12_2X12, { .name = "UYVY12_2X12", .code = MEDIA_BUS_FMT_UYVY12_2X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY12_2X12, { .name = "VYUY12_2X12", .code = MEDIA_BUS_FMT_VYUY12_2X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV12_2X12, { .name = "YUYV12_2X12", .code = MEDIA_BUS_FMT_YUYV12_2X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU12_2X12, { .name = "YVYU12_2X12", .code = MEDIA_BUS_FMT_YVYU12_2X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_UYVY12_1X24, { .name = "UYVY12_1X24", .code = MEDIA_BUS_FMT_UYVY12_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_VYUY12_1X24, { .name = "VYUY12_1X24", .code = MEDIA_BUS_FMT_VYUY12_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YUYV12_1X24, { .name = "YUYV12_1X24", .code = MEDIA_BUS_FMT_YUYV12_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_YVYU12_1X24, { .name = "YVYU12_1X24", .code = MEDIA_BUS_FMT_YVYU12_1X24, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, { MEDIA_BUS_FMT_SBGGR8_1X8, { .name = "SBGGR8_1X8", .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGBRG8_1X8, { .name = "SGBRG8_1X8", .code = MEDIA_BUS_FMT_SGBRG8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGRBG8_1X8, { .name = "SGRBG8_1X8", .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SRGGB8_1X8, { .name = "SRGGB8_1X8", .code = MEDIA_BUS_FMT_SRGGB8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, { .name = "SBGGR10_ALAW8_1X8", .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, { .name = "SGBRG10_ALAW8_1X8", .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, { .name = "SGRBG10_ALAW8_1X8", .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, { .name = "SRGGB10_ALAW8_1X8", .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, { .name = "SBGGR10_DPCM8_1X8", .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, { .name = "SGBRG10_DPCM8_1X8", .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, { .name = "SGRBG10_DPCM8_1X8", .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, { .name = "SRGGB10_DPCM8_1X8", .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, { .name = "SBGGR10_2X8_PADHI_BE", .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, { .name = "SBGGR10_2X8_PADHI_LE", .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, { .name = "SBGGR10_2X8_PADLO_BE", .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, { .name = "SBGGR10_2X8_PADLO_LE", .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR10_1X10, { .name = "SBGGR10_1X10", .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGBRG10_1X10, { .name = "SGBRG10_1X10", .code = MEDIA_BUS_FMT_SGBRG10_1X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGRBG10_1X10, { .name = "SGRBG10_1X10", .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SRGGB10_1X10, { .name = "SRGGB10_1X10", .code = MEDIA_BUS_FMT_SRGGB10_1X10, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR12_1X12, { .name = "SBGGR12_1X12", .code = MEDIA_BUS_FMT_SBGGR12_1X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGBRG12_1X12, { .name = "SGBRG12_1X12", .code = MEDIA_BUS_FMT_SGBRG12_1X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGRBG12_1X12, { .name = "SGRBG12_1X12", .code = MEDIA_BUS_FMT_SGRBG12_1X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SRGGB12_1X12, { .name = "SRGGB12_1X12", .code = MEDIA_BUS_FMT_SRGGB12_1X12, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SBGGR14_1X14, { .name = "SBGGR14_1X14", .code = MEDIA_BUS_FMT_SBGGR14_1X14, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 14, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGBRG14_1X14, { .name = "SGBRG14_1X14", .code = MEDIA_BUS_FMT_SGBRG14_1X14, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 14, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SGRBG14_1X14, { .name = "SGRBG14_1X14", .code = MEDIA_BUS_FMT_SGRBG14_1X14, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 14, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, { MEDIA_BUS_FMT_SRGGB14_1X14, { .name = "SRGGB14_1X14", .code = MEDIA_BUS_FMT_SRGGB14_1X14, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 14, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, } }, @@ -556,15 +655,24 @@ const std::map mediaBusFormatInfo{ { MEDIA_BUS_FMT_AHSV8888_1X32, { .name = "AHSV8888_1X32", .code = MEDIA_BUS_FMT_AHSV8888_1X32, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, } }, { MEDIA_BUS_FMT_JPEG_1X8, { .name = "JPEG_1X8", .code = MEDIA_BUS_FMT_JPEG_1X8, + .type = MediaBusFormatInfo::Type::Image, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, } }, + { MEDIA_BUS_FMT_METADATA_FIXED, { + .name = "METADATA_FIXED", + .code = MEDIA_BUS_FMT_METADATA_FIXED, + .type = MediaBusFormatInfo::Type::Metadata, + .bitsPerPixel = 0, + .colourEncoding = PixelFormatInfo::ColourEncodingRAW, + } }, }; } /* namespace */ From patchwork Fri Mar 15 00:16:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19724 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 F409CC3273 for ; Fri, 15 Mar 2024 00:16:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 645AA62C8C; Fri, 15 Mar 2024 01:16:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="beqel/AV"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 295E862C92 for ; Fri, 15 Mar 2024 01:16:23 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 794DB667 for ; Fri, 15 Mar 2024 01:15:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461759; bh=Pg4uQoaMWO2GUzRp2K5pv1SNBn8CsFO3mNw+aOU96RI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=beqel/AV9iGZejITN596hkQy5CuUS0m+Tvm/wwXoarBhdLONerZe9YcS/773JG+Pg r0QPHSmLhbZDSmYktoh3zzyUJggm2pDgWDVzr7Au4u8AytRX1uZXYkCo/vq9x4B1tT 7Ac+ZrAHWY4tmWpn4Sba4bMDFu6r+WfNd1Gn8uTk= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 05/14] libcamera: v4l2_subdevice: Drop V4L2SubdeviceFormat::bitsPerPixel() Date: Fri, 15 Mar 2024 02:16:04 +0200 Message-ID: <20240315001613.2033-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The V4L2SubdeviceFormat::bitsPerPixel() function is just a wrapper around a MediaBusFormatInfo lookup. It made sense when the MediaBusFormatInfo class was not exposed outside of the compilation unit, but is now redundant. Drop it and use MediaBusFormatInfo in the only caller. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/internal/v4l2_subdevice.h | 1 - src/libcamera/camera_sensor.cpp | 3 ++- src/libcamera/v4l2_subdevice.cpp | 10 ---------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index c9aa90e00ec8..a87981341d75 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -66,7 +66,6 @@ struct V4L2SubdeviceFormat { std::optional colorSpace; const std::string toString() const; - uint8_t bitsPerPixel() const; }; std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f); diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 0ef78d9c8b0a..55c9c74b10c2 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -1060,7 +1060,8 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const ret = subdev_->getFormat(pad_, &format); if (ret) return ret; - info->bitsPerPixel = format.bitsPerPixel(); + + info->bitsPerPixel = MediaBusFormatInfo::info(format.mbus_code).bitsPerPixel; info->outputSize = format.size; std::optional cfa = properties_.get(properties::draft::ColorFilterArrangement); diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index a508cef4dcbb..84ec93154951 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -793,16 +793,6 @@ const std::string V4L2SubdeviceFormat::toString() const return ss.str(); } -/** - * \brief Retrieve the number of bits per pixel for the V4L2 subdevice format - * \return The number of bits per pixel for the format, or 0 if the format is - * not supported - */ -uint8_t V4L2SubdeviceFormat::bitsPerPixel() const -{ - return MediaBusFormatInfo::info(mbus_code).bitsPerPixel; -} - /** * \brief Insert a text representation of a V4L2SubdeviceFormat into an output * stream From patchwork Fri Mar 15 00:16:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19725 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 7AF1FBD160 for ; Fri, 15 Mar 2024 00:16:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9DFE362CA1; Fri, 15 Mar 2024 01:16:31 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lyEj3LK8"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 84DD462973 for ; Fri, 15 Mar 2024 01:16:24 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D3DC2667 for ; Fri, 15 Mar 2024 01:16:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461761; bh=qiuU9sxoR9SKxXrHY+Mex/LS89GZLBA4MgKNpcBoGqw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lyEj3LK8e00/LdWhNnTbYjHOyLIPKrf2Nz8ihMkk0kdwy4O2QghkksCdQBBQTHdon Fw1e8IOZtfQeznEnrla206bOXTHm8G3WJf37FVnr8MfV3HuA5LsCwLVoTmJJMeijk9 k2H11ABf8my6Jrj3nY/J6bCC0m6+ta3sP6cHrfYE= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 06/14] libcamera: v4l2_subdevice: Rename V4L2SubdeviceFormat::mbus_code to code Date: Fri, 15 Mar 2024 02:16:05 +0200 Message-ID: <20240315001613.2033-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The V4L2SubdeviceFormat::mbus_code member doesn't follow the libcamera coding style as it should use camelCase. Fix it by renaming it to just 'code', to shorten lines in addition to fixing the coding style. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/internal/v4l2_subdevice.h | 2 +- src/libcamera/camera_sensor.cpp | 8 ++++---- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 10 +++++----- src/libcamera/pipeline/ipu3/cio2.cpp | 8 ++++---- src/libcamera/pipeline/ipu3/imgu.cpp | 4 ++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 2 +- .../pipeline/rpi/common/pipeline_base.cpp | 16 ++++++++-------- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 2 +- src/libcamera/pipeline/simple/simple.cpp | 10 +++++----- src/libcamera/pipeline/vimc/vimc.cpp | 4 ++-- src/libcamera/v4l2_subdevice.cpp | 12 ++++++------ test/camera-sensor.cpp | 2 +- test/v4l2_videodevice/v4l2_videodevice_test.cpp | 2 +- 14 files changed, 42 insertions(+), 42 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index a87981341d75..1115cfa55594 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -61,7 +61,7 @@ struct V4L2SubdeviceCapability final : v4l2_subdev_capability { }; struct V4L2SubdeviceFormat { - uint32_t mbus_code; + uint32_t code; Size size; std::optional colorSpace; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 55c9c74b10c2..af5d97f35de1 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -770,7 +770,7 @@ V4L2SubdeviceFormat CameraSensor::getFormat(const std::vector &mbu } V4L2SubdeviceFormat format{ - .mbus_code = bestCode, + .code = bestCode, .size = *bestSize, .colorSpace = ColorSpace::Raw, }; @@ -892,12 +892,12 @@ int CameraSensor::applyConfiguration(const SensorConfiguration &config, size.height != config.outputSize.height) continue; - subdevFormat.mbus_code = code; + subdevFormat.code = code; subdevFormat.size = size; break; } } - if (!subdevFormat.mbus_code) { + if (!subdevFormat.code) { LOG(CameraSensor, Error) << "Invalid output size in sensor configuration"; return -EINVAL; } @@ -1061,7 +1061,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const if (ret) return ret; - info->bitsPerPixel = MediaBusFormatInfo::info(format.mbus_code).bitsPerPixel; + info->bitsPerPixel = MediaBusFormatInfo::info(format.code).bitsPerPixel; info->outputSize = format.size; std::optional cfa = properties_.get(properties::draft::ColorFilterArrangement); diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index 9bdfff0b155e..a3782aea2ba9 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -554,7 +554,7 @@ CameraConfiguration::Status ISICameraConfiguration::validate() PixelFormat pixelFormat = config_[0].pixelFormat; V4L2SubdeviceFormat sensorFormat{}; - sensorFormat.mbus_code = data_->getMediaBusFormat(&pixelFormat); + sensorFormat.code = data_->getMediaBusFormat(&pixelFormat); sensorFormat.size = maxSize; LOG(ISI, Debug) << "Computed sensor configuration: " << sensorFormat; @@ -569,7 +569,7 @@ CameraConfiguration::Status ISICameraConfiguration::validate() * the smallest larger format without considering the aspect ratio * as the ISI can freely scale. */ - auto sizes = sensor->sizes(sensorFormat.mbus_code); + auto sizes = sensor->sizes(sensorFormat.code); Size bestSize; for (const Size &s : sizes) { @@ -595,7 +595,7 @@ CameraConfiguration::Status ISICameraConfiguration::validate() return Invalid; } - sensorFormat_.mbus_code = sensorFormat.mbus_code; + sensorFormat_.code = sensorFormat.code; sensorFormat_.size = bestSize; LOG(ISI, Debug) << "Selected sensor format: " << sensorFormat_; @@ -632,7 +632,7 @@ StreamConfiguration PipelineHandlerISI::generateYUVConfiguration(Camera *camera, /* Adjust the requested size to the sensor's capabilities. */ V4L2SubdeviceFormat sensorFmt; - sensorFmt.mbus_code = mbusCode; + sensorFmt.code = mbusCode; sensorFmt.size = size; int ret = data->sensor_->tryFormat(&sensorFmt); @@ -891,7 +891,7 @@ int PipelineHandlerISI::configure(Camera *camera, CameraConfiguration *c) unsigned int isiCode = ISICameraConfiguration::formatsMap_.at(config.pixelFormat); V4L2SubdeviceFormat isiFormat{}; - isiFormat.mbus_code = isiCode; + isiFormat.code = isiCode; isiFormat.size = config.size; ret = pipe->isi->setFormat(1, &isiFormat); diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 7400cb0b644c..43c816baf6ef 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -202,7 +202,7 @@ int CIO2Device::configure(const Size &size, const Transform &transform, if (ret) return ret; - const auto &itInfo = mbusCodesToPixelFormat.find(sensorFormat.mbus_code); + const auto &itInfo = mbusCodesToPixelFormat.find(sensorFormat.code); if (itInfo == mbusCodesToPixelFormat.end()) return -EINVAL; @@ -230,13 +230,13 @@ StreamConfiguration CIO2Device::generateConfiguration(Size size) const /* Query the sensor static information for closest match. */ std::vector mbusCodes = utils::map_keys(mbusCodesToPixelFormat); V4L2SubdeviceFormat sensorFormat = getSensorFormat(mbusCodes, size); - if (!sensorFormat.mbus_code) { + if (!sensorFormat.code) { LOG(IPU3, Error) << "Sensor does not support mbus code"; return {}; } cfg.size = sensorFormat.size; - cfg.pixelFormat = mbusCodesToPixelFormat.at(sensorFormat.mbus_code); + cfg.pixelFormat = mbusCodesToPixelFormat.at(sensorFormat.code); cfg.bufferCount = kBufferCount; return cfg; @@ -326,7 +326,7 @@ V4L2SubdeviceFormat CIO2Device::getSensorFormat(const std::vector } V4L2SubdeviceFormat format{}; - format.mbus_code = bestCode; + format.code = bestCode; format.size = bestSize; return format; diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index 531879f18183..2202438a75e0 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -504,7 +504,7 @@ int ImgUDevice::configure(const PipeConfig &pipeConfig, V4L2DeviceFormat *inputF LOG(IPU3, Debug) << "ImgU BDS rectangle = " << bds; V4L2SubdeviceFormat gdcFormat = {}; - gdcFormat.mbus_code = MEDIA_BUS_FMT_FIXED; + gdcFormat.code = MEDIA_BUS_FMT_FIXED; gdcFormat.size = pipeConfig.gdc; ret = imgu_->setFormat(PAD_INPUT, &gdcFormat); @@ -543,7 +543,7 @@ int ImgUDevice::configureVideoDevice(V4L2VideoDevice *dev, unsigned int pad, V4L2DeviceFormat *outputFormat) { V4L2SubdeviceFormat imguFormat = {}; - imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED; + imguFormat.code = MEDIA_BUS_FMT_FIXED; imguFormat.size = cfg.size; int ret = imgu_->setFormat(pad, &imguFormat); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 586b46d64630..abb21968413a 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -761,7 +761,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) /* YUYV8_2X8 is required on the ISP source path pad for YUV output. */ if (!isRaw_) - format.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; + format.code = MEDIA_BUS_FMT_YUYV8_2X8; LOG(RkISP1, Debug) << "Configuring ISP output pad with " << format diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index b62b645cae24..9195aad2cff2 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -365,7 +365,7 @@ int RkISP1Path::configure(const StreamConfiguration &config, * The configuration has been validated, the pixel format is guaranteed * to be supported and thus found in formatToMediaBus. */ - ispFormat.mbus_code = formatToMediaBus.at(config.pixelFormat); + ispFormat.code = formatToMediaBus.at(config.pixelFormat); ret = resizer_->setFormat(1, &ispFormat); if (ret < 0) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index e0bedcd8c664..9449c3dc458c 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -37,10 +37,10 @@ namespace { constexpr unsigned int defaultRawBitDepth = 12; -PixelFormat mbusCodeToPixelFormat(unsigned int mbus_code, +PixelFormat mbusCodeToPixelFormat(unsigned int code, BayerFormat::Packing packingReq) { - BayerFormat bayer = BayerFormat::fromMbusCode(mbus_code); + BayerFormat bayer = BayerFormat::fromMbusCode(code); ASSERT(bayer.isValid()); @@ -221,7 +221,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() * without modifications. */ if (sensorConfig) { - BayerFormat bayer = BayerFormat::fromMbusCode(sensorFormat_.mbus_code); + BayerFormat bayer = BayerFormat::fromMbusCode(sensorFormat_.code); if (bayer.bitDepth != sensorConfig->bitDepth || sensorFormat_.size != sensorConfig->outputSize) { @@ -236,7 +236,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() StreamConfiguration *rawStream = raw.cfg; /* Adjust the RAW stream to match the computed sensor format. */ - BayerFormat sensorBayer = BayerFormat::fromMbusCode(sensorFormat_.mbus_code); + BayerFormat sensorBayer = BayerFormat::fromMbusCode(sensorFormat_.code); /* * Some sensors change their Bayer order when they are h-flipped @@ -377,8 +377,8 @@ V4L2DeviceFormat PipelineHandlerBase::toV4L2DeviceFormat(const V4L2VideoDevice * const V4L2SubdeviceFormat &format, BayerFormat::Packing packingReq) { - unsigned int mbus_code = format.mbus_code; - const PixelFormat pix = mbusCodeToPixelFormat(mbus_code, packingReq); + unsigned int code = format.code; + const PixelFormat pix = mbusCodeToPixelFormat(code, packingReq); V4L2DeviceFormat deviceFormat; deviceFormat.fourcc = dev->toV4L2PixelFormat(pix); @@ -409,7 +409,7 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, SpanfindBestFormat(size, defaultRawBitDepth); - pixelFormat = mbusCodeToPixelFormat(sensorFormat.mbus_code, + pixelFormat = mbusCodeToPixelFormat(sensorFormat.code, BayerFormat::Packing::CSI2); ASSERT(pixelFormat.isValid()); colorSpace = ColorSpace::Raw; @@ -990,7 +990,7 @@ V4L2SubdeviceFormat CameraData::findBestFormat(const Size &req, unsigned int bit if (score <= bestScore) { bestScore = score; - bestFormat.mbus_code = mbusCode; + bestFormat.code = mbusCode; bestFormat.size = size; } diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 6b6ecd3ded7d..ad7dddde59f1 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -426,7 +426,7 @@ CameraConfiguration::Status Vc4CameraData::platformValidate(RPi::RPiCameraConfig BayerFormat rawBayer = BayerFormat::fromPixelFormat(rawStream->pixelFormat); /* Apply the sensor bitdepth. */ - rawBayer.bitDepth = BayerFormat::fromMbusCode(rpiConfig->sensorFormat_.mbus_code).bitDepth; + rawBayer.bitDepth = BayerFormat::fromMbusCode(rpiConfig->sensorFormat_.code).bitDepth; /* Default to CSI2 packing if the user request is unsupported. */ if (rawBayer.packing != BayerFormat::Packing::CSI2 && diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index e37b0d1c393f..3d0424969a89 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -563,13 +563,13 @@ void SimpleCameraData::tryPipeline(unsigned int code, const Size &size) * corresponding possible V4L2 pixel formats on the video node. */ V4L2SubdeviceFormat format{}; - format.mbus_code = code; + format.code = code; format.size = size; int ret = setupFormats(&format, V4L2Subdevice::TryFormat); if (ret < 0) { /* Pipeline configuration failed, skip this configuration. */ - format.mbus_code = code; + format.code = code; format.size = size; LOG(SimplePipeline, Debug) << "Sensor format " << format @@ -577,7 +577,7 @@ void SimpleCameraData::tryPipeline(unsigned int code, const Size &size) return; } - V4L2VideoDevice::Formats videoFormats = video_->formats(format.mbus_code); + V4L2VideoDevice::Formats videoFormats = video_->formats(format.code); LOG(SimplePipeline, Debug) << "Adding configuration for " << format.size @@ -707,7 +707,7 @@ int SimpleCameraData::setupFormats(V4L2SubdeviceFormat *format, if (ret < 0) return ret; - if (format->mbus_code != sourceFormat.mbus_code || + if (format->code != sourceFormat.code || format->size != sourceFormat.size) { LOG(SimplePipeline, Debug) << "Source '" << source->entity()->name() @@ -1121,7 +1121,7 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) const SimpleCameraData::Configuration *pipeConfig = config->pipeConfig(); V4L2SubdeviceFormat format{}; - format.mbus_code = pipeConfig->code; + format.code = pipeConfig->code; format.size = pipeConfig->sensorSize; ret = data->setupFormats(&format, V4L2Subdevice::ActiveFormat, diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 5536941ac0d5..5e66ee1d26c1 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -244,7 +244,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) /* The scaler hardcodes a x3 scale-up ratio. */ V4L2SubdeviceFormat subformat = {}; - subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8; + subformat.code = MEDIA_BUS_FMT_SGRBG8_1X8; subformat.size = { cfg.size.width / 3, cfg.size.height / 3 }; ret = data->sensor_->setFormat(&subformat); @@ -255,7 +255,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) if (ret) return ret; - subformat.mbus_code = pixelformats.find(cfg.pixelFormat)->second; + subformat.code = pixelformats.find(cfg.pixelFormat)->second; ret = data->debayer_->setFormat(1, &subformat); if (ret) return ret; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 84ec93154951..66da1edbf542 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -757,7 +757,7 @@ const MediaBusFormatInfo &MediaBusFormatInfo::info(uint32_t code) */ /** - * \var V4L2SubdeviceFormat::mbus_code + * \var V4L2SubdeviceFormat::code * \brief The image format bus code */ @@ -804,10 +804,10 @@ std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f) { out << f.size << "-"; - const auto it = mediaBusFormatInfo.find(f.mbus_code); + const auto it = mediaBusFormatInfo.find(f.code); if (it == mediaBusFormatInfo.end()) - out << utils::hex(f.mbus_code, 4); + out << utils::hex(f.code, 4); else out << it->second.name; @@ -1097,7 +1097,7 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; - format->mbus_code = subdevFmt.format.code; + format->code = subdevFmt.format.code; format->colorSpace = toColorSpace(subdevFmt.format); return 0; @@ -1123,7 +1123,7 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, subdevFmt.pad = pad; subdevFmt.format.width = format->size.width; subdevFmt.format.height = format->size.height; - subdevFmt.format.code = format->mbus_code; + subdevFmt.format.code = format->code; subdevFmt.format.field = V4L2_FIELD_NONE; if (format->colorSpace) { fromColorSpace(format->colorSpace, subdevFmt.format); @@ -1143,7 +1143,7 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; - format->mbus_code = subdevFmt.format.code; + format->code = subdevFmt.format.code; format->colorSpace = toColorSpace(subdevFmt.format); return 0; diff --git a/test/camera-sensor.cpp b/test/camera-sensor.cpp index 2a17cc79ea76..9503d7753fb9 100644 --- a/test/camera-sensor.cpp +++ b/test/camera-sensor.cpp @@ -100,7 +100,7 @@ protected: MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_BGR888_1X24 }, Size(1024, 768)); - if (format.mbus_code != MEDIA_BUS_FMT_SBGGR10_1X10 || + if (format.code != MEDIA_BUS_FMT_SBGGR10_1X10 || format.size != Size(4096, 2160)) { cerr << "Failed to get a suitable format, expected 4096x2160-0x" << utils::hex(MEDIA_BUS_FMT_SBGGR10_1X10) diff --git a/test/v4l2_videodevice/v4l2_videodevice_test.cpp b/test/v4l2_videodevice/v4l2_videodevice_test.cpp index 125aafd65041..1113cf5bf8cf 100644 --- a/test/v4l2_videodevice/v4l2_videodevice_test.cpp +++ b/test/v4l2_videodevice/v4l2_videodevice_test.cpp @@ -75,7 +75,7 @@ int V4L2VideoDeviceTest::init() format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8); V4L2SubdeviceFormat subformat = {}; - subformat.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8; + subformat.code = MEDIA_BUS_FMT_SBGGR8_1X8; subformat.size = format.size; if (sensor_->setFormat(&subformat)) From patchwork Fri Mar 15 00:16:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19726 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 20FEFC3273 for ; Fri, 15 Mar 2024 00:16:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A0FA962CA8; Fri, 15 Mar 2024 01:16:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ocGps1D8"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3098562C8F for ; Fri, 15 Mar 2024 01:16:26 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 706F6A9A for ; Fri, 15 Mar 2024 01:16:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461762; bh=kxUI0S3ZMKw94ficFFWV0BmYIt3rsPshVpVXItN6sdU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ocGps1D8a/OJjWoiOj6EcFLAgPNnRO9NuQsXHBZZUul0uk6OxNimbwoFSuw0AxBgD KGBi+OSSZ4MykbMnQy7t4q9x0sbfD47xMzEw9lSNC/IbKGLFmkzxMYgkU5+OoJ42cU S5hRw47eYAm5p0RDR0ZzuoY1Zeb7MqwV1dNL0YqY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 07/14] libcamera: v4l2_subdevice: Add stream support to get/set functions Date: Fri, 15 Mar 2024 02:16:06 +0200 Message-ID: <20240315001613.2033-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" Extend the V4L2Subdevice API with stream support for the functions that get and set formats and selection rectangles. Add a Stream structure to identify a subdev pad and stream, and use it to extend the V4L2Subdevice functions that get and set formats and selection rectangles with stream support. To preserve the existing pad-based API, implement overloaded functions that wrap the new stream-based API. This allows callers that are not stream-aware to use a simpler pad-based API, instead of having to explicitly set the stream number to 0 in all API calls. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- Changes since combined RFC: - Fix indentation in comments - Use operator<<(Stream) everywhere Changes since v1: - Drop incorrect comment change - Use operator<<(Stream) - Add comparison operators --- include/libcamera/internal/v4l2_subdevice.h | 58 ++++- src/libcamera/v4l2_subdevice.cpp | 248 +++++++++++++++----- 2 files changed, 238 insertions(+), 68 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 1115cfa55594..6cd36730371a 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -80,6 +80,21 @@ public: ActiveFormat = V4L2_SUBDEV_FORMAT_ACTIVE, }; + struct Stream { + Stream() + : pad(0), stream(0) + { + } + + Stream(unsigned int p, unsigned int s) + : pad(p), stream(s) + { + } + + unsigned int pad; + unsigned int stream; + }; + class Routing : public std::vector { public: @@ -93,17 +108,39 @@ public: const MediaEntity *entity() const { return entity_; } - int getSelection(unsigned int pad, unsigned int target, + int getSelection(const Stream &stream, unsigned int target, Rectangle *rect); - int setSelection(unsigned int pad, unsigned int target, + int getSelection(unsigned int pad, unsigned int target, Rectangle *rect) + { + return getSelection({ pad, 0 }, target, rect); + } + int setSelection(const Stream &stream, unsigned int target, Rectangle *rect); + int setSelection(unsigned int pad, unsigned int target, Rectangle *rect) + { + return setSelection({ pad, 0 }, target, rect); + } - Formats formats(unsigned int pad); + Formats formats(const Stream &stream); + Formats formats(unsigned int pad) + { + return formats({ pad, 0 }); + } + int getFormat(const Stream &stream, V4L2SubdeviceFormat *format, + Whence whence = ActiveFormat); int getFormat(unsigned int pad, V4L2SubdeviceFormat *format, + Whence whence = ActiveFormat) + { + return getFormat({ pad, 0 }, format, whence); + } + int setFormat(const Stream &stream, V4L2SubdeviceFormat *format, Whence whence = ActiveFormat); int setFormat(unsigned int pad, V4L2SubdeviceFormat *format, - Whence whence = ActiveFormat); + Whence whence = ActiveFormat) + { + return setFormat({ pad, 0 }, format, whence); + } int getRouting(Routing *routing, Whence whence = ActiveFormat); int setRouting(Routing *routing, Whence whence = ActiveFormat); @@ -123,8 +160,8 @@ private: std::optional toColorSpace(const v4l2_mbus_framefmt &format) const; - std::vector enumPadCodes(unsigned int pad); - std::vector enumPadSizes(unsigned int pad, + std::vector enumPadCodes(const Stream &stream); + std::vector enumPadSizes(const Stream &stream, unsigned int code); const MediaEntity *entity_; @@ -133,4 +170,13 @@ private: struct V4L2SubdeviceCapability caps_; }; +bool operator==(const V4L2Subdevice::Stream &lhs, const V4L2Subdevice::Stream &rhs); +static inline bool operator!=(const V4L2Subdevice::Stream &lhs, + const V4L2Subdevice::Stream &rhs) +{ + return !(lhs == rhs); +} + +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream); + } /* namespace libcamera */ diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 66da1edbf542..cc079425bb16 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -842,6 +842,62 @@ std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f) * \brief The format operation applies to TRY formats */ +/** + * \class V4L2Subdevice::Stream + * \brief V4L2 subdevice stream + * + * This class identifies a subdev stream, by bundling the pad number with the + * stream number. It is used in all stream-aware functions of the V4L2Subdevice + * class to identify the stream the functions operate on. + * + * \var V4L2Subdevice::Stream::pad + * \brief The 0-indexed pad number + * + * \var V4L2Subdevice::Stream::stream + * \brief The stream number + */ + +/** + * \fn V4L2Subdevice::Stream::Stream() + * \brief Construct a Stream with pad and stream set to 0 + */ + +/** + * \fn V4L2Subdevice::Stream::Stream(unsigned int pad, unsigned int stream) + * \brief Construct a Stream with a given \a pad and \a stream number + * \param[in] pad The indexed pad number + * \param[in] stream The stream number + */ + +/** + * \brief Compare streams for equality + * \return True if the two streams are equal, false otherwise + */ +bool operator==(const V4L2Subdevice::Stream &lhs, const V4L2Subdevice::Stream &rhs) +{ + return lhs.pad == rhs.pad && lhs.stream == rhs.stream; +} + +/** + * \fn bool operator!=(const V4L2Subdevice::Stream &lhs, const V4L2Subdevice::Stream &rhs) + * \brief Compare streams for inequality + * \return True if the two streams are not equal, false otherwise + */ + +/** + * \brief Insert a text representation of a V4L2Subdevice::Stream into an + * output stream + * \param[in] out The output stream + * \param[in] stream The V4L2Subdevice::Stream + * \return The output stream \a out + */ +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream) +{ + out << stream.pad << "/" << stream.stream; + + return out; +} + /** * \class V4L2Subdevice::Routing * \brief V4L2 subdevice routing table @@ -933,7 +989,7 @@ int V4L2Subdevice::open() /** * \brief Get selection rectangle \a rect for \a target - * \param[in] pad The 0-indexed pad number the rectangle is retrieved from + * \param[in] stream The stream the rectangle is retrieved from * \param[in] target The selection target defined by the V4L2_SEL_TGT_* flags * \param[out] rect The retrieved selection rectangle * @@ -941,13 +997,14 @@ int V4L2Subdevice::open() * * \return 0 on success or a negative error code otherwise */ -int V4L2Subdevice::getSelection(unsigned int pad, unsigned int target, +int V4L2Subdevice::getSelection(const Stream &stream, unsigned int target, Rectangle *rect) { struct v4l2_subdev_selection sel = {}; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; - sel.pad = pad; + sel.pad = stream.pad; + sel.stream = stream.stream; sel.target = target; sel.flags = 0; @@ -955,7 +1012,7 @@ int V4L2Subdevice::getSelection(unsigned int pad, unsigned int target, if (ret < 0) { LOG(V4L2, Error) << "Unable to get rectangle " << target << " on pad " - << pad << ": " << strerror(-ret); + << stream << ": " << strerror(-ret); return ret; } @@ -967,9 +1024,20 @@ int V4L2Subdevice::getSelection(unsigned int pad, unsigned int target, return 0; } +/** + * \fn V4L2Subdevice::getSelection(unsigned int pad, unsigned int target, + * Rectangle *rect) + * \brief Get selection rectangle \a rect for \a target + * \param[in] pad The 0-indexed pad number the rectangle is retrieved from + * \param[in] target The selection target defined by the V4L2_SEL_TGT_* flags + * \param[out] rect The retrieved selection rectangle + * + * \return 0 on success or a negative error code otherwise + */ + /** * \brief Set selection rectangle \a rect for \a target - * \param[in] pad The 0-indexed pad number the rectangle is to be applied to + * \param[in] stream The stream the rectangle is to be applied to * \param[in] target The selection target defined by the V4L2_SEL_TGT_* flags * \param[inout] rect The selection rectangle to be applied * @@ -977,13 +1045,14 @@ int V4L2Subdevice::getSelection(unsigned int pad, unsigned int target, * * \return 0 on success or a negative error code otherwise */ -int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, +int V4L2Subdevice::setSelection(const Stream &stream, unsigned int target, Rectangle *rect) { struct v4l2_subdev_selection sel = {}; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; - sel.pad = pad; + sel.pad = stream.pad; + sel.stream = stream.stream; sel.target = target; sel.flags = 0; @@ -996,7 +1065,7 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, if (ret < 0) { LOG(V4L2, Error) << "Unable to set rectangle " << target << " on pad " - << pad << ": " << strerror(-ret); + << stream << ": " << strerror(-ret); return ret; } @@ -1007,26 +1076,40 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, return 0; } + /** - * \brief Enumerate all media bus codes and frame sizes on a \a pad - * \param[in] pad The 0-indexed pad number to enumerate formats on + * \fn V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, + * Rectangle *rect) + * \brief Set selection rectangle \a rect for \a target + * \param[in] pad The 0-indexed pad number the rectangle is to be applied to + * \param[in] target The selection target defined by the V4L2_SEL_TGT_* flags + * \param[inout] rect The selection rectangle to be applied + * + * \todo Define a V4L2SelectionTarget enum for the selection target + * + * \return 0 on success or a negative error code otherwise + */ + +/** + * \brief Enumerate all media bus codes and frame sizes on a \a stream + * \param[in] stream The stream to enumerate formats for * * Enumerate all media bus codes and frame sizes supported by the subdevice on - * a \a pad. + * a \a stream. * * \return A list of the supported device formats */ -V4L2Subdevice::Formats V4L2Subdevice::formats(unsigned int pad) +V4L2Subdevice::Formats V4L2Subdevice::formats(const Stream &stream) { Formats formats; - if (pad >= entity_->pads().size()) { - LOG(V4L2, Error) << "Invalid pad: " << pad; + if (stream.pad >= entity_->pads().size()) { + LOG(V4L2, Error) << "Invalid pad: " << stream.pad; return {}; } - for (unsigned int code : enumPadCodes(pad)) { - std::vector sizes = enumPadSizes(pad, code); + for (unsigned int code : enumPadCodes(stream)) { + std::vector sizes = enumPadSizes(stream, code); if (sizes.empty()) return {}; @@ -1034,7 +1117,7 @@ V4L2Subdevice::Formats V4L2Subdevice::formats(unsigned int pad) if (!inserted.second) { LOG(V4L2, Error) << "Could not add sizes for media bus code " - << code << " on pad " << pad; + << code << " on pad " << stream.pad; return {}; } } @@ -1042,6 +1125,17 @@ V4L2Subdevice::Formats V4L2Subdevice::formats(unsigned int pad) return formats; } +/** + * \fn V4L2Subdevice::formats(unsigned int pad) + * \brief Enumerate all media bus codes and frame sizes on a \a pad + * \param[in] pad The 0-indexed pad number to enumerate formats on + * + * Enumerate all media bus codes and frame sizes supported by the subdevice on + * a \a pad + * + * \return A list of the supported device formats + */ + std::optional V4L2Subdevice::toColorSpace(const v4l2_mbus_framefmt &format) const { /* @@ -1073,25 +1167,26 @@ std::optional V4L2Subdevice::toColorSpace(const v4l2_mbus_framefmt & } /** - * \brief Retrieve the image format set on one of the V4L2 subdevice pads - * \param[in] pad The 0-indexed pad number the format is to be retrieved from + * \brief Retrieve the image format set on one of the V4L2 subdevice streams + * \param[in] stream The stream the format is to be retrieved from * \param[out] format The image bus format * \param[in] whence The format to get, \ref V4L2Subdevice::ActiveFormat * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" * \return 0 on success or a negative error code otherwise */ -int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, +int V4L2Subdevice::getFormat(const Stream &stream, V4L2SubdeviceFormat *format, Whence whence) { struct v4l2_subdev_format subdevFmt = {}; subdevFmt.which = whence; - subdevFmt.pad = pad; + subdevFmt.pad = stream.pad; + subdevFmt.stream = stream.stream; int ret = ioctl(VIDIOC_SUBDEV_G_FMT, &subdevFmt); if (ret) { LOG(V4L2, Error) - << "Unable to get format on pad " << pad - << ": " << strerror(-ret); + << "Unable to get format on pad " << stream << ": " + << strerror(-ret); return ret; } @@ -1104,6 +1199,66 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, } /** + * \fn V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, + * Whence whence) + * \brief Retrieve the image format set on one of the V4L2 subdevice pads + * \param[in] pad The 0-indexed pad number the format is to be retrieved from + * \param[out] format The image bus format + * \param[in] whence The format to get, \ref V4L2Subdevice::ActiveFormat + * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" + * \return 0 on success or a negative error code otherwise + */ + +/** + * \brief Set an image format on one of the V4L2 subdevice pads + * \param[in] stream The stream the format is to be applied to + * \param[inout] format The image bus format to apply to the stream + * \param[in] whence The format to set, \ref V4L2Subdevice::ActiveFormat + * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" + * + * Apply the requested image format to the desired stream and return the + * actually applied format parameters, as getFormat() would do. + * + * \return 0 on success or a negative error code otherwise + */ +int V4L2Subdevice::setFormat(const Stream &stream, V4L2SubdeviceFormat *format, + Whence whence) +{ + struct v4l2_subdev_format subdevFmt = {}; + subdevFmt.which = whence; + subdevFmt.pad = stream.pad; + subdevFmt.stream = stream.stream; + subdevFmt.format.width = format->size.width; + subdevFmt.format.height = format->size.height; + subdevFmt.format.code = format->code; + subdevFmt.format.field = V4L2_FIELD_NONE; + if (format->colorSpace) { + fromColorSpace(format->colorSpace, subdevFmt.format); + + /* The CSC flag is only applicable to source pads. */ + if (entity_->pads()[stream.pad]->flags() & MEDIA_PAD_FL_SOURCE) + subdevFmt.format.flags |= V4L2_MBUS_FRAMEFMT_SET_CSC; + } + + int ret = ioctl(VIDIOC_SUBDEV_S_FMT, &subdevFmt); + if (ret) { + LOG(V4L2, Error) + << "Unable to set format on pad " << stream << ": " + << strerror(-ret); + return ret; + } + + format->size.width = subdevFmt.format.width; + format->size.height = subdevFmt.format.height; + format->code = subdevFmt.format.code; + format->colorSpace = toColorSpace(subdevFmt.format); + + return 0; +} + +/** + * \fn V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, + * Whence whence) * \brief Set an image format on one of the V4L2 subdevice pads * \param[in] pad The 0-indexed pad number the format is to be applied to * \param[inout] format The image bus format to apply to the subdevice's pad @@ -1115,39 +1270,6 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format, * * \return 0 on success or a negative error code otherwise */ -int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, - Whence whence) -{ - struct v4l2_subdev_format subdevFmt = {}; - subdevFmt.which = whence; - subdevFmt.pad = pad; - subdevFmt.format.width = format->size.width; - subdevFmt.format.height = format->size.height; - subdevFmt.format.code = format->code; - subdevFmt.format.field = V4L2_FIELD_NONE; - if (format->colorSpace) { - fromColorSpace(format->colorSpace, subdevFmt.format); - - /* The CSC flag is only applicable to source pads. */ - if (entity_->pads()[pad]->flags() & MEDIA_PAD_FL_SOURCE) - subdevFmt.format.flags |= V4L2_MBUS_FRAMEFMT_SET_CSC; - } - - int ret = ioctl(VIDIOC_SUBDEV_S_FMT, &subdevFmt); - if (ret) { - LOG(V4L2, Error) - << "Unable to set format on pad " << pad - << ": " << strerror(-ret); - return ret; - } - - format->size.width = subdevFmt.format.width; - format->size.height = subdevFmt.format.height; - format->code = subdevFmt.format.code; - format->colorSpace = toColorSpace(subdevFmt.format); - - return 0; -} /** * \brief Retrieve the subdevice's internal routing table @@ -1310,14 +1432,15 @@ std::string V4L2Subdevice::logPrefix() const return "'" + entity_->name() + "'"; } -std::vector V4L2Subdevice::enumPadCodes(unsigned int pad) +std::vector V4L2Subdevice::enumPadCodes(const Stream &stream) { std::vector codes; int ret; for (unsigned int index = 0; ; index++) { struct v4l2_subdev_mbus_code_enum mbusEnum = {}; - mbusEnum.pad = pad; + mbusEnum.pad = stream.pad; + mbusEnum.stream = stream.stream; mbusEnum.index = index; mbusEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; @@ -1330,7 +1453,7 @@ std::vector V4L2Subdevice::enumPadCodes(unsigned int pad) if (ret < 0 && ret != -EINVAL) { LOG(V4L2, Error) - << "Unable to enumerate formats on pad " << pad + << "Unable to enumerate formats on pad " << stream << ": " << strerror(-ret); return {}; } @@ -1338,7 +1461,7 @@ std::vector V4L2Subdevice::enumPadCodes(unsigned int pad) return codes; } -std::vector V4L2Subdevice::enumPadSizes(unsigned int pad, +std::vector V4L2Subdevice::enumPadSizes(const Stream &stream, unsigned int code) { std::vector sizes; @@ -1347,7 +1470,8 @@ std::vector V4L2Subdevice::enumPadSizes(unsigned int pad, for (unsigned int index = 0;; index++) { struct v4l2_subdev_frame_size_enum sizeEnum = {}; sizeEnum.index = index; - sizeEnum.pad = pad; + sizeEnum.pad = stream.pad; + sizeEnum.stream = stream.stream; sizeEnum.code = code; sizeEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; @@ -1361,7 +1485,7 @@ std::vector V4L2Subdevice::enumPadSizes(unsigned int pad, if (ret < 0 && ret != -EINVAL && ret != -ENOTTY) { LOG(V4L2, Error) - << "Unable to enumerate sizes on pad " << pad + << "Unable to enumerate sizes on pad " << stream << ": " << strerror(-ret); return {}; } From patchwork Fri Mar 15 00:16:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19727 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 6610DBD160 for ; Fri, 15 Mar 2024 00:16:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F30FF62CAF; Fri, 15 Mar 2024 01:16:37 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SEtkEtYG"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C86AB62CA0 for ; Fri, 15 Mar 2024 01:16:27 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 051C0A9A for ; Fri, 15 Mar 2024 01:16:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461764; bh=CkwfBp+j3AvDekhK2aokSGskC6v0a7ndLCQggLj7LiQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=SEtkEtYGay2GSMNaxXc6j6cMwmH7sJj8SmOUSHvBRmjkO0P7kqbbAEGAHeRVcnVI+ tcswEga+tyg08Mu6SqfuUb5ofmzlpTflI3vC2F43thpjBWh7FTrO2jDWcvm2xe3xe8 offrnaL1tGd2Tahbb4XyKQHH92BtHrosUX1glA8s= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 08/14] libcamera: v4l2_subdevice: Replace Routing::toString() with operator<<() Date: Fri, 15 Mar 2024 02:16:07 +0200 Message-ID: <20240315001613.2033-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The main (and only at the moment) use case for the Routing::toString() function is to print a representation of the routing table in a log message. The function is implemented using an std::stringstream, and the returned std::string is then inserted into an std::ostream. This is inefficient. Replace the function with a specialization of the operator<<() and use it in the caller. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/internal/v4l2_subdevice.h | 7 ++--- src/libcamera/pipeline/simple/simple.cpp | 2 +- src/libcamera/v4l2_subdevice.cpp | 29 +++++++++++---------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 6cd36730371a..2939dc2411c6 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -95,11 +95,7 @@ public: unsigned int stream; }; - class Routing : public std::vector - { - public: - std::string toString() const; - }; + using Routing = std::vector; explicit V4L2Subdevice(const MediaEntity *entity); ~V4L2Subdevice(); @@ -178,5 +174,6 @@ static inline bool operator!=(const V4L2Subdevice::Stream &lhs, } std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream); +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Routing &routing); } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 3d0424969a89..feea26fd124f 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1388,7 +1388,7 @@ int SimplePipelineHandler::resetRoutingTable(V4L2Subdevice *subdev) LOG(SimplePipeline, Debug) << "Routing table of " << subdev->deviceNode() - << " reset to " << routing.toString(); + << " reset to " << routing; return 0; } diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index cc079425bb16..deef681e0d3a 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -899,30 +899,31 @@ std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream) } /** - * \class V4L2Subdevice::Routing + * \typedef V4L2Subdevice::Routing * \brief V4L2 subdevice routing table * * This class stores a subdevice routing table as a vector of routes. */ /** - * \brief Assemble and return a string describing the routing table - * \return A string describing the routing table + * \brief Insert a text representation of a V4L2Subdevice::Routing into an + * output stream + * \param[in] out The output stream + * \param[in] routing The V4L2Subdevice::Routing + * \return The output stream \a out */ -std::string V4L2Subdevice::Routing::toString() const +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Routing &routing) { - std::stringstream routing; - - for (const auto &[i, route] : utils::enumerate(*this)) { - routing << "[" << i << "] " - << route.sink_pad << "/" << route.sink_stream << " -> " - << route.source_pad << "/" << route.source_stream - << " (" << utils::hex(route.flags) << ")"; - if (i != size() - 1) - routing << ", "; + for (const auto &[i, route] : utils::enumerate(routing)) { + out << "[" << i << "] " + << route.sink_pad << "/" << route.sink_stream << " -> " + << route.source_pad << "/" << route.source_stream + << " (" << utils::hex(route.flags) << ")"; + if (i != routing.size() - 1) + out << ", "; } - return routing.str(); + return out; } /** From patchwork Fri Mar 15 00:16:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19728 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 8E017BD808 for ; Fri, 15 Mar 2024 00:16:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D634162CAE; Fri, 15 Mar 2024 01:16:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JeIAtNl5"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 450A362C93 for ; Fri, 15 Mar 2024 01:16:29 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 909B4A9A for ; Fri, 15 Mar 2024 01:16:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461765; bh=GqtDp/jzJkaFBfGx4Qgz8/jXuDT4suXoHYmy2+893xQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=JeIAtNl5z2lH7o0ARzHwaKwx8iIXzMjV55uLYaerdow0oUZ/VveSid/ngJMgFEmaU 4imxjdOdrTTmZnbIfnsbdJR4no5Erdbdn45G8ssXF4JdCkOYjuGIFB2dplxjotQhDf bvw6cOA9TahWX++AalFRaV1QlS7IO5bgTSr3D59Y= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 09/14] libcamera: v4l2_subdevice: Add V4L2Subdevice::Route structure Date: Fri, 15 Mar 2024 02:16:08 +0200 Message-ID: <20240315001613.2033-10-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The V4L2Subdevice class deals with streams in two places: - In routing tables, streams as expressed as a pad number and a stream number in a v4l2_subdev_route instance. - In the format and selection get and set functions, streams as expressed using the Stream structure, which binds the pad number and stream number. Expressing streams in different ways requires pipeline handlers and other helpers to convert between the two representations. This isn't much of an issue yet as libcamera has little stream-aware code, but it is expected to increasingly become a burden. To simplify the API, introduce a V4L2Subdevice::Route structure that mimicks the kernel v4l2_subdev_route structure but represents streams as V4L2Subdevice::Stream instances. This will improve seamless integration of routes, formats and selection rectangles. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- Changes since combined RFC: - Fix compilation in imx8-isi pipeline handler - Fix indentation in comments Changes since v1: - Clear routing at the beginning of getRouting() and setRouting() --- include/libcamera/internal/v4l2_subdevice.h | 19 +++- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 14 +-- src/libcamera/pipeline/simple/simple.cpp | 8 +- src/libcamera/v4l2_subdevice.cpp | 108 +++++++++++++++++-- 4 files changed, 123 insertions(+), 26 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 2939dc2411c6..01ed4c2fc397 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -95,7 +95,23 @@ public: unsigned int stream; }; - using Routing = std::vector; + struct Route { + Route() + : flags(0) + { + } + + Route(const Stream &snk, const Stream &src, uint32_t f) + : sink(snk), source(src), flags(f) + { + } + + Stream sink; + Stream source; + uint32_t flags; + }; + + using Routing = std::vector; explicit V4L2Subdevice(const MediaEntity *entity); ~V4L2Subdevice(); @@ -174,6 +190,7 @@ static inline bool operator!=(const V4L2Subdevice::Stream &lhs, } std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream); +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Route &route); std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Routing &routing); } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index a3782aea2ba9..63082cea7e56 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -827,16 +827,10 @@ int PipelineHandlerISI::configure(Camera *camera, CameraConfiguration *c) unsigned int xbarFirstSource = crossbar_->entity()->pads().size() / 2 + 1; for (const auto &[idx, config] : utils::enumerate(*c)) { - struct v4l2_subdev_route route = { - .sink_pad = data->xbarSink_, - .sink_stream = 0, - .source_pad = static_cast(xbarFirstSource + idx), - .source_stream = 0, - .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, - .reserved = {} - }; - - routing.push_back(route); + uint32_t sourcePad = xbarFirstSource + idx; + routing.emplace_back(V4L2Subdevice::Stream{ data->xbarSink_, 0 }, + V4L2Subdevice::Stream{ sourcePad, 0 }, + V4L2_SUBDEV_ROUTE_FL_ACTIVE); } int ret = crossbar_->setRouting(&routing, V4L2Subdevice::ActiveFormat); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index feea26fd124f..01f2a97798ba 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -852,17 +852,17 @@ std::vector SimpleCameraData::routedSourcePads(MediaPad *sink) std::vector pads; - for (const struct v4l2_subdev_route &route : routing) { - if (sink->index() != route.sink_pad || + for (const V4L2Subdevice::Route &route : routing) { + if (sink->index() != route.sink.pad || !(route.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) continue; - const MediaPad *pad = entity->getPadByIndex(route.source_pad); + const MediaPad *pad = entity->getPadByIndex(route.source.pad); if (!pad) { LOG(SimplePipeline, Warning) << "Entity " << entity->name() << " has invalid route source pad " - << route.source_pad; + << route.source.pad; } pads.push_back(pad); diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index deef681e0d3a..1076b7006b0b 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -898,6 +898,53 @@ std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream) return out; } +/** + * \class V4L2Subdevice::Route + * \brief V4L2 subdevice routing table entry + * + * This class models a route in the subdevice routing table. It is similar to + * the v4l2_subdev_route structure, but uses the V4L2Subdevice::Stream class + * for easier usage with the V4L2Subdevice stream-aware functions. + * + * \var V4L2Subdevice::Route::sink + * \brief The sink stream of the route + * + * \var V4L2Subdevice::Route::source + * \brief The source stream of the route + * + * \var V4L2Subdevice::Route::flags + * \brief The route flags (V4L2_SUBDEV_ROUTE_FL_*) + */ + +/** + * \fn V4L2Subdevice::Route::Route() + * \brief Construct a Route with default streams + */ + +/** + * \fn V4L2Subdevice::Route::Route(const Stream &sink, const Stream &source, + * uint32_t flags) + * \brief Construct a Route from \a sink to \a source + * \param[in] sink The sink stream + * \param[in] source The source stream + * \param[in] flags The route flags + */ + +/** + * \brief Insert a text representation of a V4L2Subdevice::Route into an + * output stream + * \param[in] out The output stream + * \param[in] route The V4L2Subdevice::Route + * \return The output stream \a out + */ +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Route &route) +{ + out << route.sink << " -> " << route.source + << " (" << utils::hex(route.flags) << ")"; + + return out; +} + /** * \typedef V4L2Subdevice::Routing * \brief V4L2 subdevice routing table @@ -907,7 +954,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream) /** * \brief Insert a text representation of a V4L2Subdevice::Routing into an - * output stream + * output stream * \param[in] out The output stream * \param[in] routing The V4L2Subdevice::Routing * \return The output stream \a out @@ -915,10 +962,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream) std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Routing &routing) { for (const auto &[i, route] : utils::enumerate(routing)) { - out << "[" << i << "] " - << route.sink_pad << "/" << route.sink_stream << " -> " - << route.source_pad << "/" << route.source_stream - << " (" << utils::hex(route.flags) << ")"; + out << "[" << i << "] " << route; if (i != routing.size() - 1) out << ", "; } @@ -1272,6 +1316,30 @@ int V4L2Subdevice::setFormat(const Stream &stream, V4L2SubdeviceFormat *format, * \return 0 on success or a negative error code otherwise */ +namespace { + +void routeFromKernel(V4L2Subdevice::Route &route, + const struct v4l2_subdev_route &kroute) +{ + route.sink.pad = kroute.sink_pad; + route.sink.stream = kroute.sink_stream; + route.source.pad = kroute.source_pad; + route.source.stream = kroute.source_stream; + route.flags = kroute.flags; +} + +void routeToKernel(const V4L2Subdevice::Route &route, + struct v4l2_subdev_route &kroute) +{ + kroute.sink_pad = route.sink.pad; + kroute.sink_stream = route.sink.stream; + kroute.source_pad = route.source.pad; + kroute.source_stream = route.source.stream; + kroute.flags = route.flags; +} + +} /* namespace */ + /** * \brief Retrieve the subdevice's internal routing table * \param[out] routing The routing table @@ -1282,6 +1350,8 @@ int V4L2Subdevice::setFormat(const Stream &stream, V4L2SubdeviceFormat *format, */ int V4L2Subdevice::getRouting(Routing *routing, Whence whence) { + routing->clear(); + if (!caps_.hasStreams()) return 0; @@ -1300,8 +1370,8 @@ int V4L2Subdevice::getRouting(Routing *routing, Whence whence) return ret; } - routing->resize(rt.num_routes); - rt.routes = reinterpret_cast(routing->data()); + std::vector routes{ rt.num_routes }; + rt.routes = reinterpret_cast(routes.data()); ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt); if (ret) { @@ -1310,11 +1380,16 @@ int V4L2Subdevice::getRouting(Routing *routing, Whence whence) return ret; } - if (rt.num_routes != routing->size()) { + if (rt.num_routes != routes.size()) { LOG(V4L2, Error) << "Invalid number of routes"; return -EINVAL; } + routing->resize(rt.num_routes); + + for (const auto &[i, route] : utils::enumerate(routes)) + routeFromKernel((*routing)[i], route); + return 0; } @@ -1332,13 +1407,20 @@ int V4L2Subdevice::getRouting(Routing *routing, Whence whence) */ int V4L2Subdevice::setRouting(Routing *routing, Whence whence) { - if (!caps_.hasStreams()) + if (!caps_.hasStreams()) { + routing->clear(); return 0; + } + + std::vector routes{ routing->size() }; + + for (const auto &[i, route] : utils::enumerate(*routing)) + routeToKernel(route, routes[i]); struct v4l2_subdev_routing rt = {}; rt.which = whence; - rt.num_routes = routing->size(); - rt.routes = reinterpret_cast(routing->data()); + rt.num_routes = routes.size(); + rt.routes = reinterpret_cast(routes.data()); int ret = ioctl(VIDIOC_SUBDEV_S_ROUTING, &rt); if (ret) { @@ -1346,8 +1428,12 @@ int V4L2Subdevice::setRouting(Routing *routing, Whence whence) return ret; } + routes.resize(rt.num_routes); routing->resize(rt.num_routes); + for (const auto &[i, route] : utils::enumerate(routes)) + routeFromKernel((*routing)[i], route); + return 0; } From patchwork Fri Mar 15 00:16:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19729 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 941FCBD160 for ; Fri, 15 Mar 2024 00:16:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0A27D62CA8; Fri, 15 Mar 2024 01:16:41 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mHDfJA6N"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A0EBD62CA2 for ; Fri, 15 Mar 2024 01:16:30 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EBE09A9A for ; Fri, 15 Mar 2024 01:16:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461767; bh=O57v2OG3VnocZRhMPuWD3+urHNWVuA4c5a6xSpOYxbg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mHDfJA6NdBss7swkkTdifOqpf2yMZdoJi+nfZXqwteAvzW7Kbt/rUXXABmaeZKgIu i4NMfsLAihWdECYxdmBuUxRgOIiwuWrOPoZaXknsFkWhw15TtIOeqtGj+c51sZOGmb oHbi7qlYdEdM50IxE6RaEUhwuuHbEZm/+WRQC3Bc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 10/14] libcamera: camera_sensor: Move related classes to subdirectory Date: Fri, 15 Mar 2024 02:16:09 +0200 Message-ID: <20240315001613.2033-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" In preparation for adding alternative implementations of the CameraSensor class, move the code to a subdirectory to avoid cluttering the main src/libcamera/ directory. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Stefan Klug --- src/libcamera/meson.build | 3 +-- src/libcamera/{ => sensor}/camera_sensor.cpp | 0 src/libcamera/{ => sensor}/camera_sensor_properties.cpp | 0 src/libcamera/sensor/meson.build | 6 ++++++ 4 files changed, 7 insertions(+), 2 deletions(-) rename src/libcamera/{ => sensor}/camera_sensor.cpp (100%) rename src/libcamera/{ => sensor}/camera_sensor_properties.cpp (100%) create mode 100644 src/libcamera/sensor/meson.build diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 45f63e932e4f..2e7b0c77e63c 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -7,8 +7,6 @@ libcamera_sources = files([ 'camera_controls.cpp', 'camera_lens.cpp', 'camera_manager.cpp', - 'camera_sensor.cpp', - 'camera_sensor_properties.cpp', 'color_space.cpp', 'controls.cpp', 'control_serializer.cpp', @@ -69,6 +67,7 @@ subdir('converter') subdir('ipa') subdir('pipeline') subdir('proxy') +subdir('sensor') null_dep = dependency('', required : false) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp similarity index 100% rename from src/libcamera/camera_sensor.cpp rename to src/libcamera/sensor/camera_sensor.cpp diff --git a/src/libcamera/camera_sensor_properties.cpp b/src/libcamera/sensor/camera_sensor_properties.cpp similarity index 100% rename from src/libcamera/camera_sensor_properties.cpp rename to src/libcamera/sensor/camera_sensor_properties.cpp diff --git a/src/libcamera/sensor/meson.build b/src/libcamera/sensor/meson.build new file mode 100644 index 000000000000..bf4b131a94b1 --- /dev/null +++ b/src/libcamera/sensor/meson.build @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: CC0-1.0 + +libcamera_sources += files([ + 'camera_sensor.cpp', + 'camera_sensor_properties.cpp', +]) From patchwork Fri Mar 15 00:16:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19730 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 22800C3273 for ; Fri, 15 Mar 2024 00:16:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1C8A762973; Fri, 15 Mar 2024 01:16:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BvZvVvDr"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 21E8862973 for ; Fri, 15 Mar 2024 01:16:32 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 69044A9A for ; Fri, 15 Mar 2024 01:16:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461768; bh=CHY3Q49LZMvBm3ZDxJhaat9S4SkYi3DGv++foHfqHaw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=BvZvVvDrOsoa2r+6wPXR1mZhDTJFEoLByY1vAIoFXgDtwbQOUTy/Jg8QT6n55CEP6 9KwRXt6QjufLcXGVzNEw/LsB5vNoaX83lQlBRWGMaWHbscElwkJ/YSTGZwINGbFbwt 4tWB+F9dBQZuPplBwKgIfanA22PUlzz6vKI5E/7E= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 11/14] libcamera: camera_sensor: Drop updateControlInfo() function Date: Fri, 15 Mar 2024 02:16:10 +0200 Message-ID: <20240315001613.2033-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The CameraSensor::updateControlInfo() function is a wrapper around the same function of the V4L2Subdevice class. It was meant to be called by pipeline handlers that modify the sensor configuration directly, bypassing the CameraSensor::setFormat() function. This never happened, and the function is called once only, internally to the CameraSensor class. No external users are foreseen, drop the function and call V4L2Subdevice::updateControlInfo() directly. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Stefan Klug --- include/libcamera/internal/camera_sensor.h | 2 -- src/libcamera/sensor/camera_sensor.cpp | 20 ++------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 60a8b106d175..b2f077b9cc75 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -75,8 +75,6 @@ public: const ControlList &properties() const { return properties_; } int sensorInfo(IPACameraSensorInfo *info) const; - void updateControlInfo(); - CameraLens *focusLens() { return focusLens_.get(); } Transform computeTransform(Orientation *orientation) const; diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp index af5d97f35de1..545f89d036df 100644 --- a/src/libcamera/sensor/camera_sensor.cpp +++ b/src/libcamera/sensor/camera_sensor.cpp @@ -814,7 +814,7 @@ int CameraSensor::setFormat(V4L2SubdeviceFormat *format, Transform transform) if (ret) return ret; - updateControlInfo(); + subdev_->updateControlInfo(); return 0; } @@ -924,9 +924,7 @@ int CameraSensor::applyConfiguration(const SensorConfiguration &config, * * Control information is updated automatically to reflect the current sensor * configuration when the setFormat() function is called, without invalidating - * any iterator on the ControlInfoMap. A manual update can also be forced by - * calling the updateControlInfo() function for pipeline handlers that change - * the sensor configuration wihtout using setFormat(). + * any iterator on the ControlInfoMap. * * \return A map of the V4L2 controls supported by the sensor */ @@ -1013,10 +1011,6 @@ int CameraSensor::setControls(ControlList *ctrls) * Sensor information is only available for raw sensors. When called for a YUV * sensor, this function returns -EINVAL. * - * Pipeline handlers that do not change the sensor format using the setFormat() - * function may need to call updateControlInfo() beforehand, to ensure all the - * control ranges are up to date. - * * \return 0 on success, a negative error code otherwise */ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const @@ -1094,16 +1088,6 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const return 0; } -/** - * \fn void CameraSensor::updateControlInfo() - * \brief Update the sensor's ControlInfoMap in case they have changed - * \sa V4L2Device::updateControlInfo() - */ -void CameraSensor::updateControlInfo() -{ - subdev_->updateControlInfo(); -} - /** * \fn CameraSensor::focusLens() * \brief Retrieve the focus lens controller From patchwork Fri Mar 15 00:16:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19731 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 1F237BD160 for ; Fri, 15 Mar 2024 00:16:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9444962973; Fri, 15 Mar 2024 01:16:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="U6zm4/Wu"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 998F462CA5 for ; Fri, 15 Mar 2024 01:16:33 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CBA59667 for ; Fri, 15 Mar 2024 01:16:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461770; bh=lyVf4HvvKQibkgR7sncBdUz8iMo0xkQB+Y6QQm3LcHY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=U6zm4/WuMSuBj6YPXBNJOGBlRv1AMQQwViLPuvpMnZ50qhcR7TLN3KNs5dyJpxtO3 EjQ7kg59/wsufFiex0PphNXur4dIXRpetQ5tzChfCg+Wln2HP/PkNArgsgCpZVtpe+ LqCWjFLDeFeDE4n5LZwoGvrBF2olt2MtFcZI7uCA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 12/14] libcamera: camera_sensor: Reorder functions Date: Fri, 15 Mar 2024 02:16:11 +0200 Message-ID: <20240315001613.2033-13-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The CameraSensor class has grown a lot since its creation, with many functions added for different types of purposes. They are not grouped by categories in the class definition, generating confusion when reading the header file. Improve readability by sorting functions by category: - Getters for static data (model, entity, focus lens, ...) - Format and sensor configuration accessors - Properties and controls (including test pattern mode) Update the .cpp file accordingly. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Stefan Klug --- include/libcamera/internal/camera_sensor.h | 29 +- src/libcamera/sensor/camera_sensor.cpp | 328 ++++++++++----------- 2 files changed, 179 insertions(+), 178 deletions(-) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index b2f077b9cc75..750d6d729cac 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -46,15 +46,15 @@ public: const std::string &model() const { return model_; } const std::string &id() const { return id_; } + const MediaEntity *entity() const { return entity_; } + V4L2Subdevice *device() { return subdev_.get(); } + + CameraLens *focusLens() { return focusLens_.get(); } + const std::vector &mbusCodes() const { return mbusCodes_; } std::vector sizes(unsigned int mbusCode) const; Size resolution() const; - const std::vector &testPatternModes() const - { - return testPatternModes_; - } - int setTestPatternMode(controls::draft::TestPatternModeEnum mode); V4L2SubdeviceFormat getFormat(const std::vector &mbusCodes, const Size &size) const; @@ -66,18 +66,19 @@ public: Transform transform = Transform::Identity, V4L2SubdeviceFormat *sensorFormat = nullptr); + const ControlList &properties() const { return properties_; } + int sensorInfo(IPACameraSensorInfo *info) const; + Transform computeTransform(Orientation *orientation) const; + const ControlInfoMap &controls() const; ControlList getControls(const std::vector &ids); int setControls(ControlList *ctrls); - V4L2Subdevice *device() { return subdev_.get(); } - - const ControlList &properties() const { return properties_; } - int sensorInfo(IPACameraSensorInfo *info) const; - - CameraLens *focusLens() { return focusLens_.get(); } - - Transform computeTransform(Orientation *orientation) const; + const std::vector &testPatternModes() const + { + return testPatternModes_; + } + int setTestPatternMode(controls::draft::TestPatternModeEnum mode); protected: std::string logPrefix() const override; @@ -91,8 +92,8 @@ private: void initStaticProperties(); void initTestPatternModes(); int initProperties(); - int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); int discoverAncillaryDevices(); + int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); const MediaEntity *entity_; std::unique_ptr subdev_; diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp index 545f89d036df..86ad9a85371c 100644 --- a/src/libcamera/sensor/camera_sensor.cpp +++ b/src/libcamera/sensor/camera_sensor.cpp @@ -215,6 +215,30 @@ int CameraSensor::init() return applyTestPatternMode(controls::draft::TestPatternModeEnum::TestPatternModeOff); } +int CameraSensor::generateId() +{ + const std::string devPath = subdev_->devicePath(); + + /* Try to get ID from firmware description. */ + id_ = sysfs::firmwareNodePath(devPath); + if (!id_.empty()) + return 0; + + /* + * Virtual sensors not described in firmware + * + * Verify it's a platform device and construct ID from the device path + * and model of sensor. + */ + if (devPath.find("/sys/devices/platform/", 0) == 0) { + id_ = devPath.substr(strlen("/sys/devices/")) + " " + model(); + return 0; + } + + LOG(CameraSensor, Error) << "Can't generate sensor ID"; + return -EINVAL; +} + int CameraSensor::validateSensorDriver() { int err = 0; @@ -580,6 +604,21 @@ int CameraSensor::discoverAncillaryDevices() * \return The sensor media entity */ +/** + * \fn CameraSensor::device() + * \brief Retrieve the camera sensor device + * \todo Remove this function by integrating DelayedControl with CameraSensor + * \return The camera sensor device + */ + +/** + * \fn CameraSensor::focusLens() + * \brief Retrieve the focus lens controller + * + * \return The focus lens controller. nullptr if no focus lens controller is + * connected to the sensor + */ + /** * \fn CameraSensor::mbusCodes() * \brief Retrieve the media bus codes supported by the camera sensor @@ -632,64 +671,6 @@ Size CameraSensor::resolution() const return std::min(sizes_.back(), activeArea_.size()); } -/** - * \fn CameraSensor::testPatternModes() - * \brief Retrieve all the supported test pattern modes of the camera sensor - * The test pattern mode values correspond to the controls::TestPattern control. - * - * \return The list of test pattern modes - */ - -/** - * \brief Set the test pattern mode for the camera sensor - * \param[in] mode The test pattern mode - * - * The new \a mode is applied to the sensor if it differs from the active test - * pattern mode. Otherwise, this function is a no-op. Setting the same test - * pattern mode for every frame thus incurs no performance penalty. - */ -int CameraSensor::setTestPatternMode(controls::draft::TestPatternModeEnum mode) -{ - if (testPatternMode_ == mode) - return 0; - - if (testPatternModes_.empty()) { - LOG(CameraSensor, Error) - << "Camera sensor does not support test pattern modes."; - return -EINVAL; - } - - return applyTestPatternMode(mode); -} - -int CameraSensor::applyTestPatternMode(controls::draft::TestPatternModeEnum mode) -{ - if (testPatternModes_.empty()) - return 0; - - auto it = std::find(testPatternModes_.begin(), testPatternModes_.end(), - mode); - if (it == testPatternModes_.end()) { - LOG(CameraSensor, Error) << "Unsupported test pattern mode " - << mode; - return -EINVAL; - } - - LOG(CameraSensor, Debug) << "Apply test pattern mode " << mode; - - int32_t index = staticProps_->testPatternModes.at(mode); - ControlList ctrls{ controls() }; - ctrls.set(V4L2_CID_TEST_PATTERN, index); - - int ret = setControls(&ctrls); - if (ret) - return ret; - - testPatternMode_ = mode; - - return 0; -} - /** * \brief Retrieve the best sensor format for a desired output * \param[in] mbusCodes The list of acceptable media bus codes @@ -919,80 +900,6 @@ int CameraSensor::applyConfiguration(const SensorConfiguration &config, return 0; } -/** - * \brief Retrieve the supported V4L2 controls and their information - * - * Control information is updated automatically to reflect the current sensor - * configuration when the setFormat() function is called, without invalidating - * any iterator on the ControlInfoMap. - * - * \return A map of the V4L2 controls supported by the sensor - */ -const ControlInfoMap &CameraSensor::controls() const -{ - return subdev_->controls(); -} - -/** - * \brief Read V4L2 controls from the sensor - * \param[in] ids The list of controls to read, specified by their ID - * - * This function reads the value of all controls contained in \a ids, and - * returns their values as a ControlList. The control identifiers are defined by - * the V4L2 specification (V4L2_CID_*). - * - * If any control in \a ids is not supported by the device, is disabled (i.e. - * has the V4L2_CTRL_FLAG_DISABLED flag set), or if any other error occurs - * during validation of the requested controls, no control is read and this - * function returns an empty control list. - * - * \sa V4L2Device::getControls() - * - * \return The control values in a ControlList on success, or an empty list on - * error - */ -ControlList CameraSensor::getControls(const std::vector &ids) -{ - return subdev_->getControls(ids); -} - -/** - * \brief Write V4L2 controls to the sensor - * \param[in] ctrls The list of controls to write - * - * This function writes the value of all controls contained in \a ctrls, and - * stores the values actually applied to the device in the corresponding \a - * ctrls entry. The control identifiers are defined by the V4L2 specification - * (V4L2_CID_*). - * - * If any control in \a ctrls is not supported by the device, is disabled (i.e. - * has the V4L2_CTRL_FLAG_DISABLED flag set), is read-only, or if any other - * error occurs during validation of the requested controls, no control is - * written and this function returns -EINVAL. - * - * If an error occurs while writing the controls, the index of the first - * control that couldn't be written is returned. All controls below that index - * are written and their values are updated in \a ctrls, while all other - * controls are not written and their values are not changed. - * - * \sa V4L2Device::setControls() - * - * \return 0 on success or an error code otherwise - * \retval -EINVAL One of the control is not supported or not accessible - * \retval i The index of the control that failed - */ -int CameraSensor::setControls(ControlList *ctrls) -{ - return subdev_->setControls(ctrls); -} - -/** - * \fn CameraSensor::device() - * \brief Retrieve the camera sensor device - * \todo Remove this function by integrating DelayedControl with CameraSensor - * \return The camera sensor device - */ - /** * \fn CameraSensor::properties() * \brief Retrieve the camera sensor properties @@ -1088,14 +995,6 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const return 0; } -/** - * \fn CameraSensor::focusLens() - * \brief Retrieve the focus lens controller - * - * \return The focus lens controller. nullptr if no focus lens controller is - * connected to the sensor - */ - /** * \brief Compute the Transform that gives the requested \a orientation * \param[inout] orientation The desired image orientation @@ -1155,33 +1054,134 @@ Transform CameraSensor::computeTransform(Orientation *orientation) const return transform; } +/** + * \brief Retrieve the supported V4L2 controls and their information + * + * Control information is updated automatically to reflect the current sensor + * configuration when the setFormat() function is called, without invalidating + * any iterator on the ControlInfoMap. + * + * \return A map of the V4L2 controls supported by the sensor + */ +const ControlInfoMap &CameraSensor::controls() const +{ + return subdev_->controls(); +} + +/** + * \brief Read V4L2 controls from the sensor + * \param[in] ids The list of controls to read, specified by their ID + * + * This function reads the value of all controls contained in \a ids, and + * returns their values as a ControlList. The control identifiers are defined by + * the V4L2 specification (V4L2_CID_*). + * + * If any control in \a ids is not supported by the device, is disabled (i.e. + * has the V4L2_CTRL_FLAG_DISABLED flag set), or if any other error occurs + * during validation of the requested controls, no control is read and this + * function returns an empty control list. + * + * \sa V4L2Device::getControls() + * + * \return The control values in a ControlList on success, or an empty list on + * error + */ +ControlList CameraSensor::getControls(const std::vector &ids) +{ + return subdev_->getControls(ids); +} + +/** + * \brief Write V4L2 controls to the sensor + * \param[in] ctrls The list of controls to write + * + * This function writes the value of all controls contained in \a ctrls, and + * stores the values actually applied to the device in the corresponding \a + * ctrls entry. The control identifiers are defined by the V4L2 specification + * (V4L2_CID_*). + * + * If any control in \a ctrls is not supported by the device, is disabled (i.e. + * has the V4L2_CTRL_FLAG_DISABLED flag set), is read-only, or if any other + * error occurs during validation of the requested controls, no control is + * written and this function returns -EINVAL. + * + * If an error occurs while writing the controls, the index of the first + * control that couldn't be written is returned. All controls below that index + * are written and their values are updated in \a ctrls, while all other + * controls are not written and their values are not changed. + * + * \sa V4L2Device::setControls() + * + * \return 0 on success or an error code otherwise + * \retval -EINVAL One of the control is not supported or not accessible + * \retval i The index of the control that failed + */ +int CameraSensor::setControls(ControlList *ctrls) +{ + return subdev_->setControls(ctrls); +} + +/** + * \fn CameraSensor::testPatternModes() + * \brief Retrieve all the supported test pattern modes of the camera sensor + * The test pattern mode values correspond to the controls::TestPattern control. + * + * \return The list of test pattern modes + */ + +/** + * \brief Set the test pattern mode for the camera sensor + * \param[in] mode The test pattern mode + * + * The new \a mode is applied to the sensor if it differs from the active test + * pattern mode. Otherwise, this function is a no-op. Setting the same test + * pattern mode for every frame thus incurs no performance penalty. + */ +int CameraSensor::setTestPatternMode(controls::draft::TestPatternModeEnum mode) +{ + if (testPatternMode_ == mode) + return 0; + + if (testPatternModes_.empty()) { + LOG(CameraSensor, Error) + << "Camera sensor does not support test pattern modes."; + return -EINVAL; + } + + return applyTestPatternMode(mode); +} + +int CameraSensor::applyTestPatternMode(controls::draft::TestPatternModeEnum mode) +{ + if (testPatternModes_.empty()) + return 0; + + auto it = std::find(testPatternModes_.begin(), testPatternModes_.end(), + mode); + if (it == testPatternModes_.end()) { + LOG(CameraSensor, Error) << "Unsupported test pattern mode " + << mode; + return -EINVAL; + } + + LOG(CameraSensor, Debug) << "Apply test pattern mode " << mode; + + int32_t index = staticProps_->testPatternModes.at(mode); + ControlList ctrls{ controls() }; + ctrls.set(V4L2_CID_TEST_PATTERN, index); + + int ret = setControls(&ctrls); + if (ret) + return ret; + + testPatternMode_ = mode; + + return 0; +} + std::string CameraSensor::logPrefix() const { return "'" + entity_->name() + "'"; } -int CameraSensor::generateId() -{ - const std::string devPath = subdev_->devicePath(); - - /* Try to get ID from firmware description. */ - id_ = sysfs::firmwareNodePath(devPath); - if (!id_.empty()) - return 0; - - /* - * Virtual sensors not described in firmware - * - * Verify it's a platform device and construct ID from the device path - * and model of sensor. - */ - if (devPath.find("/sys/devices/platform/", 0) == 0) { - id_ = devPath.substr(strlen("/sys/devices/")) + " " + model(); - return 0; - } - - LOG(CameraSensor, Error) << "Can't generate sensor ID"; - return -EINVAL; -} - } /* namespace libcamera */ From patchwork Fri Mar 15 00:16:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19732 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 97BB4BD808 for ; Fri, 15 Mar 2024 00:16:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 13F0462CEC; Fri, 15 Mar 2024 01:16:46 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="as6QV7kD"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F174D62CA1 for ; Fri, 15 Mar 2024 01:16:34 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 482CC667 for ; Fri, 15 Mar 2024 01:16:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461771; bh=2Xxd8BDrlf9YxmGtjiJTQsmA6Xvarr2niKvcfZEP2x4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=as6QV7kDFjsdI/CKRZkMgd7Jt+L2TJDaxhRlqznrwGemLpHB5VVfZ3RJo7FqsiVA+ R/LQLgYDJaoMd4IfPRYxA17GWGhftC606+V8GJHaQhWDNx/LxpP6prmr9FQYPzbcpS bV4QDMm5+s8iXP+5tUqrHM37iMvPWOFeq+WWXMLY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 13/14] libcamera: camera_sensor: Test for read-only HBLANK with READ_ONLY flag Date: Fri, 15 Mar 2024 02:16:12 +0200 Message-ID: <20240315001613.2033-14-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" The CameraSensor class tests if the sensor HBLANK control is read-only by comparing the minimum and maximum values, and documents this as being a workaround for the lack of a read-only control flag in V4L2. This is incorrect, as the V4L2 API provides such a flag. Use it to replace the workaround. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/libcamera/sensor/camera_sensor.cpp | 27 +++++++------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp index 86ad9a85371c..402025566544 100644 --- a/src/libcamera/sensor/camera_sensor.cpp +++ b/src/libcamera/sensor/camera_sensor.cpp @@ -188,28 +188,15 @@ int CameraSensor::init() * Set HBLANK to the minimum to start with a well-defined line length, * allowing IPA modules that do not modify HBLANK to use the sensor * minimum line length in their calculations. - * - * At present, there is no way of knowing if a control is read-only. - * As a workaround, assume that if the minimum and maximum values of - * the V4L2_CID_HBLANK control are the same, it implies the control - * is read-only. - * - * \todo The control API ought to have a flag to specify if a control - * is read-only which could be used below. */ - if (ctrls.infoMap()->find(V4L2_CID_HBLANK) != ctrls.infoMap()->end()) { - const ControlInfo hblank = ctrls.infoMap()->at(V4L2_CID_HBLANK); - const int32_t hblankMin = hblank.min().get(); - const int32_t hblankMax = hblank.max().get(); + const struct v4l2_query_ext_ctrl *hblankInfo = subdev_->controlInfo(V4L2_CID_HBLANK); + if (hblankInfo && !(hblankInfo->flags & V4L2_CTRL_FLAG_READ_ONLY)) { + ControlList ctrl(subdev_->controls()); - if (hblankMin != hblankMax) { - ControlList ctrl(subdev_->controls()); - - ctrl.set(V4L2_CID_HBLANK, hblankMin); - ret = subdev_->setControls(&ctrl); - if (ret) - return ret; - } + ctrl.set(V4L2_CID_HBLANK, static_cast(hblankInfo->minimum)); + ret = subdev_->setControls(&ctrl); + if (ret) + return ret; } return applyTestPatternMode(controls::draft::TestPatternModeEnum::TestPatternModeOff); From patchwork Fri Mar 15 00:16:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19733 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 1663FC3273 for ; Fri, 15 Mar 2024 00:16:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 41C5162D2B; Fri, 15 Mar 2024 01:16:47 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="G+cwvex5"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5642062CAB for ; Fri, 15 Mar 2024 01:16:36 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A05C3667 for ; Fri, 15 Mar 2024 01:16:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1710461772; bh=WMHCsHL+yRdCG0onYI/V4JB1bXqEme74Az2ttZ7EQbQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=G+cwvex5Tpdr0vRjHICNxNUwFM1jIjxBWvzG1X1ApDfKtIsdRDwMH0DlF5lH4Bnw9 r/jbZ1cyybwGbcvhzvZWh4kBRXkJteL+j6/kGCyeAz5AYF0vYn8xc3rI5GUd7WoXVp qre99qvsk9/v+RUVmFmCJS6SwKs2nBFrvYoQUW1Y= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 14/14] libcamera: camera_sensor: Expose the Bayer order Date: Fri, 15 Mar 2024 02:16:13 +0200 Message-ID: <20240315001613.2033-15-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> References: <20240315001613.2033-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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" Pipeline handlers may need to know the Bayer order produced by the sensor when a Transform is applied (horizontal or vertical flip). This is currently implemented manually in the Raspberry Pi pipeline handler. Move the implementation to the CameraSensor class to make it usable in other pipeline handlers. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Daniel Scally --- include/libcamera/internal/camera_sensor.h | 4 +- .../pipeline/rpi/common/pipeline_base.cpp | 54 +++---------------- .../pipeline/rpi/common/pipeline_base.h | 6 +-- src/libcamera/sensor/camera_sensor.cpp | 37 ++++++++++++- 4 files changed, 45 insertions(+), 56 deletions(-) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 750d6d729cac..d05f48ebeebe 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -22,12 +22,12 @@ #include +#include "libcamera/internal/bayer_format.h" #include "libcamera/internal/formats.h" #include "libcamera/internal/v4l2_subdevice.h" namespace libcamera { -class BayerFormat; class CameraLens; class MediaEntity; class SensorConfiguration; @@ -69,6 +69,7 @@ public: const ControlList &properties() const { return properties_; } int sensorInfo(IPACameraSensorInfo *info) const; Transform computeTransform(Orientation *orientation) const; + BayerFormat::Order bayerOrder(Transform t) const; const ControlInfoMap &controls() const; ControlList getControls(const std::vector &ids); @@ -114,6 +115,7 @@ private: Rectangle activeArea_; const BayerFormat *bayerFormat_; bool supportFlips_; + bool flipsAlterBayerOrder_; Orientation mountingOrientation_; ControlList properties_; diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 9449c3dc458c..7e420b3f90a4 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -235,24 +235,16 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() for (auto &raw : rawStreams_) { StreamConfiguration *rawStream = raw.cfg; - /* Adjust the RAW stream to match the computed sensor format. */ - BayerFormat sensorBayer = BayerFormat::fromMbusCode(sensorFormat_.code); - /* - * Some sensors change their Bayer order when they are h-flipped - * or v-flipped, according to the transform. If this one does, we - * must advertise the transformed Bayer order in the raw stream. - * Note how we must fetch the "native" (i.e. untransformed) Bayer - * order, because the sensor may currently be flipped! + * Some sensors change their Bayer order when they are + * h-flipped or v-flipped, according to the transform. Adjust + * the RAW stream to match the computed sensor format by + * applying the sensor Bayer order resulting from the transform + * to the user request. */ - if (data_->flipsAlterBayerOrder_) { - sensorBayer.order = data_->nativeBayerOrder_; - sensorBayer = sensorBayer.transform(combinedTransform_); - } - /* Apply the sensor adjusted Bayer order to the user request. */ BayerFormat cfgBayer = BayerFormat::fromPixelFormat(rawStream->pixelFormat); - cfgBayer.order = sensorBayer.order; + cfgBayer.order = data_->sensor_->bayerOrder(combinedTransform_); if (rawStream->pixelFormat != cfgBayer.toPixelFormat()) { rawStream->pixelFormat = cfgBayer.toPixelFormat(); @@ -840,40 +832,6 @@ int PipelineHandlerBase::registerCamera(std::unique_ptr &camera */ data->properties_.set(properties::ScalerCropMaximum, Rectangle{}); - /* - * We cache two things about the sensor in relation to transforms - * (meaning horizontal and vertical flips): if they affect the Bayer - * ordering, and what the "native" Bayer order is, when no transforms - * are applied. - * - * If flips are supported verify if they affect the Bayer ordering - * and what the "native" Bayer order is, when no transforms are - * applied. - * - * We note that the sensor's cached list of supported formats is - * already in the "native" order, with any flips having been undone. - */ - const V4L2Subdevice *sensor = data->sensor_->device(); - const struct v4l2_query_ext_ctrl *hflipCtrl = sensor->controlInfo(V4L2_CID_HFLIP); - if (hflipCtrl) { - /* We assume it will support vflips too... */ - data->flipsAlterBayerOrder_ = hflipCtrl->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT; - } - - /* Look for a valid Bayer format. */ - BayerFormat bayerFormat; - for (const auto &iter : data->sensorFormats_) { - bayerFormat = BayerFormat::fromMbusCode(iter.first); - if (bayerFormat.isValid()) - break; - } - - if (!bayerFormat.isValid()) { - LOG(RPI, Error) << "No Bayer format found"; - return -EINVAL; - } - data->nativeBayerOrder_ = bayerFormat.order; - ret = platformRegister(cameraData, frontend, backend); if (ret) return ret; diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 267eef1102f1..0608bbe5f0c7 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -48,7 +48,7 @@ class CameraData : public Camera::Private public: CameraData(PipelineHandler *pipe) : Camera::Private(pipe), state_(State::Stopped), - flipsAlterBayerOrder_(false), dropFrameCount_(0), buffersAllocated_(false), + dropFrameCount_(0), buffersAllocated_(false), ispOutputCount_(0), ispOutputTotal_(0) { } @@ -131,10 +131,6 @@ public: std::queue requestQueue_; - /* Store the "native" Bayer order (that is, with no transforms applied). */ - bool flipsAlterBayerOrder_; - BayerFormat::Order nativeBayerOrder_; - /* For handling digital zoom. */ IPACameraSensorInfo sensorInfo_; Rectangle ispCrop_; /* crop in ISP (camera mode) pixels */ diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp index 402025566544..5c4f35324055 100644 --- a/src/libcamera/sensor/camera_sensor.cpp +++ b/src/libcamera/sensor/camera_sensor.cpp @@ -58,7 +58,7 @@ LOG_DEFINE_CATEGORY(CameraSensor) CameraSensor::CameraSensor(const MediaEntity *entity) : entity_(entity), pad_(UINT_MAX), staticProps_(nullptr), bayerFormat_(nullptr), supportFlips_(false), - properties_(properties::properties) + flipsAlterBayerOrder_(false), properties_(properties::properties) { } @@ -271,9 +271,14 @@ int CameraSensor::validateSensorDriver() const struct v4l2_query_ext_ctrl *hflipInfo = subdev_->controlInfo(V4L2_CID_HFLIP); const struct v4l2_query_ext_ctrl *vflipInfo = subdev_->controlInfo(V4L2_CID_VFLIP); if (hflipInfo && !(hflipInfo->flags & V4L2_CTRL_FLAG_READ_ONLY) && - vflipInfo && !(vflipInfo->flags & V4L2_CTRL_FLAG_READ_ONLY)) + vflipInfo && !(vflipInfo->flags & V4L2_CTRL_FLAG_READ_ONLY)) { supportFlips_ = true; + if (hflipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT || + vflipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT) + flipsAlterBayerOrder_ = true; + } + if (!supportFlips_) LOG(CameraSensor, Debug) << "Camera sensor does not support horizontal/vertical flip"; @@ -1041,6 +1046,34 @@ Transform CameraSensor::computeTransform(Orientation *orientation) const return transform; } +/** + * \brief Compute the Bayer order that results from the given Transform + * \param[in] t The Transform to apply to the sensor + * + * Some sensors change their Bayer order when they are h-flipped or v-flipped. + * This function computes and returns the Bayer order that would result from the + * given transform applied to the sensor. + * + * This function is valid only when the sensor produces raw Bayer formats. + * + * \return The Bayer order produced by the sensor when the Transform is applied + */ +BayerFormat::Order CameraSensor::bayerOrder(Transform t) const +{ + /* Return a defined by meaningless value for non-Bayer sensors. */ + if (!bayerFormat_) + return BayerFormat::Order::BGGR; + + if (!flipsAlterBayerOrder_) + return bayerFormat_->order; + + /* + * Apply the transform to the native (i.e. untransformed) Bayer order, + * using the rest of the Bayer format supplied by the caller. + */ + return bayerFormat_->transform(t).order; +} + /** * \brief Retrieve the supported V4L2 controls and their information *