From patchwork Fri Aug 29 11:54:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 24267 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 8080DC32BB for ; Fri, 29 Aug 2025 11:54:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 716A469324; Fri, 29 Aug 2025 13:54:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vYahlJtQ"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B3796931D for ; Fri, 29 Aug 2025 13:54:24 +0200 (CEST) Received: from [192.168.1.102] (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3AF073BEE; Fri, 29 Aug 2025 13:53:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1756468399; bh=VaO6RxmH8AFIDeT03ooF/ZaktlSstVrtUodhVbflVZE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=vYahlJtQidSoHXXW83yEPLXmKil1AWS6YHCfHAKb1vr2cx7KiBtUB65V1qzG2RLRg sum9+mMONS3pfqfIaOrZl36ZjkVPpqReqaxLtcEBCRezeURdK40GLsF/eghgXAqYZU 6uUTUG6y89/cOVbH+nrvvWhuCj8RssflBIbaFpGo= From: Jacopo Mondi Date: Fri, 29 Aug 2025 13:54:00 +0200 Subject: [PATCH 3/4] ipa: libipa: Introduce V4L2Params MIME-Version: 1.0 Message-Id: <20250829-v4l2-params-v1-3-340773fb69ff@ideasonboard.com> References: <20250829-v4l2-params-v1-0-340773fb69ff@ideasonboard.com> In-Reply-To: <20250829-v4l2-params-v1-0-340773fb69ff@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=21834; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=VaO6RxmH8AFIDeT03ooF/ZaktlSstVrtUodhVbflVZE=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBosZTundzgBDFNHodfC1jRqNKh5qmHRFxIu0riE 0eUghvds/GJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaLGU7gAKCRByNAaPFqFW PJm/D/4lofnwlEiYqHx17XQBhuTY1yP+NrStAAgTnP+iMKS6mMsPmxfyHQyXRvGvpf+6cupKnYG lOYaJ0Aj2c75FeRUR78mbeMjpd6Fjy7wiz6zfaEsuqlfMExiPvYv1CL48iPCnwTvdBSl4xaIjAm uM/WWou5AEnmeAWYXzXoydBiiJTRKC5VdMtT9icvLFqog+iT5S1Bm3qUTfoT/vQRuLZ6HU055K/ 3kpckAgxFQSvHQlTK4gRu2Jq0nwn8dCDE/P5ieN7okydx2XvQN425SnkYxw4FFPLifk30+Mj4BZ FHV6PjhOeOPyANSd0qN5Mznb/P4A88DjzHKTnf7Y6ujctTCYZVKXEBNbWB0TRJ010ZZDWuLT8m6 QowyvrIfyxbr44bURbHPJ0gDEpyg7ytlqhVbsHIE4slrjiL2HSbhCP6MZK0IySeTKese6mfl+Qh U3c8zgGRFwjtlYh1Di01TGetCkMHoVe72g77jCH1d17OcclnCacYU+wq5atp61DJzw56uFE9J7R hVXF6Piuo36hs0gQcC1Vdj+E3Mkg1HV19JWACh/X1kvfcSnMGG6bVnmQTOQohOXNqNUdD0TvxpK +k41OANNXnRLKMtp2DiWJWtq0RyEw1A1AxJTRRlchRIZN8jf0F1HY9SOnlsAuCHLtw1ey7kLyjn IHc5B4hGuoU9TLQ== 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" The existing RkISP1Params helper classes allows the RkISP1 to handle V4L2 extensible parameters format and the legacy RkIPS1-specific fixed-size parameters format. With the introduction of v4l2-params in the Linux kernel the part of the RkISP1Params helper class that handles extensible parameters can be generalized so that other IPA modules can use the same helpers to populate a v4l2-params compatible buffer. Generalize the RkISP1Params class to a new libipa component named V4L2Params and derive the existing RkISP1Params from it, leaving in the RkISP1-specific implementation the handling of the legacy format. Deriving RkISP1Params from V4L2Params requires changing the size associated to each block to include the size of v4l2_params_block_header in the ipa:rkisp1::kBlockTypeInfo map as the V4L2Params::block() implementation doesn't account for that as RkIS1Params::block() implementation did. Signed-off-by: Jacopo Mondi --- src/ipa/libipa/meson.build | 2 + src/ipa/libipa/v4l2_params.cpp | 252 +++++++++++++++++++++++++++++++++++++++++ src/ipa/libipa/v4l2_params.h | 135 ++++++++++++++++++++++ src/ipa/rkisp1/params.cpp | 93 +-------------- src/ipa/rkisp1/params.h | 108 ++++++++---------- 5 files changed, 438 insertions(+), 152 deletions(-) diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build index 660be94054fa98b714b6bc586039081e45a6b4bc..4010739e710eb38aa6108eb8258c574a616bf3c0 100644 --- a/src/ipa/libipa/meson.build +++ b/src/ipa/libipa/meson.build @@ -16,6 +16,7 @@ libipa_headers = files([ 'lsc_polynomial.h', 'lux.h', 'module.h', + 'v4l2_params.h', 'pwl.h', ]) @@ -35,6 +36,7 @@ libipa_sources = files([ 'lsc_polynomial.cpp', 'lux.cpp', 'module.cpp', + 'v4l2_params.cpp', 'pwl.cpp', ]) diff --git a/src/ipa/libipa/v4l2_params.cpp b/src/ipa/libipa/v4l2_params.cpp new file mode 100644 index 0000000000000000000000000000000000000000..674018065ace0e1b6b48b1630e556cef590d1e84 --- /dev/null +++ b/src/ipa/libipa/v4l2_params.cpp @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Ideas On Board + * + * V4L2 Parameters + */ + +#include "v4l2_params.h" + +namespace libcamera { + +namespace ipa { + +/** + * \file v4l2_params.cpp + * \brief Helper class to populate a v4l2-params compatible parameters buffer + * + * The Linux kernel defines a generic buffer format for configuring ISP devices + * through a set of parameters in the form of V4L2 extensible parameters. The + * V4L2 extensible parameters define a serialization format for ISP parameters + * that allows userspace to populate a buffer of configuration data by appending + * them one after the other in a binary buffer. + * + * Each ISP driver compatible with the v4l2-params format will define its own + * meta-output format identifier and defines the types of the configuration data + * of each ISP block that usually match the registers layout. + * + * The V4L2Params class represent the V4L2 extensible parameters buffer and + * allows users to populate the ISP configuration blocks, represented by the + * V4L2ParamBlock class instances. + * + * IPA implementations using this helpers should define an enumeration of ISP + * blocks the IPA module supports and use a set of common abstraction to help + * their derived implementation of V4L2Params translate the enumerated ISP block + * identifier to the actual type of the configuration data as defined by the + * kernel interface. + * + * As an example of this see the RkISP1 and Mali-C55 implementations. + */ + +/** + * \class V4L2ParamsBlock + * \brief Helper class that represents a ISP configuration block + * + * Each ISP function is associated with a set of configuration parameters + * defined by the kernel interface. + * + * This class represents an ISP block configuration entry. It is constructed + * with a reference to the memory area where the block configuration will be + * stored in the parameters buffer. The template parameter represents + * the underlying kernel-defined ISP block configuration type and allow its + * user to easily cast it to said type to populate and read the configuration + * parameters. + * + * \sa V4L2Params::block() + */ + +/** + * \fn V4L2ParamsBlock::V4L2ParamsBlock() + * \brief Construct a V4L2ParamsBlock with memory represented by \a data + * \param[in] data A view on the memory area where the ISP block is located + */ + +/** + * \fn V4L2ParamsBlock::setEnabled() + * \brief Enable/disable an ISP configuration block + * \param[in] enabled The enable flag + */ + +/** + * \fn V4L2ParamsBlock::header() + * \brief Retrieve a reference to the header (struct v4l2_params_block_header) + * \return The block header + */ + +/** + * \fn V4L2ParamsBlock::data() + * \brief Retrieve a reference to block configuration data memory area + * \return The block data + */ + +/** + * \fn V4L2ParamsBlock::operator->() + * \brief Access the ISP configuration block casting it to the kernel-defined + * ISP configuration type + * + * The V4L2ParamsBlock is templated with the kernel defined ISP configuration + * block type. This function allows users to easily cast a V4L2ParamsBlock to + * the underlying kernel-defined type in order to easily populate or read + * the ISP configuration data. + * + * \code{.cpp} + * + * // The kernel header defines the ISP configuration types, in example + * // struct my_isp_awb_config_data { + * // u16 gain_ch00; + * // u16 gain_ch01; + * // u16 gain_ch10; + * // u16 gain_ch11; + * // + * // } + * + * template<> V4L2ParamsBlock awbBlock + * + * awbBlock->gain_ch00 = ...; + * awbBlock->gain_ch01 = ...; + * awbBlock->gain_ch10 = ...; + * awbBlock->gain_ch11 = ...; + * + * \endcode + * + * Users of this class are not expected to create a V4L2ParamsBlock manually but + * should rather use V4L2Params::block() to retrieve a reference to the memory + * area used to construct a V4L2ParamsBlock in their overloaded + * implementation of V4L2Params::block(). + */ + +/** + * \fn V4L2ParamsBlock::operator->() const + * \copydoc V4L2ParamsBlock::operator->() + */ + +/** + * \fn V4L2ParamsBlock::operator*() const + * \copydoc V4L2ParamsBlock::operator->() + */ + +/** + * \fn V4L2ParamsBlock::operator*() + * \copydoc V4L2ParamsBlock::operator->() + */ + + /** + * \class V4L2Params + * \brief Helper class that represent an ISP configuration buffer + * + * ISP implementation compatible with v4l2-params define their ISP configuration + * buffer types compatible with the struct v4l2_params_buffer type. + * + * This class represents an ISP configuration buffer. It is constructed + * with a reference to the memory mapped buffer that will be queued to the ISP. + * + * 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 and use the V4L2Params::block() function to retrieve the memory + * area for each ISP configuration block and use it to construct a + * V4L2ParamsBlock with it before returning it to the user. + * + * \code{.cpp} + * + * enum class myISPBlocks { + * Agc, + * Awb, + * ... + * }; + * + * template + * struct block_type { + * }; + * + * template<> + * struct block_type { + * using type = struct my_isp_kernel_config_type_agc; + * }; + * + * template<> + * struct block_type { + * using type = struct my_isp_kernel_config_type_awb; + * }; + * + * ... + * + * class MyISPParams : public V4L2Params + * { + * public: + * template + * auto block() + * { + * + * // Use the kernel defined configuration type as template + * // argument to V4L2ParamsBlock. + * using Type = typename details::block_type::type; + * + * // Each IPA module should provide the information required + * // to populate the block header + * + * ... + * + * auto data = V4L2Params::block(B, blockType, blockSize); + * + * return V4L2ParamsBlock(data); + * } + * }; + * + * \endcode + * + * As an example, see the RkISP1Params and MaliC55Params implementations. + */ + +/** + * \fn V4L2Params::V4L2Params() + * \brief Construct a V4L2Params + * \param[in] data Reference to the v4l2-buffer memory mapped area + * \param[in] version The ISP parameters version the implementation supports + */ + +/** + * \fn V4L2Params::size() + * \brief Retrieve the used size of the parameters buffer (in bytes) + * + * The parameters buffer size is mostly used to populate the v4l2_buffer + * bytesused field before queueing the buffer to the ISP. + * + * \return The number of bytes occupied by the ISP configuration parameters + */ + +/** + * \fn V4L2Params::block() + * \brief Populate an ISP configuration block a returns a reference to its + * memory + * \param[in] type The ISP block identifier enumerated by the IPA module + * \param[in] blockType The kernel-defined ISP block identifier, used to + * populate the block header + * \param[in] blockSize The ISP block size, used to populate the block header + * + * + * Initialize the block header with \a blockType and \a blockSize and + * returns a reference to the memory used to store an ISP configuration block. + * + * IPA modules that derive the V4L2Params class shall use this function to + * retrieve the memory area that will be used to construct a V4L2ParamsBlock + * before returning it to the caller. + */ + +/** + * \var V4L2Params::data_ + * \brief The ISP parameters buffer memory + */ + +/** + * \var V4L2Params::used_ + * \brief The number of bytes used in the parameters buffer + */ + +/** + * \var V4L2Params::blocks_ + * \brief Cache of ISP configuration blocks + */ + +} /* namespace ipa */ + +} /* namespace libcamera */ diff --git a/src/ipa/libipa/v4l2_params.h b/src/ipa/libipa/v4l2_params.h new file mode 100644 index 0000000000000000000000000000000000000000..5586096c7ee8a2d20877838564e8074e0fc3d1ce --- /dev/null +++ b/src/ipa/libipa/v4l2_params.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Ideas On Board + * + * V4L2 Parameters + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include + +namespace libcamera { + +namespace ipa { + +template +class V4L2ParamsBlock +{ +public: + V4L2ParamsBlock(const Span &data) + { + header_ = data.subspan(0, sizeof(v4l2_params_block_header)); + data_ = data.subspan(sizeof(v4l2_params_block_header)); + } + + void setEnabled(bool enabled) + { + struct v4l2_params_block_header *header = + reinterpret_cast(header_.data()); + + header->flags &= ~(V4L2_PARAMS_FL_BLOCK_ENABLE | + V4L2_PARAMS_FL_BLOCK_DISABLE); + header->flags |= enabled ? V4L2_PARAMS_FL_BLOCK_ENABLE + : V4L2_PARAMS_FL_BLOCK_DISABLE; + } + + Span header() const { return header_; } + Span data() const { return data_; } + + const T *operator->() const + { + return reinterpret_cast(data().data()); + } + + T *operator->() + { + return reinterpret_cast(data().data()); + } + + const T &operator*() const + { + return *reinterpret_cast(data().data()); + } + + T &operator*() + { + return *reinterpret_cast(data().data()); + } + +private: + LIBCAMERA_DISABLE_COPY(V4L2ParamsBlock) + + Span header_; + Span data_; +}; + +template +class V4L2Params +{ +public: + V4L2Params(Span data, unsigned int version) + : data_(data) + { + struct v4l2_params_buffer *cfg = + reinterpret_cast(data_.data()); + cfg->data_size = 0; + cfg->version = version; + used_ = offsetof(struct v4l2_params_buffer, data); + } + + size_t size() const { return used_; } + +protected: + Span block(T type, unsigned int blockType, size_t blockSize) + { + /* + * Look up the block in the cache first. If an algorithm + * requests the same block type twice, it should get the same + * block. + */ + auto cacheIt = blocks_.find(type); + if (cacheIt != blocks_.end()) + return cacheIt->second; + + /* Make sure we don't run out of space. */ + if (blockSize > data_.size() - used_) + return {}; + + /* Allocate a new block, clear its memory, and initialize its header. */ + Span block = data_.subspan(used_, blockSize); + used_ += blockSize; + + struct v4l2_params_buffer *cfg = + reinterpret_cast(data_.data()); + cfg->data_size += blockSize; + + memset(block.data(), 0, block.size()); + + struct v4l2_params_block_header *header = + reinterpret_cast(block.data()); + header->type = blockType; + header->size = block.size(); + + /* Update the cache. */ + blocks_[type] = block; + + return block; + } + + Span data_; + size_t used_; + + std::map> blocks_; +}; + +} /* namespace ipa */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/params.cpp b/src/ipa/rkisp1/params.cpp index 4c0b051ce65da1686323ee9c66b82e12669a754d..2b692e1a1f199d6c118af0938e1aaecef6186a2c 100644 --- a/src/ipa/rkisp1/params.cpp +++ b/src/ipa/rkisp1/params.cpp @@ -35,7 +35,7 @@ struct BlockTypeInfo { #define RKISP1_BLOCK_TYPE_ENTRY(block, id, type, category, bit) \ { BlockType::block, { \ RKISP1_EXT_PARAMS_BLOCK_TYPE_##id, \ - sizeof(struct rkisp1_cif_isp_##type##_config), \ + sizeof(struct rkisp1_ext_params_##type##_config), \ offsetof(struct rkisp1_params_cfg, category.type##_config), \ RKISP1_CIF_ISP_MODULE_##bit, \ } } @@ -49,7 +49,7 @@ struct BlockTypeInfo { #define RKISP1_BLOCK_TYPE_ENTRY_EXT(block, id, type) \ { BlockType::block, { \ RKISP1_EXT_PARAMS_BLOCK_TYPE_##id, \ - sizeof(struct rkisp1_cif_isp_##type##_config), \ + sizeof(struct rkisp1_ext_params_##type##_config), \ 0, 0, \ } } @@ -78,56 +78,6 @@ const std::map kBlockTypeInfo = { } /* namespace */ -RkISP1ParamsBlockBase::RkISP1ParamsBlockBase(RkISP1Params *params, BlockType type, - const Span &data) - : params_(params), type_(type) -{ - if (params_->format() == V4L2_META_FMT_RK_ISP1_EXT_PARAMS) { - header_ = data.subspan(0, sizeof(rkisp1_ext_params_block_header)); - data_ = data.subspan(sizeof(rkisp1_ext_params_block_header)); - } else { - data_ = data; - } -} - -void RkISP1ParamsBlockBase::setEnabled(bool enabled) -{ - /* - * For the legacy fixed format, blocks are enabled in the top-level - * header. Delegate to the RkISP1Params class. - */ - if (params_->format() == V4L2_META_FMT_RK_ISP1_PARAMS) - return params_->setBlockEnabled(type_, enabled); - - /* - * For the extensible format, set the enable and disable flags in the - * block header directly. - */ - struct rkisp1_ext_params_block_header *header = - reinterpret_cast(header_.data()); - header->flags &= ~(RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE | - RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE); - header->flags |= enabled ? RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE - : RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE; -} - -RkISP1Params::RkISP1Params(uint32_t format, Span data) - : format_(format), data_(data), used_(0) -{ - if (format_ == V4L2_META_FMT_RK_ISP1_EXT_PARAMS) { - struct rkisp1_ext_params_cfg *cfg = - reinterpret_cast(data.data()); - - cfg->version = RKISP1_EXT_PARAM_BUFFER_V1; - cfg->data_size = 0; - - used_ += offsetof(struct rkisp1_ext_params_cfg, data); - } else { - memset(data.data(), 0, data.size()); - used_ = sizeof(struct rkisp1_params_cfg); - } -} - void RkISP1Params::setBlockEnabled(BlockType type, bool enabled) { const BlockTypeInfo &info = kBlockTypeInfo.at(type); @@ -177,44 +127,7 @@ Span RkISP1Params::block(BlockType type) return data_.subspan(info.offset, info.size); } - /* - * For the extensible format, allocate memory for the block, including - * the header. Look up the block in the cache first. If an algorithm - * requests the same block type twice, it should get the same block. - */ - auto cacheIt = blocks_.find(type); - if (cacheIt != blocks_.end()) - return cacheIt->second; - - /* Make sure we don't run out of space. */ - size_t size = sizeof(struct rkisp1_ext_params_block_header) - + ((info.size + 7) & ~7); - if (size > data_.size() - used_) { - LOG(RkISP1Params, Error) - << "Out of memory to allocate block type " - << utils::to_underlying(type); - return {}; - } - - /* Allocate a new block, clear its memory, and initialize its header. */ - Span block = data_.subspan(used_, size); - used_ += size; - - struct rkisp1_ext_params_cfg *cfg = - reinterpret_cast(data_.data()); - cfg->data_size += size; - - memset(block.data(), 0, block.size()); - - struct rkisp1_ext_params_block_header *header = - reinterpret_cast(block.data()); - header->type = info.type; - header->size = block.size(); - - /* Update the cache. */ - blocks_[type] = block; - - return block; + return V4L2Params::block(type, info.type, info.size); } } /* namespace ipa::rkisp1 */ diff --git a/src/ipa/rkisp1/params.h b/src/ipa/rkisp1/params.h index 40450e34497a3aa71b5b0cda2bf045a1cc0e012f..7a21276648162a127317c75cb01d1c0059b96ee1 100644 --- a/src/ipa/rkisp1/params.h +++ b/src/ipa/rkisp1/params.h @@ -7,13 +7,10 @@ #pragma once -#include -#include - #include +#include -#include -#include +#include namespace libcamera { @@ -77,85 +74,72 @@ RKISP1_DEFINE_BLOCK_TYPE(CompandCompress, compand_curve) } /* namespace details */ -class RkISP1Params; +template +class RkISP1ParamsBlock; -class RkISP1ParamsBlockBase +class RkISP1Params : public V4L2Params { public: - RkISP1ParamsBlockBase(RkISP1Params *params, BlockType type, - const Span &data); - - Span data() const { return data_; } - - void setEnabled(bool enabled); + static constexpr unsigned int kVersion = RKISP1_EXT_PARAM_BUFFER_V1; -private: - LIBCAMERA_DISABLE_COPY(RkISP1ParamsBlockBase) - - RkISP1Params *params_; - BlockType type_; - Span header_; - Span data_; -}; - -template -class RkISP1ParamsBlock : public RkISP1ParamsBlockBase -{ -public: - using Type = typename details::block_type::type; - - RkISP1ParamsBlock(RkISP1Params *params, const Span &data) - : RkISP1ParamsBlockBase(params, B, data) + RkISP1Params(uint32_t format, Span data) + : V4L2Params(data, kVersion), format_(format) { + if (format_ == V4L2_META_FMT_RK_ISP1_PARAMS) { + memset(data.data(), 0, data.size()); + used_ = sizeof(struct rkisp1_params_cfg); + } } - const Type *operator->() const + template + auto block() { - return reinterpret_cast(data().data()); - } + using Type = typename details::block_type::type; - Type *operator->() - { - return reinterpret_cast(data().data()); + return RkISP1ParamsBlock(this, B, block(B)); } - const Type &operator*() const & - { - return *reinterpret_cast(data().data()); - } + uint32_t format() const { return format_; } + void setBlockEnabled(BlockType type, bool enabled); - Type &operator*() & - { - return *reinterpret_cast(data().data()); - } +private: + Span block(BlockType type); + + uint32_t format_; }; -class RkISP1Params +template +class RkISP1ParamsBlock : public V4L2ParamsBlock { public: - RkISP1Params(uint32_t format, Span data); - - template - RkISP1ParamsBlock block() + RkISP1ParamsBlock(RkISP1Params *params, BlockType type, + const Span &data) + : V4L2ParamsBlock(data) { - return RkISP1ParamsBlock(this, block(B)); + params_ = params; + type_ = type; + + /* Legacy param format has no header */ + if (params_->format() == V4L2_META_FMT_RK_ISP1_PARAMS) + data_ = data; } - uint32_t format() const { return format_; } - size_t size() const { return used_; } + void setEnabled(bool enabled) + { + /* + * For the legacy fixed format, blocks are enabled in the + * top-level header. Delegate to the RkISP1Params class. + */ + if (params_->format() == V4L2_META_FMT_RK_ISP1_PARAMS) + return params_->setBlockEnabled(type_, enabled); + + return V4L2ParamsBlock::setEnabled(enabled); + } private: - friend class RkISP1ParamsBlockBase; - - Span block(BlockType type); - void setBlockEnabled(BlockType type, bool enabled); - - uint32_t format_; - + RkISP1Params *params_; + BlockType type_; Span data_; - size_t used_; - - std::map> blocks_; }; } /* namespace ipa::rkisp1 */