Message ID | 20250918144333.108695-2-stefan.klug@ideasonboard.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Quoting Stefan Klug (2025-09-18 15:43:10) > The i.MX8 M Plus has a compression curve inside the compand block. This > curve is necessary to process HDR stitched data and is useful for other > aspects like applying a digital gain to the incoming sensor data. > > Add a basic algorithm for the compression curve. This algorithm has a > hardcoded input width of 20bit and output width of 12bit which matches > the imx8mp pipeline. Only a static gain is supported in this version. > > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> > > --- > > Changes in v4: > - Moved activeState.compress.supported to > configuration.compress.supported > - Added documentation > - Fixed typo in documentation > - Replaced constant with RKISP1_CIF_ISP_COMPAND_NUM_POINTS > > Changes in v3: > - Removed unused member > - Fixed comment referencing copy-paste source > - Ensure activeState.compress.supported stays false if unsupported > --- > src/ipa/rkisp1/algorithms/compress.cpp | 102 +++++++++++++++++++++++++ > src/ipa/rkisp1/algorithms/compress.h | 30 ++++++++ > src/ipa/rkisp1/algorithms/meson.build | 1 + > src/ipa/rkisp1/ipa_context.cpp | 19 +++++ > src/ipa/rkisp1/ipa_context.h | 9 +++ > 5 files changed, 161 insertions(+) > create mode 100644 src/ipa/rkisp1/algorithms/compress.cpp > create mode 100644 src/ipa/rkisp1/algorithms/compress.h > > diff --git a/src/ipa/rkisp1/algorithms/compress.cpp b/src/ipa/rkisp1/algorithms/compress.cpp > new file mode 100644 > index 000000000000..c31d71bd50d5 > --- /dev/null > +++ b/src/ipa/rkisp1/algorithms/compress.cpp > @@ -0,0 +1,102 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2025, Ideas On Board > + * > + * RkISP1 Compression curve > + */ > +#include "compress.h" > + > +#include <linux/videodev2.h> > + > +#include <libcamera/base/log.h> > +#include <libcamera/base/utils.h> > + > +#include "libcamera/internal/yaml_parser.h" > + > +#include "linux/rkisp1-config.h" > + > +/** > + * \file compress.h > + */ > + > +namespace libcamera { > + > +namespace ipa::rkisp1::algorithms { > + > +/** > + * \class Compress > + * \brief RkISP1 Compress curve > + * > + * This algorithm implements support for the compression curve in the compand > + * block available in the i.MX8 M Plus > + * > + * In its current version it only supports a static gain. This is useful for > + * the agc algorithm to compensate for exposure/gain quantization effects. > + * > + * This algorithm doesn't have any configuration options. It needs to be > + * configured per frame by other algorithms. > + * > + * Other algorithms can check configuration.compress.supported to see if > + * compression is available. If it is available they can configure it per frame > + * using frameContext.compress.enable and frameContext.compress.gain. > + */ > + > +LOG_DEFINE_CATEGORY(RkISP1Compress) > + > +constexpr static int kRkISP1CompressInBits = 20; > +constexpr static int kRkISP1CompressOutBits = 12; > + > +/** > + * \copydoc libcamera::ipa::Algorithm::configure > + */ > +int Compress::configure(IPAContext &context, > + [[maybe_unused]] const IPACameraSensorInfo &configInfo) > +{ > + if (context.configuration.paramFormat != V4L2_META_FMT_RK_ISP1_EXT_PARAMS || > + !context.hw->compand) { > + LOG(RkISP1Compress, Warning) > + << "Compression is not supported by the hardware or kernel."; > + return 0; > + } > + > + context.configuration.compress.supported = true; > + return 0; > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::prepare > + */ > +void Compress::prepare([[maybe_unused]] IPAContext &context, > + [[maybe_unused]] const uint32_t frame, > + IPAFrameContext &frameContext, > + RkISP1Params *params) > +{ > + auto comp = params->block<BlockType::CompandCompress>(); > + comp.setEnabled(frameContext.compress.enable); > + > + if (!frameContext.compress.enable) Does this need any guard against the compress being supported ? Or will compress.enable never get set in that case ? I think that will be the case so if so: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > + return; > + > + int xmax = (1 << kRkISP1CompressInBits); > + int ymax = (1 << kRkISP1CompressOutBits); > + int inLogStep = std::log2(xmax / RKISP1_CIF_ISP_COMPAND_NUM_POINTS); > + > + for (unsigned int i = 0; i < RKISP1_CIF_ISP_COMPAND_NUM_POINTS; i++) { > + double x = (i + 1) * (1.0 / RKISP1_CIF_ISP_COMPAND_NUM_POINTS); > + double y = x * frameContext.compress.gain; > + > + comp->px[i] = inLogStep; > + comp->x[i] = std::min<int>(x * xmax, xmax - 1); > + comp->y[i] = std::min<int>(y * ymax, ymax - 1); > + } > + > + LOG(RkISP1Compress, Debug) << "Compression: " << kRkISP1CompressInBits > + << " bits to " << kRkISP1CompressOutBits > + << " bits gain: " << frameContext.compress.gain; > +} > + > +REGISTER_IPA_ALGORITHM(Compress, "Compress") > + > +} /* namespace ipa::rkisp1::algorithms */ > + > +} /* namespace libcamera */ > diff --git a/src/ipa/rkisp1/algorithms/compress.h b/src/ipa/rkisp1/algorithms/compress.h > new file mode 100644 > index 000000000000..87797b8ebcc5 > --- /dev/null > +++ b/src/ipa/rkisp1/algorithms/compress.h > @@ -0,0 +1,30 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2025, Ideas On Board > + * > + * RkISP1 Compression curve > + */ > + > +#pragma once > + > +#include "algorithm.h" > + > +namespace libcamera { > + > +namespace ipa::rkisp1::algorithms { > + > +class Compress : public Algorithm > +{ > +public: > + Compress() = default; > + ~Compress() = default; > + > + int configure(IPAContext &context, > + const IPACameraSensorInfo &configInfo) override; > + void prepare(IPAContext &context, const uint32_t frame, > + IPAFrameContext &frameContext, > + RkISP1Params *params) override; > +}; > + > +} /* namespace ipa::rkisp1::algorithms */ > +} /* namespace libcamera */ > diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build > index c66b0b70b82f..2e42a80cf99d 100644 > --- a/src/ipa/rkisp1/algorithms/meson.build > +++ b/src/ipa/rkisp1/algorithms/meson.build > @@ -5,6 +5,7 @@ rkisp1_ipa_algorithms = files([ > 'awb.cpp', > 'blc.cpp', > 'ccm.cpp', > + 'compress.cpp', > 'cproc.cpp', > 'dpcc.cpp', > 'dpf.cpp', > diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp > index 6509610573c0..15cb0afe9fe8 100644 > --- a/src/ipa/rkisp1/ipa_context.cpp > +++ b/src/ipa/rkisp1/ipa_context.cpp > @@ -66,6 +66,14 @@ namespace libcamera::ipa::rkisp1 { > * operates in manual or automatic mode. > */ > > +/** > + * \var IPASessionConfiguration::compress > + * \brief Compress parameters configuration of the IPA > + * > + * \var IPASessionConfiguration::agc.supported > + * \brief true if compression is supported and the algorithm is loaded > + */ > + > /** > * \var IPASessionConfiguration::lsc > * \brief Lens Shading Correction configuration of the IPA > @@ -377,6 +385,17 @@ namespace libcamera::ipa::rkisp1 { > * \brief Colour Correction Matrix > */ > > +/** > + * \var IPAFrameContext::compress > + * \brief Compress parameters for this frame > + * > + * \struct IPAFrameContext::compress.enable > + * \brief True if compression is enabled > + * > + * \var IPAFrameContext::compress.gain > + * \brief The gain applied with the compression curve > + */ > + > /** > * \var IPAFrameContext::cproc > * \brief Color Processing parameters for this frame > diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h > index 7ccc7b501aff..a723c79b04d9 100644 > --- a/src/ipa/rkisp1/ipa_context.h > +++ b/src/ipa/rkisp1/ipa_context.h > @@ -49,6 +49,10 @@ struct IPASessionConfiguration { > bool enabled; > } awb; > > + struct { > + bool supported; > + } compress; > + > struct { > bool enabled; > } lsc; > @@ -158,6 +162,11 @@ struct IPAFrameContext : public FrameContext { > bool update; > } cproc; > > + struct { > + bool enable; > + double gain; > + } compress; > + > struct { > bool denoise; > bool update; > -- > 2.48.1 >
diff --git a/src/ipa/rkisp1/algorithms/compress.cpp b/src/ipa/rkisp1/algorithms/compress.cpp new file mode 100644 index 000000000000..c31d71bd50d5 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/compress.cpp @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Ideas On Board + * + * RkISP1 Compression curve + */ +#include "compress.h" + +#include <linux/videodev2.h> + +#include <libcamera/base/log.h> +#include <libcamera/base/utils.h> + +#include "libcamera/internal/yaml_parser.h" + +#include "linux/rkisp1-config.h" + +/** + * \file compress.h + */ + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +/** + * \class Compress + * \brief RkISP1 Compress curve + * + * This algorithm implements support for the compression curve in the compand + * block available in the i.MX8 M Plus + * + * In its current version it only supports a static gain. This is useful for + * the agc algorithm to compensate for exposure/gain quantization effects. + * + * This algorithm doesn't have any configuration options. It needs to be + * configured per frame by other algorithms. + * + * Other algorithms can check configuration.compress.supported to see if + * compression is available. If it is available they can configure it per frame + * using frameContext.compress.enable and frameContext.compress.gain. + */ + +LOG_DEFINE_CATEGORY(RkISP1Compress) + +constexpr static int kRkISP1CompressInBits = 20; +constexpr static int kRkISP1CompressOutBits = 12; + +/** + * \copydoc libcamera::ipa::Algorithm::configure + */ +int Compress::configure(IPAContext &context, + [[maybe_unused]] const IPACameraSensorInfo &configInfo) +{ + if (context.configuration.paramFormat != V4L2_META_FMT_RK_ISP1_EXT_PARAMS || + !context.hw->compand) { + LOG(RkISP1Compress, Warning) + << "Compression is not supported by the hardware or kernel."; + return 0; + } + + context.configuration.compress.supported = true; + return 0; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Compress::prepare([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + RkISP1Params *params) +{ + auto comp = params->block<BlockType::CompandCompress>(); + comp.setEnabled(frameContext.compress.enable); + + if (!frameContext.compress.enable) + return; + + int xmax = (1 << kRkISP1CompressInBits); + int ymax = (1 << kRkISP1CompressOutBits); + int inLogStep = std::log2(xmax / RKISP1_CIF_ISP_COMPAND_NUM_POINTS); + + for (unsigned int i = 0; i < RKISP1_CIF_ISP_COMPAND_NUM_POINTS; i++) { + double x = (i + 1) * (1.0 / RKISP1_CIF_ISP_COMPAND_NUM_POINTS); + double y = x * frameContext.compress.gain; + + comp->px[i] = inLogStep; + comp->x[i] = std::min<int>(x * xmax, xmax - 1); + comp->y[i] = std::min<int>(y * ymax, ymax - 1); + } + + LOG(RkISP1Compress, Debug) << "Compression: " << kRkISP1CompressInBits + << " bits to " << kRkISP1CompressOutBits + << " bits gain: " << frameContext.compress.gain; +} + +REGISTER_IPA_ALGORITHM(Compress, "Compress") + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/compress.h b/src/ipa/rkisp1/algorithms/compress.h new file mode 100644 index 000000000000..87797b8ebcc5 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/compress.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Ideas On Board + * + * RkISP1 Compression curve + */ + +#pragma once + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +class Compress : public Algorithm +{ +public: + Compress() = default; + ~Compress() = default; + + int configure(IPAContext &context, + const IPACameraSensorInfo &configInfo) override; + void prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + RkISP1Params *params) override; +}; + +} /* namespace ipa::rkisp1::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build index c66b0b70b82f..2e42a80cf99d 100644 --- a/src/ipa/rkisp1/algorithms/meson.build +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -5,6 +5,7 @@ rkisp1_ipa_algorithms = files([ 'awb.cpp', 'blc.cpp', 'ccm.cpp', + 'compress.cpp', 'cproc.cpp', 'dpcc.cpp', 'dpf.cpp', diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 6509610573c0..15cb0afe9fe8 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -66,6 +66,14 @@ namespace libcamera::ipa::rkisp1 { * operates in manual or automatic mode. */ +/** + * \var IPASessionConfiguration::compress + * \brief Compress parameters configuration of the IPA + * + * \var IPASessionConfiguration::agc.supported + * \brief true if compression is supported and the algorithm is loaded + */ + /** * \var IPASessionConfiguration::lsc * \brief Lens Shading Correction configuration of the IPA @@ -377,6 +385,17 @@ namespace libcamera::ipa::rkisp1 { * \brief Colour Correction Matrix */ +/** + * \var IPAFrameContext::compress + * \brief Compress parameters for this frame + * + * \struct IPAFrameContext::compress.enable + * \brief True if compression is enabled + * + * \var IPAFrameContext::compress.gain + * \brief The gain applied with the compression curve + */ + /** * \var IPAFrameContext::cproc * \brief Color Processing parameters for this frame diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 7ccc7b501aff..a723c79b04d9 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -49,6 +49,10 @@ struct IPASessionConfiguration { bool enabled; } awb; + struct { + bool supported; + } compress; + struct { bool enabled; } lsc; @@ -158,6 +162,11 @@ struct IPAFrameContext : public FrameContext { bool update; } cproc; + struct { + bool enable; + double gain; + } compress; + struct { bool denoise; bool update;
The i.MX8 M Plus has a compression curve inside the compand block. This curve is necessary to process HDR stitched data and is useful for other aspects like applying a digital gain to the incoming sensor data. Add a basic algorithm for the compression curve. This algorithm has a hardcoded input width of 20bit and output width of 12bit which matches the imx8mp pipeline. Only a static gain is supported in this version. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> --- Changes in v4: - Moved activeState.compress.supported to configuration.compress.supported - Added documentation - Fixed typo in documentation - Replaced constant with RKISP1_CIF_ISP_COMPAND_NUM_POINTS Changes in v3: - Removed unused member - Fixed comment referencing copy-paste source - Ensure activeState.compress.supported stays false if unsupported --- src/ipa/rkisp1/algorithms/compress.cpp | 102 +++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/compress.h | 30 ++++++++ src/ipa/rkisp1/algorithms/meson.build | 1 + src/ipa/rkisp1/ipa_context.cpp | 19 +++++ src/ipa/rkisp1/ipa_context.h | 9 +++ 5 files changed, 161 insertions(+) create mode 100644 src/ipa/rkisp1/algorithms/compress.cpp create mode 100644 src/ipa/rkisp1/algorithms/compress.h