[{"id":30349,"web_url":"https://patchwork.libcamera.org/comment/30349/","msgid":"<Zofp5U0a9pNVv4ZG@pyrite.rasen.tech>","date":"2024-07-05T12:41:09","subject":"Re: [PATCH v2 06/11] ipa: rkisp1: Use the new ISP parameters\n\tabstraction","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"On Thu, Jul 04, 2024 at 07:20:30PM +0300, Laurent Pinchart wrote:\n> Use the new ISP parameters abstraction class RkISP1Params to access the\n> ISP parameters in the IPA algorithms. The class replaces the pointer to\n> the rkisp1_params_cfg structure passed to the algorithms' prepare()\n> function, and is used to access individual parameters blocks.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n> Changes since v1:\n> \n> - Fix the DPF logic\n> - Move the params enabled state handling to a setEnabled() function\n> ---\n>  src/ipa/rkisp1/algorithms/agc.cpp    | 48 +++++++++++------------\n>  src/ipa/rkisp1/algorithms/agc.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/awb.cpp    | 58 ++++++++++++----------------\n>  src/ipa/rkisp1/algorithms/awb.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/blc.cpp    | 19 +++++----\n>  src/ipa/rkisp1/algorithms/blc.h      |  3 +-\n>  src/ipa/rkisp1/algorithms/ccm.cpp    | 15 +++----\n>  src/ipa/rkisp1/algorithms/ccm.h      |  4 +-\n>  src/ipa/rkisp1/algorithms/cproc.cpp  | 14 +++----\n>  src/ipa/rkisp1/algorithms/cproc.h    |  2 +-\n>  src/ipa/rkisp1/algorithms/dpcc.cpp   | 10 ++---\n>  src/ipa/rkisp1/algorithms/dpcc.h     |  2 +-\n>  src/ipa/rkisp1/algorithms/dpf.cpp    | 27 +++++++------\n>  src/ipa/rkisp1/algorithms/dpf.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/filter.cpp | 52 ++++++++++++-------------\n>  src/ipa/rkisp1/algorithms/filter.h   |  2 +-\n>  src/ipa/rkisp1/algorithms/goc.cpp    | 17 ++++----\n>  src/ipa/rkisp1/algorithms/goc.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/gsl.cpp    | 20 ++++------\n>  src/ipa/rkisp1/algorithms/gsl.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/lsc.cpp    | 29 +++++++-------\n>  src/ipa/rkisp1/algorithms/lsc.h      |  4 +-\n>  src/ipa/rkisp1/module.h              |  3 +-\n>  src/ipa/rkisp1/rkisp1.cpp            | 12 ++----\n>  24 files changed, 162 insertions(+), 189 deletions(-)\n> \n> diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\n> index f12f8b60de15..c01fbdf3b8af 100644\n> --- a/src/ipa/rkisp1/algorithms/agc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/agc.cpp\n> @@ -281,7 +281,7 @@ void Agc::queueRequest(IPAContext &context,\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Agc::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \tif (frameContext.agc.autoEnabled) {\n>  \t\tframeContext.agc.exposure = context.activeState.agc.automatic.exposure;\n> @@ -291,41 +291,39 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,\n>  \tif (frame > 0 && !frameContext.agc.updateMetering)\n>  \t\treturn;\n>  \n> -\t/* Configure the measurement window. */\n> -\tparams->meas.aec_config.meas_window = context.configuration.agc.measureWindow;\n> -\t/* Use a continuous method for measure. */\n> -\tparams->meas.aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;\n> -\t/* Estimate Y as (R + G + B) x (85/256). */\n> -\tparams->meas.aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;\n> +\t/*\n> +\t * Configure the AEC measurements. Set the window, measure\n> +\t * continuously, and estimate Y as (R + G + B) x (85/256).\n> +\t */\n> +\tauto aecConfig = params->block<Block::Aec>();\n> +\taecConfig.setEnabled(true);\n>  \n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AEC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_AEC;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC;\n> +\taecConfig->meas_window = context.configuration.agc.measureWindow;\n> +\taecConfig->autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;\n> +\taecConfig->mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;\n>  \n> -\t/* Configure histogram. */\n> -\tparams->meas.hst_config.meas_window = context.configuration.agc.measureWindow;\n> -\t/* Produce the luminance histogram. */\n> -\tparams->meas.hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;\n> +\t/*\n> +\t * Configure the histogram measurement. Set the window, produce a\n> +\t * luminance histogram, and set the weights and predivider.\n> +\t */\n> +\tauto hstConfig = params->block<Block::Hst>();\n> +\thstConfig.setEnabled(true);\n> +\n> +\thstConfig->meas_window = context.configuration.agc.measureWindow;\n> +\thstConfig->mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;\n>  \n> -\t/* Set an average weighted histogram. */\n>  \tSpan<uint8_t> weights{\n> -\t\tparams->meas.hst_config.hist_weight,\n> +\t\thstConfig->hist_weight,\n>  \t\tcontext.hw->numHistogramWeights\n>  \t};\n>  \tstd::vector<uint8_t> &modeWeights = meteringModes_.at(frameContext.agc.meteringMode);\n>  \tstd::copy(modeWeights.begin(), modeWeights.end(), weights.begin());\n>  \n> -\tstruct rkisp1_cif_isp_window window = params->meas.hst_config.meas_window;\n> +\tstruct rkisp1_cif_isp_window window = hstConfig->meas_window;\n>  \tSize windowSize = { window.h_size, window.v_size };\n> -\tparams->meas.hst_config.histogram_predivider =\n> +\thstConfig->histogram_predivider =\n>  \t\tcomputeHistogramPredivider(windowSize,\n> -\t\t\t\t\t   static_cast<rkisp1_cif_isp_histogram_mode>(params->meas.hst_config.mode));\n> -\n> -\t/* Update the configuration for histogram. */\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_HST;\n> -\t/* Enable the histogram measure unit. */\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_HST;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_HST;\n> +\t\t\t\t\t   static_cast<rkisp1_cif_isp_histogram_mode>(hstConfig->mode));\n>  }\n>  \n>  void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,\n> diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h\n> index 9ceaa82b099e..d64ff42c1665 100644\n> --- a/src/ipa/rkisp1/algorithms/agc.h\n> +++ b/src/ipa/rkisp1/algorithms/agc.h\n> @@ -37,7 +37,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp\n> index a01fe5d90973..e81213febd88 100644\n> --- a/src/ipa/rkisp1/algorithms/awb.cpp\n> +++ b/src/ipa/rkisp1/algorithms/awb.cpp\n> @@ -108,7 +108,7 @@ void Awb::queueRequest(IPAContext &context,\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Awb::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \t/*\n>  \t * This is the latest time we can read the active state. This is the\n> @@ -120,29 +120,30 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n>  \t\tframeContext.awb.gains.blue = context.activeState.awb.gains.automatic.blue;\n>  \t}\n>  \n> -\tparams->others.awb_gain_config.gain_green_b = 256 * frameContext.awb.gains.green;\n> -\tparams->others.awb_gain_config.gain_blue = 256 * frameContext.awb.gains.blue;\n> -\tparams->others.awb_gain_config.gain_red = 256 * frameContext.awb.gains.red;\n> -\tparams->others.awb_gain_config.gain_green_r = 256 * frameContext.awb.gains.green;\n> +\tauto gainConfig = params->block<Block::AwbGain>();\n> +\tgainConfig.setEnabled(true);\n>  \n> -\t/* Update the gains. */\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;\n> +\tgainConfig->gain_green_b = 256 * frameContext.awb.gains.green;\n> +\tgainConfig->gain_blue = 256 * frameContext.awb.gains.blue;\n> +\tgainConfig->gain_red = 256 * frameContext.awb.gains.red;\n> +\tgainConfig->gain_green_r = 256 * frameContext.awb.gains.green;\n>  \n>  \t/* If we have already set the AWB measurement parameters, return. */\n>  \tif (frame > 0)\n>  \t\treturn;\n>  \n> -\trkisp1_cif_isp_awb_meas_config &awb_config = params->meas.awb_meas_config;\n> +\tauto awbConfig = params->block<Block::Awb>();\n> +\tawbConfig.setEnabled(true);\n>  \n>  \t/* Configure the measure window for AWB. */\n> -\tawb_config.awb_wnd = context.configuration.awb.measureWindow;\n> +\tawbConfig->awb_wnd = context.configuration.awb.measureWindow;\n>  \n>  \t/* Number of frames to use to estimate the means (0 means 1 frame). */\n> -\tawb_config.frames = 0;\n> +\tawbConfig->frames = 0;\n>  \n>  \t/* Select RGB or YCbCr means measurement. */\n>  \tif (rgbMode_) {\n> -\t\tawb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;\n> +\t\tawbConfig->awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;\n>  \n>  \t\t/*\n>  \t\t * For RGB-based measurements, pixels are selected with maximum\n> @@ -150,19 +151,19 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n>  \t\t * awb_ref_cr, awb_min_y and awb_ref_cb respectively. The other\n>  \t\t * values are not used, set them to 0.\n>  \t\t */\n> -\t\tawb_config.awb_ref_cr = 250;\n> -\t\tawb_config.min_y = 250;\n> -\t\tawb_config.awb_ref_cb = 250;\n> +\t\tawbConfig->awb_ref_cr = 250;\n> +\t\tawbConfig->min_y = 250;\n> +\t\tawbConfig->awb_ref_cb = 250;\n>  \n> -\t\tawb_config.max_y = 0;\n> -\t\tawb_config.min_c = 0;\n> -\t\tawb_config.max_csum = 0;\n> +\t\tawbConfig->max_y = 0;\n> +\t\tawbConfig->min_c = 0;\n> +\t\tawbConfig->max_csum = 0;\n>  \t} else {\n> -\t\tawb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;\n> +\t\tawbConfig->awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;\n>  \n>  \t\t/* Set the reference Cr and Cb (AWB target) to white. */\n> -\t\tawb_config.awb_ref_cb = 128;\n> -\t\tawb_config.awb_ref_cr = 128;\n> +\t\tawbConfig->awb_ref_cb = 128;\n> +\t\tawbConfig->awb_ref_cr = 128;\n>  \n>  \t\t/*\n>  \t\t * Filter out pixels based on luminance and chrominance values.\n> @@ -170,20 +171,11 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n>  \t\t * range, while the acceptable chroma values are specified with\n>  \t\t * a minimum of 16 and a maximum Cb+Cr sum of 250.\n>  \t\t */\n> -\t\tawb_config.min_y = 16;\n> -\t\tawb_config.max_y = 250;\n> -\t\tawb_config.min_c = 16;\n> -\t\tawb_config.max_csum = 250;\n> +\t\tawbConfig->min_y = 16;\n> +\t\tawbConfig->max_y = 250;\n> +\t\tawbConfig->min_c = 16;\n> +\t\tawbConfig->max_csum = 250;\n>  \t}\n> -\n> -\t/* Enable the AWB gains. */\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;\n> -\n> -\t/* Update the AWB measurement parameters and enable the AWB module. */\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_AWB;\n>  }\n>  \n>  uint32_t Awb::estimateCCT(double red, double green, double blue)\n> diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h\n> index 06c92896e2dc..b3b2c0bbb9ae 100644\n> --- a/src/ipa/rkisp1/algorithms/awb.h\n> +++ b/src/ipa/rkisp1/algorithms/awb.h\n> @@ -25,7 +25,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp\n> index 871dd2047c6a..df1a91a413db 100644\n> --- a/src/ipa/rkisp1/algorithms/blc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/blc.cpp\n> @@ -113,7 +113,7 @@ int BlackLevelCorrection::init(IPAContext &context, const YamlObject &tuningData\n>  void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t   const uint32_t frame,\n>  \t\t\t\t   [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t   rkisp1_params_cfg *params)\n> +\t\t\t\t   RkISP1Params *params)\n>  {\n>  \tif (context.configuration.raw)\n>  \t\treturn;\n> @@ -124,16 +124,15 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,\n>  \tif (!tuningParameters_)\n>  \t\treturn;\n>  \n> -\tparams->others.bls_config.enable_auto = 0;\n> -\t/* The rkisp1 uses 12bit based black levels. Scale down accordingly. */\n> -\tparams->others.bls_config.fixed_val.r = blackLevelRed_ >> 4;\n> -\tparams->others.bls_config.fixed_val.gr = blackLevelGreenR_ >> 4;\n> -\tparams->others.bls_config.fixed_val.gb = blackLevelGreenB_ >> 4;\n> -\tparams->others.bls_config.fixed_val.b = blackLevelBlue_ >> 4;\n> +\tauto config = params->block<Block::Bls>();\n> +\tconfig.setEnabled(true);\n>  \n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_BLS;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_BLS;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_BLS;\n> +\tconfig->enable_auto = 0;\n> +\t/* The rkisp1 uses 12bit based black levels. Scale down accordingly. */\n> +\tconfig->fixed_val.r = blackLevelRed_ >> 4;\n> +\tconfig->fixed_val.gr = blackLevelGreenR_ >> 4;\n> +\tconfig->fixed_val.gb = blackLevelGreenB_ >> 4;\n> +\tconfig->fixed_val.b = blackLevelBlue_ >> 4;\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/rkisp1/algorithms/blc.h b/src/ipa/rkisp1/algorithms/blc.h\n> index 4ecac233f88b..372f6f7d00cc 100644\n> --- a/src/ipa/rkisp1/algorithms/blc.h\n> +++ b/src/ipa/rkisp1/algorithms/blc.h\n> @@ -22,11 +22,12 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n>  \t\t     ControlList &metadata) override;\n> +\n>  private:\n>  \tbool tuningParameters_;\n>  \tint16_t blackLevelRed_;\n> diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp\n> index c1f5403a8ab2..eb747c8e24f9 100644\n> --- a/src/ipa/rkisp1/algorithms/ccm.cpp\n> +++ b/src/ipa/rkisp1/algorithms/ccm.cpp\n> @@ -71,12 +71,10 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData\n>  \treturn 0;\n>  }\n>  \n> -void Ccm::setParameters(rkisp1_params_cfg *params,\n> +void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config,\n>  \t\t\tconst Matrix<float, 3, 3> &matrix,\n>  \t\t\tconst Matrix<int16_t, 3, 1> &offsets)\n>  {\n> -\tstruct rkisp1_cif_isp_ctk_config &config = params->others.ctk_config;\n> -\n>  \t/*\n>  \t * 4 bit integer and 7 bit fractional, ranging from -8 (0x400) to\n>  \t * +7.992 (0x3ff)\n> @@ -92,18 +90,13 @@ void Ccm::setParameters(rkisp1_params_cfg *params,\n>  \n>  \tLOG(RkISP1Ccm, Debug) << \"Setting matrix \" << matrix;\n>  \tLOG(RkISP1Ccm, Debug) << \"Setting offsets \" << offsets;\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_CTK;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_CTK;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_CTK;\n>  }\n>  \n>  /**\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Ccm::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext,\n> -\t\t  rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \tuint32_t ct = context.activeState.awb.temperatureK;\n>  \n> @@ -120,7 +113,9 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame,\n>  \n>  \tframeContext.ccm.ccm = ccm;\n>  \n> -\tsetParameters(params, ccm, offsets);\n> +\tauto config = params->block<Block::Ctk>();\n> +\tconfig.setEnabled(true);\n> +\tsetParameters(*config, ccm, offsets);\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/rkisp1/algorithms/ccm.h b/src/ipa/rkisp1/algorithms/ccm.h\n> index 30cb882180cc..9daadb6834b1 100644\n> --- a/src/ipa/rkisp1/algorithms/ccm.h\n> +++ b/src/ipa/rkisp1/algorithms/ccm.h\n> @@ -27,7 +27,7 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> @@ -35,7 +35,7 @@ public:\n>  \n>  private:\n>  \tvoid parseYaml(const YamlObject &tuningData);\n> -\tvoid setParameters(rkisp1_params_cfg *params,\n> +\tvoid setParameters(struct rkisp1_cif_isp_ctk_config &config,\n>  \t\t\t   const Matrix<float, 3, 3> &matrix,\n>  \t\t\t   const Matrix<int16_t, 3, 1> &offsets);\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp\n> index ef0931b20453..71b18fe0708f 100644\n> --- a/src/ipa/rkisp1/algorithms/cproc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/cproc.cpp\n> @@ -140,19 +140,17 @@ void ColorProcessing::queueRequest(IPAContext &context,\n>  void ColorProcessing::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t      [[maybe_unused]] const uint32_t frame,\n>  \t\t\t      IPAFrameContext &frameContext,\n> -\t\t\t      rkisp1_params_cfg *params)\n> +\t\t\t      RkISP1Params *params)\n>  {\n>  \t/* Check if the algorithm configuration has been updated. */\n>  \tif (!frameContext.cproc.update)\n>  \t\treturn;\n>  \n> -\tparams->others.cproc_config.brightness = frameContext.cproc.brightness;\n> -\tparams->others.cproc_config.contrast = frameContext.cproc.contrast;\n> -\tparams->others.cproc_config.sat = frameContext.cproc.saturation;\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_CPROC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_CPROC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_CPROC;\n> +\tauto config = params->block<Block::Cproc>();\n> +\tconfig.setEnabled(true);\n> +\tconfig->brightness = frameContext.cproc.brightness;\n> +\tconfig->contrast = frameContext.cproc.contrast;\n> +\tconfig->sat = frameContext.cproc.saturation;\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(ColorProcessing, \"ColorProcessing\")\n> diff --git a/src/ipa/rkisp1/algorithms/cproc.h b/src/ipa/rkisp1/algorithms/cproc.h\n> index e50e7200bd73..fd38fd17e8bb 100644\n> --- a/src/ipa/rkisp1/algorithms/cproc.h\n> +++ b/src/ipa/rkisp1/algorithms/cproc.h\n> @@ -29,7 +29,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  };\n>  \n>  } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> index b5a339e9137f..0a80f8efd332 100644\n> --- a/src/ipa/rkisp1/algorithms/dpcc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> @@ -232,16 +232,14 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  void DefectPixelClusterCorrection::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t\t   const uint32_t frame,\n>  \t\t\t\t\t   [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t\t   rkisp1_params_cfg *params)\n> +\t\t\t\t\t   RkISP1Params *params)\n>  {\n>  \tif (frame > 0)\n>  \t\treturn;\n>  \n> -\tparams->others.dpcc_config = config_;\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_DPCC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_DPCC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPCC;\n> +\tauto config = params->block<Block::Dpcc>();\n> +\tconfig.setEnabled(true);\n> +\t*config = config_;\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(DefectPixelClusterCorrection, \"DefectPixelClusterCorrection\")\n> diff --git a/src/ipa/rkisp1/algorithms/dpcc.h b/src/ipa/rkisp1/algorithms/dpcc.h\n> index d39b7bedc1e1..b77766c300fb 100644\n> --- a/src/ipa/rkisp1/algorithms/dpcc.h\n> +++ b/src/ipa/rkisp1/algorithms/dpcc.h\n> @@ -22,7 +22,7 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \trkisp1_cif_isp_dpcc_config config_;\n> diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp\n> index abf957288550..37291fc68e3e 100644\n> --- a/src/ipa/rkisp1/algorithms/dpf.cpp\n> +++ b/src/ipa/rkisp1/algorithms/dpf.cpp\n> @@ -215,15 +215,21 @@ void Dpf::queueRequest(IPAContext &context,\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Dpf::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n> -\tif (frame == 0) {\n> -\t\tparams->others.dpf_config = config_;\n> -\t\tparams->others.dpf_strength_config = strengthConfig_;\n> +\tif (!frameContext.dpf.update && frame > 0)\n> +\t\treturn;\n> +\n> +\tauto config = params->block<Block::Dpf>();\n> +\tconfig.setEnabled(frameContext.dpf.denoise);\n> +\n> +\tif (frameContext.dpf.denoise) {\n> +\t\t*config = config_;\n>  \n>  \t\tconst auto &awb = context.configuration.awb;\n>  \t\tconst auto &lsc = context.configuration.lsc;\n> -\t\tauto &mode = params->others.dpf_config.gain.mode;\n> +\n> +\t\tauto &mode = config->gain.mode;\n>  \n>  \t\t/*\n>  \t\t * The DPF needs to take into account the total amount of\n> @@ -241,15 +247,12 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,\n>  \t\t\tmode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS;\n>  \t\telse\n>  \t\t\tmode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED;\n> -\n> -\t\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPF |\n> -\t\t\t\t\t     RKISP1_CIF_ISP_MODULE_DPF_STRENGTH;\n>  \t}\n>  \n> -\tif (frameContext.dpf.update) {\n> -\t\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_DPF;\n> -\t\tif (frameContext.dpf.denoise)\n> -\t\t\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_DPF;\n> +\tif (frame == 0) {\n> +\t\tauto strengthConfig = params->block<Block::DpfStrength>();\n> +\t\tstrengthConfig.setEnabled(true);\n> +\t\t*strengthConfig = strengthConfig_;\n>  \t}\n>  }\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h\n> index da0115baf8f1..2dd8cd362624 100644\n> --- a/src/ipa/rkisp1/algorithms/dpf.h\n> +++ b/src/ipa/rkisp1/algorithms/dpf.h\n> @@ -27,7 +27,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \tstruct rkisp1_cif_isp_dpf_config config_;\n> diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp\n> index 9752248a5965..51ce372d0595 100644\n> --- a/src/ipa/rkisp1/algorithms/filter.cpp\n> +++ b/src/ipa/rkisp1/algorithms/filter.cpp\n> @@ -104,7 +104,7 @@ void Filter::queueRequest(IPAContext &context,\n>   */\n>  void Filter::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t     [[maybe_unused]] const uint32_t frame,\n> -\t\t     IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t     IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \t/* Check if the algorithm configuration has been updated. */\n>  \tif (!frameContext.filter.update)\n> @@ -160,23 +160,25 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,\n>  \n>  \tuint8_t denoise = frameContext.filter.denoise;\n>  \tuint8_t sharpness = frameContext.filter.sharpness;\n> -\tauto &flt_config = params->others.flt_config;\n>  \n> -\tflt_config.fac_sh0 = filt_fac_sh0[sharpness];\n> -\tflt_config.fac_sh1 = filt_fac_sh1[sharpness];\n> -\tflt_config.fac_mid = filt_fac_mid[sharpness];\n> -\tflt_config.fac_bl0 = filt_fac_bl0[sharpness];\n> -\tflt_config.fac_bl1 = filt_fac_bl1[sharpness];\n> +\tauto config = params->block<Block::Flt>();\n> +\tconfig.setEnabled(true);\n>  \n> -\tflt_config.lum_weight = kFiltLumWeightDefault;\n> -\tflt_config.mode = kFiltModeDefault;\n> -\tflt_config.thresh_sh0 = filt_thresh_sh0[denoise];\n> -\tflt_config.thresh_sh1 = filt_thresh_sh1[denoise];\n> -\tflt_config.thresh_bl0 = filt_thresh_bl0[denoise];\n> -\tflt_config.thresh_bl1 = filt_thresh_bl1[denoise];\n> -\tflt_config.grn_stage1 = stage1_select[denoise];\n> -\tflt_config.chr_v_mode = filt_chr_v_mode[denoise];\n> -\tflt_config.chr_h_mode = filt_chr_h_mode[denoise];\n> +\tconfig->fac_sh0 = filt_fac_sh0[sharpness];\n> +\tconfig->fac_sh1 = filt_fac_sh1[sharpness];\n> +\tconfig->fac_mid = filt_fac_mid[sharpness];\n> +\tconfig->fac_bl0 = filt_fac_bl0[sharpness];\n> +\tconfig->fac_bl1 = filt_fac_bl1[sharpness];\n> +\n> +\tconfig->lum_weight = kFiltLumWeightDefault;\n> +\tconfig->mode = kFiltModeDefault;\n> +\tconfig->thresh_sh0 = filt_thresh_sh0[denoise];\n> +\tconfig->thresh_sh1 = filt_thresh_sh1[denoise];\n> +\tconfig->thresh_bl0 = filt_thresh_bl0[denoise];\n> +\tconfig->thresh_bl1 = filt_thresh_bl1[denoise];\n> +\tconfig->grn_stage1 = stage1_select[denoise];\n> +\tconfig->chr_v_mode = filt_chr_v_mode[denoise];\n> +\tconfig->chr_h_mode = filt_chr_h_mode[denoise];\n>  \n>  \t/*\n>  \t * Combined high denoising and high sharpening requires some\n> @@ -186,27 +188,23 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,\n>  \t */\n>  \tif (denoise == 9) {\n>  \t\tif (sharpness > 3)\n> -\t\t\tflt_config.grn_stage1 = 2;\n> +\t\t\tconfig->grn_stage1 = 2;\n>  \t} else if (denoise == 10) {\n>  \t\tif (sharpness > 5)\n> -\t\t\tflt_config.grn_stage1 = 2;\n> +\t\t\tconfig->grn_stage1 = 2;\n>  \t\telse if (sharpness > 3)\n> -\t\t\tflt_config.grn_stage1 = 1;\n> +\t\t\tconfig->grn_stage1 = 1;\n>  \t}\n>  \n>  \tif (denoise > 7) {\n>  \t\tif (sharpness > 7) {\n> -\t\t\tflt_config.fac_bl0 /= 2;\n> -\t\t\tflt_config.fac_bl1 /= 4;\n> +\t\t\tconfig->fac_bl0 /= 2;\n> +\t\t\tconfig->fac_bl1 /= 4;\n>  \t\t} else if (sharpness > 4) {\n> -\t\t\tflt_config.fac_bl0 = flt_config.fac_bl0 * 3 / 4;\n> -\t\t\tflt_config.fac_bl1 /= 2;\n> +\t\t\tconfig->fac_bl0 = config->fac_bl0 * 3 / 4;\n> +\t\t\tconfig->fac_bl1 /= 2;\n>  \t\t}\n>  \t}\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_FLT;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_FLT;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_FLT;\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(Filter, \"Filter\")\n> diff --git a/src/ipa/rkisp1/algorithms/filter.h b/src/ipa/rkisp1/algorithms/filter.h\n> index d595811d455f..8f858e574fa2 100644\n> --- a/src/ipa/rkisp1/algorithms/filter.h\n> +++ b/src/ipa/rkisp1/algorithms/filter.h\n> @@ -26,7 +26,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  };\n>  \n>  } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp\n> index a82cee3bbf61..f1f3f90d3c6b 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/goc.cpp\n> @@ -99,11 +99,14 @@ void GammaOutCorrection::queueRequest(IPAContext &context, const uint32_t frame,\n>  void GammaOutCorrection::prepare(IPAContext &context,\n>  \t\t\t\t [[maybe_unused]] const uint32_t frame,\n>  \t\t\t\t IPAFrameContext &frameContext,\n> -\t\t\t\t rkisp1_params_cfg *params)\n> +\t\t\t\t RkISP1Params *params)\n>  {\n>  \tASSERT(context.hw->numGammaOutSamples ==\n>  \t       RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);\n>  \n> +\tif (!frameContext.goc.update)\n> +\t\treturn;\n> +\n>  \t/*\n>  \t * The logarithmic segments as specified in the reference.\n>  \t * Plus an additional 0 to make the loop easier\n> @@ -112,10 +115,11 @@ void GammaOutCorrection::prepare(IPAContext &context,\n>  \t\t64, 64, 64, 64, 128, 128, 128, 128, 256,\n>  \t\t256, 256, 512, 512, 512, 512, 512, 0\n>  \t};\n> -\t__u16 *gamma_y = params->others.goc_config.gamma_y;\n>  \n> -\tif (!frameContext.goc.update)\n> -\t\treturn;\n> +\tauto config = params->block<Block::Goc>();\n> +\tconfig.setEnabled(true);\n> +\n> +\t__u16 *gamma_y = config->gamma_y;\n>  \n>  \tunsigned x = 0;\n>  \tfor (const auto [i, size] : utils::enumerate(segments)) {\n> @@ -123,10 +127,7 @@ void GammaOutCorrection::prepare(IPAContext &context,\n>  \t\tx += size;\n>  \t}\n>  \n> -\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n> +\tconfig->mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h\n> index 0e05d7ce4a01..bb2ddfc92375 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.h\n> +++ b/src/ipa/rkisp1/algorithms/goc.h\n> @@ -28,7 +28,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> diff --git a/src/ipa/rkisp1/algorithms/gsl.cpp b/src/ipa/rkisp1/algorithms/gsl.cpp\n> index 9b056c6edd96..aea701d7c287 100644\n> --- a/src/ipa/rkisp1/algorithms/gsl.cpp\n> +++ b/src/ipa/rkisp1/algorithms/gsl.cpp\n> @@ -119,24 +119,20 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,\n>  void GammaSensorLinearization::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t       const uint32_t frame,\n>  \t\t\t\t       [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t       rkisp1_params_cfg *params)\n> +\t\t\t\t       RkISP1Params *params)\n>  {\n>  \tif (frame > 0)\n>  \t\treturn;\n>  \n> -\tparams->others.sdg_config.xa_pnts.gamma_dx0 = gammaDx_[0];\n> -\tparams->others.sdg_config.xa_pnts.gamma_dx1 = gammaDx_[1];\n> +\tauto config = params->block<Block::Sdg>();\n> +\tconfig.setEnabled(true);\n>  \n> -\tstd::copy(curveYr_.begin(), curveYr_.end(),\n> -\t\t  params->others.sdg_config.curve_r.gamma_y);\n> -\tstd::copy(curveYg_.begin(), curveYg_.end(),\n> -\t\t  params->others.sdg_config.curve_g.gamma_y);\n> -\tstd::copy(curveYb_.begin(), curveYb_.end(),\n> -\t\t  params->others.sdg_config.curve_b.gamma_y);\n> +\tconfig->xa_pnts.gamma_dx0 = gammaDx_[0];\n> +\tconfig->xa_pnts.gamma_dx1 = gammaDx_[1];\n>  \n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_SDG;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_SDG;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_SDG;\n> +\tstd::copy(curveYr_.begin(), curveYr_.end(), config->curve_r.gamma_y);\n> +\tstd::copy(curveYg_.begin(), curveYg_.end(), config->curve_g.gamma_y);\n> +\tstd::copy(curveYb_.begin(), curveYb_.end(), config->curve_b.gamma_y);\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(GammaSensorLinearization, \"GammaSensorLinearization\")\n> diff --git a/src/ipa/rkisp1/algorithms/gsl.h b/src/ipa/rkisp1/algorithms/gsl.h\n> index c404105e6310..91cf6efa7925 100644\n> --- a/src/ipa/rkisp1/algorithms/gsl.h\n> +++ b/src/ipa/rkisp1/algorithms/gsl.h\n> @@ -22,7 +22,7 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \tuint32_t gammaDx_[2];\n> diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp\n> index 161183fca352..88971372fffb 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/lsc.cpp\n> @@ -185,18 +185,12 @@ int LensShadingCorrection::configure(IPAContext &context,\n>  \treturn 0;\n>  }\n>  \n> -void LensShadingCorrection::setParameters(rkisp1_params_cfg *params)\n> +void LensShadingCorrection::setParameters(rkisp1_cif_isp_lsc_config &config)\n>  {\n> -\tstruct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config;\n> -\n>  \tmemcpy(config.x_grad_tbl, xGrad_, sizeof(config.x_grad_tbl));\n>  \tmemcpy(config.y_grad_tbl, yGrad_, sizeof(config.y_grad_tbl));\n>  \tmemcpy(config.x_size_tbl, xSizes_, sizeof(config.x_size_tbl));\n>  \tmemcpy(config.y_size_tbl, ySizes_, sizeof(config.y_size_tbl));\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_LSC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC;\n>  }\n>  \n>  void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,\n> @@ -248,10 +242,8 @@ void LensShadingCorrection::interpolateTable(rkisp1_cif_isp_lsc_config &config,\n>  void LensShadingCorrection::prepare(IPAContext &context,\n>  \t\t\t\t    const uint32_t frame,\n>  \t\t\t\t    [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t    rkisp1_params_cfg *params)\n> +\t\t\t\t    RkISP1Params *params)\n>  {\n> -\tstruct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config;\n> -\n>  \t/*\n>  \t * If there is only one set, the configuration has already been done\n>  \t * for first frame.\n> @@ -264,8 +256,11 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \t * never be relevant.\n>  \t */\n>  \tif (sets_.size() == 1) {\n> -\t\tsetParameters(params);\n> -\t\tcopyTable(config, sets_.cbegin()->second);\n> +\t\tauto config = params->block<Block::Lsc>();\n> +\t\tconfig.setEnabled(true);\n> +\n> +\t\tsetParameters(*config);\n> +\t\tcopyTable(*config, sets_.cbegin()->second);\n>  \t\treturn;\n>  \t}\n>  \n> @@ -294,13 +289,15 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \t    (lastCt_.adjusted <= ct && ct <= lastCt_.original))\n>  \t\treturn;\n>  \n> -\tsetParameters(params);\n> +\tauto config = params->block<Block::Lsc>();\n> +\tconfig.setEnabled(true);\n> +\tsetParameters(*config);\n>  \n>  \t/*\n>  \t * The color temperature matches exactly one of the available LSC tables.\n>  \t */\n>  \tif (sets_.count(ct)) {\n> -\t\tcopyTable(config, sets_[ct]);\n> +\t\tcopyTable(*config, sets_[ct]);\n>  \t\tlastCt_ = { ct, ct };\n>  \t\treturn;\n>  \t}\n> @@ -319,7 +316,7 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \tif (diff0 < threshold || diff1 < threshold) {\n>  \t\tconst Components &set = diff0 < diff1 ? set0 : set1;\n>  \t\tLOG(RkISP1Lsc, Debug) << \"using LSC table for \" << set.ct;\n> -\t\tcopyTable(config, set);\n> +\t\tcopyTable(*config, set);\n>  \t\tlastCt_ = { ct, set.ct };\n>  \t\treturn;\n>  \t}\n> @@ -331,7 +328,7 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \tLOG(RkISP1Lsc, Debug)\n>  \t\t<< \"ct is \" << ct << \", interpolating between \"\n>  \t\t<< ct0 << \" and \" << ct1;\n> -\tinterpolateTable(config, set0, set1, ct);\n> +\tinterpolateTable(*config, set0, set1, ct);\n>  \tlastCt_ = { ct, ct };\n>  }\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h\n> index 5baf592797a6..a9c7a230e0fc 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.h\n> +++ b/src/ipa/rkisp1/algorithms/lsc.h\n> @@ -25,7 +25,7 @@ public:\n>  \tint configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \tstruct Components {\n> @@ -36,7 +36,7 @@ private:\n>  \t\tstd::vector<uint16_t> b;\n>  \t};\n>  \n> -\tvoid setParameters(rkisp1_params_cfg *params);\n> +\tvoid setParameters(rkisp1_cif_isp_lsc_config &config);\n>  \tvoid copyTable(rkisp1_cif_isp_lsc_config &config, const Components &set0);\n>  \tvoid interpolateTable(rkisp1_cif_isp_lsc_config &config,\n>  \t\t\t      const Components &set0, const Components &set1,\n> diff --git a/src/ipa/rkisp1/module.h b/src/ipa/rkisp1/module.h\n> index 16c3e43e88df..69e9bc823720 100644\n> --- a/src/ipa/rkisp1/module.h\n> +++ b/src/ipa/rkisp1/module.h\n> @@ -14,13 +14,14 @@\n>  #include <libipa/module.h>\n>  \n>  #include \"ipa_context.h\"\n> +#include \"params.h\"\n>  \n>  namespace libcamera {\n>  \n>  namespace ipa::rkisp1 {\n>  \n>  using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,\n> -\t\t\t   rkisp1_params_cfg, rkisp1_stat_buffer>;\n> +\t\t\t   RkISP1Params, rkisp1_stat_buffer>;\n>  \n>  } /* namespace ipa::rkisp1 */\n>  \n> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> index 84ffe6cf2777..1a89eabf10b4 100644\n> --- a/src/ipa/rkisp1/rkisp1.cpp\n> +++ b/src/ipa/rkisp1/rkisp1.cpp\n> @@ -31,6 +31,7 @@\n>  #include \"algorithms/algorithm.h\"\n>  \n>  #include \"ipa_context.h\"\n> +#include \"params.h\"\n>  \n>  namespace libcamera {\n>  \n> @@ -322,17 +323,12 @@ void IPARkISP1::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId)\n>  {\n>  \tIPAFrameContext &frameContext = context_.frameContexts.get(frame);\n>  \n> -\trkisp1_params_cfg *params =\n> -\t\treinterpret_cast<rkisp1_params_cfg *>(\n> -\t\t\tmappedBuffers_.at(bufferId).planes()[0].data());\n> -\n> -\t/* Prepare parameters buffer. */\n> -\tmemset(params, 0, sizeof(*params));\n> +\tRkISP1Params params(paramFormat_, mappedBuffers_.at(bufferId).planes()[0]);\n>  \n>  \tfor (auto const &algo : algorithms())\n> -\t\talgo->prepare(context_, frame, frameContext, params);\n> +\t\talgo->prepare(context_, frame, frameContext, &params);\n>  \n> -\tparamsBufferReady.emit(frame, sizeof(*params));\n> +\tparamsBufferReady.emit(frame, params.size());\n>  }\n>  \n>  void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId,","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 655C2BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  5 Jul 2024 12:41:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6A91262E22;\n\tFri,  5 Jul 2024 14:41:19 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E21C1619BF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  5 Jul 2024 14:41:16 +0200 (CEST)","from pyrite.rasen.tech (h175-177-049-156.catv02.itscom.jp\n\t[175.177.49.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E5E5D4CC;\n\tFri,  5 Jul 2024 14:40:45 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jxX5QPRi\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1720183247;\n\tbh=Cvdxrw+MzZpoGvnfXqWgKEVuloAObkoDcx+1+eC3i0c=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=jxX5QPRiwYjbAwnKFMla4+4ESod3uQO/AdmgpPcnkNizo2ZmC2ESktBwde/KRUFxd\n\tpI8aes7tZpkixQN1+0HCsF7cDrdQbGQWHKMt11c5ZanKRYZAmyxNlDfjMYzIVnVQFV\n\tHUMEpthCB2ugNuefAIuyqwC/lXneDOZktT7lKc48=","Date":"Fri, 5 Jul 2024 21:41:09 +0900","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>","Subject":"Re: [PATCH v2 06/11] ipa: rkisp1: Use the new ISP parameters\n\tabstraction","Message-ID":"<Zofp5U0a9pNVv4ZG@pyrite.rasen.tech>","References":"<20240704162035.15074-1-laurent.pinchart@ideasonboard.com>\n\t<20240704162035.15074-7-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20240704162035.15074-7-laurent.pinchart@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":30355,"web_url":"https://patchwork.libcamera.org/comment/30355/","msgid":"<35r4rabw72syboghknfjnaqjk4nbuz5wga4exdeyrkjro5hgd5@hvwx3v2dnabq>","date":"2024-07-05T13:33:30","subject":"Re: [PATCH v2 06/11] ipa: rkisp1: Use the new ISP parameters\n\tabstraction","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Laurent,\n\nThank you for the patch.\n\nOn Thu, Jul 04, 2024 at 07:20:30PM +0300, Laurent Pinchart wrote:\n> Use the new ISP parameters abstraction class RkISP1Params to access the\n> ISP parameters in the IPA algorithms. The class replaces the pointer to\n> the rkisp1_params_cfg structure passed to the algorithms' prepare()\n> function, and is used to access individual parameters blocks.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\nCheers,\nStefan\n\n> ---\n> Changes since v1:\n> \n> - Fix the DPF logic\n> - Move the params enabled state handling to a setEnabled() function\n> ---\n>  src/ipa/rkisp1/algorithms/agc.cpp    | 48 +++++++++++------------\n>  src/ipa/rkisp1/algorithms/agc.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/awb.cpp    | 58 ++++++++++++----------------\n>  src/ipa/rkisp1/algorithms/awb.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/blc.cpp    | 19 +++++----\n>  src/ipa/rkisp1/algorithms/blc.h      |  3 +-\n>  src/ipa/rkisp1/algorithms/ccm.cpp    | 15 +++----\n>  src/ipa/rkisp1/algorithms/ccm.h      |  4 +-\n>  src/ipa/rkisp1/algorithms/cproc.cpp  | 14 +++----\n>  src/ipa/rkisp1/algorithms/cproc.h    |  2 +-\n>  src/ipa/rkisp1/algorithms/dpcc.cpp   | 10 ++---\n>  src/ipa/rkisp1/algorithms/dpcc.h     |  2 +-\n>  src/ipa/rkisp1/algorithms/dpf.cpp    | 27 +++++++------\n>  src/ipa/rkisp1/algorithms/dpf.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/filter.cpp | 52 ++++++++++++-------------\n>  src/ipa/rkisp1/algorithms/filter.h   |  2 +-\n>  src/ipa/rkisp1/algorithms/goc.cpp    | 17 ++++----\n>  src/ipa/rkisp1/algorithms/goc.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/gsl.cpp    | 20 ++++------\n>  src/ipa/rkisp1/algorithms/gsl.h      |  2 +-\n>  src/ipa/rkisp1/algorithms/lsc.cpp    | 29 +++++++-------\n>  src/ipa/rkisp1/algorithms/lsc.h      |  4 +-\n>  src/ipa/rkisp1/module.h              |  3 +-\n>  src/ipa/rkisp1/rkisp1.cpp            | 12 ++----\n>  24 files changed, 162 insertions(+), 189 deletions(-)\n> \n> diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\n> index f12f8b60de15..c01fbdf3b8af 100644\n> --- a/src/ipa/rkisp1/algorithms/agc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/agc.cpp\n> @@ -281,7 +281,7 @@ void Agc::queueRequest(IPAContext &context,\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Agc::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \tif (frameContext.agc.autoEnabled) {\n>  \t\tframeContext.agc.exposure = context.activeState.agc.automatic.exposure;\n> @@ -291,41 +291,39 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,\n>  \tif (frame > 0 && !frameContext.agc.updateMetering)\n>  \t\treturn;\n>  \n> -\t/* Configure the measurement window. */\n> -\tparams->meas.aec_config.meas_window = context.configuration.agc.measureWindow;\n> -\t/* Use a continuous method for measure. */\n> -\tparams->meas.aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;\n> -\t/* Estimate Y as (R + G + B) x (85/256). */\n> -\tparams->meas.aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;\n> +\t/*\n> +\t * Configure the AEC measurements. Set the window, measure\n> +\t * continuously, and estimate Y as (R + G + B) x (85/256).\n> +\t */\n> +\tauto aecConfig = params->block<Block::Aec>();\n> +\taecConfig.setEnabled(true);\n>  \n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AEC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_AEC;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC;\n> +\taecConfig->meas_window = context.configuration.agc.measureWindow;\n> +\taecConfig->autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;\n> +\taecConfig->mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;\n>  \n> -\t/* Configure histogram. */\n> -\tparams->meas.hst_config.meas_window = context.configuration.agc.measureWindow;\n> -\t/* Produce the luminance histogram. */\n> -\tparams->meas.hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;\n> +\t/*\n> +\t * Configure the histogram measurement. Set the window, produce a\n> +\t * luminance histogram, and set the weights and predivider.\n> +\t */\n> +\tauto hstConfig = params->block<Block::Hst>();\n> +\thstConfig.setEnabled(true);\n> +\n> +\thstConfig->meas_window = context.configuration.agc.measureWindow;\n> +\thstConfig->mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;\n>  \n> -\t/* Set an average weighted histogram. */\n>  \tSpan<uint8_t> weights{\n> -\t\tparams->meas.hst_config.hist_weight,\n> +\t\thstConfig->hist_weight,\n>  \t\tcontext.hw->numHistogramWeights\n>  \t};\n>  \tstd::vector<uint8_t> &modeWeights = meteringModes_.at(frameContext.agc.meteringMode);\n>  \tstd::copy(modeWeights.begin(), modeWeights.end(), weights.begin());\n>  \n> -\tstruct rkisp1_cif_isp_window window = params->meas.hst_config.meas_window;\n> +\tstruct rkisp1_cif_isp_window window = hstConfig->meas_window;\n>  \tSize windowSize = { window.h_size, window.v_size };\n> -\tparams->meas.hst_config.histogram_predivider =\n> +\thstConfig->histogram_predivider =\n>  \t\tcomputeHistogramPredivider(windowSize,\n> -\t\t\t\t\t   static_cast<rkisp1_cif_isp_histogram_mode>(params->meas.hst_config.mode));\n> -\n> -\t/* Update the configuration for histogram. */\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_HST;\n> -\t/* Enable the histogram measure unit. */\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_HST;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_HST;\n> +\t\t\t\t\t   static_cast<rkisp1_cif_isp_histogram_mode>(hstConfig->mode));\n>  }\n>  \n>  void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,\n> diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h\n> index 9ceaa82b099e..d64ff42c1665 100644\n> --- a/src/ipa/rkisp1/algorithms/agc.h\n> +++ b/src/ipa/rkisp1/algorithms/agc.h\n> @@ -37,7 +37,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp\n> index a01fe5d90973..e81213febd88 100644\n> --- a/src/ipa/rkisp1/algorithms/awb.cpp\n> +++ b/src/ipa/rkisp1/algorithms/awb.cpp\n> @@ -108,7 +108,7 @@ void Awb::queueRequest(IPAContext &context,\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Awb::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \t/*\n>  \t * This is the latest time we can read the active state. This is the\n> @@ -120,29 +120,30 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n>  \t\tframeContext.awb.gains.blue = context.activeState.awb.gains.automatic.blue;\n>  \t}\n>  \n> -\tparams->others.awb_gain_config.gain_green_b = 256 * frameContext.awb.gains.green;\n> -\tparams->others.awb_gain_config.gain_blue = 256 * frameContext.awb.gains.blue;\n> -\tparams->others.awb_gain_config.gain_red = 256 * frameContext.awb.gains.red;\n> -\tparams->others.awb_gain_config.gain_green_r = 256 * frameContext.awb.gains.green;\n> +\tauto gainConfig = params->block<Block::AwbGain>();\n> +\tgainConfig.setEnabled(true);\n>  \n> -\t/* Update the gains. */\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;\n> +\tgainConfig->gain_green_b = 256 * frameContext.awb.gains.green;\n> +\tgainConfig->gain_blue = 256 * frameContext.awb.gains.blue;\n> +\tgainConfig->gain_red = 256 * frameContext.awb.gains.red;\n> +\tgainConfig->gain_green_r = 256 * frameContext.awb.gains.green;\n>  \n>  \t/* If we have already set the AWB measurement parameters, return. */\n>  \tif (frame > 0)\n>  \t\treturn;\n>  \n> -\trkisp1_cif_isp_awb_meas_config &awb_config = params->meas.awb_meas_config;\n> +\tauto awbConfig = params->block<Block::Awb>();\n> +\tawbConfig.setEnabled(true);\n>  \n>  \t/* Configure the measure window for AWB. */\n> -\tawb_config.awb_wnd = context.configuration.awb.measureWindow;\n> +\tawbConfig->awb_wnd = context.configuration.awb.measureWindow;\n>  \n>  \t/* Number of frames to use to estimate the means (0 means 1 frame). */\n> -\tawb_config.frames = 0;\n> +\tawbConfig->frames = 0;\n>  \n>  \t/* Select RGB or YCbCr means measurement. */\n>  \tif (rgbMode_) {\n> -\t\tawb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;\n> +\t\tawbConfig->awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;\n>  \n>  \t\t/*\n>  \t\t * For RGB-based measurements, pixels are selected with maximum\n> @@ -150,19 +151,19 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n>  \t\t * awb_ref_cr, awb_min_y and awb_ref_cb respectively. The other\n>  \t\t * values are not used, set them to 0.\n>  \t\t */\n> -\t\tawb_config.awb_ref_cr = 250;\n> -\t\tawb_config.min_y = 250;\n> -\t\tawb_config.awb_ref_cb = 250;\n> +\t\tawbConfig->awb_ref_cr = 250;\n> +\t\tawbConfig->min_y = 250;\n> +\t\tawbConfig->awb_ref_cb = 250;\n>  \n> -\t\tawb_config.max_y = 0;\n> -\t\tawb_config.min_c = 0;\n> -\t\tawb_config.max_csum = 0;\n> +\t\tawbConfig->max_y = 0;\n> +\t\tawbConfig->min_c = 0;\n> +\t\tawbConfig->max_csum = 0;\n>  \t} else {\n> -\t\tawb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;\n> +\t\tawbConfig->awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;\n>  \n>  \t\t/* Set the reference Cr and Cb (AWB target) to white. */\n> -\t\tawb_config.awb_ref_cb = 128;\n> -\t\tawb_config.awb_ref_cr = 128;\n> +\t\tawbConfig->awb_ref_cb = 128;\n> +\t\tawbConfig->awb_ref_cr = 128;\n>  \n>  \t\t/*\n>  \t\t * Filter out pixels based on luminance and chrominance values.\n> @@ -170,20 +171,11 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,\n>  \t\t * range, while the acceptable chroma values are specified with\n>  \t\t * a minimum of 16 and a maximum Cb+Cr sum of 250.\n>  \t\t */\n> -\t\tawb_config.min_y = 16;\n> -\t\tawb_config.max_y = 250;\n> -\t\tawb_config.min_c = 16;\n> -\t\tawb_config.max_csum = 250;\n> +\t\tawbConfig->min_y = 16;\n> +\t\tawbConfig->max_y = 250;\n> +\t\tawbConfig->min_c = 16;\n> +\t\tawbConfig->max_csum = 250;\n>  \t}\n> -\n> -\t/* Enable the AWB gains. */\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;\n> -\n> -\t/* Update the AWB measurement parameters and enable the AWB module. */\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_AWB;\n>  }\n>  \n>  uint32_t Awb::estimateCCT(double red, double green, double blue)\n> diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h\n> index 06c92896e2dc..b3b2c0bbb9ae 100644\n> --- a/src/ipa/rkisp1/algorithms/awb.h\n> +++ b/src/ipa/rkisp1/algorithms/awb.h\n> @@ -25,7 +25,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp\n> index 871dd2047c6a..df1a91a413db 100644\n> --- a/src/ipa/rkisp1/algorithms/blc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/blc.cpp\n> @@ -113,7 +113,7 @@ int BlackLevelCorrection::init(IPAContext &context, const YamlObject &tuningData\n>  void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t   const uint32_t frame,\n>  \t\t\t\t   [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t   rkisp1_params_cfg *params)\n> +\t\t\t\t   RkISP1Params *params)\n>  {\n>  \tif (context.configuration.raw)\n>  \t\treturn;\n> @@ -124,16 +124,15 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,\n>  \tif (!tuningParameters_)\n>  \t\treturn;\n>  \n> -\tparams->others.bls_config.enable_auto = 0;\n> -\t/* The rkisp1 uses 12bit based black levels. Scale down accordingly. */\n> -\tparams->others.bls_config.fixed_val.r = blackLevelRed_ >> 4;\n> -\tparams->others.bls_config.fixed_val.gr = blackLevelGreenR_ >> 4;\n> -\tparams->others.bls_config.fixed_val.gb = blackLevelGreenB_ >> 4;\n> -\tparams->others.bls_config.fixed_val.b = blackLevelBlue_ >> 4;\n> +\tauto config = params->block<Block::Bls>();\n> +\tconfig.setEnabled(true);\n>  \n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_BLS;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_BLS;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_BLS;\n> +\tconfig->enable_auto = 0;\n> +\t/* The rkisp1 uses 12bit based black levels. Scale down accordingly. */\n> +\tconfig->fixed_val.r = blackLevelRed_ >> 4;\n> +\tconfig->fixed_val.gr = blackLevelGreenR_ >> 4;\n> +\tconfig->fixed_val.gb = blackLevelGreenB_ >> 4;\n> +\tconfig->fixed_val.b = blackLevelBlue_ >> 4;\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/rkisp1/algorithms/blc.h b/src/ipa/rkisp1/algorithms/blc.h\n> index 4ecac233f88b..372f6f7d00cc 100644\n> --- a/src/ipa/rkisp1/algorithms/blc.h\n> +++ b/src/ipa/rkisp1/algorithms/blc.h\n> @@ -22,11 +22,12 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n>  \t\t     ControlList &metadata) override;\n> +\n>  private:\n>  \tbool tuningParameters_;\n>  \tint16_t blackLevelRed_;\n> diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp\n> index c1f5403a8ab2..eb747c8e24f9 100644\n> --- a/src/ipa/rkisp1/algorithms/ccm.cpp\n> +++ b/src/ipa/rkisp1/algorithms/ccm.cpp\n> @@ -71,12 +71,10 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData\n>  \treturn 0;\n>  }\n>  \n> -void Ccm::setParameters(rkisp1_params_cfg *params,\n> +void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config,\n>  \t\t\tconst Matrix<float, 3, 3> &matrix,\n>  \t\t\tconst Matrix<int16_t, 3, 1> &offsets)\n>  {\n> -\tstruct rkisp1_cif_isp_ctk_config &config = params->others.ctk_config;\n> -\n>  \t/*\n>  \t * 4 bit integer and 7 bit fractional, ranging from -8 (0x400) to\n>  \t * +7.992 (0x3ff)\n> @@ -92,18 +90,13 @@ void Ccm::setParameters(rkisp1_params_cfg *params,\n>  \n>  \tLOG(RkISP1Ccm, Debug) << \"Setting matrix \" << matrix;\n>  \tLOG(RkISP1Ccm, Debug) << \"Setting offsets \" << offsets;\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_CTK;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_CTK;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_CTK;\n>  }\n>  \n>  /**\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Ccm::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext,\n> -\t\t  rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \tuint32_t ct = context.activeState.awb.temperatureK;\n>  \n> @@ -120,7 +113,9 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame,\n>  \n>  \tframeContext.ccm.ccm = ccm;\n>  \n> -\tsetParameters(params, ccm, offsets);\n> +\tauto config = params->block<Block::Ctk>();\n> +\tconfig.setEnabled(true);\n> +\tsetParameters(*config, ccm, offsets);\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/rkisp1/algorithms/ccm.h b/src/ipa/rkisp1/algorithms/ccm.h\n> index 30cb882180cc..9daadb6834b1 100644\n> --- a/src/ipa/rkisp1/algorithms/ccm.h\n> +++ b/src/ipa/rkisp1/algorithms/ccm.h\n> @@ -27,7 +27,7 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> @@ -35,7 +35,7 @@ public:\n>  \n>  private:\n>  \tvoid parseYaml(const YamlObject &tuningData);\n> -\tvoid setParameters(rkisp1_params_cfg *params,\n> +\tvoid setParameters(struct rkisp1_cif_isp_ctk_config &config,\n>  \t\t\t   const Matrix<float, 3, 3> &matrix,\n>  \t\t\t   const Matrix<int16_t, 3, 1> &offsets);\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp\n> index ef0931b20453..71b18fe0708f 100644\n> --- a/src/ipa/rkisp1/algorithms/cproc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/cproc.cpp\n> @@ -140,19 +140,17 @@ void ColorProcessing::queueRequest(IPAContext &context,\n>  void ColorProcessing::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t      [[maybe_unused]] const uint32_t frame,\n>  \t\t\t      IPAFrameContext &frameContext,\n> -\t\t\t      rkisp1_params_cfg *params)\n> +\t\t\t      RkISP1Params *params)\n>  {\n>  \t/* Check if the algorithm configuration has been updated. */\n>  \tif (!frameContext.cproc.update)\n>  \t\treturn;\n>  \n> -\tparams->others.cproc_config.brightness = frameContext.cproc.brightness;\n> -\tparams->others.cproc_config.contrast = frameContext.cproc.contrast;\n> -\tparams->others.cproc_config.sat = frameContext.cproc.saturation;\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_CPROC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_CPROC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_CPROC;\n> +\tauto config = params->block<Block::Cproc>();\n> +\tconfig.setEnabled(true);\n> +\tconfig->brightness = frameContext.cproc.brightness;\n> +\tconfig->contrast = frameContext.cproc.contrast;\n> +\tconfig->sat = frameContext.cproc.saturation;\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(ColorProcessing, \"ColorProcessing\")\n> diff --git a/src/ipa/rkisp1/algorithms/cproc.h b/src/ipa/rkisp1/algorithms/cproc.h\n> index e50e7200bd73..fd38fd17e8bb 100644\n> --- a/src/ipa/rkisp1/algorithms/cproc.h\n> +++ b/src/ipa/rkisp1/algorithms/cproc.h\n> @@ -29,7 +29,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  };\n>  \n>  } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> index b5a339e9137f..0a80f8efd332 100644\n> --- a/src/ipa/rkisp1/algorithms/dpcc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp\n> @@ -232,16 +232,14 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,\n>  void DefectPixelClusterCorrection::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t\t   const uint32_t frame,\n>  \t\t\t\t\t   [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t\t   rkisp1_params_cfg *params)\n> +\t\t\t\t\t   RkISP1Params *params)\n>  {\n>  \tif (frame > 0)\n>  \t\treturn;\n>  \n> -\tparams->others.dpcc_config = config_;\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_DPCC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_DPCC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPCC;\n> +\tauto config = params->block<Block::Dpcc>();\n> +\tconfig.setEnabled(true);\n> +\t*config = config_;\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(DefectPixelClusterCorrection, \"DefectPixelClusterCorrection\")\n> diff --git a/src/ipa/rkisp1/algorithms/dpcc.h b/src/ipa/rkisp1/algorithms/dpcc.h\n> index d39b7bedc1e1..b77766c300fb 100644\n> --- a/src/ipa/rkisp1/algorithms/dpcc.h\n> +++ b/src/ipa/rkisp1/algorithms/dpcc.h\n> @@ -22,7 +22,7 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \trkisp1_cif_isp_dpcc_config config_;\n> diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp\n> index abf957288550..37291fc68e3e 100644\n> --- a/src/ipa/rkisp1/algorithms/dpf.cpp\n> +++ b/src/ipa/rkisp1/algorithms/dpf.cpp\n> @@ -215,15 +215,21 @@ void Dpf::queueRequest(IPAContext &context,\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n>  void Dpf::prepare(IPAContext &context, const uint32_t frame,\n> -\t\t  IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t  IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n> -\tif (frame == 0) {\n> -\t\tparams->others.dpf_config = config_;\n> -\t\tparams->others.dpf_strength_config = strengthConfig_;\n> +\tif (!frameContext.dpf.update && frame > 0)\n> +\t\treturn;\n> +\n> +\tauto config = params->block<Block::Dpf>();\n> +\tconfig.setEnabled(frameContext.dpf.denoise);\n> +\n> +\tif (frameContext.dpf.denoise) {\n> +\t\t*config = config_;\n>  \n>  \t\tconst auto &awb = context.configuration.awb;\n>  \t\tconst auto &lsc = context.configuration.lsc;\n> -\t\tauto &mode = params->others.dpf_config.gain.mode;\n> +\n> +\t\tauto &mode = config->gain.mode;\n>  \n>  \t\t/*\n>  \t\t * The DPF needs to take into account the total amount of\n> @@ -241,15 +247,12 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,\n>  \t\t\tmode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS;\n>  \t\telse\n>  \t\t\tmode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED;\n> -\n> -\t\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPF |\n> -\t\t\t\t\t     RKISP1_CIF_ISP_MODULE_DPF_STRENGTH;\n>  \t}\n>  \n> -\tif (frameContext.dpf.update) {\n> -\t\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_DPF;\n> -\t\tif (frameContext.dpf.denoise)\n> -\t\t\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_DPF;\n> +\tif (frame == 0) {\n> +\t\tauto strengthConfig = params->block<Block::DpfStrength>();\n> +\t\tstrengthConfig.setEnabled(true);\n> +\t\t*strengthConfig = strengthConfig_;\n>  \t}\n>  }\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h\n> index da0115baf8f1..2dd8cd362624 100644\n> --- a/src/ipa/rkisp1/algorithms/dpf.h\n> +++ b/src/ipa/rkisp1/algorithms/dpf.h\n> @@ -27,7 +27,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \tstruct rkisp1_cif_isp_dpf_config config_;\n> diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp\n> index 9752248a5965..51ce372d0595 100644\n> --- a/src/ipa/rkisp1/algorithms/filter.cpp\n> +++ b/src/ipa/rkisp1/algorithms/filter.cpp\n> @@ -104,7 +104,7 @@ void Filter::queueRequest(IPAContext &context,\n>   */\n>  void Filter::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t     [[maybe_unused]] const uint32_t frame,\n> -\t\t     IPAFrameContext &frameContext, rkisp1_params_cfg *params)\n> +\t\t     IPAFrameContext &frameContext, RkISP1Params *params)\n>  {\n>  \t/* Check if the algorithm configuration has been updated. */\n>  \tif (!frameContext.filter.update)\n> @@ -160,23 +160,25 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,\n>  \n>  \tuint8_t denoise = frameContext.filter.denoise;\n>  \tuint8_t sharpness = frameContext.filter.sharpness;\n> -\tauto &flt_config = params->others.flt_config;\n>  \n> -\tflt_config.fac_sh0 = filt_fac_sh0[sharpness];\n> -\tflt_config.fac_sh1 = filt_fac_sh1[sharpness];\n> -\tflt_config.fac_mid = filt_fac_mid[sharpness];\n> -\tflt_config.fac_bl0 = filt_fac_bl0[sharpness];\n> -\tflt_config.fac_bl1 = filt_fac_bl1[sharpness];\n> +\tauto config = params->block<Block::Flt>();\n> +\tconfig.setEnabled(true);\n>  \n> -\tflt_config.lum_weight = kFiltLumWeightDefault;\n> -\tflt_config.mode = kFiltModeDefault;\n> -\tflt_config.thresh_sh0 = filt_thresh_sh0[denoise];\n> -\tflt_config.thresh_sh1 = filt_thresh_sh1[denoise];\n> -\tflt_config.thresh_bl0 = filt_thresh_bl0[denoise];\n> -\tflt_config.thresh_bl1 = filt_thresh_bl1[denoise];\n> -\tflt_config.grn_stage1 = stage1_select[denoise];\n> -\tflt_config.chr_v_mode = filt_chr_v_mode[denoise];\n> -\tflt_config.chr_h_mode = filt_chr_h_mode[denoise];\n> +\tconfig->fac_sh0 = filt_fac_sh0[sharpness];\n> +\tconfig->fac_sh1 = filt_fac_sh1[sharpness];\n> +\tconfig->fac_mid = filt_fac_mid[sharpness];\n> +\tconfig->fac_bl0 = filt_fac_bl0[sharpness];\n> +\tconfig->fac_bl1 = filt_fac_bl1[sharpness];\n> +\n> +\tconfig->lum_weight = kFiltLumWeightDefault;\n> +\tconfig->mode = kFiltModeDefault;\n> +\tconfig->thresh_sh0 = filt_thresh_sh0[denoise];\n> +\tconfig->thresh_sh1 = filt_thresh_sh1[denoise];\n> +\tconfig->thresh_bl0 = filt_thresh_bl0[denoise];\n> +\tconfig->thresh_bl1 = filt_thresh_bl1[denoise];\n> +\tconfig->grn_stage1 = stage1_select[denoise];\n> +\tconfig->chr_v_mode = filt_chr_v_mode[denoise];\n> +\tconfig->chr_h_mode = filt_chr_h_mode[denoise];\n>  \n>  \t/*\n>  \t * Combined high denoising and high sharpening requires some\n> @@ -186,27 +188,23 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,\n>  \t */\n>  \tif (denoise == 9) {\n>  \t\tif (sharpness > 3)\n> -\t\t\tflt_config.grn_stage1 = 2;\n> +\t\t\tconfig->grn_stage1 = 2;\n>  \t} else if (denoise == 10) {\n>  \t\tif (sharpness > 5)\n> -\t\t\tflt_config.grn_stage1 = 2;\n> +\t\t\tconfig->grn_stage1 = 2;\n>  \t\telse if (sharpness > 3)\n> -\t\t\tflt_config.grn_stage1 = 1;\n> +\t\t\tconfig->grn_stage1 = 1;\n>  \t}\n>  \n>  \tif (denoise > 7) {\n>  \t\tif (sharpness > 7) {\n> -\t\t\tflt_config.fac_bl0 /= 2;\n> -\t\t\tflt_config.fac_bl1 /= 4;\n> +\t\t\tconfig->fac_bl0 /= 2;\n> +\t\t\tconfig->fac_bl1 /= 4;\n>  \t\t} else if (sharpness > 4) {\n> -\t\t\tflt_config.fac_bl0 = flt_config.fac_bl0 * 3 / 4;\n> -\t\t\tflt_config.fac_bl1 /= 2;\n> +\t\t\tconfig->fac_bl0 = config->fac_bl0 * 3 / 4;\n> +\t\t\tconfig->fac_bl1 /= 2;\n>  \t\t}\n>  \t}\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_FLT;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_FLT;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_FLT;\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(Filter, \"Filter\")\n> diff --git a/src/ipa/rkisp1/algorithms/filter.h b/src/ipa/rkisp1/algorithms/filter.h\n> index d595811d455f..8f858e574fa2 100644\n> --- a/src/ipa/rkisp1/algorithms/filter.h\n> +++ b/src/ipa/rkisp1/algorithms/filter.h\n> @@ -26,7 +26,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  };\n>  \n>  } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp\n> index a82cee3bbf61..f1f3f90d3c6b 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/goc.cpp\n> @@ -99,11 +99,14 @@ void GammaOutCorrection::queueRequest(IPAContext &context, const uint32_t frame,\n>  void GammaOutCorrection::prepare(IPAContext &context,\n>  \t\t\t\t [[maybe_unused]] const uint32_t frame,\n>  \t\t\t\t IPAFrameContext &frameContext,\n> -\t\t\t\t rkisp1_params_cfg *params)\n> +\t\t\t\t RkISP1Params *params)\n>  {\n>  \tASSERT(context.hw->numGammaOutSamples ==\n>  \t       RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);\n>  \n> +\tif (!frameContext.goc.update)\n> +\t\treturn;\n> +\n>  \t/*\n>  \t * The logarithmic segments as specified in the reference.\n>  \t * Plus an additional 0 to make the loop easier\n> @@ -112,10 +115,11 @@ void GammaOutCorrection::prepare(IPAContext &context,\n>  \t\t64, 64, 64, 64, 128, 128, 128, 128, 256,\n>  \t\t256, 256, 512, 512, 512, 512, 512, 0\n>  \t};\n> -\t__u16 *gamma_y = params->others.goc_config.gamma_y;\n>  \n> -\tif (!frameContext.goc.update)\n> -\t\treturn;\n> +\tauto config = params->block<Block::Goc>();\n> +\tconfig.setEnabled(true);\n> +\n> +\t__u16 *gamma_y = config->gamma_y;\n>  \n>  \tunsigned x = 0;\n>  \tfor (const auto [i, size] : utils::enumerate(segments)) {\n> @@ -123,10 +127,7 @@ void GammaOutCorrection::prepare(IPAContext &context,\n>  \t\tx += size;\n>  \t}\n>  \n> -\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n> +\tconfig->mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h\n> index 0e05d7ce4a01..bb2ddfc92375 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.h\n> +++ b/src/ipa/rkisp1/algorithms/goc.h\n> @@ -28,7 +28,7 @@ public:\n>  \t\t\t  const ControlList &controls) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \tvoid process(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n>  \t\t     const rkisp1_stat_buffer *stats,\n> diff --git a/src/ipa/rkisp1/algorithms/gsl.cpp b/src/ipa/rkisp1/algorithms/gsl.cpp\n> index 9b056c6edd96..aea701d7c287 100644\n> --- a/src/ipa/rkisp1/algorithms/gsl.cpp\n> +++ b/src/ipa/rkisp1/algorithms/gsl.cpp\n> @@ -119,24 +119,20 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,\n>  void GammaSensorLinearization::prepare([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t       const uint32_t frame,\n>  \t\t\t\t       [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t       rkisp1_params_cfg *params)\n> +\t\t\t\t       RkISP1Params *params)\n>  {\n>  \tif (frame > 0)\n>  \t\treturn;\n>  \n> -\tparams->others.sdg_config.xa_pnts.gamma_dx0 = gammaDx_[0];\n> -\tparams->others.sdg_config.xa_pnts.gamma_dx1 = gammaDx_[1];\n> +\tauto config = params->block<Block::Sdg>();\n> +\tconfig.setEnabled(true);\n>  \n> -\tstd::copy(curveYr_.begin(), curveYr_.end(),\n> -\t\t  params->others.sdg_config.curve_r.gamma_y);\n> -\tstd::copy(curveYg_.begin(), curveYg_.end(),\n> -\t\t  params->others.sdg_config.curve_g.gamma_y);\n> -\tstd::copy(curveYb_.begin(), curveYb_.end(),\n> -\t\t  params->others.sdg_config.curve_b.gamma_y);\n> +\tconfig->xa_pnts.gamma_dx0 = gammaDx_[0];\n> +\tconfig->xa_pnts.gamma_dx1 = gammaDx_[1];\n>  \n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_SDG;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_SDG;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_SDG;\n> +\tstd::copy(curveYr_.begin(), curveYr_.end(), config->curve_r.gamma_y);\n> +\tstd::copy(curveYg_.begin(), curveYg_.end(), config->curve_g.gamma_y);\n> +\tstd::copy(curveYb_.begin(), curveYb_.end(), config->curve_b.gamma_y);\n>  }\n>  \n>  REGISTER_IPA_ALGORITHM(GammaSensorLinearization, \"GammaSensorLinearization\")\n> diff --git a/src/ipa/rkisp1/algorithms/gsl.h b/src/ipa/rkisp1/algorithms/gsl.h\n> index c404105e6310..91cf6efa7925 100644\n> --- a/src/ipa/rkisp1/algorithms/gsl.h\n> +++ b/src/ipa/rkisp1/algorithms/gsl.h\n> @@ -22,7 +22,7 @@ public:\n>  \tint init(IPAContext &context, const YamlObject &tuningData) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \tuint32_t gammaDx_[2];\n> diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp\n> index 161183fca352..88971372fffb 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/lsc.cpp\n> @@ -185,18 +185,12 @@ int LensShadingCorrection::configure(IPAContext &context,\n>  \treturn 0;\n>  }\n>  \n> -void LensShadingCorrection::setParameters(rkisp1_params_cfg *params)\n> +void LensShadingCorrection::setParameters(rkisp1_cif_isp_lsc_config &config)\n>  {\n> -\tstruct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config;\n> -\n>  \tmemcpy(config.x_grad_tbl, xGrad_, sizeof(config.x_grad_tbl));\n>  \tmemcpy(config.y_grad_tbl, yGrad_, sizeof(config.y_grad_tbl));\n>  \tmemcpy(config.x_size_tbl, xSizes_, sizeof(config.x_size_tbl));\n>  \tmemcpy(config.y_size_tbl, ySizes_, sizeof(config.y_size_tbl));\n> -\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_LSC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC;\n>  }\n>  \n>  void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,\n> @@ -248,10 +242,8 @@ void LensShadingCorrection::interpolateTable(rkisp1_cif_isp_lsc_config &config,\n>  void LensShadingCorrection::prepare(IPAContext &context,\n>  \t\t\t\t    const uint32_t frame,\n>  \t\t\t\t    [[maybe_unused]] IPAFrameContext &frameContext,\n> -\t\t\t\t    rkisp1_params_cfg *params)\n> +\t\t\t\t    RkISP1Params *params)\n>  {\n> -\tstruct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config;\n> -\n>  \t/*\n>  \t * If there is only one set, the configuration has already been done\n>  \t * for first frame.\n> @@ -264,8 +256,11 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \t * never be relevant.\n>  \t */\n>  \tif (sets_.size() == 1) {\n> -\t\tsetParameters(params);\n> -\t\tcopyTable(config, sets_.cbegin()->second);\n> +\t\tauto config = params->block<Block::Lsc>();\n> +\t\tconfig.setEnabled(true);\n> +\n> +\t\tsetParameters(*config);\n> +\t\tcopyTable(*config, sets_.cbegin()->second);\n>  \t\treturn;\n>  \t}\n>  \n> @@ -294,13 +289,15 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \t    (lastCt_.adjusted <= ct && ct <= lastCt_.original))\n>  \t\treturn;\n>  \n> -\tsetParameters(params);\n> +\tauto config = params->block<Block::Lsc>();\n> +\tconfig.setEnabled(true);\n> +\tsetParameters(*config);\n>  \n>  \t/*\n>  \t * The color temperature matches exactly one of the available LSC tables.\n>  \t */\n>  \tif (sets_.count(ct)) {\n> -\t\tcopyTable(config, sets_[ct]);\n> +\t\tcopyTable(*config, sets_[ct]);\n>  \t\tlastCt_ = { ct, ct };\n>  \t\treturn;\n>  \t}\n> @@ -319,7 +316,7 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \tif (diff0 < threshold || diff1 < threshold) {\n>  \t\tconst Components &set = diff0 < diff1 ? set0 : set1;\n>  \t\tLOG(RkISP1Lsc, Debug) << \"using LSC table for \" << set.ct;\n> -\t\tcopyTable(config, set);\n> +\t\tcopyTable(*config, set);\n>  \t\tlastCt_ = { ct, set.ct };\n>  \t\treturn;\n>  \t}\n> @@ -331,7 +328,7 @@ void LensShadingCorrection::prepare(IPAContext &context,\n>  \tLOG(RkISP1Lsc, Debug)\n>  \t\t<< \"ct is \" << ct << \", interpolating between \"\n>  \t\t<< ct0 << \" and \" << ct1;\n> -\tinterpolateTable(config, set0, set1, ct);\n> +\tinterpolateTable(*config, set0, set1, ct);\n>  \tlastCt_ = { ct, ct };\n>  }\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h\n> index 5baf592797a6..a9c7a230e0fc 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.h\n> +++ b/src/ipa/rkisp1/algorithms/lsc.h\n> @@ -25,7 +25,7 @@ public:\n>  \tint configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;\n>  \tvoid prepare(IPAContext &context, const uint32_t frame,\n>  \t\t     IPAFrameContext &frameContext,\n> -\t\t     rkisp1_params_cfg *params) override;\n> +\t\t     RkISP1Params *params) override;\n>  \n>  private:\n>  \tstruct Components {\n> @@ -36,7 +36,7 @@ private:\n>  \t\tstd::vector<uint16_t> b;\n>  \t};\n>  \n> -\tvoid setParameters(rkisp1_params_cfg *params);\n> +\tvoid setParameters(rkisp1_cif_isp_lsc_config &config);\n>  \tvoid copyTable(rkisp1_cif_isp_lsc_config &config, const Components &set0);\n>  \tvoid interpolateTable(rkisp1_cif_isp_lsc_config &config,\n>  \t\t\t      const Components &set0, const Components &set1,\n> diff --git a/src/ipa/rkisp1/module.h b/src/ipa/rkisp1/module.h\n> index 16c3e43e88df..69e9bc823720 100644\n> --- a/src/ipa/rkisp1/module.h\n> +++ b/src/ipa/rkisp1/module.h\n> @@ -14,13 +14,14 @@\n>  #include <libipa/module.h>\n>  \n>  #include \"ipa_context.h\"\n> +#include \"params.h\"\n>  \n>  namespace libcamera {\n>  \n>  namespace ipa::rkisp1 {\n>  \n>  using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,\n> -\t\t\t   rkisp1_params_cfg, rkisp1_stat_buffer>;\n> +\t\t\t   RkISP1Params, rkisp1_stat_buffer>;\n>  \n>  } /* namespace ipa::rkisp1 */\n>  \n> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> index 84ffe6cf2777..1a89eabf10b4 100644\n> --- a/src/ipa/rkisp1/rkisp1.cpp\n> +++ b/src/ipa/rkisp1/rkisp1.cpp\n> @@ -31,6 +31,7 @@\n>  #include \"algorithms/algorithm.h\"\n>  \n>  #include \"ipa_context.h\"\n> +#include \"params.h\"\n>  \n>  namespace libcamera {\n>  \n> @@ -322,17 +323,12 @@ void IPARkISP1::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId)\n>  {\n>  \tIPAFrameContext &frameContext = context_.frameContexts.get(frame);\n>  \n> -\trkisp1_params_cfg *params =\n> -\t\treinterpret_cast<rkisp1_params_cfg *>(\n> -\t\t\tmappedBuffers_.at(bufferId).planes()[0].data());\n> -\n> -\t/* Prepare parameters buffer. */\n> -\tmemset(params, 0, sizeof(*params));\n> +\tRkISP1Params params(paramFormat_, mappedBuffers_.at(bufferId).planes()[0]);\n>  \n>  \tfor (auto const &algo : algorithms())\n> -\t\talgo->prepare(context_, frame, frameContext, params);\n> +\t\talgo->prepare(context_, frame, frameContext, &params);\n>  \n> -\tparamsBufferReady.emit(frame, sizeof(*params));\n> +\tparamsBufferReady.emit(frame, params.size());\n>  }\n>  \n>  void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId,\n> -- \n> Regards,\n> \n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id CBBDABD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  5 Jul 2024 13:33:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AEC8E62E22;\n\tFri,  5 Jul 2024 15:33:35 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9BF2B619BF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  5 Jul 2024 15:33:33 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:60b6:33a3:3a20:6030])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D6022541;\n\tFri,  5 Jul 2024 15:33:03 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"rm4NMwRr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1720186384;\n\tbh=e2uQKWIUIlUIuMFjQJiCSL9e/rMaEyOvsLGYbgLtoQU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=rm4NMwRrkj2CzBKN/yMQ3jTcVNbutmsD4JlHZcR7Q+vtcjqS0PzRyQKI4Mtaq8RQD\n\t9pSZgTOleQoPif2fKMYmqOSPQIjOy2EEz9Qxhb2Y4AXMZXVlEvvXryB2N5+czf7a2G\n\tmCc7AZBCzBLwqZuiLtLIUNTRPyMS0PlIHp4MJxxo=","Date":"Fri, 5 Jul 2024 15:33:30 +0200","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>","Subject":"Re: [PATCH v2 06/11] ipa: rkisp1: Use the new ISP parameters\n\tabstraction","Message-ID":"<35r4rabw72syboghknfjnaqjk4nbuz5wga4exdeyrkjro5hgd5@hvwx3v2dnabq>","References":"<20240704162035.15074-1-laurent.pinchart@ideasonboard.com>\n\t<20240704162035.15074-7-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20240704162035.15074-7-laurent.pinchart@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]