[{"id":39871,"web_url":"https://patchwork.libcamera.org/comment/39871/","msgid":"<20260727131455.GA1382797@killaraus.ideasonboard.com>","date":"2026-07-27T13:14:55","subject":"Re: About loading / creating IPAs by (proxy) type name","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Hans,\n\nOn Mon, Jul 27, 2026 at 01:58:23PM +0200, Hans de Goede wrote:\n> Hi All,\n> \n> As discussed I've been looking into loading / creating IPAs by (proxy) type name.\n> \n> A way to do this was proposed by Barnabás here:\n> \n> https://patchwork.libcamera.org/patch/26503/\n> \n> Barnabás Pőcze wrote:\n> \n> \"\"\"\n> > --- a/include/libcamera/internal/ipa_manager.h\n> > +++ b/include/libcamera/internal/ipa_manager.h\n> > @@ -34,12 +34,13 @@ public:\n> >   \n> >   \ttemplate<typename T>\n> >   \tstatic std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> > +\t\t\t\t\t    const char *name,\n> >   \t\t\t\t\t    uint32_t minVersion,\n> >   \t\t\t\t\t    uint32_t maxVersion)\n> >   \t{\n> \n> I agree with this change, but I wish that the name could be derived from `T`.\n> And that is quite easy to do, just adding a\n> \n>    static constexpr const char *name() { return \"...\"; }\n> \n> and then using `T::name()` here works mostly.\n> \n> But unfortunately the raspberry pi ipa modules are not compatible at the moment\n> with this approach. I have tried to come up with something, but so for has failed.\n> \n> Maybe the `name` argument could be kept like this:\n> \n>    const char *name = T::name()\n> \n> and then the rpi pipeline handler could be changed to use the specific names. Not\n> a fan of this in any case.\n> \"\"\"\n> \n> This sounds nice and simple, but the <typename T> being passed to\n> the template here is an IPA proxy which gets auto-generated by mojo.\n> \n> mojo does support const variables so I've tried this:\n\nAs discussed on IRC, you don't need to modify the .mojom files. The\nproxy class is generated by a jinja2 template, see\nutils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl.\nAdding a static name() function there should be enough.\n\n> diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom\n> index d9a50b01d..b430ae5fd 100644\n> --- a/include/libcamera/ipa/ipu3.mojom\n> +++ b/include/libcamera/ipa/ipu3.mojom\n> @@ -9,6 +9,8 @@ module ipa.ipu3;\n>  import \"include/libcamera/ipa/core.mojom\";\n>  \n>  struct IPAConfigInfo {\n> +\tconst string kInterfaceName = \"ipu3\";\n> +\n>  \tlibcamera.IPACameraSensorInfo sensorInfo;\n>  \tlibcamera.ControlInfoMap sensorControls;\n>  \tlibcamera.ControlInfoMap lensControls;\n> @@ -17,6 +19,8 @@ struct IPAConfigInfo {\n>  };\n>  \n>  interface IPAIPU3Interface {\n> +\tconst string kInterfaceName = \"ipu3\";\n> +\n>  \tinit(libcamera.IPASettings settings,\n>  \t     libcamera.IPACameraSensorInfo sensorInfo,\n>  \t     libcamera.ControlInfoMap sensorControls)\n> \n> \n> Unfortunately this results in the follow autogenerated code:\n> \n> struct IPAConfigInfo\n> {\n> public:\n> #ifndef __DOXYGEN__\n> \tIPAConfigInfo() = default;\n> \n> \ttemplate<\n> \t\ttypename T1 = IPACameraSensorInfo,\n> \t\ttypename T2 = ControlInfoMap,\n> \t\ttypename T3 = ControlInfoMap,\n> \t\ttypename T4 = Size,\n> \t\ttypename T5 = Size,\n> \t\tstd::enable_if_t<std::is_convertible_v<T1&&, IPACameraSensorInfo>> * = nullptr,\n> \t\tstd::enable_if_t<std::is_convertible_v<T2&&, ControlInfoMap>> * = nullptr,\n> \t\tstd::enable_if_t<std::is_convertible_v<T3&&, ControlInfoMap>> * = nullptr,\n> \t\tstd::enable_if_t<std::is_convertible_v<T4&&, Size>> * = nullptr,\n> \t\tstd::enable_if_t<std::is_convertible_v<T5&&, Size>> * = nullptr\n> \t>\n> \tIPAConfigInfo(T1 &&_sensorInfo, T2 &&_sensorControls, T3 &&_lensControls, T4 &&_bdsOutputSize, T5 &&_iif)\n> \t\t: sensorInfo(std::forward<T1>(_sensorInfo))\n> \t\t, sensorControls(std::forward<T2>(_sensorControls))\n> \t\t, lensControls(std::forward<T3>(_lensControls))\n> \t\t, bdsOutputSize(std::forward<T4>(_bdsOutputSize))\n> \t\t, iif(std::forward<T5>(_iif))\n> \t{\n> \t}\n> #endif\n> \n> \n> \tIPACameraSensorInfo sensorInfo;\n> \tControlInfoMap sensorControls;\n> \tControlInfoMap lensControls;\n> \tSize bdsOutputSize;\n> \tSize iif;\n> };\n> \n> class IPAIPU3Interface : public IPAInterface\n> {\n> public:\n> \n> \tvirtual int32_t init(\n> \t\tconst IPASettings &settings,\n> \t\tconst IPACameraSensorInfo &sensorInfo,\n> \t\tconst ControlInfoMap &sensorControls,\n> \t\tControlInfoMap *ipaControls) = 0;\n> \n> \tvirtual int32_t start() = 0;\n> \n> \tvirtual void stop() = 0;\n> \n> \tvirtual int32_t configure(\n> \t\tconst IPAConfigInfo &configInfo,\n> \t\tControlInfoMap *ipaControls) = 0;\n> \n> \tvirtual void mapBuffers(\n> \t\tconst std::vector<libcamera::IPABuffer> &buffers) = 0;\n> \n> \tvirtual void unmapBuffers(\n> \t\tconst std::vector<uint32_t> &ids) = 0;\n> \n> \tvirtual void queueRequest(\n> \t\tconst uint32_t frame,\n> \t\tconst ControlList &controls) = 0;\n> \n> \tvirtual void computeParams(\n> \t\tconst uint32_t frame,\n> \t\tconst uint32_t bufferId) = 0;\n> \n> \tvirtual void processStats(\n> \t\tconst uint32_t frame,\n> \t\tconst int64_t frameTimestamp,\n> \t\tconst uint32_t bufferId,\n> \t\tconst ControlList &sensorControls) = 0;\n> \n> \tSignal<uint32_t, const ControlList &, const ControlList &> setSensorControls;\n> \n> \tSignal<uint32_t> paramsComputed;\n> \n> \tSignal<uint32_t, const ControlList &> metadataReady;\n> };\n> \n> which does not change by adding the const lines to the .mojo file.\n> \n> it seems the const declarations inside mojo files are only intended for use\n> inside the mojo files (for e.g. arg default values) and are nor propagated\n> to the generic code.\n> \n> So AFAICT this means that the whole load/create IPA by IPA-proxy type idea\n> will not work.","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 D6B9BBDE4C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jul 2026 13:14:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DA8FB67F69;\n\tMon, 27 Jul 2026 15:14:57 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2E99967EB2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jul 2026 15:14:57 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-70f3-e800--a06.rev.dnainternet.fi\n\t[IPv6:2001:14ba:70f3:e800::a06])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 354A6492;\n\tMon, 27 Jul 2026 15:13:53 +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=\"MnZzrhvs\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1785158033;\n\tbh=lXYRQ/l+MrnOo2MEPXLUxIsvoLhOVfM3dNy0NVWM2gg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=MnZzrhvskOb2UpiaTIiwkRBnbFIMg3Dv6VzPmHPOkHeP3wxDCJQYjYvCYr5omab/t\n\tRmSkEvTBUuabT8s4FGpxXj4APCkh5SIWgs6eIm332iFybWiVKU7IpN+8NEKazIGURB\n\tdb+4Xk1CCdGQ3g8H8EZNFEpfMeKxJiFMWP1/yY4c=","Date":"Mon, 27 Jul 2026 16:14:55 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Hans de Goede <johannes.goede@oss.qualcomm.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>, =?utf-8?q?Barna?=\n\t=?utf-8?b?YsOhcyBQxZFjemU=?= <barnabas.pocze@ideasonboard.com>","Subject":"Re: About loading / creating IPAs by (proxy) type name","Message-ID":"<20260727131455.GA1382797@killaraus.ideasonboard.com>","References":"<9c7e79d2-1b12-4a30-9126-019607673bb7@oss.qualcomm.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<9c7e79d2-1b12-4a30-9126-019607673bb7@oss.qualcomm.com>","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>"}},{"id":39890,"web_url":"https://patchwork.libcamera.org/comment/39890/","msgid":"<178522907699.8891.15722034549804357307@neptunite.rasen.tech>","date":"2026-07-28T08:57:56","subject":"Re: About loading / creating IPAs by (proxy) type name","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2026-07-27 22:14:55)\n> Hi Hans,\n> \n> On Mon, Jul 27, 2026 at 01:58:23PM +0200, Hans de Goede wrote:\n> > Hi All,\n> > \n> > As discussed I've been looking into loading / creating IPAs by (proxy) type name.\n> > \n> > A way to do this was proposed by Barnabás here:\n> > \n> > https://patchwork.libcamera.org/patch/26503/\n> > \n> > Barnabás Pőcze wrote:\n> > \n> > \"\"\"\n> > > --- a/include/libcamera/internal/ipa_manager.h\n> > > +++ b/include/libcamera/internal/ipa_manager.h\n> > > @@ -34,12 +34,13 @@ public:\n> > >   \n> > >     template<typename T>\n> > >     static std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> > > +                                       const char *name,\n> > >                                         uint32_t minVersion,\n> > >                                         uint32_t maxVersion)\n> > >     {\n> > \n> > I agree with this change, but I wish that the name could be derived from `T`.\n> > And that is quite easy to do, just adding a\n> > \n> >    static constexpr const char *name() { return \"...\"; }\n> > \n> > and then using `T::name()` here works mostly.\n> > \n> > But unfortunately the raspberry pi ipa modules are not compatible at the moment\n> > with this approach. I have tried to come up with something, but so for has failed.\n> > \n> > Maybe the `name` argument could be kept like this:\n> > \n> >    const char *name = T::name()\n> > \n> > and then the rpi pipeline handler could be changed to use the specific names. Not\n> > a fan of this in any case.\n> > \"\"\"\n> > \n> > This sounds nice and simple, but the <typename T> being passed to\n> > the template here is an IPA proxy which gets auto-generated by mojo.\n> > \n> > mojo does support const variables so I've tried this:\n\nYes the language does, but our code generator doesn't (although I see a\ncomment in core.mojom that says we do... maybe I need to fix that).\n\n> As discussed on IRC, you don't need to modify the .mojom files. The\n> proxy class is generated by a jinja2 template, see\n> utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl.\n> Adding a static name() function there should be enough.\n\nYes, the IPA implementation name does not belong in the mojom file as\nthat is the definition of the interface between the pipeline handler and\nthe IPA.\n\nI haven't been following the discussion so I'm probably missing a lot of\ncontext, but I'd have put IPA implementation name in IPAModuleInfo.\n\nPaul\n\n> \n> > diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom\n> > index d9a50b01d..b430ae5fd 100644\n> > --- a/include/libcamera/ipa/ipu3.mojom\n> > +++ b/include/libcamera/ipa/ipu3.mojom\n> > @@ -9,6 +9,8 @@ module ipa.ipu3;\n> >  import \"include/libcamera/ipa/core.mojom\";\n> >  \n> >  struct IPAConfigInfo {\n> > +     const string kInterfaceName = \"ipu3\";\n> > +\n> >       libcamera.IPACameraSensorInfo sensorInfo;\n> >       libcamera.ControlInfoMap sensorControls;\n> >       libcamera.ControlInfoMap lensControls;\n> > @@ -17,6 +19,8 @@ struct IPAConfigInfo {\n> >  };\n> >  \n> >  interface IPAIPU3Interface {\n> > +     const string kInterfaceName = \"ipu3\";\n> > +\n> >       init(libcamera.IPASettings settings,\n> >            libcamera.IPACameraSensorInfo sensorInfo,\n> >            libcamera.ControlInfoMap sensorControls)\n> > \n> > \n> > Unfortunately this results in the follow autogenerated code:\n> > \n> > struct IPAConfigInfo\n> > {\n> > public:\n> > #ifndef __DOXYGEN__\n> >       IPAConfigInfo() = default;\n> > \n> >       template<\n> >               typename T1 = IPACameraSensorInfo,\n> >               typename T2 = ControlInfoMap,\n> >               typename T3 = ControlInfoMap,\n> >               typename T4 = Size,\n> >               typename T5 = Size,\n> >               std::enable_if_t<std::is_convertible_v<T1&&, IPACameraSensorInfo>> * = nullptr,\n> >               std::enable_if_t<std::is_convertible_v<T2&&, ControlInfoMap>> * = nullptr,\n> >               std::enable_if_t<std::is_convertible_v<T3&&, ControlInfoMap>> * = nullptr,\n> >               std::enable_if_t<std::is_convertible_v<T4&&, Size>> * = nullptr,\n> >               std::enable_if_t<std::is_convertible_v<T5&&, Size>> * = nullptr\n> >       >\n> >       IPAConfigInfo(T1 &&_sensorInfo, T2 &&_sensorControls, T3 &&_lensControls, T4 &&_bdsOutputSize, T5 &&_iif)\n> >               : sensorInfo(std::forward<T1>(_sensorInfo))\n> >               , sensorControls(std::forward<T2>(_sensorControls))\n> >               , lensControls(std::forward<T3>(_lensControls))\n> >               , bdsOutputSize(std::forward<T4>(_bdsOutputSize))\n> >               , iif(std::forward<T5>(_iif))\n> >       {\n> >       }\n> > #endif\n> > \n> > \n> >       IPACameraSensorInfo sensorInfo;\n> >       ControlInfoMap sensorControls;\n> >       ControlInfoMap lensControls;\n> >       Size bdsOutputSize;\n> >       Size iif;\n> > };\n> > \n> > class IPAIPU3Interface : public IPAInterface\n> > {\n> > public:\n> > \n> >       virtual int32_t init(\n> >               const IPASettings &settings,\n> >               const IPACameraSensorInfo &sensorInfo,\n> >               const ControlInfoMap &sensorControls,\n> >               ControlInfoMap *ipaControls) = 0;\n> > \n> >       virtual int32_t start() = 0;\n> > \n> >       virtual void stop() = 0;\n> > \n> >       virtual int32_t configure(\n> >               const IPAConfigInfo &configInfo,\n> >               ControlInfoMap *ipaControls) = 0;\n> > \n> >       virtual void mapBuffers(\n> >               const std::vector<libcamera::IPABuffer> &buffers) = 0;\n> > \n> >       virtual void unmapBuffers(\n> >               const std::vector<uint32_t> &ids) = 0;\n> > \n> >       virtual void queueRequest(\n> >               const uint32_t frame,\n> >               const ControlList &controls) = 0;\n> > \n> >       virtual void computeParams(\n> >               const uint32_t frame,\n> >               const uint32_t bufferId) = 0;\n> > \n> >       virtual void processStats(\n> >               const uint32_t frame,\n> >               const int64_t frameTimestamp,\n> >               const uint32_t bufferId,\n> >               const ControlList &sensorControls) = 0;\n> > \n> >       Signal<uint32_t, const ControlList &, const ControlList &> setSensorControls;\n> > \n> >       Signal<uint32_t> paramsComputed;\n> > \n> >       Signal<uint32_t, const ControlList &> metadataReady;\n> > };\n> > \n> > which does not change by adding the const lines to the .mojo file.\n> > \n> > it seems the const declarations inside mojo files are only intended for use\n> > inside the mojo files (for e.g. arg default values) and are nor propagated\n> > to the generic code.\n> > \n> > So AFAICT this means that the whole load/create IPA by IPA-proxy type idea\n> > will not work.\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","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 A3E5DBDE4C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jul 2026 08:58:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8062D67F96;\n\tTue, 28 Jul 2026 10:58:05 +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 9E36967F85\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jul 2026 10:58:03 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2400:2411:160:2f00:9c6c:50c4:8fa3:37f4])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 7FFC522E;\n\tTue, 28 Jul 2026 10:56:58 +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=\"Ra/IkNL4\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1785229019;\n\tbh=U+P5w1uBhKD+tVUpw2kldyAxjpO+3RDQ/Tw7prpVg54=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=Ra/IkNL48HN9smAK7+bKuZZlFjy/0yqvw7L93ZY8RKCP1JQMxUXQlKc/MVqQEsJpv\n\tSRMruxa1Sbou9oWNlh+zDX8WJgdSKtHQ/biCaegBlZkfd8FxbtqbD5SqrfRLvHcoyH\n\tLAQo5DzbEGc5Wc/vV3QQkvLSk0uil3BhbZpQdJiA=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260727131455.GA1382797@killaraus.ideasonboard.com>","References":"<9c7e79d2-1b12-4a30-9126-019607673bb7@oss.qualcomm.com>\n\t<20260727131455.GA1382797@killaraus.ideasonboard.com>","Subject":"Re: About loading / creating IPAs by (proxy) type name","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>, =?utf-8?q?Barna?=\n\t=?utf-8?b?YsOhcyBQxZFjemU=?= <barnabas.pocze@ideasonboard.com>","To":"Hans de Goede <johannes.goede@oss.qualcomm.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Tue, 28 Jul 2026 17:57:56 +0900","Message-ID":"<178522907699.8891.15722034549804357307@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","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>"}}]