[{"id":37692,"web_url":"https://patchwork.libcamera.org/comment/37692/","msgid":"<176856802105.3486172.8329012851310849006@ping.linuxembedded.co.uk>","date":"2026-01-16T12:53:41","subject":"Re: [PATCH v3 15/15] ipa: rkisp1: Implement\n\tLensShadingCorrectionEnable control","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2026-01-14 11:58:08)\n> Implement the LensShadingCorrectionEnable control for rkisp1.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> \n> ---\n> \n> Changes in v3:\n> - Include LensShadingCorrectionEnable in metadata\n> - Add the queueRequest function in the header in logical order instead\n>   of alphabetical order\n> \n> Changes in v2:\n> - Add the control only if LSC is properly configured in the tuning file\n> - Introduce enable flag in frame context for per frame control\n> ---\n>  src/ipa/rkisp1/algorithms/dpf.cpp |  2 +-\n>  src/ipa/rkisp1/algorithms/lsc.cpp | 67 +++++++++++++++++++++++++++++++++------\n>  src/ipa/rkisp1/algorithms/lsc.h   |  7 ++++\n>  src/ipa/rkisp1/ipa_context.h      | 13 +++++---\n>  4 files changed, 74 insertions(+), 15 deletions(-)\n> \n> diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp\n> index 39f3e461f313dfbf35cb5d6a0daca0540bdf7b6b..83c1e4b7b355041295cbe0498a8dd70877ea6636 100644\n> --- a/src/ipa/rkisp1/algorithms/dpf.cpp\n> +++ b/src/ipa/rkisp1/algorithms/dpf.cpp\n> @@ -233,7 +233,7 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,\n>                 *strengthConfig = strengthConfig_;\n>  \n>                 const auto &awb = context.configuration.awb;\n> -               const auto &lsc = context.configuration.lsc;\n> +               const auto &lsc = context.activeState.lsc;\n>  \n>                 auto &mode = config->gain.mode;\n>  \n> diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp\n> index 8427c48f65b2e6e200f834db506939c6c85fd2a3..bcf44e83a0b99cc617a1d849d56ca4f288f472a3 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/lsc.cpp\n> @@ -416,6 +416,8 @@ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context,\n>         if (ret)\n>                 return ret;\n>  \n> +       context.ctrlMap[&controls::LensShadingCorrectionEnable] = ControlInfo(false, true, true);\n> +\n>         shadingDescriptors_ = std::move(lscData);\n>  \n>         return 0;\n> @@ -460,7 +462,7 @@ int LensShadingCorrection::configure(IPAContext &context,\n>  \n>         sets_.setData(std::move(shadingData));\n>  \n> -       context.configuration.lsc.enabled = true;\n> +       context.activeState.lsc.enabled = true;\n>         return 0;\n>  }\n>  \n> @@ -481,6 +483,29 @@ void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,\n>         std::copy(set.b.begin(), set.b.end(), &config.b_data_tbl[0][0]);\n>  }\n>  \n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::queueRequest\n> + */\n> +void LensShadingCorrection::queueRequest(IPAContext &context,\n> +                                        [[maybe_unused]] const uint32_t frame,\n> +                                        IPAFrameContext &frameContext,\n> +                                        const ControlList &controls)\n> +{\n> +       auto &lsc = context.activeState.lsc;\n> +\n> +       const auto &lscEnable = controls.get(controls::LensShadingCorrectionEnable);\n> +       if (lscEnable && *lscEnable != lsc.enabled) {\n> +               lsc.enabled = *lscEnable;\n> +\n> +               LOG(RkISP1Lsc, Debug)\n> +                       << (lsc.enabled ? \"Enabling\" : \"Disabling\") << \" Lsc\";\n> +\n> +               frameContext.lsc.update = true;\n> +       }\n> +\n> +       frameContext.lsc.enabled = lsc.enabled;\n> +}\n> +\n>  /**\n>   * \\copydoc libcamera::ipa::Algorithm::prepare\n>   */\n> @@ -493,18 +518,28 @@ void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,\n>         unsigned int quantizedCt = quantize(ct, kColourTemperatureQuantization);\n>         int ctDiff = static_cast<int>(ct) - static_cast<int>(lastAppliedCt_);\n>  \n> -       /*\n> -        * Add a threshold so that oscillations around a quantization step don't\n> -        * lead to constant changes.\n> -        */\n> -       if (std::abs(ctDiff) < kColourTemperatureQuantization / 2)\n> -               return;\n> +       /* Check if we can skip the update. */\n> +       if (!frameContext.lsc.update) {\n> +               if (!frameContext.lsc.enabled)\n> +                       return;\n>  \n> -       if (quantizedCt == lastAppliedQuantizedCt_)\n> -               return;\n> +               /*\n> +                * Add a threshold so that oscillations around a quantization\n> +                * step don't lead to constant changes.\n> +                */\n> +               if (std::abs(ctDiff) < kColourTemperatureQuantization / 2)\n\nIf you update std::abs on ctDiff to utils::abs_diff be sure to catch\nthis move which might otherwise be easy to miss.\n\nBut I like that this means we'll be able to visually see the impact of\nthe Lsc in realtime in camshark (or other tuning use cases perhaps)!\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> +                       return;\n> +\n> +               if (quantizedCt == lastAppliedQuantizedCt_)\n> +                       return;\n> +       }\n>  \n>         auto config = params->block<BlockType::Lsc>();\n> -       config.setEnabled(true);\n> +       config.setEnabled(frameContext.lsc.enabled);\n> +\n> +       if (!frameContext.lsc.enabled)\n> +               return;\n> +\n>         setParameters(*config);\n>  \n>         const Components &set = sets_.getInterpolated(quantizedCt);\n> @@ -518,6 +553,18 @@ void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,\n>                 << quantizedCt;\n>  }\n>  \n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::process\n> + */\n> +void LensShadingCorrection::process([[maybe_unused]] IPAContext &context,\n> +                                   [[maybe_unused]] const uint32_t frame,\n> +                                   IPAFrameContext &frameContext,\n> +                                   [[maybe_unused]] const rkisp1_stat_buffer *stats,\n> +                                   ControlList &metadata)\n> +{\n> +       metadata.set(controls::LensShadingCorrectionEnable, frameContext.lsc.enabled);\n> +}\n> +\n>  REGISTER_IPA_ALGORITHM(LensShadingCorrection, \"LensShadingCorrection\")\n>  \n>  } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h\n> index 3097740a6cb2ce9063a4ba087856987a489b0ab6..fb9dcc1a52af4a88a52808346b5da99e3f2b1c87 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.h\n> +++ b/src/ipa/rkisp1/algorithms/lsc.h\n> @@ -26,9 +26,16 @@ public:\n>  \n>         int init(IPAContext &context, const YamlObject &tuningData) override;\n>         int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;\n> +       void queueRequest(IPAContext &context, const uint32_t frame,\n> +                         IPAFrameContext &frameContext,\n> +                         const ControlList &controls) override;\n>         void prepare(IPAContext &context, const uint32_t frame,\n>                      IPAFrameContext &frameContext,\n>                      RkISP1Params *params) override;\n> +       void process(IPAContext &context, const uint32_t frame,\n> +                    IPAFrameContext &frameContext,\n> +                    const rkisp1_stat_buffer *stats,\n> +                    ControlList &metadata) override;\n>  \n>         struct Components {\n>                 std::vector<uint16_t> r;\n> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> index b257cee55379ad932b42e613f94eccbe69a939e3..fa748811be743b43ce6ee289408c054c6f9a7046 100644\n> --- a/src/ipa/rkisp1/ipa_context.h\n> +++ b/src/ipa/rkisp1/ipa_context.h\n> @@ -55,10 +55,6 @@ struct IPASessionConfiguration {\n>                 bool supported;\n>         } compress;\n>  \n> -       struct {\n> -               bool enabled;\n> -       } lsc;\n> -\n>         struct {\n>                 utils::Duration minExposureTime;\n>                 utils::Duration maxExposureTime;\n> @@ -143,6 +139,10 @@ struct IPAActiveState {\n>                 double gain;\n>                 double strength;\n>         } wdr;\n> +\n> +       struct {\n> +               bool enabled;\n> +       } lsc;\n>  };\n>  \n>  struct IPAFrameContext : public FrameContext {\n> @@ -218,6 +218,11 @@ struct IPAFrameContext : public FrameContext {\n>                 double strength;\n>                 double gain;\n>         } wdr;\n> +\n> +       struct {\n> +               bool enabled;\n> +               bool update;\n> +       } lsc;\n>  };\n>  \n>  struct IPAContext {\n> \n> -- \n> 2.51.0\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 8D113C3226\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 16 Jan 2026 12:53:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B81A961FBC;\n\tFri, 16 Jan 2026 13:53:45 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1DAA3615B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 16 Jan 2026 13:53:44 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B8F444B3;\n\tFri, 16 Jan 2026 13:53:15 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"gHUT4VVs\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1768567995;\n\tbh=PCqOI1a6Y1J5B0d4X7zyzBjrSEeN3I1fhcPpR7lQ87o=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=gHUT4VVs2+ILN7HJ6BwzyhzEYzxB7JkSSRjBIN7LPAb/07jFjyw7F9ixSJ42AgHlj\n\ttQlW2+mGhnBvD+V5YVvtRa79weLYhLSq1wydHe3nxncQBB2eIs13QKZ5ueEz0orjw7\n\te9NskZ9nZynkbbIEPTNlHa5isk3DXyjfzQTafaqU=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260114-sklug-lsc-resampling-v2-dev-v3-15-80cd24f4dd61@ideasonboard.com>","References":"<20260114-sklug-lsc-resampling-v2-dev-v3-0-80cd24f4dd61@ideasonboard.com>\n\t<20260114-sklug-lsc-resampling-v2-dev-v3-15-80cd24f4dd61@ideasonboard.com>","Subject":"Re: [PATCH v3 15/15] ipa: rkisp1: Implement\n\tLensShadingCorrectionEnable control","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>, =?utf-8?q?Barnab=C3=A1s_P?=\n\t=?utf-8?b?xZFjemU=?= <barnabas.pocze@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Fri, 16 Jan 2026 12:53:41 +0000","Message-ID":"<176856802105.3486172.8329012851310849006@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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>"}}]