Message ID | 20250815102945.1602071-2-stefan.klug@ideasonboard.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Quoting Stefan Klug (2025-08-15 19:29:21) > 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 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.h | 9 +++ > 4 files changed, 142 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..e076727de4f1 > --- /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 compressions curve in the compand s/compressions/compression/ > + * 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 activeState.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.activeState.compress.supported = true; imo this sounds like something that should be in the session configuration instead of the active state. > + 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); Should this be not enabled if not frameContext.compress.enable? > + > + if (!frameContext.compress.enable) > + return; > + > + int xmax = (1 << kRkISP1CompressInBits); > + int ymax = (1 << kRkISP1CompressOutBits); > + int inLogStep = std::log2(xmax / 64); imo s/64/RKISP1_CIF_ISP_COMPAND_NUM_POINTS/ is clearer as to what the 64 means. Paul > + > + 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.h b/src/ipa/rkisp1/ipa_context.h > index 7ccc7b501aff..37a74215ce19 100644 > --- a/src/ipa/rkisp1/ipa_context.h > +++ b/src/ipa/rkisp1/ipa_context.h > @@ -106,6 +106,10 @@ struct IPAActiveState { > Matrix<float, 3, 3> automatic; > } ccm; > > + struct { > + bool supported; > + } compress; > + > struct { > int8_t brightness; > uint8_t contrast; > @@ -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..e076727de4f1 --- /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 compressions 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 activeState.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.activeState.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 / 64); + + 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.h b/src/ipa/rkisp1/ipa_context.h index 7ccc7b501aff..37a74215ce19 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -106,6 +106,10 @@ struct IPAActiveState { Matrix<float, 3, 3> automatic; } ccm; + struct { + bool supported; + } compress; + struct { int8_t brightness; uint8_t contrast; @@ -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 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.h | 9 +++ 4 files changed, 142 insertions(+) create mode 100644 src/ipa/rkisp1/algorithms/compress.cpp create mode 100644 src/ipa/rkisp1/algorithms/compress.h