From patchwork Fri Aug 29 11:54:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 24268 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 F0F7CBD87C for ; Fri, 29 Aug 2025 11:54:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A726B6932C; Fri, 29 Aug 2025 13:54:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="YmPOVztj"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A75B669322 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 8E1D24AF1; 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=8+Mh+sXxXH0o5FPqJYtuLIntBuAz28Ck0YbwSIor11M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YmPOVztjqpJTpL6MzZkqDtfE36AQAHJSGESvu//2RhJAMlnMjWls0pxh+qtUKjgr2 kM2cXmEhPScSKzQD9zQCi/bnxX/FHQ5sPCZ/QVYijuD5yr95vczzUZtlEmv4ZwA/Wz D+T+THrfWgHVpy2HudLLDd30s9AMePD0JZVA7afQ= From: Jacopo Mondi Date: Fri, 29 Aug 2025 13:54:01 +0200 Subject: [PATCH 4/4] ipa: mali-c55: Introduce MaliC55Params MIME-Version: 1.0 Message-Id: <20250829-v4l2-params-v1-4-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=25188; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=8+Mh+sXxXH0o5FPqJYtuLIntBuAz28Ck0YbwSIor11M=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBosZTun04/UcxeR8qNYTjuZd1Y8NmEajJN5Q5kI EO0dpU3BAmJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaLGU7gAKCRByNAaPFqFW PG91EADEbQftmyC7tqubJk8eZ2M/nlAO02oWmESoMTv23IoN8Gf4yBpCTORlgd26et8CAUMB73c yO3SgwKBSOJqPze8qijE9iKlTgJ78rfnGSI5rz8D80Ejhas9DTjITvzwfQpYAyuvVElMQQo2Q26 dfw7Y+h+Ab4vrKYuTY+bDlphdc1b/aAywqvB6c0wWCu5K6AlKay+SM7IV0ED3zsH83VJjm1R2OW pERXhiOMSm3sSDJsT0UK2jICU7DOIEhZXvaUAnYPKief2A1MoKxjFP2r3BXl1kcIvq7tHM/sG5O O6iD2VYDYeu5nXuk42ZOgrjSPaDiWpikQYfZWqxmxoLSPMeKI2gtPR6uEKCwUDyVRvugRLH5cFe l99eywMDNAs5E1SngaOyKPJVlCX3HoiKXuH6dou1fsquD0tfhkvF7y6I6PL4WqtmVddjM0F5xrA EWgLJw1JGZRnUmxyaoqHgPZ4361CMZlCj6Ls+b1sKZwG67byzBNGAwnkplJUQngb4OmnZHST4l2 Gh8Jn0zm6I47zqOAO9CgOurOFh605MQ5ygLuUdX1VCeyXm5AyWtANm831lHotIKMCR2+KSUHzx1 PXSFmK1LYoxVI7DQ+8NPDbY5v3VKBvWyrek2kj4OPBHqQSfcikVMoIhQbKcqSP81qi85psTaRwA ncv1JoUXi9YbMig== 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" Implement MaliC55Params to derive from V4L2Params and use the new helpers in the Mali C55 IPA algorithms implementation. Signed-off-by: Jacopo Mondi --- src/ipa/mali-c55/algorithms/agc.cpp | 87 +++++++++++++++--------------------- src/ipa/mali-c55/algorithms/agc.h | 14 +++--- src/ipa/mali-c55/algorithms/awb.cpp | 64 +++++++++++--------------- src/ipa/mali-c55/algorithms/awb.h | 10 ++--- src/ipa/mali-c55/algorithms/blc.cpp | 20 +++------ src/ipa/mali-c55/algorithms/blc.h | 3 +- src/ipa/mali-c55/algorithms/lsc.cpp | 58 ++++++++++-------------- src/ipa/mali-c55/algorithms/lsc.h | 8 ++-- src/ipa/mali-c55/mali-c55.cpp | 19 +++----- src/ipa/mali-c55/module.h | 3 +- src/ipa/mali-c55/params.h | 89 +++++++++++++++++++++++++++++++++++++ 11 files changed, 203 insertions(+), 172 deletions(-) diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp index 80d9d956d07d1665e61876b0429fb94a30c7cbe1..c1ed1cd78430e8ea0b3ea6998c7ee17e43ed777d 100644 --- a/src/ipa/mali-c55/algorithms/agc.cpp +++ b/src/ipa/mali-c55/algorithms/agc.cpp @@ -240,8 +240,8 @@ void Agc::queueRequest(IPAContext &context, const uint32_t frame, } } -size_t Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContext, - mali_c55_params_block block) +void Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContext, + MaliC55Params *params) { IPAActiveState &activeState = context.activeState; double gain; @@ -251,52 +251,50 @@ size_t Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContex else gain = activeState.agc.manual.ispGain; - block.header->type = MALI_C55_PARAM_BLOCK_DIGITAL_GAIN; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_digital_gain); + auto block = params->block(); + block->gain = floatingToFixedPoint<5, 8, uint16_t, double>(gain); - block.digital_gain->gain = floatingToFixedPoint<5, 8, uint16_t, double>(gain); frameContext.agc.ispGain = gain; - - return block.header->size; } -size_t Agc::fillParamsBuffer(mali_c55_params_block block, - enum mali_c55_param_block_type type) +void Agc::fillParamsBuffer(MaliC55Params *params, enum MaliC55Blocks type) { - block.header->type = type; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_aexp_hist); + + assert(type == MaliC55Blocks::AexpHist || type == MaliC55Blocks::AexpIhist); + + auto block = type == MaliC55Blocks::AexpHist ? + params->block() : + params->block(); /* Collect every 3rd pixel horizontally */ - block.aexp_hist->skip_x = 1; + block->skip_x = 1; /* Start from first column */ - block.aexp_hist->offset_x = 0; + block->offset_x = 0; /* Collect every pixel vertically */ - block.aexp_hist->skip_y = 0; + block->skip_y = 0; /* Start from the first row */ - block.aexp_hist->offset_y = 0; + block->offset_y = 0; /* 1x scaling (i.e. none) */ - block.aexp_hist->scale_bottom = 0; - block.aexp_hist->scale_top = 0; + block->scale_bottom = 0; + block->scale_top = 0; /* Collect all Bayer planes into 4 separate histograms */ - block.aexp_hist->plane_mode = 1; + block->plane_mode = 1; /* Tap the data immediately after the digital gain block */ - block.aexp_hist->tap_point = MALI_C55_AEXP_HIST_TAP_FS; - - return block.header->size; + block->tap_point = MALI_C55_AEXP_HIST_TAP_FS; } -size_t Agc::fillWeightsArrayBuffer(mali_c55_params_block block, - enum mali_c55_param_block_type type) +void Agc::fillWeightsArrayBuffer(MaliC55Params *params, const enum MaliC55Blocks type) { - block.header->type = type; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_aexp_weights); + assert(type == MaliC55Blocks::AexpHistWeights || + type == MaliC55Blocks::AexpIhistWeights); + + auto block = type == MaliC55Blocks::AexpHistWeights ? + params->block() : + params->block(); /* We use every zone - a 15x15 grid */ - block.aexp_weights->nodes_used_horiz = 15; - block.aexp_weights->nodes_used_vert = 15; + block->nodes_used_horiz = 15; + block->nodes_used_vert = 15; /* * We uniformly weight the zones to 1 - this results in the collected @@ -304,40 +302,25 @@ size_t Agc::fillWeightsArrayBuffer(mali_c55_params_block block, * approximate colour channel averages for the image. */ Span weights{ - block.aexp_weights->zone_weights, + block->zone_weights, MALI_C55_MAX_ZONES }; std::fill(weights.begin(), weights.end(), 1); - - return block.header->size; } void Agc::prepare(IPAContext &context, const uint32_t frame, - IPAFrameContext &frameContext, v4l2_params_buffer *params) + IPAFrameContext &frameContext, MaliC55Params *params) { - mali_c55_params_block block; - - block.data = ¶ms->data[params->data_size]; - params->data_size += fillGainParamBlock(context, frameContext, block); + fillGainParamBlock(context, frameContext, params); if (frame > 0) return; - block.data = ¶ms->data[params->data_size]; - params->data_size += fillParamsBuffer(block, - MALI_C55_PARAM_BLOCK_AEXP_HIST); - - block.data = ¶ms->data[params->data_size]; - params->data_size += fillWeightsArrayBuffer(block, - MALI_C55_PARAM_BLOCK_AEXP_HIST_WEIGHTS); - - block.data = ¶ms->data[params->data_size]; - params->data_size += fillParamsBuffer(block, - MALI_C55_PARAM_BLOCK_AEXP_IHIST); + fillParamsBuffer(params, MaliC55Blocks::AexpHist); + fillWeightsArrayBuffer(params, MaliC55Blocks::AexpHistWeights); - block.data = ¶ms->data[params->data_size]; - params->data_size += fillWeightsArrayBuffer(block, - MALI_C55_PARAM_BLOCK_AEXP_IHIST_WEIGHTS); + fillParamsBuffer(params, MaliC55Blocks::AexpIhist); + fillWeightsArrayBuffer(params, MaliC55Blocks::AexpIhistWeights); } double Agc::estimateLuminance(const double gain) const diff --git a/src/ipa/mali-c55/algorithms/agc.h b/src/ipa/mali-c55/algorithms/agc.h index 64caf99350c1d1835832311a94a88a2bfde5721c..9684fff664bc67d287bb00f8dc88e238d8dd0cea 100644 --- a/src/ipa/mali-c55/algorithms/agc.h +++ b/src/ipa/mali-c55/algorithms/agc.h @@ -57,7 +57,7 @@ public: const ControlList &controls) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, - v4l2_params_buffer *params) override; + MaliC55Params *params) override; void process(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, const mali_c55_stats_buffer *stats, @@ -65,13 +65,11 @@ public: private: double estimateLuminance(const double gain) const override; - size_t fillGainParamBlock(IPAContext &context, - IPAFrameContext &frameContext, - mali_c55_params_block block); - size_t fillParamsBuffer(mali_c55_params_block block, - enum mali_c55_param_block_type type); - size_t fillWeightsArrayBuffer(mali_c55_params_block block, - enum mali_c55_param_block_type type); + void fillGainParamBlock(IPAContext &context, + IPAFrameContext &frameContext, + MaliC55Params *params); + void fillParamsBuffer(MaliC55Params *params, enum MaliC55Blocks type); + void fillWeightsArrayBuffer(MaliC55Params *params, enum MaliC55Blocks type); AgcStatistics statistics_; }; diff --git a/src/ipa/mali-c55/algorithms/awb.cpp b/src/ipa/mali-c55/algorithms/awb.cpp index 6b2cbed9de1ebfe9a2466ebe999eceac44fe5deb..964e810882a93cce02f991675d74bbf163d51e7c 100644 --- a/src/ipa/mali-c55/algorithms/awb.cpp +++ b/src/ipa/mali-c55/algorithms/awb.cpp @@ -43,13 +43,9 @@ int Awb::configure([[maybe_unused]] IPAContext &context, return 0; } -size_t Awb::fillGainsParamBlock(mali_c55_params_block block, IPAContext &context, +void Awb::fillGainsParamBlock(MaliC55Params *params, IPAContext &context, IPAFrameContext &frameContext) { - block.header->type = MALI_C55_PARAM_BLOCK_AWB_GAINS; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_awb_gains); - double rGain = context.activeState.awb.rGain; double bGain = context.activeState.awb.bGain; @@ -63,34 +59,32 @@ size_t Awb::fillGainsParamBlock(mali_c55_params_block block, IPAContext &context * This holds true regardless of the bayer order of the input data, as * the mapping is done internally in the ISP. */ - block.awb_gains->gain00 = floatingToFixedPoint<4, 8, uint16_t, double>(rGain); - block.awb_gains->gain01 = floatingToFixedPoint<4, 8, uint16_t, double>(1.0); - block.awb_gains->gain10 = floatingToFixedPoint<4, 8, uint16_t, double>(1.0); - block.awb_gains->gain11 = floatingToFixedPoint<4, 8, uint16_t, double>(bGain); + auto block = params->block(); + + block->gain00 = floatingToFixedPoint<4, 8, uint16_t, double>(rGain); + block->gain01 = floatingToFixedPoint<4, 8, uint16_t, double>(1.0); + block->gain10 = floatingToFixedPoint<4, 8, uint16_t, double>(1.0); + block->gain11 = floatingToFixedPoint<4, 8, uint16_t, double>(bGain); frameContext.awb.rGain = rGain; frameContext.awb.bGain = bGain; - - return sizeof(struct mali_c55_params_awb_gains); } -size_t Awb::fillConfigParamBlock(mali_c55_params_block block) +void Awb::fillConfigParamBlock(MaliC55Params *params) { - block.header->type = MALI_C55_PARAM_BLOCK_AWB_CONFIG; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_awb_config); + auto block = params->block(); /* Tap the stats after the purple fringe block */ - block.awb_config->tap_point = MALI_C55_AWB_STATS_TAP_PF; + block->tap_point = MALI_C55_AWB_STATS_TAP_PF; /* Get R/G and B/G ratios as statistics */ - block.awb_config->stats_mode = MALI_C55_AWB_MODE_RGBG; + block->stats_mode = MALI_C55_AWB_MODE_RGBG; /* Default white level */ - block.awb_config->white_level = 1023; + block->white_level = 1023; /* Default black level */ - block.awb_config->black_level = 0; + block->black_level = 0; /* * By default pixels are included who's colour ratios are bounded in a @@ -104,40 +98,34 @@ size_t Awb::fillConfigParamBlock(mali_c55_params_block block) * * \todo should these perhaps be tunable? */ - block.awb_config->cr_max = 511; - block.awb_config->cr_min = 64; - block.awb_config->cb_max = 511; - block.awb_config->cb_min = 64; + block->cr_max = 511; + block->cr_min = 64; + block->cb_max = 511; + block->cb_min = 64; /* We use the full 15x15 zoning scheme */ - block.awb_config->nodes_used_horiz = 15; - block.awb_config->nodes_used_vert = 15; + block->nodes_used_horiz = 15; + block->nodes_used_vert = 15; /* * We set the trimming boundaries equivalent to the main boundaries. In * other words; no trimming. */ - block.awb_config->cr_high = 511; - block.awb_config->cr_low = 64; - block.awb_config->cb_high = 511; - block.awb_config->cb_low = 64; - - return sizeof(struct mali_c55_params_awb_config); + block->cr_high = 511; + block->cr_low = 64; + block->cb_high = 511; + block->cb_low = 64; } void Awb::prepare(IPAContext &context, const uint32_t frame, - IPAFrameContext &frameContext, v4l2_params_buffer *params) + IPAFrameContext &frameContext, MaliC55Params *params) { - mali_c55_params_block block; - block.data = ¶ms->data[params->data_size]; - - params->data_size += fillGainsParamBlock(block, context, frameContext); + fillGainsParamBlock(params, context, frameContext); if (frame > 0) return; - block.data = ¶ms->data[params->data_size]; - params->data_size += fillConfigParamBlock(block); + fillConfigParamBlock(params); } void Awb::process(IPAContext &context, const uint32_t frame, diff --git a/src/ipa/mali-c55/algorithms/awb.h b/src/ipa/mali-c55/algorithms/awb.h index b5ff121041d1a01e3a51d64b87a90fb2e1d8dd10..683a62af263a14d2f5d5b261448953ada6669b2f 100644 --- a/src/ipa/mali-c55/algorithms/awb.h +++ b/src/ipa/mali-c55/algorithms/awb.h @@ -22,17 +22,17 @@ public: const IPACameraSensorInfo &configInfo) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, - v4l2_params_buffer *params) override; + MaliC55Params *params) override; void process(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, const mali_c55_stats_buffer *stats, ControlList &metadata) override; private: - size_t fillGainsParamBlock(mali_c55_params_block block, - IPAContext &context, - IPAFrameContext &frameContext); - size_t fillConfigParamBlock(mali_c55_params_block block); + void fillGainsParamBlock(MaliC55Params *params, + IPAContext &context, + IPAFrameContext &frameContext); + void fillConfigParamBlock(MaliC55Params *params); }; } /* namespace ipa::mali_c55::algorithms */ diff --git a/src/ipa/mali-c55/algorithms/blc.cpp b/src/ipa/mali-c55/algorithms/blc.cpp index 8fd0f10c3082030a36a256830042d733ed4c8c78..d099219c3e43ec96fa452ed13fa46ada2025edc9 100644 --- a/src/ipa/mali-c55/algorithms/blc.cpp +++ b/src/ipa/mali-c55/algorithms/blc.cpp @@ -85,27 +85,19 @@ int BlackLevelCorrection::configure(IPAContext &context, void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context, const uint32_t frame, [[maybe_unused]] IPAFrameContext &frameContext, - v4l2_params_buffer *params) + MaliC55Params *params) { - mali_c55_params_block block; - block.data = ¶ms->data[params->data_size]; - if (frame > 0) return; if (!tuningParameters_) return; - block.header->type = MALI_C55_PARAM_BLOCK_SENSOR_OFFS; - block.header->flags = 0; - block.header->size = sizeof(mali_c55_params_sensor_off_preshading); - - block.sensor_offs->chan00 = offset00; - block.sensor_offs->chan01 = offset01; - block.sensor_offs->chan10 = offset10; - block.sensor_offs->chan11 = offset11; - - params->data_size += block.header->size; + auto block = params->block(); + block->chan00 = offset00; + block->chan01 = offset01; + block->chan10 = offset10; + block->chan11 = offset11; } void BlackLevelCorrection::process([[maybe_unused]] IPAContext &context, diff --git a/src/ipa/mali-c55/algorithms/blc.h b/src/ipa/mali-c55/algorithms/blc.h index cf10505ce2908df0d5e658d3fdce663729c7ea76..fc5a7ea310cbdbcf271eb26c73b17243aea744cd 100644 --- a/src/ipa/mali-c55/algorithms/blc.h +++ b/src/ipa/mali-c55/algorithms/blc.h @@ -6,6 +6,7 @@ */ #include "algorithm.h" +#include "params.h" namespace libcamera { @@ -22,7 +23,7 @@ public: const IPACameraSensorInfo &configInfo) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, - v4l2_params_buffer *params) override; + MaliC55Params *params) override; void process(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, const mali_c55_stats_buffer *stats, diff --git a/src/ipa/mali-c55/algorithms/lsc.cpp b/src/ipa/mali-c55/algorithms/lsc.cpp index 35f1d876e60db252a45cadb771e541735749d106..5b042c757bc70fe4eb4a5aaa848266b3afce9100 100644 --- a/src/ipa/mali-c55/algorithms/lsc.cpp +++ b/src/ipa/mali-c55/algorithms/lsc.cpp @@ -108,41 +108,33 @@ int Lsc::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData return 0; } -size_t Lsc::fillConfigParamsBlock(mali_c55_params_block block) const +void Lsc::fillConfigParamsBlock(MaliC55Params *params) const { - block.header->type = MALI_C55_PARAM_MESH_SHADING_CONFIG; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_mesh_shading_config); + auto block = params->block(); - block.shading_config->mesh_show = false; - block.shading_config->mesh_scale = meshScale_; - block.shading_config->mesh_page_r = 0; - block.shading_config->mesh_page_g = 1; - block.shading_config->mesh_page_b = 2; - block.shading_config->mesh_width = meshSize_; - block.shading_config->mesh_height = meshSize_; + block->mesh_show = false; + block->mesh_scale = meshScale_; + block->mesh_page_r = 0; + block->mesh_page_g = 1; + block->mesh_page_b = 2; + block->mesh_width = meshSize_; + block->mesh_height = meshSize_; - std::copy(mesh_.begin(), mesh_.end(), block.shading_config->mesh); - - return block.header->size; + std::copy(mesh_.begin(), mesh_.end(), block->mesh); } -size_t Lsc::fillSelectionParamsBlock(mali_c55_params_block block, uint8_t bank, +void Lsc::fillSelectionParamsBlock(MaliC55Params *params, uint8_t bank, uint8_t alpha) const { - block.header->type = MALI_C55_PARAM_MESH_SHADING_SELECTION; - block.header->flags = 0; - block.header->size = sizeof(struct mali_c55_params_mesh_shading_selection); - - block.shading_selection->mesh_alpha_bank_r = bank; - block.shading_selection->mesh_alpha_bank_g = bank; - block.shading_selection->mesh_alpha_bank_b = bank; - block.shading_selection->mesh_alpha_r = alpha; - block.shading_selection->mesh_alpha_g = alpha; - block.shading_selection->mesh_alpha_b = alpha; - block.shading_selection->mesh_strength = 0x1000; /* Otherwise known as 1.0 */ - - return block.header->size; + auto block = params->block(); + + block->mesh_alpha_bank_r = bank; + block->mesh_alpha_bank_g = bank; + block->mesh_alpha_bank_b = bank; + block->mesh_alpha_r = alpha; + block->mesh_alpha_g = alpha; + block->mesh_alpha_b = alpha; + block->mesh_strength = 0x1000; /* Otherwise known as 1.0 */ } std::tuple Lsc::findBankAndAlpha(uint32_t ct) const @@ -170,7 +162,7 @@ std::tuple Lsc::findBankAndAlpha(uint32_t ct) const void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame, [[maybe_unused]] IPAFrameContext &frameContext, - v4l2_params_buffer *params) + MaliC55Params *params) { /* * For each frame we assess the colour temperature of the **last** frame @@ -193,10 +185,7 @@ void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame, std::tie(bank, alpha) = findBankAndAlpha(temperatureK); } - mali_c55_params_block block; - block.data = ¶ms->data[params->data_size]; - - params->data_size += fillSelectionParamsBlock(block, bank, alpha); + fillSelectionParamsBlock(params, bank, alpha); if (frame > 0) return; @@ -205,8 +194,7 @@ void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame, * If this is the first frame, we need to load the parsed coefficient * tables from tuning data to the ISP. */ - block.data = ¶ms->data[params->data_size]; - params->data_size += fillConfigParamsBlock(block); + fillConfigParamsBlock(params); } REGISTER_IPA_ALGORITHM(Lsc, "Lsc") diff --git a/src/ipa/mali-c55/algorithms/lsc.h b/src/ipa/mali-c55/algorithms/lsc.h index 9019a61aa547e41154615eba88547d3eee1634e2..e7092bc74a0b0301463167d16e1e888696547d10 100644 --- a/src/ipa/mali-c55/algorithms/lsc.h +++ b/src/ipa/mali-c55/algorithms/lsc.h @@ -23,15 +23,15 @@ public: int init(IPAContext &context, const YamlObject &tuningData) override; void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, - v4l2_params_buffer *params) override; + MaliC55Params *params) override; private: static constexpr unsigned int kRedOffset = 0; static constexpr unsigned int kGreenOffset = 1024; static constexpr unsigned int kBlueOffset = 2048; - size_t fillConfigParamsBlock(mali_c55_params_block block) const; - size_t fillSelectionParamsBlock(mali_c55_params_block block, - uint8_t bank, uint8_t alpha) const; + void fillConfigParamsBlock(MaliC55Params *params) const; + void fillSelectionParamsBlock(MaliC55Params *params, + uint8_t bank, uint8_t alpha) const; std::tuple findBankAndAlpha(uint32_t ct) const; std::vector mesh_ = std::vector(3072); diff --git a/src/ipa/mali-c55/mali-c55.cpp b/src/ipa/mali-c55/mali-c55.cpp index a6d3e984a438c01509ed27469d9f20c25bc884cf..fe36d4445c3ac75abe48dbe2335fa1f3aded9609 100644 --- a/src/ipa/mali-c55/mali-c55.cpp +++ b/src/ipa/mali-c55/mali-c55.cpp @@ -28,6 +28,7 @@ #include "libipa/camera_sensor_helper.h" #include "ipa_context.h" +#include "params.h" namespace libcamera { @@ -331,23 +332,13 @@ void IPAMaliC55::queueRequest(const uint32_t request, const ControlList &control void IPAMaliC55::fillParams(unsigned int request, [[maybe_unused]] uint32_t bufferId) { - struct v4l2_params_buffer *params; IPAFrameContext &frameContext = context_.frameContexts.get(request); + MaliC55Params params(buffers_.at(bufferId).planes()[0]); - params = reinterpret_cast( - buffers_.at(bufferId).planes()[0].data()); - memset(params, 0, sizeof(v4l2_params_buffer)); - - params->version = MALI_C55_PARAM_BUFFER_V1; - - for (auto const &algo : algorithms()) { - algo->prepare(context_, request, frameContext, params); - - ASSERT(params->data_size <= MALI_C55_PARAMS_MAX_SIZE); - } + for (auto const &algo : algorithms()) + algo->prepare(context_, request, frameContext, ¶ms); - size_t bytesused = offsetof(struct v4l2_params_buffer, data) + params->data_size; - paramsComputed.emit(request, bytesused); + paramsComputed.emit(request, params.size()); } void IPAMaliC55::processStats(unsigned int request, unsigned int bufferId, diff --git a/src/ipa/mali-c55/module.h b/src/ipa/mali-c55/module.h index 434d2c585d2f4eb03402c57e87302fc82e82a0f0..13b34eb2839530a3518340165e6ca895d0f6bcaf 100644 --- a/src/ipa/mali-c55/module.h +++ b/src/ipa/mali-c55/module.h @@ -14,13 +14,14 @@ #include #include "ipa_context.h" +#include "params.h" namespace libcamera { namespace ipa::mali_c55 { using Module = ipa::Module; + MaliC55Params, mali_c55_stats_buffer>; } /* namespace ipa::mali_c55 */ diff --git a/src/ipa/mali-c55/params.h b/src/ipa/mali-c55/params.h new file mode 100644 index 0000000000000000000000000000000000000000..1cc56dbad539ba6720f9b1e73c8339eb3bf885c7 --- /dev/null +++ b/src/ipa/mali-c55/params.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Ideas On Board + * + * Mali C55 ISP Parameters + */ + +#pragma once + +#include +#include + +#include + +namespace libcamera { + +namespace ipa::mali_c55 { + +enum class MaliC55Blocks { + Bls, + AexpHist, + AexpHistWeights, + AexpIhist, + AexpIhistWeights, + Dgain, + AwbGains, + AwbConfig, + MeshShadingConfig, + MeshShadingSel, +}; + +namespace details { + +template +struct block_type { +}; + +#define MALI_C55_DEFINE_BLOCK_TYPE(id, cfgType, blkType) \ +template<> \ +struct block_type { \ + using type = struct mali_c55_params_##cfgType; \ + static constexpr mali_c55_param_block_type blockType = \ + mali_c55_param_block_type::MALI_C55_PARAM_##blkType; \ +}; + +MALI_C55_DEFINE_BLOCK_TYPE(Bls, sensor_off_preshading, BLOCK_SENSOR_OFFS) +MALI_C55_DEFINE_BLOCK_TYPE(AexpHist, aexp_hist, BLOCK_AEXP_HIST) +MALI_C55_DEFINE_BLOCK_TYPE(AexpHistWeights, aexp_weights, + BLOCK_AEXP_HIST_WEIGHTS) +MALI_C55_DEFINE_BLOCK_TYPE(AexpIhist, aexp_hist, BLOCK_AEXP_IHIST) +MALI_C55_DEFINE_BLOCK_TYPE(AexpIhistWeights, aexp_weights, + BLOCK_AEXP_IHIST_WEIGHTS) +MALI_C55_DEFINE_BLOCK_TYPE(Dgain, digital_gain, BLOCK_DIGITAL_GAIN) +MALI_C55_DEFINE_BLOCK_TYPE(AwbGains, awb_gains, BLOCK_AWB_GAINS) +MALI_C55_DEFINE_BLOCK_TYPE(AwbConfig, awb_config, BLOCK_AWB_CONFIG) +MALI_C55_DEFINE_BLOCK_TYPE(MeshShadingConfig, mesh_shading_config, + MESH_SHADING_CONFIG) +MALI_C55_DEFINE_BLOCK_TYPE(MeshShadingSel, mesh_shading_selection, + MESH_SHADING_SELECTION) + +} /* namespace details */ + +class MaliC55Params : public V4L2Params +{ +public: + static constexpr unsigned int kVersion = MALI_C55_PARAM_BUFFER_V1; + + MaliC55Params(Span data) + : V4L2Params(data, kVersion) + { + } + + template + auto block() + { + using Type = typename details::block_type::type; + + auto blockType = details::block_type::blockType; + size_t blockSize = sizeof(Type); + + auto data = V4L2Params::block(B, blockType, blockSize); + + return V4L2ParamsBlock(data); + } +}; + +} /* namespace ipa::mali_c55 */ + +} /* namespace libcamera */