| Message ID | 20260616-ipu3-libipa-rework-v1-4-d4448b54f1d8@ideasonboard.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Quoting Daniel Scally (2026-06-16 07:41:38) > Add a Colour Correction Matrix algorithm that uses the new libipa > implementation. The module isn't well documented in the kernel but > the default values from the driver suggest a Q3.13 format. > > Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> > --- > src/ipa/ipu3/algorithms/ccm.cpp | 116 ++++++++++++++++++++++++++++++++++++ > src/ipa/ipu3/algorithms/ccm.h | 43 +++++++++++++ > src/ipa/ipu3/algorithms/meson.build | 1 + > src/ipa/ipu3/ipa_context.cpp | 10 ++++ > src/ipa/ipu3/ipa_context.h | 3 + > 5 files changed, 173 insertions(+) > > diff --git a/src/ipa/ipu3/algorithms/ccm.cpp b/src/ipa/ipu3/algorithms/ccm.cpp > new file mode 100644 > index 0000000000000000000000000000000000000000..44b8c107b079c544c5afd1fce3cbe355f6dacd76 > --- /dev/null > +++ b/src/ipa/ipu3/algorithms/ccm.cpp > @@ -0,0 +1,116 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2026, Ideas On Board > + * > + * IPU3 Colour correction matrix algorithm > + */ > + > +#include "ccm.h" > + > +/** > + * \file ccm.h > + */ > + > +namespace libcamera { > + > +namespace ipa::ipu3::algorithms { > + > +/** > + * \class Ccm > + * \brief The IPU3 color correction matrix algorithm > + */ > + > +LOG_DEFINE_CATEGORY(IPU3Ccm) > + > +/** > + * \copydoc libcamera::ipa::Algorithm::init > + */ > +int Ccm::init(IPAContext &context, const ValueNode &tuningData) > +{ > + return ccmAlgo_.init(tuningData, context.ctrlMap); > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::configure > + */ > +int Ccm::configure(IPAContext &context, > + [[maybe_unused]] const IPAConfigInfo &configInfo) > +{ > + return ccmAlgo_.configure(context.activeState.ccm, > + context.activeState.awb.automatic.temperatureK); > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::queueRequest > + */ > +void Ccm::queueRequest(IPAContext &context, [[maybe_unused]] const uint32_t frame, > + IPAFrameContext &frameContext, > + const ControlList &controls) > +{ > + /* Nothing to do here, the ccm will be calculated in prepare() */ > + if (frameContext.awb.autoEnabled) > + return; > + > + ccmAlgo_.queueRequest(context.activeState.ccm, frameContext.ccm, controls); > +} I still think it's awesome seeing how easy the implementations become with the composition patterns here. I got to the bottom of the file with nothing else to add, so I've come back up here to say: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Will be very interesting to see some calibration through the lightbox to test this. > + > +void Ccm::setParameters(ipu3_uapi_params *params, IPAFrameContext &context) > +{ > + const Matrix<float, 3, 3> &matrix = context.ccm.ccm; > + const Matrix<int16_t, 3, 1> &offsets = context.ccm.offsets; > + > + params->use.acc_ccm = 1; > + > + params->acc_param.ccm.coeff_m11 = Q<3, 13>(matrix[0][0]).quantized(); > + params->acc_param.ccm.coeff_m12 = Q<3, 13>(matrix[0][1]).quantized(); > + params->acc_param.ccm.coeff_m13 = Q<3, 13>(matrix[0][2]).quantized(); > + params->acc_param.ccm.coeff_o_r = offsets[0][0]; > + > + params->acc_param.ccm.coeff_m21 = Q<3, 13>(matrix[1][0]).quantized(); > + params->acc_param.ccm.coeff_m22 = Q<3, 13>(matrix[1][1]).quantized(); > + params->acc_param.ccm.coeff_m23 = Q<3, 13>(matrix[1][2]).quantized(); > + params->acc_param.ccm.coeff_o_g = offsets[1][0]; > + > + params->acc_param.ccm.coeff_m31 = Q<3, 13>(matrix[2][0]).quantized(); > + params->acc_param.ccm.coeff_m32 = Q<3, 13>(matrix[2][1]).quantized(); > + params->acc_param.ccm.coeff_m33 = Q<3, 13>(matrix[2][2]).quantized(); > + params->acc_param.ccm.coeff_o_b = offsets[2][0]; > + > + LOG(IPU3Ccm, Debug) << "Setting matrix " << matrix; > + LOG(IPU3Ccm, Debug) << "Setting offsets " << offsets; > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::prepare > + */ > +void Ccm::prepare(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, ipu3_uapi_params *params) > +{ > + if (!frameContext.awb.autoEnabled) { > + setParameters(params, frameContext); > + return; > + } > + > + ccmAlgo_.prepare(context.activeState.ccm, frameContext.ccm, frame, > + frameContext.awb.temperatureK); > + > + setParameters(params, frameContext); > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::process > + */ > +void Ccm::process([[maybe_unused]] IPAContext &context, > + [[maybe_unused]] const uint32_t frame, > + IPAFrameContext &frameContext, > + [[maybe_unused]] const ipu3_uapi_stats_3a *stats, > + ControlList &metadata) > +{ > + ccmAlgo_.process(frameContext.ccm, metadata); > +} > + > +REGISTER_IPA_ALGORITHM(Ccm, "Ccm") > + > +} /* namespace ipa::ipu3::algorithms */ > + > +} /* namespace libcamera */ > diff --git a/src/ipa/ipu3/algorithms/ccm.h b/src/ipa/ipu3/algorithms/ccm.h > new file mode 100644 > index 0000000000000000000000000000000000000000..39719c986267aff02e3129aad9dbe4baeec8f8a1 > --- /dev/null > +++ b/src/ipa/ipu3/algorithms/ccm.h > @@ -0,0 +1,43 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2026, Ideas On Board > + * > + * IPU3 Colour correction matrix algorithm > + */ > + > +#pragma once > + > +#include <linux/intel-ipu3.h> > + > +#include <libipa/ccm.h> > +#include <libipa/fixedpoint.h> > + > +#include "algorithm.h" > + > +namespace libcamera { > + > +namespace ipa::ipu3::algorithms { > + > +class Ccm : public Algorithm > +{ > +public: > + int init(IPAContext &context, const ValueNode &tuningData) override; > + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; > + void queueRequest(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + const ControlList &controls) override; > + void prepare(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + ipu3_uapi_params *params) override; > + void process(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + const ipu3_uapi_stats_3a *stats, > + ControlList &metadata) override; > + > +private: > + void setParameters(ipu3_uapi_params *params, IPAFrameContext &context); > + CcmAlgorithm<Q<3, 13>> ccmAlgo_; > +}; > + > +} /* namespace ipa::ipu3::algorithms */ > +} /* namespace libcamera */ > diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build > index b70a551cacf6cbdedf3ab41771a34ddcdae9fd8b..3dafd2fda9897942cf87d9640665c4fcff383859 100644 > --- a/src/ipa/ipu3/algorithms/meson.build > +++ b/src/ipa/ipu3/algorithms/meson.build > @@ -5,5 +5,6 @@ ipu3_ipa_algorithms = files([ > 'agc.cpp', > 'awb.cpp', > 'blc.cpp', > + 'ccm.cpp', > 'tone_mapping.cpp', > ]) > diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp > index b35c925d959027c540257e47944047c238f85571..dc43bc0877ed5c2e7287414e12667374f5ee1c80 100644 > --- a/src/ipa/ipu3/ipa_context.cpp > +++ b/src/ipa/ipu3/ipa_context.cpp > @@ -114,6 +114,11 @@ namespace libcamera::ipa::ipu3 { > * \brief Active auto-white balance parameters for the IPA > */ > > +/** > + * \var IPAActiveState::ccm > + * \brief Active colour Correction Matrix parameters for the IPA > + */ > + > /** > * \var IPASessionConfiguration::sensor > * \brief Sensor-specific configuration of the IPA > @@ -182,4 +187,9 @@ namespace libcamera::ipa::ipu3 { > * \brief Per-frame auto-white balance parameters for the IPA > */ > > +/** > + * \var IPAFrameContext::ccm > + * \brief Per-frame colour Correction Matrix parameters for the IPA > + */ > + > } /* namespace libcamera::ipa::ipu3 */ > diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h > index 245cf8b50b270a61df863e314128bede40d30541..be626d30d966b1bdaa322e5154f95f745f799976 100644 > --- a/src/ipa/ipu3/ipa_context.h > +++ b/src/ipa/ipu3/ipa_context.h > @@ -16,6 +16,7 @@ > #include <libcamera/geometry.h> > > #include <libipa/awb.h> > +#include <libipa/ccm.h> > #include <libipa/fc_queue.h> > > namespace libcamera { > @@ -64,6 +65,7 @@ struct IPAActiveState { > } agc; > > ipa::awb::ActiveState awb; > + ipa::ccm::ActiveState ccm; > > struct { > double gamma; > @@ -78,6 +80,7 @@ struct IPAFrameContext : public FrameContext { > } sensor; > > ipa::awb::FrameContext awb; > + ipa::ccm::FrameContext ccm; > }; > > struct IPAContext { > > -- > 2.43.0 >
Hi Dan On Tue, Jun 16, 2026 at 07:41:38AM +0100, Daniel Scally wrote: > Add a Colour Correction Matrix algorithm that uses the new libipa > implementation. The module isn't well documented in the kernel but > the default values from the driver suggest a Q3.13 format. > > Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> > --- > src/ipa/ipu3/algorithms/ccm.cpp | 116 ++++++++++++++++++++++++++++++++++++ > src/ipa/ipu3/algorithms/ccm.h | 43 +++++++++++++ > src/ipa/ipu3/algorithms/meson.build | 1 + > src/ipa/ipu3/ipa_context.cpp | 10 ++++ > src/ipa/ipu3/ipa_context.h | 3 + > 5 files changed, 173 insertions(+) > > diff --git a/src/ipa/ipu3/algorithms/ccm.cpp b/src/ipa/ipu3/algorithms/ccm.cpp > new file mode 100644 > index 0000000000000000000000000000000000000000..44b8c107b079c544c5afd1fce3cbe355f6dacd76 > --- /dev/null > +++ b/src/ipa/ipu3/algorithms/ccm.cpp > @@ -0,0 +1,116 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2026, Ideas On Board > + * > + * IPU3 Colour correction matrix algorithm > + */ > + > +#include "ccm.h" > + > +/** > + * \file ccm.h > + */ > + > +namespace libcamera { > + > +namespace ipa::ipu3::algorithms { > + > +/** > + * \class Ccm > + * \brief The IPU3 color correction matrix algorithm > + */ > + > +LOG_DEFINE_CATEGORY(IPU3Ccm) > + > +/** > + * \copydoc libcamera::ipa::Algorithm::init > + */ > +int Ccm::init(IPAContext &context, const ValueNode &tuningData) > +{ > + return ccmAlgo_.init(tuningData, context.ctrlMap); > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::configure > + */ > +int Ccm::configure(IPAContext &context, > + [[maybe_unused]] const IPAConfigInfo &configInfo) > +{ > + return ccmAlgo_.configure(context.activeState.ccm, > + context.activeState.awb.automatic.temperatureK); > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::queueRequest > + */ > +void Ccm::queueRequest(IPAContext &context, [[maybe_unused]] const uint32_t frame, > + IPAFrameContext &frameContext, > + const ControlList &controls) > +{ > + /* Nothing to do here, the ccm will be calculated in prepare() */ > + if (frameContext.awb.autoEnabled) > + return; > + > + ccmAlgo_.queueRequest(context.activeState.ccm, frameContext.ccm, controls); > +} > + > +void Ccm::setParameters(ipu3_uapi_params *params, IPAFrameContext &context) > +{ > + const Matrix<float, 3, 3> &matrix = context.ccm.ccm; > + const Matrix<int16_t, 3, 1> &offsets = context.ccm.offsets; > + > + params->use.acc_ccm = 1; > + > + params->acc_param.ccm.coeff_m11 = Q<3, 13>(matrix[0][0]).quantized(); > + params->acc_param.ccm.coeff_m12 = Q<3, 13>(matrix[0][1]).quantized(); > + params->acc_param.ccm.coeff_m13 = Q<3, 13>(matrix[0][2]).quantized(); > + params->acc_param.ccm.coeff_o_r = offsets[0][0]; > + > + params->acc_param.ccm.coeff_m21 = Q<3, 13>(matrix[1][0]).quantized(); > + params->acc_param.ccm.coeff_m22 = Q<3, 13>(matrix[1][1]).quantized(); > + params->acc_param.ccm.coeff_m23 = Q<3, 13>(matrix[1][2]).quantized(); > + params->acc_param.ccm.coeff_o_g = offsets[1][0]; > + > + params->acc_param.ccm.coeff_m31 = Q<3, 13>(matrix[2][0]).quantized(); > + params->acc_param.ccm.coeff_m32 = Q<3, 13>(matrix[2][1]).quantized(); > + params->acc_param.ccm.coeff_m33 = Q<3, 13>(matrix[2][2]).quantized(); > + params->acc_param.ccm.coeff_o_b = offsets[2][0]; > + > + LOG(IPU3Ccm, Debug) << "Setting matrix " << matrix; > + LOG(IPU3Ccm, Debug) << "Setting offsets " << offsets; > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::prepare > + */ > +void Ccm::prepare(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, ipu3_uapi_params *params) > +{ > + if (!frameContext.awb.autoEnabled) { > + setParameters(params, frameContext); > + return; > + } > + > + ccmAlgo_.prepare(context.activeState.ccm, frameContext.ccm, frame, > + frameContext.awb.temperatureK); > + > + setParameters(params, frameContext); > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::process > + */ > +void Ccm::process([[maybe_unused]] IPAContext &context, > + [[maybe_unused]] const uint32_t frame, > + IPAFrameContext &frameContext, > + [[maybe_unused]] const ipu3_uapi_stats_3a *stats, > + ControlList &metadata) > +{ > + ccmAlgo_.process(frameContext.ccm, metadata); > +} > + > +REGISTER_IPA_ALGORITHM(Ccm, "Ccm") > + > +} /* namespace ipa::ipu3::algorithms */ > + > +} /* namespace libcamera */ splendid! > diff --git a/src/ipa/ipu3/algorithms/ccm.h b/src/ipa/ipu3/algorithms/ccm.h > new file mode 100644 > index 0000000000000000000000000000000000000000..39719c986267aff02e3129aad9dbe4baeec8f8a1 > --- /dev/null > +++ b/src/ipa/ipu3/algorithms/ccm.h > @@ -0,0 +1,43 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2026, Ideas On Board > + * > + * IPU3 Colour correction matrix algorithm > + */ > + > +#pragma once > + > +#include <linux/intel-ipu3.h> Missing includes for ControlList and ValueNode #include <libcamera/controls.h> #include "libcamera/internal/value_node.h" > + > +#include <libipa/ccm.h> > +#include <libipa/fixedpoint.h> > + > +#include "algorithm.h" Missing include for IPAContext #include "ipa_context.h" Please check the same includes are there in awb.h from the previous patch > + > +namespace libcamera { > + > +namespace ipa::ipu3::algorithms { > + > +class Ccm : public Algorithm > +{ > +public: > + int init(IPAContext &context, const ValueNode &tuningData) override; > + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; > + void queueRequest(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + const ControlList &controls) override; > + void prepare(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + ipu3_uapi_params *params) override; > + void process(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + const ipu3_uapi_stats_3a *stats, > + ControlList &metadata) override; > + > +private: > + void setParameters(ipu3_uapi_params *params, IPAFrameContext &context); > + CcmAlgorithm<Q<3, 13>> ccmAlgo_; > +}; > + > +} /* namespace ipa::ipu3::algorithms */ > +} /* namespace libcamera */ > diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build > index b70a551cacf6cbdedf3ab41771a34ddcdae9fd8b..3dafd2fda9897942cf87d9640665c4fcff383859 100644 > --- a/src/ipa/ipu3/algorithms/meson.build > +++ b/src/ipa/ipu3/algorithms/meson.build > @@ -5,5 +5,6 @@ ipu3_ipa_algorithms = files([ > 'agc.cpp', > 'awb.cpp', > 'blc.cpp', > + 'ccm.cpp', > 'tone_mapping.cpp', > ]) > diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp > index b35c925d959027c540257e47944047c238f85571..dc43bc0877ed5c2e7287414e12667374f5ee1c80 100644 > --- a/src/ipa/ipu3/ipa_context.cpp > +++ b/src/ipa/ipu3/ipa_context.cpp > @@ -114,6 +114,11 @@ namespace libcamera::ipa::ipu3 { > * \brief Active auto-white balance parameters for the IPA > */ > > +/** > + * \var IPAActiveState::ccm > + * \brief Active colour Correction Matrix parameters for the IPA > + */ > + > /** > * \var IPASessionConfiguration::sensor > * \brief Sensor-specific configuration of the IPA > @@ -182,4 +187,9 @@ namespace libcamera::ipa::ipu3 { > * \brief Per-frame auto-white balance parameters for the IPA > */ > > +/** > + * \var IPAFrameContext::ccm > + * \brief Per-frame colour Correction Matrix parameters for the IPA > + */ > + > } /* namespace libcamera::ipa::ipu3 */ > diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h > index 245cf8b50b270a61df863e314128bede40d30541..be626d30d966b1bdaa322e5154f95f745f799976 100644 > --- a/src/ipa/ipu3/ipa_context.h > +++ b/src/ipa/ipu3/ipa_context.h > @@ -16,6 +16,7 @@ > #include <libcamera/geometry.h> > > #include <libipa/awb.h> > +#include <libipa/ccm.h> > #include <libipa/fc_queue.h> > > namespace libcamera { > @@ -64,6 +65,7 @@ struct IPAActiveState { > } agc; > > ipa::awb::ActiveState awb; > + ipa::ccm::ActiveState ccm; > > struct { > double gamma; > @@ -78,6 +80,7 @@ struct IPAFrameContext : public FrameContext { > } sensor; > > ipa::awb::FrameContext awb; > + ipa::ccm::FrameContext ccm; > }; > > struct IPAContext { > Ship it! Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Thanks j > -- > 2.43.0 >
diff --git a/src/ipa/ipu3/algorithms/ccm.cpp b/src/ipa/ipu3/algorithms/ccm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..44b8c107b079c544c5afd1fce3cbe355f6dacd76 --- /dev/null +++ b/src/ipa/ipu3/algorithms/ccm.cpp @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * IPU3 Colour correction matrix algorithm + */ + +#include "ccm.h" + +/** + * \file ccm.h + */ + +namespace libcamera { + +namespace ipa::ipu3::algorithms { + +/** + * \class Ccm + * \brief The IPU3 color correction matrix algorithm + */ + +LOG_DEFINE_CATEGORY(IPU3Ccm) + +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int Ccm::init(IPAContext &context, const ValueNode &tuningData) +{ + return ccmAlgo_.init(tuningData, context.ctrlMap); +} + +/** + * \copydoc libcamera::ipa::Algorithm::configure + */ +int Ccm::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) +{ + return ccmAlgo_.configure(context.activeState.ccm, + context.activeState.awb.automatic.temperatureK); +} + +/** + * \copydoc libcamera::ipa::Algorithm::queueRequest + */ +void Ccm::queueRequest(IPAContext &context, [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) +{ + /* Nothing to do here, the ccm will be calculated in prepare() */ + if (frameContext.awb.autoEnabled) + return; + + ccmAlgo_.queueRequest(context.activeState.ccm, frameContext.ccm, controls); +} + +void Ccm::setParameters(ipu3_uapi_params *params, IPAFrameContext &context) +{ + const Matrix<float, 3, 3> &matrix = context.ccm.ccm; + const Matrix<int16_t, 3, 1> &offsets = context.ccm.offsets; + + params->use.acc_ccm = 1; + + params->acc_param.ccm.coeff_m11 = Q<3, 13>(matrix[0][0]).quantized(); + params->acc_param.ccm.coeff_m12 = Q<3, 13>(matrix[0][1]).quantized(); + params->acc_param.ccm.coeff_m13 = Q<3, 13>(matrix[0][2]).quantized(); + params->acc_param.ccm.coeff_o_r = offsets[0][0]; + + params->acc_param.ccm.coeff_m21 = Q<3, 13>(matrix[1][0]).quantized(); + params->acc_param.ccm.coeff_m22 = Q<3, 13>(matrix[1][1]).quantized(); + params->acc_param.ccm.coeff_m23 = Q<3, 13>(matrix[1][2]).quantized(); + params->acc_param.ccm.coeff_o_g = offsets[1][0]; + + params->acc_param.ccm.coeff_m31 = Q<3, 13>(matrix[2][0]).quantized(); + params->acc_param.ccm.coeff_m32 = Q<3, 13>(matrix[2][1]).quantized(); + params->acc_param.ccm.coeff_m33 = Q<3, 13>(matrix[2][2]).quantized(); + params->acc_param.ccm.coeff_o_b = offsets[2][0]; + + LOG(IPU3Ccm, Debug) << "Setting matrix " << matrix; + LOG(IPU3Ccm, Debug) << "Setting offsets " << offsets; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Ccm::prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, ipu3_uapi_params *params) +{ + if (!frameContext.awb.autoEnabled) { + setParameters(params, frameContext); + return; + } + + ccmAlgo_.prepare(context.activeState.ccm, frameContext.ccm, frame, + frameContext.awb.temperatureK); + + setParameters(params, frameContext); +} + +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void Ccm::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] const ipu3_uapi_stats_3a *stats, + ControlList &metadata) +{ + ccmAlgo_.process(frameContext.ccm, metadata); +} + +REGISTER_IPA_ALGORITHM(Ccm, "Ccm") + +} /* namespace ipa::ipu3::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/ipu3/algorithms/ccm.h b/src/ipa/ipu3/algorithms/ccm.h new file mode 100644 index 0000000000000000000000000000000000000000..39719c986267aff02e3129aad9dbe4baeec8f8a1 --- /dev/null +++ b/src/ipa/ipu3/algorithms/ccm.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * IPU3 Colour correction matrix algorithm + */ + +#pragma once + +#include <linux/intel-ipu3.h> + +#include <libipa/ccm.h> +#include <libipa/fixedpoint.h> + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::ipu3::algorithms { + +class Ccm : public Algorithm +{ +public: + int init(IPAContext &context, const ValueNode &tuningData) override; + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; + void queueRequest(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) override; + void prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + ipu3_uapi_params *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const ipu3_uapi_stats_3a *stats, + ControlList &metadata) override; + +private: + void setParameters(ipu3_uapi_params *params, IPAFrameContext &context); + CcmAlgorithm<Q<3, 13>> ccmAlgo_; +}; + +} /* namespace ipa::ipu3::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index b70a551cacf6cbdedf3ab41771a34ddcdae9fd8b..3dafd2fda9897942cf87d9640665c4fcff383859 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -5,5 +5,6 @@ ipu3_ipa_algorithms = files([ 'agc.cpp', 'awb.cpp', 'blc.cpp', + 'ccm.cpp', 'tone_mapping.cpp', ]) diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index b35c925d959027c540257e47944047c238f85571..dc43bc0877ed5c2e7287414e12667374f5ee1c80 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -114,6 +114,11 @@ namespace libcamera::ipa::ipu3 { * \brief Active auto-white balance parameters for the IPA */ +/** + * \var IPAActiveState::ccm + * \brief Active colour Correction Matrix parameters for the IPA + */ + /** * \var IPASessionConfiguration::sensor * \brief Sensor-specific configuration of the IPA @@ -182,4 +187,9 @@ namespace libcamera::ipa::ipu3 { * \brief Per-frame auto-white balance parameters for the IPA */ +/** + * \var IPAFrameContext::ccm + * \brief Per-frame colour Correction Matrix parameters for the IPA + */ + } /* namespace libcamera::ipa::ipu3 */ diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 245cf8b50b270a61df863e314128bede40d30541..be626d30d966b1bdaa322e5154f95f745f799976 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -16,6 +16,7 @@ #include <libcamera/geometry.h> #include <libipa/awb.h> +#include <libipa/ccm.h> #include <libipa/fc_queue.h> namespace libcamera { @@ -64,6 +65,7 @@ struct IPAActiveState { } agc; ipa::awb::ActiveState awb; + ipa::ccm::ActiveState ccm; struct { double gamma; @@ -78,6 +80,7 @@ struct IPAFrameContext : public FrameContext { } sensor; ipa::awb::FrameContext awb; + ipa::ccm::FrameContext ccm; }; struct IPAContext {
Add a Colour Correction Matrix algorithm that uses the new libipa implementation. The module isn't well documented in the kernel but the default values from the driver suggest a Q3.13 format. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> --- src/ipa/ipu3/algorithms/ccm.cpp | 116 ++++++++++++++++++++++++++++++++++++ src/ipa/ipu3/algorithms/ccm.h | 43 +++++++++++++ src/ipa/ipu3/algorithms/meson.build | 1 + src/ipa/ipu3/ipa_context.cpp | 10 ++++ src/ipa/ipu3/ipa_context.h | 3 + 5 files changed, 173 insertions(+)