From patchwork Tue May 5 16:11:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 26636 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 0E63FC32F6 for ; Tue, 5 May 2026 16:11:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CB9FB63029; Tue, 5 May 2026 18:11:24 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="rzkwlJxf"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D700562E9D for ; Tue, 5 May 2026 18:11:21 +0200 (CEST) Received: from [192.168.1.83] (unknown [IPv6:2001:b07:6462:5de2:520d:d7a3:63ca:99e8]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 09F4E42B; Tue, 5 May 2026 18:11:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1777997479; bh=WTFVLYLDPHtLp+7CaQwrMc3NpGXKvEVJ+deMngTUpr0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rzkwlJxfWjVlBIqYwy3GAptqn2y401k2G90wp9rJl4YA3M9dwLpBg0NZsWZQh4ySX sFDtVtYMW44egDF98IJpUr167mPpdmjbcUWP5g/2B7P95z8MrJi4bu7V/2XTT7AT82 u14WBNvONtlsQrbTbE+CeIhovpIyfew/5ztd1Z3A= From: Jacopo Mondi Date: Tue, 05 May 2026 18:11:09 +0200 Subject: [PATCH 1/3] include: v4l2-isp: Update to support extensible stats MIME-Version: 1.0 Message-Id: <20260505-extensible-stats-v1-1-0b56c7b1bbd6@ideasonboard.com> References: <20260505-extensible-stats-v1-0-0b56c7b1bbd6@ideasonboard.com> In-Reply-To: <20260505-extensible-stats-v1-0-0b56c7b1bbd6@ideasonboard.com> To: libcamera-devel@lists.libcamera.org, Antoine Bouyer Cc: Jacopo Mondi X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=8828; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=WTFVLYLDPHtLp+7CaQwrMc3NpGXKvEVJ+deMngTUpr0=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBp+haovwoaL5x5h4LdD02JSfLBDkhuxh3YFiBlk YfIL0LyipGJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCafoWqAAKCRByNAaPFqFW PCoVD/93HbkOYbxHObBr4hGUa1A7SnLxLuVhj7JU0fli9LLifNXvh8UkklskRiR70rXcoUjOoke 7Z6PZJQefy5U2xMMpxPvufHMKSZUU4CtS64BPVlv1yT2fsnAV8ZFbz9Gbqu2VqTRV5BT93V7uX/ /YmRp7d0mhP9pJA+qD+vT+LTwWHqATSOINe+lMRL4pVqr3O7zMeAcFZJJLMzyrUehywjVGHfd/j c749ugrkZIY2cx6CbWDNZBGdVywYbl2grdtqWcyR4p+CkZi07cou59XQ5a2pCu8L0GE+cI4ff5B udjCLD5OiIxX6p1HJJsqZJshUud68dRIGiAFma12vIghQ2VhQZlSo6erUVUv98Vx6CEqrelCiLk AikrK1AcFXAvpxL0UCcFKQXs0ZJjUeMm2pjXlimIjv9NdoRFjrx60r3X/mqlbMDRy0s4ZCP+oEk SjKg9vzVbBHYpU7JLHcXFNkumdW1ZN+LNk/UXtkxWJPmfvi4NtF+MeAumzFAykBB2ChkesW1ZTC ajRrID7APpa/8WicxUYyIUKfQRbTqk6Jp1ml39xFZXCUN8NIBnabp6Ud7lOVpFFBKo/LntRvIyQ zWblkx/5m7NFrQpr4f26rRSFBfqEMyFRCurSVHVkRoCxkK+XMh7DW9JQAcwaUgN3Tn+1g8Od1OU +tCMWCoFsbAsIMQ== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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" Update the v4l2-isp.h header to prepare to support extensible statistics. The new header version is generated from the following in-review patch series: https://patchwork.linuxtv.org/project/linux-media/patch/20260505-extensible-stats-v1-1-e16f326b8dad@ideasonboard.com/ Signed-off-by: Jacopo Mondi --- include/linux/media/v4l2-isp.h | 125 ++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 46 deletions(-) diff --git a/include/linux/media/v4l2-isp.h b/include/linux/media/v4l2-isp.h index 0cfc4ab94967..60a716177d52 100644 --- a/include/linux/media/v4l2-isp.h +++ b/include/linux/media/v4l2-isp.h @@ -13,25 +13,33 @@ #include /** - * enum v4l2_isp_params_version - V4L2 ISP parameters versioning + * enum v4l2_isp_version - V4L2 ISP serialization format versioning * - * @V4L2_ISP_PARAMS_VERSION_V0: First version of the V4L2 ISP parameters format - * (for compatibility) - * @V4L2_ISP_PARAMS_VERSION_V1: First version of the V4L2 ISP parameters format + * @V4L2_ISP_VERSION_V0: First version of the V4L2 ISP serialization format + * (for compatibility) + * @V4L2_ISP_VERSION_V1: First version of the V4L2 ISP serialization format * * V0 and V1 are identical in order to support drivers compatible with the V4L2 - * ISP parameters format already upstreamed which use either 0 or 1 as their - * versioning identifier. Both V0 and V1 refers to the first version of the - * V4L2 ISP parameters format. + * ISP format already upstreamed which use either 0 or 1 as their versioning + * identifier. Both V0 and V1 refers to the first version of the V4L2 ISP + * serialization format. * - * Future revisions of the V4L2 ISP parameters format should start from the + * Future revisions of the V4L2 ISP serialization format should start from the * value of 2. */ -enum v4l2_isp_params_version { - V4L2_ISP_PARAMS_VERSION_V0 = 0, - V4L2_ISP_PARAMS_VERSION_V1 +enum v4l2_isp_version { + V4L2_ISP_VERSION_V0 = 0, + V4L2_ISP_VERSION_V1 }; +/* + * Compatibility with existing users of v4l2_isp_params which pre-date the + * introduction of v4l2_isp_stats. + */ +#define v4l2_isp_params_version v4l2_isp_version +#define V4L2_ISP_PARAMS_VERSION_V0 V4L2_ISP_VERSION_V0 +#define V4L2_ISP_PARAMS_VERSION_V1 V4L2_ISP_VERSION_V1 + #define V4L2_ISP_PARAMS_FL_BLOCK_DISABLE (1U << 0) #define V4L2_ISP_PARAMS_FL_BLOCK_ENABLE (1U << 1) @@ -39,64 +47,89 @@ enum v4l2_isp_params_version { * Reserve the first 8 bits for V4L2_ISP_PARAMS_FL_* flag. * * Driver-specific flags should be defined as: - * #define DRIVER_SPECIFIC_FLAG0 ((1U << V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(0)) - * #define DRIVER_SPECIFIC_FLAG1 ((1U << V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(1)) + * #define DRIVER_SPECIFIC_FLAG0 ((1U << V4L2_ISP_FL_DRIVER_FLAGS(0)) + * #define DRIVER_SPECIFIC_FLAG1 ((1U << V4L2_ISP_FL_DRIVER_FLAGS(1)) */ -#define V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(n) ((n) + 8) +#define V4L2_ISP_FL_DRIVER_FLAGS(n) ((n) + 8) /** - * struct v4l2_isp_params_block_header - V4L2 extensible parameters block header - * @type: The parameters block type (driver-specific) + * struct v4l2_isp_block_header - V4L2 extensible block header + * @type: The parameters or statistics block type (driver-specific) * @flags: A bitmask of block flags (driver-specific) - * @size: Size (in bytes) of the parameters block, including this header + * @size: Size (in bytes) of the block, including this header * - * This structure represents the common part of all the ISP configuration - * blocks. Each parameters block shall embed an instance of this structure type - * as its first member, followed by the block-specific configuration data. + * This structure represents the common part of all the ISP configuration or + * statistic blocks. Each block shall embed an instance of this structure type + * as its first member, followed by the block-specific configuration or + * statistic data. * * The @type field is an ISP driver-specific value that identifies the block - * type. The @size field specifies the size of the parameters block. + * type. The @size field specifies the size of the block, including this + * header. * - * The @flags field is a bitmask of per-block flags V4L2_PARAMS_ISP_FL_* and - * driver-specific flags specified by the driver header. + * The @flags field is a bitmask of per-block flags. If a block is used for + * configuration parameters this field can be a combination of + * V4L2_ISP_PARAMS_FL_* and driver-specific flags. If a block is used + * for statistics this fields is used to report optional + * driver-specific flags, if any. */ -struct v4l2_isp_params_block_header { +struct v4l2_isp_block_header { __u16 type; __u16 flags; __u32 size; } __attribute__((aligned(8))); /** - * struct v4l2_isp_params_buffer - V4L2 extensible parameters configuration - * @version: The parameters buffer version (driver-specific) - * @data_size: The configuration data effective size, excluding this header - * @data: The configuration data + * v4l2_isp_params_block_header - V4L2 extensible parameters block header + * + * Compatibility with existing users of v4l2_isp_params_block_header + * which pre-date the introduction of v4l2_isp_block_header. + */ +#define v4l2_isp_params_block_header v4l2_isp_block_header + +/** + * struct v4l2_isp_buffer - V4L2 extensible buffer + * @version: The extensible buffer version (driver-specific) + * @data_size: The data effective size, excluding this header + * @data: The configuration or statistics data * - * This structure contains the configuration parameters of the ISP algorithms, - * serialized by userspace into a data buffer. Each configuration parameter - * block is represented by a block-specific structure which contains a - * :c:type:`v4l2_isp_params_block_header` entry as first member. Userspace - * populates the @data buffer with configuration parameters for the blocks that - * it intends to configure. As a consequence, the data buffer effective size - * changes according to the number of ISP blocks that userspace intends to - * configure and is set by userspace in the @data_size field. + * This structure contains ISP configuration parameters or ISP hardware + * statistics serialized into a data buffer. Each block is represented by a + * block-specific structure which contains a :c:type:`v4l2_isp_block_header` + * entry as first member. * - * The parameters buffer is versioned by the @version field to allow modifying - * and extending its definition. Userspace shall populate the @version field to - * inform the driver about the version it intends to use. The driver will parse - * and handle the @data buffer according to the data layout specific to the - * indicated version and return an error if the desired version is not + * When used for ISP parameters, userspace populates the @data buffer with + * configuration parameters for the blocks that it intends to configure. As a + * consequence, the data buffer effective size changes according to the number + * of ISP blocks that userspace intends to configure. + * + * When used to report ISP statistics, the driver populates the @data buffer + * with statistics for each supported measurement block. + * + * The buffer is versioned by the @version field to allow modifying + * and extending its definition. The writer shall populate the @version field + * to inform the reader about the version it intends to use. The reader will + * parse and handle the @data buffer according to the data layout specific to + * the indicated version and return an error if the desired version is not * supported. * - * For each ISP block that userspace wants to configure, a block-specific - * structure is appended to the @data buffer, one after the other without gaps - * in between. Userspace shall populate the @data_size field with the effective - * size, in bytes, of the @data buffer. + * For each ISP block, a block-specific structure is appended to the @data + * buffer, one after the other without gaps in between. The writer shall + * populate the @data_size field with the effective size, in bytes, of the + * @data buffer. */ -struct v4l2_isp_params_buffer { +struct v4l2_isp_buffer { __u32 version; __u32 data_size; __u8 data[] __counted_by(data_size); }; +/** + * v4l2_isp_params_buffer - V4L2 extensible parameters compatibility + * + * Compatibility with existing users of v4l2_isp_params_buffer which + * pre-date the introduction of v4l2_isp_buffer. + */ +#define v4l2_isp_params_buffer v4l2_isp_buffer + #endif /* _V4L2_ISP_H_ */ From patchwork Tue May 5 16:11:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 26637 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 CCE42C32F7 for ; Tue, 5 May 2026 16:11:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8FE0163030; Tue, 5 May 2026 18:11:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XxBerSDd"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 35B2762DC4 for ; Tue, 5 May 2026 18:11:22 +0200 (CEST) Received: from [192.168.1.83] (unknown [IPv6:2001:b07:6462:5de2:520d:d7a3:63ca:99e8]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 69ACC874; Tue, 5 May 2026 18:11:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1777997479; bh=bGgqS43n/jFzC4FRyn+b3LDWNsNBrG90ma0D+MzewpQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XxBerSDdCzJV1pYSpnLFiZ0jukAM0tEhG/eDMwJt3Y0Gq2Qk5TGUcYgIU4E9Rfoi9 ofS7BS+aqdoGC+yQMeVA490klfaofzZNhe8b3xg/9MGT3hgfwRsm7MtqA6+qF+BvzM udjzHD37AYHs/UcxjLlh/I/9MsOjI2skLN6Z7GMM= From: Jacopo Mondi Date: Tue, 05 May 2026 18:11:10 +0200 Subject: [PATCH 2/3] ipa: libipa: Introduce V4L2Stats MIME-Version: 1.0 Message-Id: <20260505-extensible-stats-v1-2-0b56c7b1bbd6@ideasonboard.com> References: <20260505-extensible-stats-v1-0-0b56c7b1bbd6@ideasonboard.com> In-Reply-To: <20260505-extensible-stats-v1-0-0b56c7b1bbd6@ideasonboard.com> To: libcamera-devel@lists.libcamera.org, Antoine Bouyer Cc: Jacopo Mondi X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11093; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=bGgqS43n/jFzC4FRyn+b3LDWNsNBrG90ma0D+MzewpQ=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBp+hao6oHk4Q0wT5k+uW0q371es/KGiYotaP0zx pvxL2VkZLWJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCafoWqAAKCRByNAaPFqFW PMfyD/9Q5CP1rsF1qHs1D8RGXESPjF2xeFar1nsF9EHUIKUZUSVbDerg5FpkrFUDFsDPEGEN6SG 8jGRVG3vjX8KLK4E4TONzzBNII/95i79h9c8YDLwKFMsVh8dUrC2d+pMrZpwdDLiIPapYFeXYVJ smQDu4BB97zuI29qbrhA36tEzff4mKROgENyAEZkWcW30df86MePanqChhcGCqKBxqNHIRrHoe2 gt7yhI6O+/fGYrt8TMfHDsj8LE6E/7xir+OwfQ6Tg+yIEoD8/0q31Z6imL0mrXCmLxN3mKyTKEL Y/MdBptLGZP2r5JlURpkKFcVkvGKeVa3CUQXM++U2Lx/dZtR6hGZSEFyanvTm9hzEUSfg9m8JCo 1gILq5Xm3RZB80Syn7pFDowIw8nPxZMLUQPuZjtgxiVNh69CADlV40ndwmCW91KkUpnCY6Ss83D N91Q2fn7K4CK/wkXaTkGILE0hmNSNVGQmuna9/H3aFiXUNr+YoJQWSFHphVRJHqyEa6k0W2qlNX BDvXp8H5FCx2SBQ9QYB1RztZCaBVCEQ5oOmI1H4mVYFE/rruks9hdMwTwFusiyhtaTTx8FjI45Z vAE2XDE3SK0I2DJv/u1z9M6DOA3OK6EMmdOGhG1vQlNXf5Nbp+Z72kGlvBw6y4bXmYuKHV49I+z UZb5S10S280YEsg== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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" Add a V4L2Stats class similar in spirit to the existing V4L2Params class to allow IPA modules to easily sub-class it to access ISP statistics blocks serialized into a v4l2_isp_buffer. Signed-off-by: Jacopo Mondi --- src/ipa/libipa/meson.build | 2 + src/ipa/libipa/v4l2_stats.cpp | 226 ++++++++++++++++++++++++++++++++++++++++++ src/ipa/libipa/v4l2_stats.h | 124 +++++++++++++++++++++++ 3 files changed, 352 insertions(+) diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build index 963c5ee73063..16f4b095f220 100644 --- a/src/ipa/libipa/meson.build +++ b/src/ipa/libipa/meson.build @@ -19,6 +19,7 @@ libipa_headers = files([ 'pwl.h', 'quantized.h', 'v4l2_params.h', + 'v4l2_stats.h', ]) libipa_sources = files([ @@ -40,6 +41,7 @@ libipa_sources = files([ 'pwl.cpp', 'quantized.cpp', 'v4l2_params.cpp', + 'v4l2_stats.cpp', ]) libipa_includes = include_directories('..') diff --git a/src/ipa/libipa/v4l2_stats.cpp b/src/ipa/libipa/v4l2_stats.cpp new file mode 100644 index 000000000000..050e2329dfa9 --- /dev/null +++ b/src/ipa/libipa/v4l2_stats.cpp @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * V4L2 Statistics + */ + +#include "v4l2_stats.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(V4L2Stats) + +namespace ipa { + +/** + * \file v4l2_stats.cpp + * \brief Helper class to handle an ISP statistics buffer compatible with + * the generic V4L2 ISP format + * + * The Linux kernel defines a generic buffer format for ISP statistics. + * The format describes a serialisation method that allows userspace to + * access statistics data from a binary buffer. + * + * The V4L2Stats class implements support the V4L2 ISP statistics buffer format + * and allows users to retrieve an ISP statistics blocks, represented as + * V4L2StatsBlock class instances. + * + * IPA implementations using this helpers should define an enumeration of ISP + * blocks supported by the IPA module and use a set of common abstraction to + * help their derived implementation of V4L2Stats translate the enumerated ISP + * block identifiers to the actual type of the statistics data as defined by + * the kernel interface. + */ + +/** + * \class V4L2StatsBlock + * \brief Helper class that represents an ISP statistics block + * + * Each ISP measurement block produces a set of statistics data whose memory + * layout is defined by the kernel interface. + * + * This class represents an ISP statistics block entry. It is constructed + * with a reference to the memory area where the statistics block is + * stored in the statistics buffer. The template parameter represents + * the underlying kernel-defined ISP statistics block type and allows its + * user to easily cast it to said type to read the statistics data. + * + * \sa V4L2Stats::block() + */ + +/** + * \fn V4L2StatsBlock::V4L2StatsBlock() + * \brief Construct a V4L2StatsBlock with memory represented by \a data + * \param[in] data The memory area where the statistics block is located + */ + +/** + * \fn V4L2StatsBlock::operator->() const + * \brief Access the statistics block casting it to the kernel-defined + * ISP block type + * + * The V4L2StatsBlock is templated with the kernel defined ISP block type. This + * function allows users to easily cast a V4L2StatsBlock to the underlying + * kernel-defined type in order to easily access the statistics data. + * + * \code{.cpp} + * + * // The kernel header defines the ISP statistics types, in example + * // struct my_isp_awb_stats_data { + * // u16 mean_r; + * // u16 mean_g; + * // u16 mean_b; + * // } + * + * template<> V4L2StatsBlock awbStats = ... + * + * u16 mean_r = awbStats->mean_r; + * u16 mean_g = awbStats->mean_g; + * u16 mean_b = awbStats->mean_b; + * + * \endcode + * + * Users of this class shall not create a V4L2StatsBlock manually but should + * use V4L2Stats::block(). + */ + +/** + * \fn V4L2StatsBlock::operator*() const + * \copydoc V4L2StatsBlock::operator->() const + */ + +/** + * \fn V4L2StatsBlock::size() const + * \brief Retrieve the size (in bytes) of the ISP statistics block, including + * the block's header + * \return The size of the stats block + */ + +/** + * \var V4L2StatsBlock::data_ + * \brief Memory area where ISP statistics have been serialized + */ + +/** + * \class V4L2Stats + * \brief Helper class that represent an ISP statistics buffer + * + * This class represents an ISP statistics buffer. It is constructed with a + * reference to the memory mapped buffer that has been dequeued from the ISP + * driver. + * + * This class is templated with the type of the enumeration of ISP blocks that + * each IPA module is expected to support. IPA modules are expected to derive + * this class by providing a 'stats_traits' type that helps the class associate + * a block type with the actual memory area that represents the ISP statistics + * block. + * + * \code{.cpp} + * + * // Define the supported ISP statistics blocks + * enum class myISPStats { + * Agc, + * Awb, + * ... + * }; + * + * // Maps the C++ enum type to the kernel enum type and concrete parameter type + * template + * struct block_type { + * }; + * + * template<> + * struct block_type { + * using type = struct my_isp_kernel_stats_type_agc; + * static constexpr kernel_enum_type blockType = MY_ISP_STATS_TYPE_AGC; + * }; + * + * template<> + * struct block_type { + * using type = struct my_isp_kernel_stats_type_awb; + * static constexpr kernel_enum_type blockType = MY_ISP_STATS_TYPE_AWB; + * }; + * + * + * // Convenience type to associate a block id to the 'block_type' overload + * struct stats_traits { + * using id_type = myISPStats; + * template using id_to_details = block_type; + * }; + * + * ... + * + * // Derive the V4L2Stats class by providing stats_traits + * class MyISPStats : public V4L2Stats + * { + * public: + * MyISPStats::MyISPStats(Span data) + * : V4L2Stats(data) + * { + * } + * }; + * + * \endcode + * + * Users of this class can then easily access an ISP statistics block as a + * V4L2StatsBlock instance. + * + * \code{.cpp} + * + * MyISPStats stats(data); + * + * auto awb = stats.block(); + * auto mean_r = awb->mean_r; + * auto mean_g = awb->mean_g; + * auto mean_b = awb->mean_b; + * \endcode + */ + +/** + * \fn V4L2Stats::V4L2Stats() + * \brief Construct an instance of V4L2Stats + * \param[in] data Reference to the v4l2-buffer memory mapped area + * \param[in] version The expected V4L2 ISP serialization format version + */ + +/** + * \fn V4L2Stats::bytesused() + * \brief Retrieve the size of the statistics buffer (in bytes) + * \return The number of bytes occupied by the ISP statistics + */ + +/** + * \fn V4L2Stats::block() const + * \brief Retrieve the location of an ISP statistics block a return it + * \return A V4L2StatsBlock instance that points to the ISP statistics block + */ + +/** + * \fn V4L2Stats::block(unsigned int blockType, size_t blockSize) const + * \brief Retrieve an ISP statistics block a returns a reference to it + * \param[in] blockType The kernel-defined ISP block identifier, used to + * identify the block header + * \param[in] blockSize The ISP statistics block size, for validation + * + * Parse the buffer of serialized statistics data and retrieve the location + * of the block with type \a blockType of size \a blockSize. + * + * IPA modules that derive the V4L2Stats class shall use this function to + * retrieve the memory area that will be used to construct a V4L2StatsBlock + * before returning it to the caller. + */ + +/** + * \var V4L2Stats::data_ + * \brief The ISP statistics buffer memory + */ + +/** + * \var V4L2Stats::used_ + * \brief The number of bytes used by the statistics buffer + */ + +} /* namespace ipa */ + +} /* namespace libcamera */ diff --git a/src/ipa/libipa/v4l2_stats.h b/src/ipa/libipa/v4l2_stats.h new file mode 100644 index 000000000000..404cb606e135 --- /dev/null +++ b/src/ipa/libipa/v4l2_stats.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * V4L2 Stats + */ + +#pragma once + +#include + +#include + +#include +#include + +namespace libcamera { + +LOG_DECLARE_CATEGORY(V4L2Stats) + +namespace ipa { + +template +class V4L2StatsBlock +{ +public: + V4L2StatsBlock(const Span data) + : data_(data) + { + } + + virtual ~V4L2StatsBlock() {} + + virtual const T *operator->() const + { + return reinterpret_cast(data_.data()); + } + + virtual const T &operator*() const + { + return *reinterpret_cast(data_.data()); + } + + size_t size() const + { + return data_.size(); + } + +protected: + Span data_; +}; + +template +class V4L2Stats +{ +public: + V4L2Stats(Span data, unsigned int version) + : data_(data) + { + struct v4l2_isp_buffer *stats = + reinterpret_cast(data_.data()); + used_ = stats->data_size; + + if (version != stats->version) + LOG(V4L2Stats, Error) + << "Unsupported v4l2-isp version: " << stats->version; + } + + size_t bytesused() const { return used_; } + + template + auto block() const + { + using Details = typename Traits::template id_to_details; + + using Type = typename Details::type; + constexpr auto kernelId = Details::blockType; + + auto data = block(kernelId, sizeof(Type)); + return V4L2StatsBlock(data); + } + +protected: + const Span block(unsigned int blockType, size_t blockSize) const + { + struct v4l2_isp_buffer *stats = + reinterpret_cast(data_.data()); + + __u8 *data = stats->data; + while (data < stats->data + stats->data_size) { + struct v4l2_isp_block_header *header = + reinterpret_cast(data); + + if (header->type != blockType) { + data += header->size; + continue; + } + + if (header->size != blockSize) { + LOG(V4L2Stats, Error) + << "Block type " << blockType + << " size mistmatch: expected " + << blockSize << " got:" + << header->size; + return {}; + } + + Span block(data, header->size); + return block; + } + + LOG(V4L2Stats, Error) << "Unsupported stats block type: " + << blockType; + + return {}; + } + + Span data_; + size_t used_; +}; + +} /* namespace ipa */ + +} /* namespace libcamera */ From patchwork Tue May 5 16:11:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 26638 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 470F3C32F8 for ; Tue, 5 May 2026 16:11:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0FA1062E9D; Tue, 5 May 2026 18:11:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gpxCO+/O"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 90FD162E9D for ; Tue, 5 May 2026 18:11:22 +0200 (CEST) Received: from [192.168.1.83] (unknown [IPv6:2001:b07:6462:5de2:520d:d7a3:63ca:99e8]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C77DD1C4D; Tue, 5 May 2026 18:11:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1777997480; bh=AMIQXsPx5v0Jjh0BKv7/KwlCqpCPnhei5fzAY+Lz8Xc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gpxCO+/Ozn5nQ8wKIgtAEZFwp0plzRv1DpQaHE5e0+fek58DcdHwuolMCqmE1JaTg SnJODckbnMVzG8slRry+tcxjo9TYJjLgRqRenCU/JtOP8XHa12JMmZoTfEgp22yK1r Tl6YPN9dBinD7fGVOWs3PXJ2be3UDokLEuweAsWY= From: Jacopo Mondi Date: Tue, 05 May 2026 18:11:11 +0200 Subject: [PATCH 3/3] ipa: libipa: v4l2_params: Fix code example in doc MIME-Version: 1.0 Message-Id: <20260505-extensible-stats-v1-3-0b56c7b1bbd6@ideasonboard.com> References: <20260505-extensible-stats-v1-0-0b56c7b1bbd6@ideasonboard.com> In-Reply-To: <20260505-extensible-stats-v1-0-0b56c7b1bbd6@ideasonboard.com> To: libcamera-devel@lists.libcamera.org, Antoine Bouyer Cc: Jacopo Mondi X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1042; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=AMIQXsPx5v0Jjh0BKv7/KwlCqpCPnhei5fzAY+Lz8Xc=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBp+haoHzwHQ432zd0i8NYUAioAAF4EQ5dbv62n7 mymuUEQX2OJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCafoWqAAKCRByNAaPFqFW PPCqD/0dYDRgH7PMIG0/x3PBM4Eme6D0a+3KFQQOci4zQoj8hbGWuMPMqJPgvJY/trUQiXK8GRP vRgEl8Hh1/qbD9v4Zw0CMQuRb2XrLTZMHqRq2hrc3W2Y9qt320fb6YKwz43zcj8VbkLGFsdl9I4 RhF9wjSjonWLT6kO8DVMYuhmHDX8OEVqYmqJSeEkBrXKZ5kcacF5xOSnr7uR3t8PHlXFaRPLCXk UPYIoonG9+6WjRtLyFv9js/fu598fESGcCep/ZkoQH67FdDuyLYHDS+lhSffvBjHaslpSwsA5jF zS854fjIs0dt9Jo7ORvqDoBzgCRD1t1ghBVWUlw646Nc79cHid8sHAsP5Ai1V4dEPmZl5vTXyxK mFH0A1k4u0gJVRsIN9CixHx5ntBSOfh7QzsDA1+ft2hTmf14jAyg5zebS9DovFM8AnaH7GXjFyL j6/hb85HYf1qtYbO+haplRVQ7t6BURGvBQHWwugYjUPnuthxZ724wAGK5KT9dEYOzRAIie/YfSV c4tQbESJBWODnSWkdiB2PSrzypOwLfclVhA4G+UV56+8czzR/08V6tqu5os5oRoDF2Z45pATqf1 voButSIbR694BdI1RsaB1B/haD65t6DSKst8APT7cyCSGMNDGMc/JfyC+49l0JnR8mTalDjmU6i uBhCV4rGkEcVEng== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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" Fix the code example in documentation to actually use the myISPBlocks type define a few lines above instead of the mis-spelled myISPBlock type. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Barnabás Pőcze --- src/ipa/libipa/v4l2_params.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ipa/libipa/v4l2_params.cpp b/src/ipa/libipa/v4l2_params.cpp index a1eeeb1b0e6a..b756bfee4de2 100644 --- a/src/ipa/libipa/v4l2_params.cpp +++ b/src/ipa/libipa/v4l2_params.cpp @@ -146,13 +146,13 @@ namespace ipa { * }; * * template<> - * struct block_type { + * struct block_type { * using type = struct my_isp_kernel_config_type_agc; * static constexpr kernel_enum_type blockType = MY_ISP_TYPE_AGC; * }; * * template<> - * struct block_type { + * struct block_type { * using type = struct my_isp_kernel_config_type_awb; * static constexpr kernel_enum_type blockType = MY_ISP_TYPE_AWB; * };