Message ID | 20220726143635.518227-4-fsylvestre@baylibre.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Florian, Thank you for the patch. On Tue, Jul 26, 2022 at 04:36:33PM +0200, Florian Sylvestre via libcamera-devel wrote: > The Lens Shading Correction algorithm applies multipliers to all pixels > to compensate for the lens shading effect. The coefficients are > specified in a downscaled table in the YAML tuning file. > > Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com> > --- > src/ipa/rkisp1/algorithms/lsc.cpp | 195 ++++++++++++++++++++++++++ > src/ipa/rkisp1/algorithms/lsc.h | 38 +++++ > src/ipa/rkisp1/algorithms/meson.build | 1 + > src/ipa/rkisp1/data/ov5640.yaml | 79 +++++++++++ > src/ipa/rkisp1/ipa_context.cpp | 3 + > src/ipa/rkisp1/ipa_context.h | 1 + > src/ipa/rkisp1/rkisp1.cpp | 1 + > 7 files changed, 318 insertions(+) > create mode 100644 src/ipa/rkisp1/algorithms/lsc.cpp > create mode 100644 src/ipa/rkisp1/algorithms/lsc.h > > diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp > new file mode 100644 > index 00000000..5809e154 > --- /dev/null > +++ b/src/ipa/rkisp1/algorithms/lsc.cpp > @@ -0,0 +1,195 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2021-2022, Ideas On Board > + * > + * lsc.cpp - RkISP1 Lens Shading Correction control > + */ > + > +#include "lsc.h" > + > +#include <cmath> > +#include <numeric> > + > +#include <libcamera/base/log.h> > + > +#include "libcamera/internal/yaml_parser.h" > + > +#include "linux/rkisp1-config.h" > + > +/** > + * \file lsc.h > + */ > + > +namespace libcamera { > + > +namespace ipa::rkisp1::algorithms { > + > +/** > + * \class LensShadingCorrection > + * \brief RkISP1 Lens Shading Correction control > + * > + * Due to the optical characteristics of the lens, the light intensity received > + * by the sensor is not uniform. > + * > + * The Lens Shading Correction algorithm applies multipliers to all pixels > + * to compensate for the lens shading effect. The coefficients are > + * specified in a downscaled table in the YAML tuning file. > + */ > + > +LOG_DEFINE_CATEGORY(RkISP1Lsc) > + > +LensShadingCorrection::LensShadingCorrection() > + : initialized_(false) > +{ > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::init > + */ > +int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, > + const YamlObject &tuningData) > +{ > + static constexpr unsigned int kLscNumSamples = > + RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX; > + float sum; > + > + xSize_ = tuningData["x-size"].getList<double>(); > + if (xSize_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'x-size' values: expected " > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE > + << " elements, got " << xSize_.size(); > + return -EINVAL; > + } > + > + /* > + * Check that the sum of elements is the expected one with a tolerance > + * of 1%. > + */ > + sum = std::accumulate(xSize_.begin(), xSize_.end(), 0.0f); > + if (sum < 0.495 || sum > 0.505) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'x-size' values: sum of the elements should" > + << " be 0.5 , got " << sum; > + return -EINVAL; > + } > + > + ySize_ = tuningData["y-size"].getList<double>(); > + if (ySize_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'y-size' values: expected " > + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE > + << " elements, got " << ySize_.size(); > + return -EINVAL; > + } > + > + /* > + * Check that the sum of elements is the expected one with a tolerance > + * of 1%. > + */ > + sum = std::accumulate(ySize_.begin(), ySize_.end(), 0.0f); > + if (sum < 0.495 || sum > 0.505) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'y-size' values: sum of the elements should" > + << " be 0.5 , got " << sum; > + return -EINVAL; > + } Let's avoid code duplication: static std::vector<double> parseSizes(const YamlObject &tuningData, const char *prop) { std::vector<double> sizes = tuningData["prop"].getList<double>(); if (sizes.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { LOG(RkISP1Lsc, Error) << "Invalid '" << prop << "' values: expected " << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE << " elements, got " << sizes.size(); return {}; } /* * The sum of all elements must be 0.5 to satisfy hardware constraints. * Validate it here, allowing a 1% tolerance as rounding errors may * prevent an exact match (further adjustements will be performed in * LensShadingCorrection::prepare()). */ float sum = std::accumulate(sizes.begin(), sizes.end(), 0.0f); if (sum < 0.495 || sum > 0.505) { LOG(RkISP1Lsc, Error) << "Invalid '" << prop << "' values: sum of the elements" << " should be 0.5, got " << sum; return {}; } return sizes; } /** * \copydoc libcamera::ipa::Algorithm::init */ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) { xSize_ = parseSizes(tuningData, "x-size"); ySize_ = parseSizes(tuningData, "y-size"); if (xSize_.empty() || ySize_.empty()) return -EINVAL; static constexpr unsigned int kLscNumSamples = RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX; ... } > + > + rData_ = tuningData["r"].getList<uint16_t>(); > + if (rData_.size() != kLscNumSamples) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'r' values: expected " > + << kLscNumSamples > + << " elements, got " << rData_.size(); > + return -EINVAL; > + } > + > + grData_ = tuningData["gr"].getList<uint16_t>(); > + if (grData_.size() != kLscNumSamples) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'gr' values: expected " > + << kLscNumSamples > + << " elements, got " << grData_.size(); > + return -EINVAL; > + } > + > + gbData_ = tuningData["gb"].getList<uint16_t>(); > + if (gbData_.size() != kLscNumSamples) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'gb' values: expected " > + << kLscNumSamples > + << " elements, got " << gbData_.size(); > + return -EINVAL; > + } > + > + bData_ = tuningData["b"].getList<uint16_t>(); > + if (bData_.size() != kLscNumSamples) { > + LOG(RkISP1Lsc, Error) > + << "Invalid 'b' values: expected " > + << kLscNumSamples > + << " elements, got " << bData_.size(); > + return -EINVAL; > + } And you could do the same for these too, with a parseTable() function. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > + > + initialized_ = true; > + > + return 0; > +} > + > +/** > + * \copydoc libcamera::ipa::Algorithm::prepare > + */ > +void LensShadingCorrection::prepare(IPAContext &context, > + rkisp1_params_cfg *params) > +{ > + if (context.frameContext.frameCount > 0) > + return; > + > + if (!initialized_) > + return; > + > + struct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config; > + const Size &size = context.configuration.sensor.size; > + Size totalSize{}; > + > + for (unsigned int i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE; ++i) { > + config.x_size_tbl[i] = xSize_[i] * size.width; > + config.y_size_tbl[i] = ySize_[i] * size.height; > + > + /* > + * To prevent unexpected behavior of the ISP, the sum of x_size_tbl and > + * y_size_tbl items shall be equal to respectively size.width/2 and > + * size.height/2. Enforce it by computing the last tables value to avoid > + * rounding-induced errors. > + */ > + if (i == RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE - 1) { > + config.x_size_tbl[i] = size.width / 2 - totalSize.width; > + config.y_size_tbl[i] = size.height / 2 - totalSize.height; > + } > + > + totalSize.width += config.x_size_tbl[i]; > + totalSize.height += config.y_size_tbl[i]; > + > + config.x_grad_tbl[i] = std::round(32768 / config.x_size_tbl[i]); > + config.y_grad_tbl[i] = std::round(32768 / config.y_size_tbl[i]); > + } > + > + std::copy(rData_.begin(), rData_.end(), > + ¶ms->others.lsc_config.r_data_tbl[0][0]); > + std::copy(grData_.begin(), grData_.end(), > + ¶ms->others.lsc_config.gr_data_tbl[0][0]); > + std::copy(gbData_.begin(), gbData_.end(), > + ¶ms->others.lsc_config.gb_data_tbl[0][0]); > + std::copy(bData_.begin(), bData_.end(), > + ¶ms->others.lsc_config.b_data_tbl[0][0]); > + > + params->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC; > + params->module_ens |= RKISP1_CIF_ISP_MODULE_LSC; > + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC; > +} > + > +REGISTER_IPA_ALGORITHM(LensShadingCorrection, "LensShadingCorrection") > + > +} /* namespace ipa::rkisp1::algorithms */ > + > +} /* namespace libcamera */ > diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h > new file mode 100644 > index 00000000..fdb2ec1d > --- /dev/null > +++ b/src/ipa/rkisp1/algorithms/lsc.h > @@ -0,0 +1,38 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2021-2022, Ideas On Board > + * > + * lsc.h - RkISP1 Lens Shading Correction control > + */ > + > +#pragma once > + > +#include "algorithm.h" > + > +namespace libcamera { > + > +namespace ipa::rkisp1::algorithms { > + > +class LensShadingCorrection : public Algorithm > +{ > +public: > + LensShadingCorrection(); > + ~LensShadingCorrection() = default; > + > + int init(IPAContext &context, const YamlObject &tuningData) override; > + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; > + > +private: > + bool initialized_; > + > + std::vector<uint16_t> rData_; > + std::vector<uint16_t> grData_; > + std::vector<uint16_t> gbData_; > + std::vector<uint16_t> bData_; > + > + std::vector<double> xSize_; > + std::vector<double> ySize_; > +}; > + > +} /* namespace ipa::rkisp1::algorithms */ > +} /* namespace libcamera */ > diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build > index 0597c353..64e11dce 100644 > --- a/src/ipa/rkisp1/algorithms/meson.build > +++ b/src/ipa/rkisp1/algorithms/meson.build > @@ -5,4 +5,5 @@ rkisp1_ipa_algorithms = files([ > 'awb.cpp', > 'blc.cpp', > 'gsl.cpp', > + 'lsc.cpp', > ]) > diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml > index 13f76412..fa2ae436 100644 > --- a/src/ipa/rkisp1/data/ov5640.yaml > +++ b/src/ipa/rkisp1/data/ov5640.yaml > @@ -16,4 +16,83 @@ algorithms: > red: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4095 ] > green: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4095 ] > blue: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4095 ] > + - LensShadingCorrection: > + x-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ] > + y-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ] > + r: [ > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + ] > + gr: [ > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + ] > + gb: [ > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + ] > + b: [ > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, > + ] > ... > diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp > index 1559d3ff..30bb87a9 100644 > --- a/src/ipa/rkisp1/ipa_context.cpp > +++ b/src/ipa/rkisp1/ipa_context.cpp > @@ -95,6 +95,9 @@ namespace libcamera::ipa::rkisp1 { > * > * \var IPASessionConfiguration::sensor.lineDuration > * \brief Line duration in microseconds > + * > + * \var IPASessionConfiguration::sensor.size > + * \brief Sensor output resolution > */ > > /** > diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h > index f387cace..3bfb262c 100644 > --- a/src/ipa/rkisp1/ipa_context.h > +++ b/src/ipa/rkisp1/ipa_context.h > @@ -33,6 +33,7 @@ struct IPASessionConfiguration { > > struct { > utils::Duration lineDuration; > + Size size; > } sensor; > > struct { > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp > index 4018265c..e5010f6a 100644 > --- a/src/ipa/rkisp1/rkisp1.cpp > +++ b/src/ipa/rkisp1/rkisp1.cpp > @@ -211,6 +211,7 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, > /* Set the hardware revision for the algorithms. */ > context_.configuration.hw.revision = hwRevision_; > > + context_.configuration.sensor.size = info.outputSize; > context_.configuration.sensor.lineDuration = info.lineLength * 1.0s / info.pixelRate; > > /*
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp new file mode 100644 index 00000000..5809e154 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/lsc.cpp @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * lsc.cpp - RkISP1 Lens Shading Correction control + */ + +#include "lsc.h" + +#include <cmath> +#include <numeric> + +#include <libcamera/base/log.h> + +#include "libcamera/internal/yaml_parser.h" + +#include "linux/rkisp1-config.h" + +/** + * \file lsc.h + */ + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +/** + * \class LensShadingCorrection + * \brief RkISP1 Lens Shading Correction control + * + * Due to the optical characteristics of the lens, the light intensity received + * by the sensor is not uniform. + * + * The Lens Shading Correction algorithm applies multipliers to all pixels + * to compensate for the lens shading effect. The coefficients are + * specified in a downscaled table in the YAML tuning file. + */ + +LOG_DEFINE_CATEGORY(RkISP1Lsc) + +LensShadingCorrection::LensShadingCorrection() + : initialized_(false) +{ +} + +/** + * \copydoc libcamera::ipa::Algorithm::init + */ +int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, + const YamlObject &tuningData) +{ + static constexpr unsigned int kLscNumSamples = + RKISP1_CIF_ISP_LSC_SAMPLES_MAX * RKISP1_CIF_ISP_LSC_SAMPLES_MAX; + float sum; + + xSize_ = tuningData["x-size"].getList<double>(); + if (xSize_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { + LOG(RkISP1Lsc, Error) + << "Invalid 'x-size' values: expected " + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE + << " elements, got " << xSize_.size(); + return -EINVAL; + } + + /* + * Check that the sum of elements is the expected one with a tolerance + * of 1%. + */ + sum = std::accumulate(xSize_.begin(), xSize_.end(), 0.0f); + if (sum < 0.495 || sum > 0.505) { + LOG(RkISP1Lsc, Error) + << "Invalid 'x-size' values: sum of the elements should" + << " be 0.5 , got " << sum; + return -EINVAL; + } + + ySize_ = tuningData["y-size"].getList<double>(); + if (ySize_.size() != RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE) { + LOG(RkISP1Lsc, Error) + << "Invalid 'y-size' values: expected " + << RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE + << " elements, got " << ySize_.size(); + return -EINVAL; + } + + /* + * Check that the sum of elements is the expected one with a tolerance + * of 1%. + */ + sum = std::accumulate(ySize_.begin(), ySize_.end(), 0.0f); + if (sum < 0.495 || sum > 0.505) { + LOG(RkISP1Lsc, Error) + << "Invalid 'y-size' values: sum of the elements should" + << " be 0.5 , got " << sum; + return -EINVAL; + } + + rData_ = tuningData["r"].getList<uint16_t>(); + if (rData_.size() != kLscNumSamples) { + LOG(RkISP1Lsc, Error) + << "Invalid 'r' values: expected " + << kLscNumSamples + << " elements, got " << rData_.size(); + return -EINVAL; + } + + grData_ = tuningData["gr"].getList<uint16_t>(); + if (grData_.size() != kLscNumSamples) { + LOG(RkISP1Lsc, Error) + << "Invalid 'gr' values: expected " + << kLscNumSamples + << " elements, got " << grData_.size(); + return -EINVAL; + } + + gbData_ = tuningData["gb"].getList<uint16_t>(); + if (gbData_.size() != kLscNumSamples) { + LOG(RkISP1Lsc, Error) + << "Invalid 'gb' values: expected " + << kLscNumSamples + << " elements, got " << gbData_.size(); + return -EINVAL; + } + + bData_ = tuningData["b"].getList<uint16_t>(); + if (bData_.size() != kLscNumSamples) { + LOG(RkISP1Lsc, Error) + << "Invalid 'b' values: expected " + << kLscNumSamples + << " elements, got " << bData_.size(); + return -EINVAL; + } + + initialized_ = true; + + return 0; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void LensShadingCorrection::prepare(IPAContext &context, + rkisp1_params_cfg *params) +{ + if (context.frameContext.frameCount > 0) + return; + + if (!initialized_) + return; + + struct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config; + const Size &size = context.configuration.sensor.size; + Size totalSize{}; + + for (unsigned int i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE; ++i) { + config.x_size_tbl[i] = xSize_[i] * size.width; + config.y_size_tbl[i] = ySize_[i] * size.height; + + /* + * To prevent unexpected behavior of the ISP, the sum of x_size_tbl and + * y_size_tbl items shall be equal to respectively size.width/2 and + * size.height/2. Enforce it by computing the last tables value to avoid + * rounding-induced errors. + */ + if (i == RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE - 1) { + config.x_size_tbl[i] = size.width / 2 - totalSize.width; + config.y_size_tbl[i] = size.height / 2 - totalSize.height; + } + + totalSize.width += config.x_size_tbl[i]; + totalSize.height += config.y_size_tbl[i]; + + config.x_grad_tbl[i] = std::round(32768 / config.x_size_tbl[i]); + config.y_grad_tbl[i] = std::round(32768 / config.y_size_tbl[i]); + } + + std::copy(rData_.begin(), rData_.end(), + ¶ms->others.lsc_config.r_data_tbl[0][0]); + std::copy(grData_.begin(), grData_.end(), + ¶ms->others.lsc_config.gr_data_tbl[0][0]); + std::copy(gbData_.begin(), gbData_.end(), + ¶ms->others.lsc_config.gb_data_tbl[0][0]); + std::copy(bData_.begin(), bData_.end(), + ¶ms->others.lsc_config.b_data_tbl[0][0]); + + params->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC; + params->module_ens |= RKISP1_CIF_ISP_MODULE_LSC; + params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC; +} + +REGISTER_IPA_ALGORITHM(LensShadingCorrection, "LensShadingCorrection") + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h new file mode 100644 index 00000000..fdb2ec1d --- /dev/null +++ b/src/ipa/rkisp1/algorithms/lsc.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021-2022, Ideas On Board + * + * lsc.h - RkISP1 Lens Shading Correction control + */ + +#pragma once + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::rkisp1::algorithms { + +class LensShadingCorrection : public Algorithm +{ +public: + LensShadingCorrection(); + ~LensShadingCorrection() = default; + + int init(IPAContext &context, const YamlObject &tuningData) override; + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; + +private: + bool initialized_; + + std::vector<uint16_t> rData_; + std::vector<uint16_t> grData_; + std::vector<uint16_t> gbData_; + std::vector<uint16_t> bData_; + + std::vector<double> xSize_; + std::vector<double> ySize_; +}; + +} /* namespace ipa::rkisp1::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build index 0597c353..64e11dce 100644 --- a/src/ipa/rkisp1/algorithms/meson.build +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -5,4 +5,5 @@ rkisp1_ipa_algorithms = files([ 'awb.cpp', 'blc.cpp', 'gsl.cpp', + 'lsc.cpp', ]) diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml index 13f76412..fa2ae436 100644 --- a/src/ipa/rkisp1/data/ov5640.yaml +++ b/src/ipa/rkisp1/data/ov5640.yaml @@ -16,4 +16,83 @@ algorithms: red: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4095 ] green: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4095 ] blue: [ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4095 ] + - LensShadingCorrection: + x-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ] + y-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ] + r: [ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + ] + gr: [ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + ] + gb: [ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + ] + b: [ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + ] ... diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 1559d3ff..30bb87a9 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -95,6 +95,9 @@ namespace libcamera::ipa::rkisp1 { * * \var IPASessionConfiguration::sensor.lineDuration * \brief Line duration in microseconds + * + * \var IPASessionConfiguration::sensor.size + * \brief Sensor output resolution */ /** diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index f387cace..3bfb262c 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -33,6 +33,7 @@ struct IPASessionConfiguration { struct { utils::Duration lineDuration; + Size size; } sensor; struct { diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 4018265c..e5010f6a 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -211,6 +211,7 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, /* Set the hardware revision for the algorithms. */ context_.configuration.hw.revision = hwRevision_; + context_.configuration.sensor.size = info.outputSize; context_.configuration.sensor.lineDuration = info.lineLength * 1.0s / info.pixelRate; /*
The Lens Shading Correction algorithm applies multipliers to all pixels to compensate for the lens shading effect. The coefficients are specified in a downscaled table in the YAML tuning file. Signed-off-by: Florian Sylvestre <fsylvestre@baylibre.com> --- src/ipa/rkisp1/algorithms/lsc.cpp | 195 ++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/lsc.h | 38 +++++ src/ipa/rkisp1/algorithms/meson.build | 1 + src/ipa/rkisp1/data/ov5640.yaml | 79 +++++++++++ src/ipa/rkisp1/ipa_context.cpp | 3 + src/ipa/rkisp1/ipa_context.h | 1 + src/ipa/rkisp1/rkisp1.cpp | 1 + 7 files changed, 318 insertions(+) create mode 100644 src/ipa/rkisp1/algorithms/lsc.cpp create mode 100644 src/ipa/rkisp1/algorithms/lsc.h