[{"id":38588,"web_url":"https://patchwork.libcamera.org/comment/38588/","msgid":"<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>","date":"2026-04-13T10:21:59","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n> Currently createIPA() / IPAManager::module() assume that there is a 1:1\n> relationship between pipeline handlers and IPAs and IPA matching is done\n> based on matching the pipe to ipaModuleInfo.pipelineName[].\n> \n> One way to allow using a single IPA with multiple pipelines would be to\n> allow the IPA to declare itself compatible with more than one pipeline,\n> turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n> ipaModuleInfo is loaded as an ELF symbol requires it to be a simple flat\n> C-struct.\n> \n> Instead, move the IPA creation procedure to be name-based, introducing\n> an overload to IPAManager::createIPA(pipe, name, minVer, maxVer)  that\n> allows to specify the name of the IPA module to match. Pipeline handlers\n> that wants to use their name as matching criteria can continue doing so\n> using the already existing createIPA(pipe, minVer, maxVer) overload.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n> ---\n>   include/libcamera/internal/ipa_manager.h | 13 +++++++--\n>   include/libcamera/internal/ipa_module.h  |  4 +--\n>   src/libcamera/ipa_manager.cpp            | 34 +++++++++++++++++++-----\n>   src/libcamera/ipa_module.cpp             | 12 ++++-----\n>   4 files changed, 47 insertions(+), 16 deletions(-)\n> \n> diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\n> index f8ce78016..4c01e76f1 100644\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\nI agree with this change, but I wish that the name could be derived from `T`.\nAnd that is quite easy to do, just adding a\n\n   static constexpr const char *name() { return \"...\"; }\n\nand then using `T::name()` here works mostly.\n\nBut unfortunately the raspberry pi ipa modules are not compatible at the moment\nwith this approach. I have tried to come up with something, but so for has failed.\n\nMaybe the `name` argument could be kept like this:\n\n   const char *name = T::name()\n\nand then the rpi pipeline handler could be changed to use the specific names. Not\na fan of this in any case.\n\n\nRegards,\nBarnabás Pőcze\n\n\n>   \t\tCameraManager *cm = pipe->cameraManager();\n>   \t\tIPAManager *self = cm->_d()->ipaManager();\n> -\t\tIPAModule *m = self->module(pipe, minVersion, maxVersion);\n> +\t\tIPAModule *m = self->module(name, minVersion, maxVersion);\n>   \t\tif (!m)\n>   \t\t\treturn nullptr;\n>   \n> @@ -60,6 +61,14 @@ public:\n>   \t\treturn proxy;\n>   \t}\n>   \n> +\ttemplate<typename T>\n> +\tstatic std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> +\t\t\t\t\t    uint32_t minVersion,\n> +\t\t\t\t\t    uint32_t maxVersion)\n> +\t{\n> +\t\treturn createIPA<T>(pipe, pipe->name(), minVersion, maxVersion);\n> +\t}\n> +\n>   #if HAVE_IPA_PUBKEY\n>   \tstatic const PubKey &pubKey()\n>   \t{\n> @@ -72,7 +81,7 @@ private:\n>   \t\t      std::vector<std::string> &files);\n>   \tunsigned int addDir(const char *libDir, unsigned int maxDepth = 0);\n>   \n> -\tIPAModule *module(PipelineHandler *pipe, uint32_t minVersion,\n> +\tIPAModule *module(const char *name, uint32_t minVersion,\n>   \t\t\t  uint32_t maxVersion);\n>   \n>   \tbool isSignatureValid(IPAModule *ipa) const;\n> diff --git a/include/libcamera/internal/ipa_module.h b/include/libcamera/internal/ipa_module.h\n> index 15f19492c..a0a53764e 100644\n> --- a/include/libcamera/internal/ipa_module.h\n> +++ b/include/libcamera/internal/ipa_module.h\n> @@ -36,8 +36,8 @@ public:\n>   \n>   \tIPAInterface *createInterface();\n>   \n> -\tbool match(PipelineHandler *pipe,\n> -\t\t   uint32_t minVersion, uint32_t maxVersion) const;\n> +\tbool match(const char *name, uint32_t minVersion,\n> +\t\t   uint32_t maxVersion) const;\n>   \n>   protected:\n>   \tstd::string logPrefix() const override;\n> diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\n> index 35171d097..f62a4ee5f 100644\n> --- a/src/libcamera/ipa_manager.cpp\n> +++ b/src/libcamera/ipa_manager.cpp\n> @@ -247,15 +247,15 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\n>   \n>   /**\n>    * \\brief Retrieve an IPA module that matches a given pipeline handler\n> - * \\param[in] pipe The pipeline handler\n> + * \\param[in] name The IPA module string identifier\n>    * \\param[in] minVersion Minimum acceptable version of IPA module\n>    * \\param[in] maxVersion Maximum acceptable version of IPA module\n>    */\n> -IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> +IPAModule *IPAManager::module(const char *name, uint32_t minVersion,\n>   \t\t\t      uint32_t maxVersion)\n>   {\n>   \tfor (const auto &module : modules_) {\n> -\t\tif (module->match(pipe, minVersion, maxVersion))\n> +\t\tif (module->match(name, minVersion, maxVersion))\n>   \t\t\treturn module.get();\n>   \t}\n>   \n> @@ -263,12 +263,34 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n>   }\n>   \n>   /**\n> - * \\fn IPAManager::createIPA()\n> - * \\brief Create an IPA proxy that matches a given pipeline handler\n> - * \\param[in] pipe The pipeline handler that wants a matching IPA proxy\n> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, const char *ipaName, uint32_t minVersion, uint32_t maxVersion)\n> + * \\brief Create an IPA proxy that matches the requested name and version\n> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> + * \\param[in] ipaName The IPA module name\n>    * \\param[in] minVersion Minimum acceptable version of IPA module\n>    * \\param[in] maxVersion Maximum acceptable version of IPA module\n>    *\n> + * Create an IPA module using \\a name as the matching identifier. This overload\n> + * allows pipeline handlers to create an IPA module by specifying its name\n> + * instead of relying on the fact that the IPA module matches the pipeline\n> + * handler's one.\n> + *\n> + * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> + * found or if the IPA proxy fails to initialize\n> + */\n> +\n> +/**\n> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, uint32_t minVersion, uint32_t maxVersion)\n> + * \\brief Create an IPA proxy that matches the pipeline handler name and the\n> + * requested version\n> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> + * \\param[in] minVersion Minimum acceptable version of IPA module\n> + * \\param[in] maxVersion Maximum acceptable version of IPA module\n> + *\n> + * Create an IPA module using the pipeline handler name as the matching\n> + * identifier. This overload allows pipeline handler to create an IPA module\n> + * whose name matches the pipeline handler one.\n> + *\n>    * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n>    * found or if the IPA proxy fails to initialize\n>    */\n> diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp\n> index e6ea61e44..0bd6f1462 100644\n> --- a/src/libcamera/ipa_module.cpp\n> +++ b/src/libcamera/ipa_module.cpp\n> @@ -463,21 +463,21 @@ IPAInterface *IPAModule::createInterface()\n>   \n>   /**\n>    * \\brief Verify if the IPA module matches a given pipeline handler\n> - * \\param[in] pipe Pipeline handler to match with\n> + * \\param[in] name The IPA module name\n>    * \\param[in] minVersion Minimum acceptable version of IPA module\n>    * \\param[in] maxVersion Maximum acceptable version of IPA module\n>    *\n> - * This function checks if this IPA module matches the \\a pipe pipeline handler,\n> + * This function checks if this IPA module matches the requested \\a name\n>    * and the input version range.\n>    *\n> - * \\return True if the pipeline handler matches the IPA module, or false otherwise\n> + * \\return True if the IPA module matches, or false otherwise\n>    */\n> -bool IPAModule::match(PipelineHandler *pipe,\n> -\t\t      uint32_t minVersion, uint32_t maxVersion) const\n> +bool IPAModule::match(const char *name, uint32_t minVersion,\n> +\t\t      uint32_t maxVersion) const\n>   {\n>   \treturn info_.pipelineVersion >= minVersion &&\n>   \t       info_.pipelineVersion <= maxVersion &&\n> -\t       !strcmp(info_.pipelineName, pipe->name());\n> +\t       !strcmp(info_.name, name);\n>   }\n>   \n>   std::string IPAModule::logPrefix() const","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 0BF78C32BB\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 13 Apr 2026 10:22:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3DF5862E7F;\n\tMon, 13 Apr 2026 12:22:06 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B56CA6271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 13 Apr 2026 12:22:04 +0200 (CEST)","from [192.168.33.49] (185.182.214.8.nat.pool.zt.hu [185.182.214.8])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id DBD9A4F1;\n\tMon, 13 Apr 2026 12:20:31 +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=\"asENg4iL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1776075632;\n\tbh=m+fEmBwLuHVPKLCpMxJOEi6MEXwANvPBfHLNYfYiqLE=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=asENg4iLvRe3yYOjknbU42aXSA0lnQjTNluqTYNjwzDGvPdvKONlGjWqWqxWPGiNp\n\t/NtavIi6pN/ONKYdJjqvnA7Cfkk667rNALmObWE+f9fp5i3nWao4+bdsBxaVjsBoR9\n\tjjPf1rhO2EfUHWceUka7qYXK1YNfdO2UjFUdNe7U=","Message-ID":"<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>","Date":"Mon, 13 Apr 2026 12:21:59 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","To":"Hans de Goede <johannes.goede@oss.qualcomm.com>,\n\tlibcamera-devel@lists.libcamera.org,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Loic Poulain <loic.poulain@oss.qualcomm.com>, Jacopo Mondi\n\t<jacopo.mondi@ideasonboard.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Niklas_S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260408115606.12417-2-johannes.goede@oss.qualcomm.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>"}},{"id":38603,"web_url":"https://patchwork.libcamera.org/comment/38603/","msgid":"<adzvfswl6-ATwae1@zed>","date":"2026-04-13T13:32:00","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Barnabás\n\nOn Mon, Apr 13, 2026 at 12:21:59PM +0200, Barnabás Pőcze wrote:\n> Hi\n>\n> 2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n> > Currently createIPA() / IPAManager::module() assume that there is a 1:1\n> > relationship between pipeline handlers and IPAs and IPA matching is done\n> > based on matching the pipe to ipaModuleInfo.pipelineName[].\n> >\n> > One way to allow using a single IPA with multiple pipelines would be to\n> > allow the IPA to declare itself compatible with more than one pipeline,\n> > turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n> > ipaModuleInfo is loaded as an ELF symbol requires it to be a simple flat\n> > C-struct.\n> >\n> > Instead, move the IPA creation procedure to be name-based, introducing\n> > an overload to IPAManager::createIPA(pipe, name, minVer, maxVer)  that\n> > allows to specify the name of the IPA module to match. Pipeline handlers\n> > that wants to use their name as matching criteria can continue doing so\n> > using the already existing createIPA(pipe, minVer, maxVer) overload.\n> >\n> > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> > Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n> > ---\n> >   include/libcamera/internal/ipa_manager.h | 13 +++++++--\n> >   include/libcamera/internal/ipa_module.h  |  4 +--\n> >   src/libcamera/ipa_manager.cpp            | 34 +++++++++++++++++++-----\n> >   src/libcamera/ipa_module.cpp             | 12 ++++-----\n> >   4 files changed, 47 insertions(+), 16 deletions(-)\n> >\n> > diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\n> > index f8ce78016..4c01e76f1 100644\n> > --- a/include/libcamera/internal/ipa_manager.h\n> > +++ b/include/libcamera/internal/ipa_manager.h\n> > @@ -34,12 +34,13 @@ public:\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\nWhat is the issue ? That the proxy is the same for v4 and v5 ?\n\n\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> Regards,\n> Barnabás Pőcze\n>\n>\n> >   \t\tCameraManager *cm = pipe->cameraManager();\n> >   \t\tIPAManager *self = cm->_d()->ipaManager();\n> > -\t\tIPAModule *m = self->module(pipe, minVersion, maxVersion);\n> > +\t\tIPAModule *m = self->module(name, minVersion, maxVersion);\n> >   \t\tif (!m)\n> >   \t\t\treturn nullptr;\n> > @@ -60,6 +61,14 @@ public:\n> >   \t\treturn proxy;\n> >   \t}\n> > +\ttemplate<typename T>\n> > +\tstatic std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> > +\t\t\t\t\t    uint32_t minVersion,\n> > +\t\t\t\t\t    uint32_t maxVersion)\n> > +\t{\n> > +\t\treturn createIPA<T>(pipe, pipe->name(), minVersion, maxVersion);\n> > +\t}\n> > +\n> >   #if HAVE_IPA_PUBKEY\n> >   \tstatic const PubKey &pubKey()\n> >   \t{\n> > @@ -72,7 +81,7 @@ private:\n> >   \t\t      std::vector<std::string> &files);\n> >   \tunsigned int addDir(const char *libDir, unsigned int maxDepth = 0);\n> > -\tIPAModule *module(PipelineHandler *pipe, uint32_t minVersion,\n> > +\tIPAModule *module(const char *name, uint32_t minVersion,\n> >   \t\t\t  uint32_t maxVersion);\n> >   \tbool isSignatureValid(IPAModule *ipa) const;\n> > diff --git a/include/libcamera/internal/ipa_module.h b/include/libcamera/internal/ipa_module.h\n> > index 15f19492c..a0a53764e 100644\n> > --- a/include/libcamera/internal/ipa_module.h\n> > +++ b/include/libcamera/internal/ipa_module.h\n> > @@ -36,8 +36,8 @@ public:\n> >   \tIPAInterface *createInterface();\n> > -\tbool match(PipelineHandler *pipe,\n> > -\t\t   uint32_t minVersion, uint32_t maxVersion) const;\n> > +\tbool match(const char *name, uint32_t minVersion,\n> > +\t\t   uint32_t maxVersion) const;\n> >   protected:\n> >   \tstd::string logPrefix() const override;\n> > diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\n> > index 35171d097..f62a4ee5f 100644\n> > --- a/src/libcamera/ipa_manager.cpp\n> > +++ b/src/libcamera/ipa_manager.cpp\n> > @@ -247,15 +247,15 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\n> >   /**\n> >    * \\brief Retrieve an IPA module that matches a given pipeline handler\n> > - * \\param[in] pipe The pipeline handler\n> > + * \\param[in] name The IPA module string identifier\n> >    * \\param[in] minVersion Minimum acceptable version of IPA module\n> >    * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >    */\n> > -IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> > +IPAModule *IPAManager::module(const char *name, uint32_t minVersion,\n> >   \t\t\t      uint32_t maxVersion)\n> >   {\n> >   \tfor (const auto &module : modules_) {\n> > -\t\tif (module->match(pipe, minVersion, maxVersion))\n> > +\t\tif (module->match(name, minVersion, maxVersion))\n> >   \t\t\treturn module.get();\n> >   \t}\n> > @@ -263,12 +263,34 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> >   }\n> >   /**\n> > - * \\fn IPAManager::createIPA()\n> > - * \\brief Create an IPA proxy that matches a given pipeline handler\n> > - * \\param[in] pipe The pipeline handler that wants a matching IPA proxy\n> > + * \\fn IPAManager::createIPA(PipelineHandler *pipe, const char *ipaName, uint32_t minVersion, uint32_t maxVersion)\n> > + * \\brief Create an IPA proxy that matches the requested name and version\n> > + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> > + * \\param[in] ipaName The IPA module name\n> >    * \\param[in] minVersion Minimum acceptable version of IPA module\n> >    * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >    *\n> > + * Create an IPA module using \\a name as the matching identifier. This overload\n> > + * allows pipeline handlers to create an IPA module by specifying its name\n> > + * instead of relying on the fact that the IPA module matches the pipeline\n> > + * handler's one.\n> > + *\n> > + * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> > + * found or if the IPA proxy fails to initialize\n> > + */\n> > +\n> > +/**\n> > + * \\fn IPAManager::createIPA(PipelineHandler *pipe, uint32_t minVersion, uint32_t maxVersion)\n> > + * \\brief Create an IPA proxy that matches the pipeline handler name and the\n> > + * requested version\n> > + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> > + * \\param[in] minVersion Minimum acceptable version of IPA module\n> > + * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > + *\n> > + * Create an IPA module using the pipeline handler name as the matching\n> > + * identifier. This overload allows pipeline handler to create an IPA module\n> > + * whose name matches the pipeline handler one.\n> > + *\n> >    * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> >    * found or if the IPA proxy fails to initialize\n> >    */\n> > diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp\n> > index e6ea61e44..0bd6f1462 100644\n> > --- a/src/libcamera/ipa_module.cpp\n> > +++ b/src/libcamera/ipa_module.cpp\n> > @@ -463,21 +463,21 @@ IPAInterface *IPAModule::createInterface()\n> >   /**\n> >    * \\brief Verify if the IPA module matches a given pipeline handler\n> > - * \\param[in] pipe Pipeline handler to match with\n> > + * \\param[in] name The IPA module name\n> >    * \\param[in] minVersion Minimum acceptable version of IPA module\n> >    * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >    *\n> > - * This function checks if this IPA module matches the \\a pipe pipeline handler,\n> > + * This function checks if this IPA module matches the requested \\a name\n> >    * and the input version range.\n> >    *\n> > - * \\return True if the pipeline handler matches the IPA module, or false otherwise\n> > + * \\return True if the IPA module matches, or false otherwise\n> >    */\n> > -bool IPAModule::match(PipelineHandler *pipe,\n> > -\t\t      uint32_t minVersion, uint32_t maxVersion) const\n> > +bool IPAModule::match(const char *name, uint32_t minVersion,\n> > +\t\t      uint32_t maxVersion) const\n> >   {\n> >   \treturn info_.pipelineVersion >= minVersion &&\n> >   \t       info_.pipelineVersion <= maxVersion &&\n> > -\t       !strcmp(info_.pipelineName, pipe->name());\n> > +\t       !strcmp(info_.name, name);\n> >   }\n> >   std::string IPAModule::logPrefix() const\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 1352BBDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 13 Apr 2026 13:32:05 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3777862E8E;\n\tMon, 13 Apr 2026 15:32:04 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0C6CF6271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 13 Apr 2026 15:32:03 +0200 (CEST)","from ideasonboard.com (93-46-82-201.ip106.fastwebnet.it\n\t[93.46.82.201])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 08F477FE;\n\tMon, 13 Apr 2026 15:30: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=\"V888OuhW\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1776087031;\n\tbh=RLxKR4QSCxYXbpf93L7lVLXHHgbB53i96UQYfJTF+Ug=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=V888OuhWJzuPuXmWBaXx2xONbabWyFm7m1kFFb4ZjWkXdvpAyqVoY6Giuh2DUyfl+\n\t2kZo/WC4D2eBkiNjmMmXeZHhovdUT9v0/SyNquF/F8/78qCaJK4iKTuqXio+6qzXR9\n\tIlyi9nXYCPgR0HShZ/uKaRSrGGglIJ/Ce9DNtTeg=","Date":"Mon, 13 Apr 2026 15:32:00 +0200","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"Hans de Goede <johannes.goede@oss.qualcomm.com>, \n\tlibcamera-devel@lists.libcamera.org, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>, Loic Poulain\n\t<loic.poulain@oss.qualcomm.com>, Jacopo Mondi\n\t<jacopo.mondi@ideasonboard.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, Niklas =?utf-8?q?S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","Message-ID":"<adzvfswl6-ATwae1@zed>","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>\n\t<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.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":38605,"web_url":"https://patchwork.libcamera.org/comment/38605/","msgid":"<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.com>","date":"2026-04-13T13:55:58","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 04. 13. 15:32 keltezéssel, Jacopo Mondi írta:\n> Hi Barnabás\n> \n> On Mon, Apr 13, 2026 at 12:21:59PM +0200, Barnabás Pőcze wrote:\n>> Hi\n>>\n>> 2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n>>> Currently createIPA() / IPAManager::module() assume that there is a 1:1\n>>> relationship between pipeline handlers and IPAs and IPA matching is done\n>>> based on matching the pipe to ipaModuleInfo.pipelineName[].\n>>>\n>>> One way to allow using a single IPA with multiple pipelines would be to\n>>> allow the IPA to declare itself compatible with more than one pipeline,\n>>> turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n>>> ipaModuleInfo is loaded as an ELF symbol requires it to be a simple flat\n>>> C-struct.\n>>>\n>>> Instead, move the IPA creation procedure to be name-based, introducing\n>>> an overload to IPAManager::createIPA(pipe, name, minVer, maxVer)  that\n>>> allows to specify the name of the IPA module to match. Pipeline handlers\n>>> that wants to use their name as matching criteria can continue doing so\n>>> using the already existing createIPA(pipe, minVer, maxVer) overload.\n>>>\n>>> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n>>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>>> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n>>> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n>>> ---\n>>>    include/libcamera/internal/ipa_manager.h | 13 +++++++--\n>>>    include/libcamera/internal/ipa_module.h  |  4 +--\n>>>    src/libcamera/ipa_manager.cpp            | 34 +++++++++++++++++++-----\n>>>    src/libcamera/ipa_module.cpp             | 12 ++++-----\n>>>    4 files changed, 47 insertions(+), 16 deletions(-)\n>>>\n>>> diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\n>>> index f8ce78016..4c01e76f1 100644\n>>> --- a/include/libcamera/internal/ipa_manager.h\n>>> +++ b/include/libcamera/internal/ipa_manager.h\n>>> @@ -34,12 +34,13 @@ public:\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> What is the issue ? That the proxy is the same for v4 and v5 ?\n\nThe proxy type is the same, but different names need to be used.\n\n\n> \n> \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>> Regards,\n>> Barnabás Pőcze\n>>\n>>\n>>>    \t\tCameraManager *cm = pipe->cameraManager();\n>>>    \t\tIPAManager *self = cm->_d()->ipaManager();\n>>> -\t\tIPAModule *m = self->module(pipe, minVersion, maxVersion);\n>>> +\t\tIPAModule *m = self->module(name, minVersion, maxVersion);\n>>>    \t\tif (!m)\n>>>    \t\t\treturn nullptr;\n>>> @@ -60,6 +61,14 @@ public:\n>>>    \t\treturn proxy;\n>>>    \t}\n>>> +\ttemplate<typename T>\n>>> +\tstatic std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n>>> +\t\t\t\t\t    uint32_t minVersion,\n>>> +\t\t\t\t\t    uint32_t maxVersion)\n>>> +\t{\n>>> +\t\treturn createIPA<T>(pipe, pipe->name(), minVersion, maxVersion);\n>>> +\t}\n>>> +\n>>>    #if HAVE_IPA_PUBKEY\n>>>    \tstatic const PubKey &pubKey()\n>>>    \t{\n>>> @@ -72,7 +81,7 @@ private:\n>>>    \t\t      std::vector<std::string> &files);\n>>>    \tunsigned int addDir(const char *libDir, unsigned int maxDepth = 0);\n>>> -\tIPAModule *module(PipelineHandler *pipe, uint32_t minVersion,\n>>> +\tIPAModule *module(const char *name, uint32_t minVersion,\n>>>    \t\t\t  uint32_t maxVersion);\n>>>    \tbool isSignatureValid(IPAModule *ipa) const;\n>>> diff --git a/include/libcamera/internal/ipa_module.h b/include/libcamera/internal/ipa_module.h\n>>> index 15f19492c..a0a53764e 100644\n>>> --- a/include/libcamera/internal/ipa_module.h\n>>> +++ b/include/libcamera/internal/ipa_module.h\n>>> @@ -36,8 +36,8 @@ public:\n>>>    \tIPAInterface *createInterface();\n>>> -\tbool match(PipelineHandler *pipe,\n>>> -\t\t   uint32_t minVersion, uint32_t maxVersion) const;\n>>> +\tbool match(const char *name, uint32_t minVersion,\n>>> +\t\t   uint32_t maxVersion) const;\n>>>    protected:\n>>>    \tstd::string logPrefix() const override;\n>>> diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\n>>> index 35171d097..f62a4ee5f 100644\n>>> --- a/src/libcamera/ipa_manager.cpp\n>>> +++ b/src/libcamera/ipa_manager.cpp\n>>> @@ -247,15 +247,15 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\n>>>    /**\n>>>     * \\brief Retrieve an IPA module that matches a given pipeline handler\n>>> - * \\param[in] pipe The pipeline handler\n>>> + * \\param[in] name The IPA module string identifier\n>>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n>>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n>>>     */\n>>> -IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n>>> +IPAModule *IPAManager::module(const char *name, uint32_t minVersion,\n>>>    \t\t\t      uint32_t maxVersion)\n>>>    {\n>>>    \tfor (const auto &module : modules_) {\n>>> -\t\tif (module->match(pipe, minVersion, maxVersion))\n>>> +\t\tif (module->match(name, minVersion, maxVersion))\n>>>    \t\t\treturn module.get();\n>>>    \t}\n>>> @@ -263,12 +263,34 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n>>>    }\n>>>    /**\n>>> - * \\fn IPAManager::createIPA()\n>>> - * \\brief Create an IPA proxy that matches a given pipeline handler\n>>> - * \\param[in] pipe The pipeline handler that wants a matching IPA proxy\n>>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, const char *ipaName, uint32_t minVersion, uint32_t maxVersion)\n>>> + * \\brief Create an IPA proxy that matches the requested name and version\n>>> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n>>> + * \\param[in] ipaName The IPA module name\n>>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n>>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n>>>     *\n>>> + * Create an IPA module using \\a name as the matching identifier. This overload\n>>> + * allows pipeline handlers to create an IPA module by specifying its name\n>>> + * instead of relying on the fact that the IPA module matches the pipeline\n>>> + * handler's one.\n>>> + *\n>>> + * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n>>> + * found or if the IPA proxy fails to initialize\n>>> + */\n>>> +\n>>> +/**\n>>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, uint32_t minVersion, uint32_t maxVersion)\n>>> + * \\brief Create an IPA proxy that matches the pipeline handler name and the\n>>> + * requested version\n>>> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n>>> + * \\param[in] minVersion Minimum acceptable version of IPA module\n>>> + * \\param[in] maxVersion Maximum acceptable version of IPA module\n>>> + *\n>>> + * Create an IPA module using the pipeline handler name as the matching\n>>> + * identifier. This overload allows pipeline handler to create an IPA module\n>>> + * whose name matches the pipeline handler one.\n>>> + *\n>>>     * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n>>>     * found or if the IPA proxy fails to initialize\n>>>     */\n>>> diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp\n>>> index e6ea61e44..0bd6f1462 100644\n>>> --- a/src/libcamera/ipa_module.cpp\n>>> +++ b/src/libcamera/ipa_module.cpp\n>>> @@ -463,21 +463,21 @@ IPAInterface *IPAModule::createInterface()\n>>>    /**\n>>>     * \\brief Verify if the IPA module matches a given pipeline handler\n>>> - * \\param[in] pipe Pipeline handler to match with\n>>> + * \\param[in] name The IPA module name\n>>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n>>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n>>>     *\n>>> - * This function checks if this IPA module matches the \\a pipe pipeline handler,\n>>> + * This function checks if this IPA module matches the requested \\a name\n>>>     * and the input version range.\n>>>     *\n>>> - * \\return True if the pipeline handler matches the IPA module, or false otherwise\n>>> + * \\return True if the IPA module matches, or false otherwise\n>>>     */\n>>> -bool IPAModule::match(PipelineHandler *pipe,\n>>> -\t\t      uint32_t minVersion, uint32_t maxVersion) const\n>>> +bool IPAModule::match(const char *name, uint32_t minVersion,\n>>> +\t\t      uint32_t maxVersion) const\n>>>    {\n>>>    \treturn info_.pipelineVersion >= minVersion &&\n>>>    \t       info_.pipelineVersion <= maxVersion &&\n>>> -\t       !strcmp(info_.pipelineName, pipe->name());\n>>> +\t       !strcmp(info_.name, name);\n>>>    }\n>>>    std::string IPAModule::logPrefix() const\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 CF36ABDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 13 Apr 2026 13:56:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A292B62E90;\n\tMon, 13 Apr 2026 15:56:03 +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 918D66271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 13 Apr 2026 15:56:02 +0200 (CEST)","from [192.168.33.49] (185.182.214.8.nat.pool.zt.hu [185.182.214.8])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 432F77FE;\n\tMon, 13 Apr 2026 15:54: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=\"rMlBb67G\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1776088470;\n\tbh=KsSAVurekdcOslE6luBp5mKTtLP0JUuqSj/q4Rl9ye4=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=rMlBb67G1He/cKNqFKuVyY0iS/m5lMEzfKJ6V7cFQhHgug8E5i8omwXiviSz8hYGD\n\tzOhprHeV3/jgAmZEuMZzKu4//GPuRC9RIKuY2Pd6GgjBEgIl8nSPyArgr7Jssl+uUk\n\t7127nWMHyeRX4+qiy83VHr5vuiY2pMc4RajRaFDk=","Message-ID":"<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.com>","Date":"Mon, 13 Apr 2026 15:55:58 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"Hans de Goede <johannes.goede@oss.qualcomm.com>,\n\tlibcamera-devel@lists.libcamera.org, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>, Loic Poulain\n\t<loic.poulain@oss.qualcomm.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Niklas_S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>\n\t<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>\n\t<adzvfswl6-ATwae1@zed>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<adzvfswl6-ATwae1@zed>","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>"}},{"id":38891,"web_url":"https://patchwork.libcamera.org/comment/38891/","msgid":"<20260513235615.GA404935@killaraus.ideasonboard.com>","date":"2026-05-13T23:56:15","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"CC'ing Naush and David.\n\nOn Mon, Apr 13, 2026 at 03:55:58PM +0200, Barnabás Pőcze wrote:\n> 2026. 04. 13. 15:32 keltezéssel, Jacopo Mondi írta:\n> > On Mon, Apr 13, 2026 at 12:21:59PM +0200, Barnabás Pőcze wrote:\n> >> 2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n> >>> Currently createIPA() / IPAManager::module() assume that there is a 1:1\n> >>> relationship between pipeline handlers and IPAs and IPA matching is done\n> >>> based on matching the pipe to ipaModuleInfo.pipelineName[].\n> >>>\n> >>> One way to allow using a single IPA with multiple pipelines would be to\n> >>> allow the IPA to declare itself compatible with more than one pipeline,\n> >>> turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n> >>> ipaModuleInfo is loaded as an ELF symbol requires it to be a simple flat\n> >>> C-struct.\n> >>>\n> >>> Instead, move the IPA creation procedure to be name-based, introducing\n> >>> an overload to IPAManager::createIPA(pipe, name, minVer, maxVer)  that\n> >>> allows to specify the name of the IPA module to match. Pipeline handlers\n> >>> that wants to use their name as matching criteria can continue doing so\n> >>> using the already existing createIPA(pipe, minVer, maxVer) overload.\n> >>>\n> >>> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> >>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> >>> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> >>> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n> >>> ---\n> >>>    include/libcamera/internal/ipa_manager.h | 13 +++++++--\n> >>>    include/libcamera/internal/ipa_module.h  |  4 +--\n> >>>    src/libcamera/ipa_manager.cpp            | 34 +++++++++++++++++++-----\n> >>>    src/libcamera/ipa_module.cpp             | 12 ++++-----\n> >>>    4 files changed, 47 insertions(+), 16 deletions(-)\n> >>>\n> >>> diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\n> >>> index f8ce78016..4c01e76f1 100644\n> >>> --- a/include/libcamera/internal/ipa_manager.h\n> >>> +++ b/include/libcamera/internal/ipa_manager.h\n> >>> @@ -34,12 +34,13 @@ public:\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> > What is the issue ? That the proxy is the same for v4 and v5 ?\n> \n> The proxy type is the same, but different names need to be used.\n\nThe more I think about it, the more uncomfortable I get with specifying\na name here.\n\nThe API contract between the pipeline handler is the IPA interface.\nThat's all we should have to specify in the pipeline handler. Adding a\nname gives the pipeline handler the ability to select any IPA module,\nwithout any check whatsoever to ensure compatibility of the interface.\nThat sounds like a very bad idea.\n\nRaspberry Pi is the only platform where we have two IPA modules using\nthe same IPA interface without being interchangeable. Trying to use the\nPi4 IPA module on a Pi5 will not work, and vice versa. I would really\nlike to fix that, and I see two options:\n\n- Merging the two IPA modules into a single one, compatible with both\n  platforms. The IPA interface functions in the IPA module would\n  essentially dispatch to Pi4 or Pi5 implementations, based on a\n  platform version identifier (passed to the init() function I suppose).\n\n- Splitting the IPA interface into two different interfaces. The\n  interfaces can still share the same API, the important part is to have\n  two different interface names in two .mojom files. All the data\n  structures can be defined in a shared .mojom file imported by both\n  interfaces (and maybe there's a way to also share a common interface\n  definition instead of duplicating it).\n\nThe drawback of the first option is that the IPA module will contain\ndead code (Pi4 code won't run on Pi5 and vice versa), while the drawback\nof the second option is that we'll duplicate proxy and worker code (as\nthe code is generated, it's just a matter of binary size, there's no\nadditional maintenance burden there).\n\nNaush, David, any opinion ?\n\n\nNote that we would still support multiple intercheangeable IPA modules\nusing the same interface (and therefore compatible with the same\npipeline handler).\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> >>>    \t\tCameraManager *cm = pipe->cameraManager();\n> >>>    \t\tIPAManager *self = cm->_d()->ipaManager();\n> >>> -\t\tIPAModule *m = self->module(pipe, minVersion, maxVersion);\n> >>> +\t\tIPAModule *m = self->module(name, minVersion, maxVersion);\n> >>>    \t\tif (!m)\n> >>>    \t\t\treturn nullptr;\n> >>> @@ -60,6 +61,14 @@ public:\n> >>>    \t\treturn proxy;\n> >>>    \t}\n> >>> +\ttemplate<typename T>\n> >>> +\tstatic std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> >>> +\t\t\t\t\t    uint32_t minVersion,\n> >>> +\t\t\t\t\t    uint32_t maxVersion)\n> >>> +\t{\n> >>> +\t\treturn createIPA<T>(pipe, pipe->name(), minVersion, maxVersion);\n> >>> +\t}\n> >>> +\n> >>>    #if HAVE_IPA_PUBKEY\n> >>>    \tstatic const PubKey &pubKey()\n> >>>    \t{\n> >>> @@ -72,7 +81,7 @@ private:\n> >>>    \t\t      std::vector<std::string> &files);\n> >>>    \tunsigned int addDir(const char *libDir, unsigned int maxDepth = 0);\n> >>> -\tIPAModule *module(PipelineHandler *pipe, uint32_t minVersion,\n> >>> +\tIPAModule *module(const char *name, uint32_t minVersion,\n> >>>    \t\t\t  uint32_t maxVersion);\n> >>>    \tbool isSignatureValid(IPAModule *ipa) const;\n> >>> diff --git a/include/libcamera/internal/ipa_module.h b/include/libcamera/internal/ipa_module.h\n> >>> index 15f19492c..a0a53764e 100644\n> >>> --- a/include/libcamera/internal/ipa_module.h\n> >>> +++ b/include/libcamera/internal/ipa_module.h\n> >>> @@ -36,8 +36,8 @@ public:\n> >>>    \tIPAInterface *createInterface();\n> >>> -\tbool match(PipelineHandler *pipe,\n> >>> -\t\t   uint32_t minVersion, uint32_t maxVersion) const;\n> >>> +\tbool match(const char *name, uint32_t minVersion,\n> >>> +\t\t   uint32_t maxVersion) const;\n> >>>    protected:\n> >>>    \tstd::string logPrefix() const override;\n> >>> diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\n> >>> index 35171d097..f62a4ee5f 100644\n> >>> --- a/src/libcamera/ipa_manager.cpp\n> >>> +++ b/src/libcamera/ipa_manager.cpp\n> >>> @@ -247,15 +247,15 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\n> >>>    /**\n> >>>     * \\brief Retrieve an IPA module that matches a given pipeline handler\n> >>> - * \\param[in] pipe The pipeline handler\n> >>> + * \\param[in] name The IPA module string identifier\n> >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >>>     */\n> >>> -IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> >>> +IPAModule *IPAManager::module(const char *name, uint32_t minVersion,\n> >>>    \t\t\t      uint32_t maxVersion)\n> >>>    {\n> >>>    \tfor (const auto &module : modules_) {\n> >>> -\t\tif (module->match(pipe, minVersion, maxVersion))\n> >>> +\t\tif (module->match(name, minVersion, maxVersion))\n> >>>    \t\t\treturn module.get();\n> >>>    \t}\n> >>> @@ -263,12 +263,34 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> >>>    }\n> >>>    /**\n> >>> - * \\fn IPAManager::createIPA()\n> >>> - * \\brief Create an IPA proxy that matches a given pipeline handler\n> >>> - * \\param[in] pipe The pipeline handler that wants a matching IPA proxy\n> >>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, const char *ipaName, uint32_t minVersion, uint32_t maxVersion)\n> >>> + * \\brief Create an IPA proxy that matches the requested name and version\n> >>> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> >>> + * \\param[in] ipaName The IPA module name\n> >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >>>     *\n> >>> + * Create an IPA module using \\a name as the matching identifier. This overload\n> >>> + * allows pipeline handlers to create an IPA module by specifying its name\n> >>> + * instead of relying on the fact that the IPA module matches the pipeline\n> >>> + * handler's one.\n> >>> + *\n> >>> + * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> >>> + * found or if the IPA proxy fails to initialize\n> >>> + */\n> >>> +\n> >>> +/**\n> >>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, uint32_t minVersion, uint32_t maxVersion)\n> >>> + * \\brief Create an IPA proxy that matches the pipeline handler name and the\n> >>> + * requested version\n> >>> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> >>> + * \\param[in] minVersion Minimum acceptable version of IPA module\n> >>> + * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >>> + *\n> >>> + * Create an IPA module using the pipeline handler name as the matching\n> >>> + * identifier. This overload allows pipeline handler to create an IPA module\n> >>> + * whose name matches the pipeline handler one.\n> >>> + *\n> >>>     * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> >>>     * found or if the IPA proxy fails to initialize\n> >>>     */\n> >>> diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp\n> >>> index e6ea61e44..0bd6f1462 100644\n> >>> --- a/src/libcamera/ipa_module.cpp\n> >>> +++ b/src/libcamera/ipa_module.cpp\n> >>> @@ -463,21 +463,21 @@ IPAInterface *IPAModule::createInterface()\n> >>>    /**\n> >>>     * \\brief Verify if the IPA module matches a given pipeline handler\n> >>> - * \\param[in] pipe Pipeline handler to match with\n> >>> + * \\param[in] name The IPA module name\n> >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> >>>     *\n> >>> - * This function checks if this IPA module matches the \\a pipe pipeline handler,\n> >>> + * This function checks if this IPA module matches the requested \\a name\n> >>>     * and the input version range.\n> >>>     *\n> >>> - * \\return True if the pipeline handler matches the IPA module, or false otherwise\n> >>> + * \\return True if the IPA module matches, or false otherwise\n> >>>     */\n> >>> -bool IPAModule::match(PipelineHandler *pipe,\n> >>> -\t\t      uint32_t minVersion, uint32_t maxVersion) const\n> >>> +bool IPAModule::match(const char *name, uint32_t minVersion,\n> >>> +\t\t      uint32_t maxVersion) const\n> >>>    {\n> >>>    \treturn info_.pipelineVersion >= minVersion &&\n> >>>    \t       info_.pipelineVersion <= maxVersion &&\n> >>> -\t       !strcmp(info_.pipelineName, pipe->name());\n> >>> +\t       !strcmp(info_.name, name);\n> >>>    }\n> >>>    std::string IPAModule::logPrefix() const","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 428B9BDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 13 May 2026 23:56:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B137E63025;\n\tThu, 14 May 2026 01:56:18 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D20B76271A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 14 May 2026 01:56:16 +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 9E66563C;\n\tThu, 14 May 2026 01:56:07 +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=\"S4HgPToR\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778716567;\n\tbh=XPg6cGkqIMhNiY35ZX+vqZBcQeBpzi4XyPFp+xeIs1U=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=S4HgPToReItDVBnpInhwVqRzlHHtWGHQV1hPhEK5d7INL6EhBnYyCkFxuTqLQdCIt\n\tuPB2r0X9ihSIU7txhr6WeyCIjBLitvW+pdT6ZszSnM7+MQSPsWL7nZ22PpmW6RLvv1\n\tyqFa2EMV+I1jlsK5HqM6jFkMoKZpYu8NoXGsZVPI=","Date":"Thu, 14 May 2026 02:56:15 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>, Hans de Goede\n\t<johannes.goede@oss.qualcomm.com>, libcamera-devel@lists.libcamera.org, \n\tLoic Poulain <loic.poulain@oss.qualcomm.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, Niklas =?utf-8?q?S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>, Naushir Patuck\n\t<naush@raspberrypi.com>,  David Plowman <david.plowman@raspberrypi.com>","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","Message-ID":"<20260513235615.GA404935@killaraus.ideasonboard.com>","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>\n\t<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>\n\t<adzvfswl6-ATwae1@zed>\n\t<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.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":38892,"web_url":"https://patchwork.libcamera.org/comment/38892/","msgid":"<CAEmqJPrqneuX5S2=B7DgDww=-i=nppbGG3HHtjz64DpeubxXtg@mail.gmail.com>","date":"2026-05-14T07:57:12","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Laurent,\n\nOn Thu, 14 May 2026 at 00:56, Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> CC'ing Naush and David.\n>\n> On Mon, Apr 13, 2026 at 03:55:58PM +0200, Barnabás Pőcze wrote:\n> > 2026. 04. 13. 15:32 keltezéssel, Jacopo Mondi írta:\n> > > On Mon, Apr 13, 2026 at 12:21:59PM +0200, Barnabás Pőcze wrote:\n> > >> 2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n> > >>> Currently createIPA() / IPAManager::module() assume that there is a\n> 1:1\n> > >>> relationship between pipeline handlers and IPAs and IPA matching is\n> done\n> > >>> based on matching the pipe to ipaModuleInfo.pipelineName[].\n> > >>>\n> > >>> One way to allow using a single IPA with multiple pipelines would be\n> to\n> > >>> allow the IPA to declare itself compatible with more than one\n> pipeline,\n> > >>> turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n> > >>> ipaModuleInfo is loaded as an ELF symbol requires it to be a simple\n> flat\n> > >>> C-struct.\n> > >>>\n> > >>> Instead, move the IPA creation procedure to be name-based,\n> introducing\n> > >>> an overload to IPAManager::createIPA(pipe, name, minVer, maxVer)\n> that\n> > >>> allows to specify the name of the IPA module to match. Pipeline\n> handlers\n> > >>> that wants to use their name as matching criteria can continue doing\n> so\n> > >>> using the already existing createIPA(pipe, minVer, maxVer) overload.\n> > >>>\n> > >>> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> > >>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > >>> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> > >>> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n> > >>> ---\n> > >>>    include/libcamera/internal/ipa_manager.h | 13 +++++++--\n> > >>>    include/libcamera/internal/ipa_module.h  |  4 +--\n> > >>>    src/libcamera/ipa_manager.cpp            | 34\n> +++++++++++++++++++-----\n> > >>>    src/libcamera/ipa_module.cpp             | 12 ++++-----\n> > >>>    4 files changed, 47 insertions(+), 16 deletions(-)\n> > >>>\n> > >>> diff --git a/include/libcamera/internal/ipa_manager.h\n> b/include/libcamera/internal/ipa_manager.h\n> > >>> index f8ce78016..4c01e76f1 100644\n> > >>> --- a/include/libcamera/internal/ipa_manager.h\n> > >>> +++ b/include/libcamera/internal/ipa_manager.h\n> > >>> @@ -34,12 +34,13 @@ public:\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\n> 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\n> the moment\n> > >> with this approach. I have tried to come up with something, but so\n> for has failed.\n> > >\n> > > What is the issue ? That the proxy is the same for v4 and v5 ?\n> >\n> > The proxy type is the same, but different names need to be used.\n>\n> The more I think about it, the more uncomfortable I get with specifying\n> a name here.\n>\n> The API contract between the pipeline handler is the IPA interface.\n> That's all we should have to specify in the pipeline handler. Adding a\n> name gives the pipeline handler the ability to select any IPA module,\n> without any check whatsoever to ensure compatibility of the interface.\n> That sounds like a very bad idea.\n>\n> Raspberry Pi is the only platform where we have two IPA modules using\n> the same IPA interface without being interchangeable. Trying to use the\n> Pi4 IPA module on a Pi5 will not work, and vice versa. I would really\n> like to fix that, and I see two options:\n>\n> - Merging the two IPA modules into a single one, compatible with both\n>   platforms. The IPA interface functions in the IPA module would\n>   essentially dispatch to Pi4 or Pi5 implementations, based on a\n>   platform version identifier (passed to the init() function I suppose).\n>\n> - Splitting the IPA interface into two different interfaces. The\n>   interfaces can still share the same API, the important part is to have\n>   two different interface names in two .mojom files. All the data\n>   structures can be defined in a shared .mojom file imported by both\n>   interfaces (and maybe there's a way to also share a common interface\n>   definition instead of duplicating it).\n>\n> The drawback of the first option is that the IPA module will contain\n> dead code (Pi4 code won't run on Pi5 and vice versa), while the drawback\n> of the second option is that we'll duplicate proxy and worker code (as\n> the code is generated, it's just a matter of binary size, there's no\n> additional maintenance burden there).\n>\n> Naush, David, any opinion ?\n>\n\nI would opt for the second option, i.e. splitting the IPA interface in this\ncase.  There will be quite a lot of duplicate code, but our IPAs are pretty\nstable at this point so maintaining fixes/changes across both should be\nmanageable.\n\nWould you like me to prototype this?  I'll likely only have a chance to do\nthis after the Nice F2F though.\n\nNaush\n\n\n\n>\n>\n> Note that we would still support multiple intercheangeable IPA modules\n> using the same interface (and therefore compatible with the same\n> pipeline handler).\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\n> specific names. Not\n> > >> a fan of this in any case.\n> > >>\n> > >>>                   CameraManager *cm = pipe->cameraManager();\n> > >>>                   IPAManager *self = cm->_d()->ipaManager();\n> > >>> -         IPAModule *m = self->module(pipe, minVersion, maxVersion);\n> > >>> +         IPAModule *m = self->module(name, minVersion, maxVersion);\n> > >>>                   if (!m)\n> > >>>                           return nullptr;\n> > >>> @@ -60,6 +61,14 @@ public:\n> > >>>                   return proxy;\n> > >>>           }\n> > >>> + template<typename T>\n> > >>> + static std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> > >>> +                                     uint32_t minVersion,\n> > >>> +                                     uint32_t maxVersion)\n> > >>> + {\n> > >>> +         return createIPA<T>(pipe, pipe->name(), minVersion,\n> maxVersion);\n> > >>> + }\n> > >>> +\n> > >>>    #if HAVE_IPA_PUBKEY\n> > >>>           static const PubKey &pubKey()\n> > >>>           {\n> > >>> @@ -72,7 +81,7 @@ private:\n> > >>>                         std::vector<std::string> &files);\n> > >>>           unsigned int addDir(const char *libDir, unsigned int\n> maxDepth = 0);\n> > >>> - IPAModule *module(PipelineHandler *pipe, uint32_t minVersion,\n> > >>> + IPAModule *module(const char *name, uint32_t minVersion,\n> > >>>                             uint32_t maxVersion);\n> > >>>           bool isSignatureValid(IPAModule *ipa) const;\n> > >>> diff --git a/include/libcamera/internal/ipa_module.h\n> b/include/libcamera/internal/ipa_module.h\n> > >>> index 15f19492c..a0a53764e 100644\n> > >>> --- a/include/libcamera/internal/ipa_module.h\n> > >>> +++ b/include/libcamera/internal/ipa_module.h\n> > >>> @@ -36,8 +36,8 @@ public:\n> > >>>           IPAInterface *createInterface();\n> > >>> - bool match(PipelineHandler *pipe,\n> > >>> -            uint32_t minVersion, uint32_t maxVersion) const;\n> > >>> + bool match(const char *name, uint32_t minVersion,\n> > >>> +            uint32_t maxVersion) const;\n> > >>>    protected:\n> > >>>           std::string logPrefix() const override;\n> > >>> diff --git a/src/libcamera/ipa_manager.cpp\n> b/src/libcamera/ipa_manager.cpp\n> > >>> index 35171d097..f62a4ee5f 100644\n> > >>> --- a/src/libcamera/ipa_manager.cpp\n> > >>> +++ b/src/libcamera/ipa_manager.cpp\n> > >>> @@ -247,15 +247,15 @@ unsigned int IPAManager::addDir(const char\n> *libDir, unsigned int maxDepth)\n> > >>>    /**\n> > >>>     * \\brief Retrieve an IPA module that matches a given pipeline\n> handler\n> > >>> - * \\param[in] pipe The pipeline handler\n> > >>> + * \\param[in] name The IPA module string identifier\n> > >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> > >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > >>>     */\n> > >>> -IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t\n> minVersion,\n> > >>> +IPAModule *IPAManager::module(const char *name, uint32_t minVersion,\n> > >>>                                 uint32_t maxVersion)\n> > >>>    {\n> > >>>           for (const auto &module : modules_) {\n> > >>> -         if (module->match(pipe, minVersion, maxVersion))\n> > >>> +         if (module->match(name, minVersion, maxVersion))\n> > >>>                           return module.get();\n> > >>>           }\n> > >>> @@ -263,12 +263,34 @@ IPAModule *IPAManager::module(PipelineHandler\n> *pipe, uint32_t minVersion,\n> > >>>    }\n> > >>>    /**\n> > >>> - * \\fn IPAManager::createIPA()\n> > >>> - * \\brief Create an IPA proxy that matches a given pipeline handler\n> > >>> - * \\param[in] pipe The pipeline handler that wants a matching IPA\n> proxy\n> > >>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, const char\n> *ipaName, uint32_t minVersion, uint32_t maxVersion)\n> > >>> + * \\brief Create an IPA proxy that matches the requested name and\n> version\n> > >>> + * \\param[in] pipe The pipeline handler that wants to create the\n> IPA module\n> > >>> + * \\param[in] ipaName The IPA module name\n> > >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> > >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > >>>     *\n> > >>> + * Create an IPA module using \\a name as the matching identifier.\n> This overload\n> > >>> + * allows pipeline handlers to create an IPA module by specifying\n> its name\n> > >>> + * instead of relying on the fact that the IPA module matches the\n> pipeline\n> > >>> + * handler's one.\n> > >>> + *\n> > >>> + * \\return A newly created IPA proxy, or nullptr if no matching IPA\n> module is\n> > >>> + * found or if the IPA proxy fails to initialize\n> > >>> + */\n> > >>> +\n> > >>> +/**\n> > >>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, uint32_t\n> minVersion, uint32_t maxVersion)\n> > >>> + * \\brief Create an IPA proxy that matches the pipeline handler\n> name and the\n> > >>> + * requested version\n> > >>> + * \\param[in] pipe The pipeline handler that wants to create the\n> IPA module\n> > >>> + * \\param[in] minVersion Minimum acceptable version of IPA module\n> > >>> + * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > >>> + *\n> > >>> + * Create an IPA module using the pipeline handler name as the\n> matching\n> > >>> + * identifier. This overload allows pipeline handler to create an\n> IPA module\n> > >>> + * whose name matches the pipeline handler one.\n> > >>> + *\n> > >>>     * \\return A newly created IPA proxy, or nullptr if no matching\n> IPA module is\n> > >>>     * found or if the IPA proxy fails to initialize\n> > >>>     */\n> > >>> diff --git a/src/libcamera/ipa_module.cpp\n> b/src/libcamera/ipa_module.cpp\n> > >>> index e6ea61e44..0bd6f1462 100644\n> > >>> --- a/src/libcamera/ipa_module.cpp\n> > >>> +++ b/src/libcamera/ipa_module.cpp\n> > >>> @@ -463,21 +463,21 @@ IPAInterface *IPAModule::createInterface()\n> > >>>    /**\n> > >>>     * \\brief Verify if the IPA module matches a given pipeline\n> handler\n> > >>> - * \\param[in] pipe Pipeline handler to match with\n> > >>> + * \\param[in] name The IPA module name\n> > >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> > >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > >>>     *\n> > >>> - * This function checks if this IPA module matches the \\a pipe\n> pipeline handler,\n> > >>> + * This function checks if this IPA module matches the requested \\a\n> name\n> > >>>     * and the input version range.\n> > >>>     *\n> > >>> - * \\return True if the pipeline handler matches the IPA module, or\n> false otherwise\n> > >>> + * \\return True if the IPA module matches, or false otherwise\n> > >>>     */\n> > >>> -bool IPAModule::match(PipelineHandler *pipe,\n> > >>> -               uint32_t minVersion, uint32_t maxVersion) const\n> > >>> +bool IPAModule::match(const char *name, uint32_t minVersion,\n> > >>> +               uint32_t maxVersion) const\n> > >>>    {\n> > >>>           return info_.pipelineVersion >= minVersion &&\n> > >>>                  info_.pipelineVersion <= maxVersion &&\n> > >>> -        !strcmp(info_.pipelineName, pipe->name());\n> > >>> +        !strcmp(info_.name, name);\n> > >>>    }\n> > >>>    std::string IPAModule::logPrefix() const\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\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 1B2D8BDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 14 May 2026 07:57:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0B95862FEC;\n\tThu, 14 May 2026 09:57:54 +0200 (CEST)","from mail-ua1-x936.google.com (mail-ua1-x936.google.com\n\t[IPv6:2607:f8b0:4864:20::936])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 017C762FB1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 14 May 2026 09:57:51 +0200 (CEST)","by mail-ua1-x936.google.com with SMTP id\n\ta1e0cc1a2514c-95f2cafb65bso126143241.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 14 May 2026 00:57:51 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"MI9VXcKq\"; dkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1778745471; cv=none;\n\td=google.com; s=arc-20240605;\n\tb=LK4n/eWoh6KEdQbpezksuFKPyjs5fj+CmdDE5ztuNKLU7bll4kW+hfijv7kIz5Y4Gy\n\teQ/ZYqIjQHdIlQ+27kO1nldvTOTOD1/lnO9oVXqqTNaOVMLP0WnZj7gBjg/PKGDfM7CF\n\tPLi4PqzTkzyPks0+3muhyclM71rSN8T0DmW1ze0z/alQBPZSZFOTU8Nq5KxD7DC07eVq\n\tv9eURuuHWdFAWV3tyhZSflUivu2yVR/XgtGvJIu6YVq0L5Y4jWtUwVTooHzJpuSJTIp4\n\txObJu5YFBm7OmPhvwjciQ3TuUvGOEoMu7jjGk8azf908vGHUpUP5YxccHEut8+Izik6x\n\t+gXg==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n\ts=arc-20240605; \n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:dkim-signature;\n\tbh=dJQrH8Ja6wajWHHKF/ovoqmhI+48a78RLdwmsFkfqTY=;\n\tfh=3oJ7FrijXUCHwDZusHZZTpEatSlFJwqk1HFP2FdFRGo=;\n\tb=lLxYpbLtLzbdL1SE3z4savjgCyTfvNwVqiwuJgWYMzV505C8+nBxp4UFgOsXSB1K51\n\tKpCwWDHrJR2Qcl3lKG2Npbf1NNWnkWl35uOgsbU9KumKOIcHcUvdcqtMgW1FRfizdO1M\n\tL6LEc2bRyYE3nWInnVwNmSWCVk/MztryrWaiJ5rJgmFcDpeaQkmYYX94L2XRIYWVh3L+\n\tARM3xdyHMKacbfvuZzJxQa0FVaw73xb3zRx3g/nC+W/PXHJN1pLcVh2GYl6Nt1HUC4oJ\n\tHDj21e68zcI8pO337FrrDgRIvK+WDWhMNPy8dFMY+iaYxo+OOpb35DvZf2YxmiCQpkCh\n\tXrPw==; darn=lists.libcamera.org","ARC-Authentication-Results":"i=1; mx.google.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1778745471; x=1779350271;\n\tdarn=lists.libcamera.org; \n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:from:to:cc:subject:date:message-id:reply-to;\n\tbh=dJQrH8Ja6wajWHHKF/ovoqmhI+48a78RLdwmsFkfqTY=;\n\tb=MI9VXcKqJAN2HOFj4klbkUquYx5Zc8cXJtuXMvdX3IAN6XlAaSBUmoLpGnczKKeAin\n\t+d9Gk3zxGU2EWW55rtxvbGlA7tYOfOvOp3UT50N9N2j8n4/zZD95Ad5XWBnJ4XfCHMZP\n\tzqqhrLLkdAPSy9BXxOKMlhCCj0GdLE6o6S3E5RUFBUBd3yitrjyPYF3G8wpQuMxilcHJ\n\t1Oszz7tGQ2DEEGWNDuE9lgHspUMkeqnBBSlIxrNB6p3aEzYwJTm0wtDJQrNWuyGN1xaD\n\t13Log7Mmk/7a6nMY00o5IJFK5l7stA34Z3G/lCSmedGfaVx9JMPpZ537G9IyIoWOxLDt\n\tMmIA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1778745471; x=1779350271;\n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=dJQrH8Ja6wajWHHKF/ovoqmhI+48a78RLdwmsFkfqTY=;\n\tb=AX/f0OzCI38zkbd/5dULTKZkW4aIT87vPbm8hiYTEnTbipweqA1r5dIBoedMscpJjz\n\tdWJheltqaFnogLtasSqauS6sRKZPm7R8k13cDgwgHp8u/9PDaYmUimRhkWjtxeI7drhc\n\teSrIyhx3p3wTQaBAGA8lkrIw2bw2pOyeeYN35+Redtea6IG/K5NGdA2w0Sh3R6SJBc0m\n\teRpaqyqMiptdczc2zKAd91Im8d/sNsmu6N7OsGco1zxLSSa24Dc5JSUE21Uk97QWmaBE\n\tOD9xUG/Mg8MEU1spVWO09W7C3ct/pEf07goSncsNXh/cmvkpDtJp+DIS68GIpuxIbViK\n\teOJA==","X-Forwarded-Encrypted":"i=1;\n\tAFNElJ/9IT9IitTcn/axtZQvOFc3wwRUDjW9OBW4A5DxIs8QezbWLWBWYkCRbOn2UeZq+SZb908n4qPUCp97KWzWSRg=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Yzfw4xOOnOCgoxtR+gTTLJm5HeQnUfys9OK+Cnzx433tu0i+nHS\n\tgLZrRZAJDtvBoJpYeaTHSpiBvo9x812fj+z/cNaDdr9YN4N2j+CTH5veVyMrTKL/8d9bfKukzfb\n\t1GEye3xHzWWJsqRpe1/R9ohRAVIzHR0lVXZMOn9Pevg==","X-Gm-Gg":"Acq92OEepIzzUE4/z14mVYs6q3U1z9WXljTVulLI5dKsPHLX6giqE+deItHND7lmLA2\n\tzqOXcO0NeFDKlpbgO/msXTkzUDSBhyBcv4NwnPu94mGJmWInH4RFXNjkeO8mDFPz3zTNQXiLOk3\n\ti+/FZlaCglUOSQVM2GJAYAL81swRyAvJ4ZDKlhXY2tIVWU9NleCIaHKoAbz/78crQVNHUWqPhk3\n\tHc+rwOguJD44GhgUoJlKbqVEk9gPIpXL2dTMl1O4zjE1xLr0tsNqvGurKppfXDucuVKMrrE+hQZ\n\toggqfFA49B9MZoy3LJXcGrxxoshsybEeItM7xdnPUQBMZPl2dhqRzURg1bC/Y0cFa7L5pTWYXA/\n\txhs9tWJM1fVdJT6l1mAHmMVXfGciD9iFAYb2lzUtCNTwsz7kxD4II8/Aett09qggtiEYpXkwl7G\n\tLV788YKj0/CBnK80AgELH9pYg=","X-Received":"by 2002:a05:6102:727:b0:605:53ef:d53f with SMTP id\n\tada2fe7eead31-637731dde41mr1098121137.2.1778745470588;\n\tThu, 14 May 2026 00:57:50 -0700 (PDT)","MIME-Version":"1.0","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>\n\t<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>\n\t<adzvfswl6-ATwae1@zed>\n\t<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.com>\n\t<20260513235615.GA404935@killaraus.ideasonboard.com>","In-Reply-To":"<20260513235615.GA404935@killaraus.ideasonboard.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Thu, 14 May 2026 08:57:12 +0100","X-Gm-Features":"AVHnY4I20NpSL0KjWRl0eigfR6vngzji-hpO16v6D5OYJqHq5540Mvsf_8UIujU","Message-ID":"<CAEmqJPrqneuX5S2=B7DgDww=-i=nppbGG3HHtjz64DpeubxXtg@mail.gmail.com>","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>, Hans de Goede\n\t<johannes.goede@oss.qualcomm.com>, libcamera-devel@lists.libcamera.org, \n\tLoic Poulain <loic.poulain@oss.qualcomm.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Niklas_S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>, David Plowman\n\t<david.plowman@raspberrypi.com>","Content-Type":"multipart/alternative; boundary=\"000000000000ebb2780651c27365\"","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":38894,"web_url":"https://patchwork.libcamera.org/comment/38894/","msgid":"<20260514083219.GA413597@killaraus.ideasonboard.com>","date":"2026-05-14T08:32:19","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, May 14, 2026 at 08:57:12AM +0100, Naushir Patuck wrote:\n> On Thu, 14 May 2026 at 00:56, Laurent Pinchart wrote:\n> > CC'ing Naush and David.\n> >\n> > On Mon, Apr 13, 2026 at 03:55:58PM +0200, Barnabás Pőcze wrote:\n> > > 2026. 04. 13. 15:32 keltezéssel, Jacopo Mondi írta:\n> > > > On Mon, Apr 13, 2026 at 12:21:59PM +0200, Barnabás Pőcze wrote:\n> > > >> 2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n> > > >>> Currently createIPA() / IPAManager::module() assume that there is a 1:1\n> > > >>> relationship between pipeline handlers and IPAs and IPA matching is done\n> > > >>> based on matching the pipe to ipaModuleInfo.pipelineName[].\n> > > >>>\n> > > >>> One way to allow using a single IPA with multiple pipelines would be to\n> > > >>> allow the IPA to declare itself compatible with more than one pipeline,\n> > > >>> turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n> > > >>> ipaModuleInfo is loaded as an ELF symbol requires it to be a simple flat\n> > > >>> C-struct.\n> > > >>>\n> > > >>> Instead, move the IPA creation procedure to be name-based, introducing\n> > > >>> an overload to IPAManager::createIPA(pipe, name, minVer, maxVer) that\n> > > >>> allows to specify the name of the IPA module to match. Pipeline handlers\n> > > >>> that wants to use their name as matching criteria can continue doing so\n> > > >>> using the already existing createIPA(pipe, minVer, maxVer) overload.\n> > > >>>\n> > > >>> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> > > >>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > >>> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> > > >>> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n> > > >>> ---\n> > > >>>    include/libcamera/internal/ipa_manager.h | 13 +++++++--\n> > > >>>    include/libcamera/internal/ipa_module.h  |  4 +--\n> > > >>>    src/libcamera/ipa_manager.cpp            | 34 +++++++++++++++++++-----\n> > > >>>    src/libcamera/ipa_module.cpp             | 12 ++++-----\n> > > >>>    4 files changed, 47 insertions(+), 16 deletions(-)\n> > > >>>\n> > > >>> diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\n> > > >>> index f8ce78016..4c01e76f1 100644\n> > > >>> --- a/include/libcamera/internal/ipa_manager.h\n> > > >>> +++ b/include/libcamera/internal/ipa_manager.h\n> > > >>> @@ -34,12 +34,13 @@ public:\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> > > > What is the issue ? That the proxy is the same for v4 and v5 ?\n> > >\n> > > The proxy type is the same, but different names need to be used.\n> >\n> > The more I think about it, the more uncomfortable I get with specifying\n> > a name here.\n> >\n> > The API contract between the pipeline handler is the IPA interface.\n> > That's all we should have to specify in the pipeline handler. Adding a\n> > name gives the pipeline handler the ability to select any IPA module,\n> > without any check whatsoever to ensure compatibility of the interface.\n> > That sounds like a very bad idea.\n> >\n> > Raspberry Pi is the only platform where we have two IPA modules using\n> > the same IPA interface without being interchangeable. Trying to use the\n> > Pi4 IPA module on a Pi5 will not work, and vice versa. I would really\n> > like to fix that, and I see two options:\n> >\n> > - Merging the two IPA modules into a single one, compatible with both\n> >   platforms. The IPA interface functions in the IPA module would\n> >   essentially dispatch to Pi4 or Pi5 implementations, based on a\n> >   platform version identifier (passed to the init() function I suppose).\n> >\n> > - Splitting the IPA interface into two different interfaces. The\n> >   interfaces can still share the same API, the important part is to have\n> >   two different interface names in two .mojom files. All the data\n> >   structures can be defined in a shared .mojom file imported by both\n> >   interfaces (and maybe there's a way to also share a common interface\n> >   definition instead of duplicating it).\n> >\n> > The drawback of the first option is that the IPA module will contain\n> > dead code (Pi4 code won't run on Pi5 and vice versa), while the drawback\n> > of the second option is that we'll duplicate proxy and worker code (as\n> > the code is generated, it's just a matter of binary size, there's no\n> > additional maintenance burden there).\n> >\n> > Naush, David, any opinion ?\n> >\n> \n> I would opt for the second option, i.e. splitting the IPA interface in this\n> case.  There will be quite a lot of duplicate code, but our IPAs are pretty\n> stable at this point so maintaining fixes/changes across both should be\n> manageable.\n> \n> Would you like me to prototype this?  I'll likely only have a chance to do\n> this after the Nice F2F though.\n\nI would appreciate that, thank you. I gave it a quick try last night,\nand the IPABase class was in the way as it inherits from\nIPARPiInterface. We would need to move the inheritance to individual IPA\nmodules, but you can still use an IPABase helper that contains the\nshared code, as long as it doesn't inherit from the interface class.\nThat likely means that some of the platform*() functions could be removed.\n\n> > Note that we would still support multiple intercheangeable IPA modules\n> > using the same interface (and therefore compatible with the same\n> > pipeline handler).\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> > > >>>                   CameraManager *cm = pipe->cameraManager();\n> > > >>>                   IPAManager *self = cm->_d()->ipaManager();\n> > > >>> -         IPAModule *m = self->module(pipe, minVersion, maxVersion);\n> > > >>> +         IPAModule *m = self->module(name, minVersion, maxVersion);\n> > > >>>                   if (!m)\n> > > >>>                           return nullptr;\n> > > >>> @@ -60,6 +61,14 @@ public:\n> > > >>>                   return proxy;\n> > > >>>           }\n> > > >>> + template<typename T>\n> > > >>> + static std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n> > > >>> +                                     uint32_t minVersion,\n> > > >>> +                                     uint32_t maxVersion)\n> > > >>> + {\n> > > >>> +         return createIPA<T>(pipe, pipe->name(), minVersion, maxVersion);\n> > > >>> + }\n> > > >>> +\n> > > >>>    #if HAVE_IPA_PUBKEY\n> > > >>>           static const PubKey &pubKey()\n> > > >>>           {\n> > > >>> @@ -72,7 +81,7 @@ private:\n> > > >>>                         std::vector<std::string> &files);\n> > > >>>           unsigned int addDir(const char *libDir, unsigned int maxDepth = 0);\n> > > >>> - IPAModule *module(PipelineHandler *pipe, uint32_t minVersion,\n> > > >>> + IPAModule *module(const char *name, uint32_t minVersion,\n> > > >>>                             uint32_t maxVersion);\n> > > >>>           bool isSignatureValid(IPAModule *ipa) const;\n> > > >>> diff --git a/include/libcamera/internal/ipa_module.h b/include/libcamera/internal/ipa_module.h\n> > > >>> index 15f19492c..a0a53764e 100644\n> > > >>> --- a/include/libcamera/internal/ipa_module.h\n> > > >>> +++ b/include/libcamera/internal/ipa_module.h\n> > > >>> @@ -36,8 +36,8 @@ public:\n> > > >>>           IPAInterface *createInterface();\n> > > >>> - bool match(PipelineHandler *pipe,\n> > > >>> -            uint32_t minVersion, uint32_t maxVersion) const;\n> > > >>> + bool match(const char *name, uint32_t minVersion,\n> > > >>> +            uint32_t maxVersion) const;\n> > > >>>    protected:\n> > > >>>           std::string logPrefix() const override;\n> > > >>> diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\n> > > >>> index 35171d097..f62a4ee5f 100644\n> > > >>> --- a/src/libcamera/ipa_manager.cpp\n> > > >>> +++ b/src/libcamera/ipa_manager.cpp\n> > > >>> @@ -247,15 +247,15 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\n> > > >>>    /**\n> > > >>>     * \\brief Retrieve an IPA module that matches a given pipeline handler\n> > > >>> - * \\param[in] pipe The pipeline handler\n> > > >>> + * \\param[in] name The IPA module string identifier\n> > > >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> > > >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > > >>>     */\n> > > >>> -IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> > > >>> +IPAModule *IPAManager::module(const char *name, uint32_t minVersion,\n> > > >>>                                 uint32_t maxVersion)\n> > > >>>    {\n> > > >>>           for (const auto &module : modules_) {\n> > > >>> -         if (module->match(pipe, minVersion, maxVersion))\n> > > >>> +         if (module->match(name, minVersion, maxVersion))\n> > > >>>                           return module.get();\n> > > >>>           }\n> > > >>> @@ -263,12 +263,34 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n> > > >>>    }\n> > > >>>    /**\n> > > >>> - * \\fn IPAManager::createIPA()\n> > > >>> - * \\brief Create an IPA proxy that matches a given pipeline handler\n> > > >>> - * \\param[in] pipe The pipeline handler that wants a matching IPA proxy\n> > > >>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, const char *ipaName, uint32_t minVersion, uint32_t maxVersion)\n> > > >>> + * \\brief Create an IPA proxy that matches the requested name and version\n> > > >>> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> > > >>> + * \\param[in] ipaName The IPA module name\n> > > >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> > > >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > > >>>     *\n> > > >>> + * Create an IPA module using \\a name as the matching identifier. This overload\n> > > >>> + * allows pipeline handlers to create an IPA module by specifying its name\n> > > >>> + * instead of relying on the fact that the IPA module matches the pipeline\n> > > >>> + * handler's one.\n> > > >>> + *\n> > > >>> + * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> > > >>> + * found or if the IPA proxy fails to initialize\n> > > >>> + */\n> > > >>> +\n> > > >>> +/**\n> > > >>> + * \\fn IPAManager::createIPA(PipelineHandler *pipe, uint32_t minVersion, uint32_t maxVersion)\n> > > >>> + * \\brief Create an IPA proxy that matches the pipeline handler name and the\n> > > >>> + * requested version\n> > > >>> + * \\param[in] pipe The pipeline handler that wants to create the IPA module\n> > > >>> + * \\param[in] minVersion Minimum acceptable version of IPA module\n> > > >>> + * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > > >>> + *\n> > > >>> + * Create an IPA module using the pipeline handler name as the matching\n> > > >>> + * identifier. This overload allows pipeline handler to create an IPA module\n> > > >>> + * whose name matches the pipeline handler one.\n> > > >>> + *\n> > > >>>     * \\return A newly created IPA proxy, or nullptr if no matching IPA module is\n> > > >>>     * found or if the IPA proxy fails to initialize\n> > > >>>     */\n> > > >>> diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp\n> > > >>> index e6ea61e44..0bd6f1462 100644\n> > > >>> --- a/src/libcamera/ipa_module.cpp\n> > > >>> +++ b/src/libcamera/ipa_module.cpp\n> > > >>> @@ -463,21 +463,21 @@ IPAInterface *IPAModule::createInterface()\n> > > >>>    /**\n> > > >>>     * \\brief Verify if the IPA module matches a given pipeline handler\n> > > >>> - * \\param[in] pipe Pipeline handler to match with\n> > > >>> + * \\param[in] name The IPA module name\n> > > >>>     * \\param[in] minVersion Minimum acceptable version of IPA module\n> > > >>>     * \\param[in] maxVersion Maximum acceptable version of IPA module\n> > > >>>     *\n> > > >>> - * This function checks if this IPA module matches the \\a pipe pipeline handler,\n> > > >>> + * This function checks if this IPA module matches the requested \\a name\n> > > >>>     * and the input version range.\n> > > >>>     *\n> > > >>> - * \\return True if the pipeline handler matches the IPA module, or false otherwise\n> > > >>> + * \\return True if the IPA module matches, or false otherwise\n> > > >>>     */\n> > > >>> -bool IPAModule::match(PipelineHandler *pipe,\n> > > >>> -               uint32_t minVersion, uint32_t maxVersion) const\n> > > >>> +bool IPAModule::match(const char *name, uint32_t minVersion,\n> > > >>> +               uint32_t maxVersion) const\n> > > >>>    {\n> > > >>>           return info_.pipelineVersion >= minVersion &&\n> > > >>>                  info_.pipelineVersion <= maxVersion &&\n> > > >>> -        !strcmp(info_.pipelineName, pipe->name());\n> > > >>> +        !strcmp(info_.name, name);\n> > > >>>    }\n> > > >>>    std::string IPAModule::logPrefix() const","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 82C04BDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 14 May 2026 08:32:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A6E6663021;\n\tThu, 14 May 2026 10:32:23 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1349F62FEA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 14 May 2026 10:32:22 +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 A83D28E0;\n\tThu, 14 May 2026 10:32:12 +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=\"HYwlZkau\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778747532;\n\tbh=o1N8MGs1i6mTmuj/eCpGUesZtzMBB8lt6Fya/787QGE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=HYwlZkauIqbWvds3Qd4uv4eiTbxtXqEGs9xVgZDbWz7d/q21Y+zLaxSigSdDLwXjT\n\tn8SpM7B3n9E4GwoBOAVVCh1eqPhZjbUCO175gbu7k4KRGpkvPw4gsuQrwaaPeLnftL\n\tHM1GfWA9fyng9ffutQn8tZTjKhffxoPAnSl5dY+0=","Date":"Thu, 14 May 2026 11:32:19 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Naushir Patuck <naush@raspberrypi.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>, Hans de Goede\n\t<johannes.goede@oss.qualcomm.com>, libcamera-devel@lists.libcamera.org, \n\tLoic Poulain <loic.poulain@oss.qualcomm.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, Niklas =?utf-8?q?S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>, David Plowman\n\t<david.plowman@raspberrypi.com>","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","Message-ID":"<20260514083219.GA413597@killaraus.ideasonboard.com>","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>\n\t<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>\n\t<adzvfswl6-ATwae1@zed>\n\t<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.com>\n\t<20260513235615.GA404935@killaraus.ideasonboard.com>\n\t<CAEmqJPrqneuX5S2=B7DgDww=-i=nppbGG3HHtjz64DpeubxXtg@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<CAEmqJPrqneuX5S2=B7DgDww=-i=nppbGG3HHtjz64DpeubxXtg@mail.gmail.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":38903,"web_url":"https://patchwork.libcamera.org/comment/38903/","msgid":"<1d2d33cb-4f52-4519-b94d-4534474db542@oss.qualcomm.com>","date":"2026-05-15T07:37:43","subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","submitter":{"id":242,"url":"https://patchwork.libcamera.org/api/people/242/","name":"Hans de Goede","email":"johannes.goede@oss.qualcomm.com"},"content":"Hi Laurent,\n\nOn 14-May-26 01:56, Laurent Pinchart wrote:\n> CC'ing Naush and David.\n> \n> On Mon, Apr 13, 2026 at 03:55:58PM +0200, Barnabás Pőcze wrote:\n>> 2026. 04. 13. 15:32 keltezéssel, Jacopo Mondi írta:\n>>> On Mon, Apr 13, 2026 at 12:21:59PM +0200, Barnabás Pőcze wrote:\n>>>> 2026. 04. 08. 13:56 keltezéssel, Hans de Goede írta:\n>>>>> Currently createIPA() / IPAManager::module() assume that there is a 1:1\n>>>>> relationship between pipeline handlers and IPAs and IPA matching is done\n>>>>> based on matching the pipe to ipaModuleInfo.pipelineName[].\n>>>>>\n>>>>> One way to allow using a single IPA with multiple pipelines would be to\n>>>>> allow the IPA to declare itself compatible with more than one pipeline,\n>>>>> turning ipaModuleInfo.pipelineName[] into e.g. a vector. But the way\n>>>>> ipaModuleInfo is loaded as an ELF symbol requires it to be a simple flat\n>>>>> C-struct.\n>>>>>\n>>>>> Instead, move the IPA creation procedure to be name-based, introducing\n>>>>> an overload to IPAManager::createIPA(pipe, name, minVer, maxVer)  that\n>>>>> allows to specify the name of the IPA module to match. Pipeline handlers\n>>>>> that wants to use their name as matching criteria can continue doing so\n>>>>> using the already existing createIPA(pipe, minVer, maxVer) overload.\n>>>>>\n>>>>> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n>>>>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>>>>> Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n>>>>> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>\n>>>>> ---\n>>>>>    include/libcamera/internal/ipa_manager.h | 13 +++++++--\n>>>>>    include/libcamera/internal/ipa_module.h  |  4 +--\n>>>>>    src/libcamera/ipa_manager.cpp            | 34 +++++++++++++++++++-----\n>>>>>    src/libcamera/ipa_module.cpp             | 12 ++++-----\n>>>>>    4 files changed, 47 insertions(+), 16 deletions(-)\n>>>>>\n>>>>> diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\n>>>>> index f8ce78016..4c01e76f1 100644\n>>>>> --- a/include/libcamera/internal/ipa_manager.h\n>>>>> +++ b/include/libcamera/internal/ipa_manager.h\n>>>>> @@ -34,12 +34,13 @@ public:\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>>> What is the issue ? That the proxy is the same for v4 and v5 ?\n>>\n>> The proxy type is the same, but different names need to be used.\n> \n> The more I think about it, the more uncomfortable I get with specifying\n> a name here.\n> \n> The API contract between the pipeline handler is the IPA interface.\n> That's all we should have to specify in the pipeline handler. Adding a\n> name gives the pipeline handler the ability to select any IPA module,\n> without any check whatsoever to ensure compatibility of the interface.\n> That sounds like a very bad idea.\n\nYes we all agreed in the softISP meeting last Wednesday that eventually\nwe want to move to using the IPA interface type as the thing on which\nwe should match when loading an IPA.\n\nI'm a bit confused here though now, we also agreed to move forward\nwith v5 of this patch-set for now, with a follow up patch to add\na TODO comment to move to using the IPA interface type in the future.\n\nIs this a nack for moving forward with v5 as previously agreed on ?\n\nOr did you just want to get the discussion on the TODO item started?\n\nRegards,\n\nHans","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 0AB67BDCBC\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 15 May 2026 07:37:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E542C63020;\n\tFri, 15 May 2026 09:37:49 +0200 (CEST)","from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n\t[205.220.168.131])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AFD6662E9D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 May 2026 09:37:48 +0200 (CEST)","from pps.filterd (m0279863.ppops.net [127.0.0.1])\n\tby mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n\t64F5TMsV3200288 for <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 May 2026 07:37:46 GMT","from mail-ua1-f71.google.com (mail-ua1-f71.google.com\n\t[209.85.222.71])\n\tby mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e5m1qt5yr-1\n\t(version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 May 2026 07:37:46 +0000 (GMT)","by mail-ua1-f71.google.com with SMTP id\n\ta1e0cc1a2514c-95fc8572552so240449241.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 May 2026 00:37:46 -0700 (PDT)","from ?IPV6:2001:1c00:c32:7800:5bfa:a036:83f0:f9ec?\n\t(2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl.\n\t[2001:1c00:c32:7800:5bfa:a036:83f0:f9ec])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-bd4f4dec7d1sm183740066b.32.2026.05.15.00.37.43\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tFri, 15 May 2026 00:37:44 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=qualcomm.com header.i=@qualcomm.com\n\theader.b=\"I6drQrXv\"; dkim=pass (2048-bit key;\n\tunprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n\theader.b=\"eRbdcxw6\"; dkim-atps=neutral","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n\tcc:content-transfer-encoding:content-type:date:from:in-reply-to\n\t:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n\tbaEGJ0Kh3XPiz9wIfiJcIDPqecMBXdgNC3m0MqGcVRY=; b=I6drQrXv/CQ1hX5L\n\tb4CSqqsVhU0D1HatH0OPdF4e5n/uUXbLlBvmnD0lh44Fs7Ule4tJCITMDWUP4/IS\n\t6EkFriXTBT3t+RYo0lI1iy5wjNkKXkZF3CvQaqzDqbZ8FV94Ct4Scp6rN0UgpsjZ\n\t0uFo/6QNd8y29TBIh1o9DlxztBmmQqNLwbISbipm+2woG+3T5b4ONxtfKKCoXwaE\n\tL8fZrUuG9l1M2NvxaTc7AjArK7pghbG2BF/d77bCGRFqkbzUJHO4QItYRNN4OYPq\n\tDqhi2+rVgUCDg07xeHZx2WAQpaUD3vQPb1ArRUMARca45985qRdw1djmA4Gy3YJM\n\tsybntA==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=oss.qualcomm.com; s=google; t=1778830665; x=1779435465;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:in-reply-to:content-language:references\n\t:cc:to:subject:from:user-agent:mime-version:date:message-id:from:to\n\t:cc:subject:date:message-id:reply-to;\n\tbh=baEGJ0Kh3XPiz9wIfiJcIDPqecMBXdgNC3m0MqGcVRY=;\n\tb=eRbdcxw6JCtsGdalesoKehjA0Zqd4GoWU2CGIPaOHXoharkGsxeqjsPQntnYP0YC1m\n\tw53KqszULGcm+MGQuEyxLHnQnBEcjLfLPS6bENa95/32CwECxAH9MLM6oAmCdmMUhDCC\n\tB/e7Z0EgqoVhNenlxLQmMOzIXxVLFDLqt4ie1lbGOqLKilT4m7dmOgyMSuRncp4uIXFP\n\tB5aANGe07Jfgxj0rmTxVWIOY85arvBTG9Y633Ee6jFIpbuv5G3ijiu7kSupFe3+2bL2h\n\toXAJ1YHRZCJX3DWNYORoRnB5x93aVF/a+nj3dBQ0ijI8IZMAXpucdpFnMvXZMJKgqXL3\n\tJ3UA=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1778830665; x=1779435465;\n\th=content-transfer-encoding:in-reply-to:content-language:references\n\t:cc:to:subject:from:user-agent:mime-version:date:message-id:x-gm-gg\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=baEGJ0Kh3XPiz9wIfiJcIDPqecMBXdgNC3m0MqGcVRY=;\n\tb=MYDtV5Hr/LZc9yEVKsIF3fzPBL6PRgRSFNMgX7kcoIMURj1axEQVjH2JTdwRtbt0vJ\n\tpsQZ33ZYT/Jw6/RGDaPkgxOi4WNWkBhayyZhlWy+FefypO8mbRCSNLyDAQeW5CoiagjY\n\tiPFJ/WZMOGRgV0YEX1sFGTXpT1qFMUFzfJMprfqJjnG/NJcv7THT1Qf0qtwW2GD2vxFO\n\twHXUb/2HZH9jNaqv4lUm9rG2iLHakPcG3DlQ5pkGZufkn1Q0xKkJxdKq1DrgKF9WFUcp\n\tCb1Swl7s6nrv4FZM+Y5qCGY/OyBlbvQyFRPPGJL1RTJQmfPg+0EOyABmlprPKmQSVwz4\n\tyC5Q==","X-Forwarded-Encrypted":"i=1;\n\tAFNElJ8ClRf+LlP4o4g1Pp8x2ffY+P4M63gRV5Dtu39OHXzIi8CvzAyrSP7uKWiM5oP9I8BWdwb27dyr8LNuBFpfx54=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Yz7tlCy0ySwG+gZQHGT3u1qQPdC1/82f5/BGQU5mdbTm95YyQk6\n\tKkMsUuO2AUmEirU6t0zlE50fsyN/Nnb5OH//EZnqaqhckpVGfW8huJBe0h5RDS8lpaeSEsrzwKL\n\tAOm6pmgL0R3l3hXTnNpoLBY5dt6lJjcE/mJIE6fnaOPFZCBctUkLPjXoPE40rEjVztBz8Zz1r7C\n\txd","X-Gm-Gg":"Acq92OHPaervJVSELp61Dh+1y08Y/PYGZVZTKJ9oRk5mwF1v+Mx2R+1S2F55OrY03dv\n\tKGifFOSA/dxw3JAcm1DhcAUDjp7P6F2rUcKl/CmPhBZoRS67Ku8ZsovGCJsju25/9FsKyZanYTc\n\tFPunNLlCma5+r3pAy1MQcZZlx7K4nwnsLV7jSO4CiXkG0Q7i5vXn+Df7VJPxJno1ySAS5Ei8tRg\n\tfO4EWDQiGziOzeFn5a46XUteiMD0E8DQNptCqm1Zv2lvnS5fbwru1ZKo9zzcV/o8Woi2HErN2Zz\n\tGuwdtYrAgCWHVyr7hrWk+0dWlMJlkzpiiFvdbJYlP3cWTz9/MZH0pq3TggrrOFCPly1AfYUHs//\n\tCZmMKqd/gsOoMxPT+EMemnZ9oCu/9sUjpdz73ufZjrCraTx3YgXtXS9BuFGZgpL6lNYWppKTFxe\n\t91N+C+FYpdir0nG33rQZ2U+wppCT999IgKTmugTiIHjgRp6MVAJM+J+evJUG31Mb2DrzMSVt9Sj\n\t1/BISd1ZHdh+vZN","X-Received":["by 2002:a05:6102:8029:b0:610:db51:6f3d with SMTP id\n\tada2fe7eead31-63a3d42f341mr1411653137.12.1778830665345; \n\tFri, 15 May 2026 00:37:45 -0700 (PDT)","by 2002:a05:6102:8029:b0:610:db51:6f3d with SMTP id\n\tada2fe7eead31-63a3d42f341mr1411644137.12.1778830664930; \n\tFri, 15 May 2026 00:37:44 -0700 (PDT)"],"Message-ID":"<1d2d33cb-4f52-4519-b94d-4534474db542@oss.qualcomm.com>","Date":"Fri, 15 May 2026 09:37:43 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","From":"Hans de Goede <johannes.goede@oss.qualcomm.com>","Subject":"Re: [PATCH v4 1/4] libcamera: ipa_manager: Create IPA by name","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>, =?utf-8?q?Barnab?=\n\t=?utf-8?b?w6FzIFDFkWN6ZQ==?= <barnabas.pocze@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org, Loic Poulain\n\t<loic.poulain@oss.qualcomm.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Niklas_S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>, Naushir Patuck\n\t<naush@raspberrypi.com>,  David Plowman <david.plowman@raspberrypi.com>","References":"<20260408115606.12417-1-johannes.goede@oss.qualcomm.com>\n\t<20260408115606.12417-2-johannes.goede@oss.qualcomm.com>\n\t<400a8a2e-5eb7-461e-a4d8-46f5079a7f6f@ideasonboard.com>\n\t<adzvfswl6-ATwae1@zed>\n\t<49bc1167-eb5d-4e30-a50f-4122ac5fb543@ideasonboard.com>\n\t<20260513235615.GA404935@killaraus.ideasonboard.com>","Content-Language":"en-US, nl","In-Reply-To":"<20260513235615.GA404935@killaraus.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","X-Authority-Analysis":"v=2.4 cv=HbkkiCE8 c=1 sm=1 tr=0 ts=6a06cd4a cx=c_pps\n\ta=KB4UBwrhAZV1kjiGHFQexw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10\n\ta=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22\n\ta=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=P1BnusSwAAAA:8\n\ta=EUspDBNiAAAA:8 a=Xqld0b58iK7W1AGY2j0A:9 a=3ZKOabzyN94A:10\n\ta=QEXdDO2ut3YA:10\n\ta=o1xkdb1NAhiiM49bd1HK:22 a=D0XLA9XvdZm18NrgonBM:22","X-Proofpoint-GUID":"VDhewdX0WFuoObv4hLqrAM3yG1Anjw2a","X-Proofpoint-ORIG-GUID":"VDhewdX0WFuoObv4hLqrAM3yG1Anjw2a","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwNTE1MDA3NCBTYWx0ZWRfX431y73NzEVvM\n\tZcQ+Og/5QYXaL6TOed0tNydI01m3q3vsb6/UG/PJtMD9o0m5McHM72wBAQLqCRWsCEGUbsNxhtF\n\tF7ha+ORaAFgDG+E0lcou9fUeGDK2KD8ftP/lzU5n/y38v7bj10thMaXZIpNEQIDebQwix94+ykc\n\tJYTtmaO7FYA9Q2upAU8ZVwaI3weQ93e+XXYj7qNgiHwqT48c1BEFa5+YUtj38QxuYiH3EwthsNA\n\tkgCKHDuazUvC4/gpOpAoU0g8rj30iz8RS7zrDUF3rGvZex4fZOaBRXlYG7WgNspqZwHlTjdpxQX\n\tZpubvMXzng0xoP7+KhRKaWqSmC/dt59A8GPlfrJsfL5ZfEz2xzFS2ZWMRwpt8Mb2z5nZlG5S9rI\n\ttVp0m6eDf+F5I5mTyh1rY+kynxL+Q19CUb4Q9zBc4mtSVYLBHoYNcbUYIIhz7BRviBCMP2HjOq7\n\tEa/3GTTwkXm2vLNPhMQ==","X-Proofpoint-Virus-Version":"vendor=baseguard\n\tengine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51,\n\tFMLib:17.12.100.49\n\tdefinitions=2026-05-15_01,2026-05-13_01,2025-10-01_01","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n\tphishscore=0 priorityscore=1501 spamscore=0 adultscore=0\n\tsuspectscore=0\n\tbulkscore=0 clxscore=1015 impostorscore=0 malwarescore=0\n\tlowpriorityscore=0\n\tclassifier=typeunknown authscore=0 authtc= authcc= route=outbound\n\tadjust=0\n\treason=mlx scancount=1 engine=8.22.0-2605130000\n\tdefinitions=main-2605150074","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>"}}]