[{"id":39816,"web_url":"https://patchwork.libcamera.org/comment/39816/","msgid":"<cb7015a1-6ff4-437a-b628-8d323166c3a5@ideasonboard.com>","date":"2026-07-24T09:13:28","subject":"Re: [PATCH v6 28/31] ipa: libipa: lsc: Quantize gains in\n\tLscAlgorithm","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 07. 20. 16:59 keltezéssel, Jacopo Mondi írta:\n> Template the LscAlgorithm class with the LSC engine register format.\n> \n> This allows to quantize gains in the LscAlgorithm class and not in the\n> IPA modules.\n> \n> Split the LscAlgorithm class in two, one LscAlgorithmBase one for\n> non-templated function implementations and one for the templated\n> configure() implementation and for templated data members and accessor.\n> \n> Modify the LscAlgorithm interpolator interface. As now the returned list\n> of gains is in register format, a dedicated Interpolator::interpolate()\n> overload has to be defined for each IPA module.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> ---\n>   src/ipa/libipa/lsc.cpp            | 88 +++++++++++++++++++++-----------------\n>   src/ipa/libipa/lsc.h              | 90 +++++++++++++++++++++++++++++++++------\n>   src/ipa/libipa/lsc_base.cpp       | 13 ------\n>   src/ipa/libipa/lsc_base.h         | 19 ---------\n>   src/ipa/rkisp1/algorithms/lsc.cpp | 40 +++++------------\n>   src/ipa/rkisp1/algorithms/lsc.h   | 44 +++++++++++++++++--\n>   6 files changed, 177 insertions(+), 117 deletions(-)\n> \n> [...]\n> diff --git a/src/ipa/libipa/lsc.h b/src/ipa/libipa/lsc.h\n> index 9fe8ad67ea33..15c8a9cb7b9c 100644\n> --- a/src/ipa/libipa/lsc.h\n> +++ b/src/ipa/libipa/lsc.h\n> @@ -35,35 +35,101 @@ struct FrameContext {\n>   \n>   } /* namespace lsc */\n>   \n> -class LscAlgorithm\n> +class LscAlgorithmBase\n>   {\n>   public:\n>   \tint init(const ValueNode &tuningData, ControlInfoMap::Map &controls,\n>   \t\t const LscDescriptor &descriptor);\n>   \n> -\tint configure(lsc::ActiveState &state, const Rectangle &analogCrop,\n> -\t\t      const std::vector<double> &xPos,\n> -\t\t      const std::vector<double> &yPos);\n> -\n>   \tvoid queueRequest(lsc::ActiveState &state, lsc::FrameContext &context,\n>   \t\t\t  const ControlList &controls);\n>   \tvoid process(lsc::FrameContext &context, ControlList &metadata);\n>   \n> -\tconst lsc::Components interpolateComponents(unsigned int ct)\n> +protected:\n> +\tLscAlgorithmBase() = default;\n> +\n> +\tstd::unique_ptr<LscImplementation> impl_;\n> +\tbool polynomial_;\n> +};\n> +\n> +template<typename U>\n> +class LscAlgorithm : public LscAlgorithmBase\n> +{\n> +private:\n> +\tusing T = typename U::QuantizedType;\n> +\n> +\ttemplate<typename V>\n> +\tclass _Components : public std::map<std::string, std::vector<V>>\n> +\t{\n> +\t};\n> +\n> +\ttemplate<typename V>\n> +\tclass _ComponentsMap : public std::map<unsigned int, _Components<V>>\n>   \t{\n> -\t\treturn sets_.getInterpolated(ct);\n> +\t};\n> +\n> +public:\n> +\tusing Components = _Components<T>;\n> +\tusing ComponentsMap = _ComponentsMap<T>;\n\nWhy not just\n\n   using Components = std::map<...>;\n   // etc.\n\n?\n\n\n> +\n> +\tLscAlgorithm() = default;\n> +\n> +\tint configure(lsc::ActiveState &state, const Rectangle &analogCrop,\n> +\t\t      const std::vector<double> &xPos,\n> +\t\t      const std::vector<double> &yPos)\n> +\t{\n> +\t\tlsc::ComponentsMap data =\n> +\t\t\timpl_->sampleForCrop(analogCrop, xPos, yPos);\n> +\n> +\t\tComponentsMap lscData;\n> +\t\tfor (const auto &[t, c] : data) {\n> +\t\t\tComponents comp;\n> +\n> +\t\t\tfor (const auto &[k, gains] : c) {\n> +\t\t\t\tstd::vector<T> quantizedGains;\n\nYou could do `auto &quantizedGains = comp[k];` and avoid the move below.\n\n\n> +\t\t\t\tquantizedGains.reserve(gains.size());\n> +\n> +\t\t\t\tfor (const float &gain : gains) {\n> +\t\t\t\t\tif (polynomial_)\n> +\t\t\t\t\t\tquantizedGains.push_back(U(gain).quantized());\n> +\t\t\t\t\telse\n> +\t\t\t\t\t\tquantizedGains.push_back(gain);\n> +\t\t\t\t}\n> +\n> +\t\t\t\tcomp[k] = std::move(quantizedGains);\n> +\t\t\t}\n> +\n> +\t\t\tlscData[t] = comp;\n\n   std::move(comp);\n\n\n> +\t\t}\n> +\n> +\t\t/*\n> +\t\t * Retain a copy of the components table.\n> +\t\t *\n> +\t\t * We could avoid a copy here if getComponents() could\n> +\t\t * return sets_.data() but I wasn't able to work around the\n> +\t\t * compiler refusing it.\n\nIf you use `using Components{,Map}`, then it will work.\n\n\n> +\t\t */\n> +\t\tlscData_ = lscData;\n> +\n> +\t\tsets_.setData(std::move(lscData));\n> +\t\tstate.enabled = true;\n> +\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tInterpolator<Components> &getInterpolator()\n> +\t{\n> +\t\treturn sets_;\n>   \t}\n>   \n> -\tconst lsc::ComponentsMap getComponents()\n> +\tconst ComponentsMap &getComponents() const\n>   \t{\n>   \t\treturn lscData_;\n>   \t}\n>   \n>   private:\n> -\tstd::unique_ptr<LscImplementation> impl_;\n> -\tInterpolator<lsc::Components> sets_;\n> -\tlsc::ComponentsMap lscData_;\n> -\tbool polynomial_;\n> +\tComponentsMap lscData_;\n> +\tInterpolator<Components> sets_;\n>   };\n>   \n>   } /* namespace ipa */\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 50CCFBDE4C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jul 2026 09:13:35 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 60CBE67EE1;\n\tFri, 24 Jul 2026 11:13:34 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8417E67E8A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jul 2026 11:13:32 +0200 (CEST)","from [192.168.33.42] (185.182.215.156.nat.pool.zt.hu\n\t[185.182.215.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EAE4E524;\n\tFri, 24 Jul 2026 11:12:30 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"R7BHcRSL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1784884351;\n\tbh=PNIhS5Fr5+ZpWvCtQafDuElioIPNmOQj10QczD/Emoo=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=R7BHcRSLV4x/1uq4ZppGekOhg7cLam9y9oxzxhetEqYlXxsp/YbcTKdK0Y+06xDhM\n\t2zx/g6iNhJKCg5m9h8WJC0RAsdc6z4Td/eqmb+BqQt7hkiLEH3EGs9T+Xzg4PXtDND\n\t97nqBLnHm2zOrejkgxqc1AVYkln67XD1ikL/UGEs=","Message-ID":"<cb7015a1-6ff4-437a-b628-8d323166c3a5@ideasonboard.com>","Date":"Fri, 24 Jul 2026 11:13:28 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v6 28/31] ipa: libipa: lsc: Quantize gains in\n\tLscAlgorithm","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org,\n\tStefan Klug <stefan.klug@ideasonboard.com>,\n\tMilan Zamazal <mzamazal@redhat.com>","References":"<20260720-libipa-algorithms-v6-0-ececb73f97cb@ideasonboard.com>\n\t<20260720-libipa-algorithms-v6-28-ececb73f97cb@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260720-libipa-algorithms-v6-28-ececb73f97cb@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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>"}}]