Patch Detail
Show a patch.
GET /api/1.1/patches/26444/?format=api
{ "id": 26444, "url": "https://patchwork.libcamera.org/api/1.1/patches/26444/?format=api", "web_url": "https://patchwork.libcamera.org/patch/26444/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260407153427.1825999-5-laurent.pinchart@ideasonboard.com>", "date": "2026-04-07T15:33:49", "name": "[v2,04/42] libcamera: pipeline_handler: Add createIPA() function", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "2bec9f55dc40d7d4fe2fc8c73c87df5ddc473d44", "submitter": { "id": 2, "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api", "name": "Laurent Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/26444/mbox/", "series": [ { "id": 5873, "url": "https://patchwork.libcamera.org/api/1.1/series/5873/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5873", "date": "2026-04-07T15:33:45", "name": "libcamera: Global configuration file improvements", "version": 2, "mbox": "https://patchwork.libcamera.org/series/5873/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/26444/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/26444/checks/", "tags": {}, "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 82E2DBDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 7 Apr 2026 15:34:40 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 511B262DAB;\n\tTue, 7 Apr 2026 17:34:39 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 148CA62DA5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 7 Apr 2026 17:34:34 +0200 (CEST)", "from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 77BC56A6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 7 Apr 2026 17:33:06 +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=\"MYKqL4Fo\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1775575986;\n\tbh=u15Vd1kV4ZYY8y9yeM0esvzrrLktDSirH1g7l59rCZA=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=MYKqL4Foz0qc0LnsCsOOxTyTNHTLwhaVYLhroi2Ts5PFkmpHC+KgJ6yWh9Ia3/sKg\n\tMLZ33NWRrUes1tzuMpdTMFdttggMetjq0NTbMcy0p7OvdtJZHky0gHZMHTV4wLNDxz\n\tqEMEPPXp50WoBZdc3z+34pICTz3GCg1n8KpJvEPo=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[PATCH v2 04/42] libcamera: pipeline_handler: Add createIPA()\n\tfunction", "Date": "Tue, 7 Apr 2026 18:33:49 +0300", "Message-ID": "<20260407153427.1825999-5-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>", "References": "<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "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>" }, "content": "IPA proxies are created with a call to IPAManager::createIPA(), which is\na static member function. This requires a complicated dance in the\ncreateIPA() function to retrieve the IPAManager instance through the\ncamera manager, itself retrieved from the pipeline handler. Simplify the\ncode by turning IPAManager::createIPA() into a non-static member\nfunction, and providing a wrapper in the PipelineHandler class to keep\ninstantiation of IPA proxies easy in pipeline handlers.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n---\n Documentation/guides/ipa.rst | 8 +++---\n include/libcamera/internal/ipa_manager.h | 25 ++++++++-----------\n include/libcamera/internal/pipeline_handler.h | 11 +++++++-\n src/libcamera/ipa_manager.cpp | 1 +\n src/libcamera/pipeline/ipu3/ipu3.cpp | 3 +--\n src/libcamera/pipeline/mali-c55/mali-c55.cpp | 3 +--\n src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 +--\n .../pipeline/rpi/common/pipeline_base.cpp | 3 +--\n src/libcamera/pipeline/vimc/vimc.cpp | 3 +--\n src/libcamera/pipeline_handler.cpp | 10 ++++++++\n src/libcamera/software_isp/software_isp.cpp | 3 +--\n test/ipa/ipa_interface_test.cpp | 3 +--\n 12 files changed, 43 insertions(+), 33 deletions(-)", "diff": "diff --git a/Documentation/guides/ipa.rst b/Documentation/guides/ipa.rst\nindex 25deadefaf7c..42993924dd79 100644\n--- a/Documentation/guides/ipa.rst\n+++ b/Documentation/guides/ipa.rst\n@@ -387,20 +387,20 @@ In the pipeline handler, we first need to construct a specialized IPA proxy.\n From the point of view of the pipeline hander, this is the object that is the\n IPA.\n \n-To do so, we invoke the IPAManager:\n+To do so, we call the PipelineHandler::createIPA() function:\n \n .. code-block:: C++\n \n std::unique_ptr<ipa::rpi::IPAProxyRPi> ipa_ =\n- IPAManager::createIPA<ipa::rpi::IPAProxyRPi>(pipe_, 1, 1);\n+ pipe_->createIPA<ipa::rpi::IPAProxyRPi>(1, 1);\n \n The ipa::rpi namespace comes from the namespace that we defined in the mojo\n data definition file, in the \"Namespacing\" section. The name of the proxy,\n IPAProxyRPi, comes from the name given to the main IPA interface,\n IPARPiInterface, in the \"The Main IPA interface\" section.\n \n-The return value of IPAManager::createIPA shall be error-checked, to confirm\n-that the returned pointer is not a nullptr.\n+The return value of createIPA() shall be error-checked, to confirm that the\n+returned pointer is not a nullptr.\n \n After this, before initializing the IPA, slots should be connected to all of\n the IPA's signals, as defined in the Event IPA interface:\ndiff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\nindex f8ce780169e6..ecb6ae896e0c 100644\n--- a/include/libcamera/internal/ipa_manager.h\n+++ b/include/libcamera/internal/ipa_manager.h\n@@ -17,15 +17,16 @@\n #include <libcamera/ipa/ipa_module_info.h>\n \n #include \"libcamera/internal/camera_manager.h\"\n-#include \"libcamera/internal/global_configuration.h\"\n-#include \"libcamera/internal/ipa_module.h\"\n-#include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/pub_key.h\"\n \n namespace libcamera {\n \n LOG_DECLARE_CATEGORY(IPAManager)\n \n+class GlobalConfiguration;\n+class IPAModule;\n+class PipelineHandler;\n+\n class IPAManager\n {\n public:\n@@ -33,23 +34,18 @@ public:\n \t~IPAManager();\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+\tstd::unique_ptr<T> createIPA(PipelineHandler *pipe, uint32_t minVersion,\n+\t\t\t\t uint32_t maxVersion)\n \t{\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 = module(pipe, minVersion, maxVersion);\n \t\tif (!m)\n \t\t\treturn nullptr;\n \n-\t\tconst GlobalConfiguration &configuration = cm->_d()->configuration();\n-\n \t\tauto proxy = [&]() -> std::unique_ptr<T> {\n-\t\t\tif (self->isSignatureValid(m))\n-\t\t\t\treturn std::make_unique<typename T::Threaded>(m, configuration);\n+\t\t\tif (isSignatureValid(m))\n+\t\t\t\treturn std::make_unique<typename T::Threaded>(m, configuration_);\n \t\t\telse\n-\t\t\t\treturn std::make_unique<typename T::Isolated>(m, configuration);\n+\t\t\t\treturn std::make_unique<typename T::Isolated>(m, configuration_);\n \t\t}();\n \n \t\tif (!proxy->isValid()) {\n@@ -77,6 +73,7 @@ private:\n \n \tbool isSignatureValid(IPAModule *ipa) const;\n \n+\tconst GlobalConfiguration &configuration_;\n \tstd::vector<std::unique_ptr<IPAModule>> modules_;\n \n #if HAVE_IPA_PUBKEY\ndiff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex b4f97477acec..6922ce18ec87 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -17,11 +17,13 @@\n #include <libcamera/controls.h>\n #include <libcamera/stream.h>\n \n+#include \"libcamera/internal/camera_manager.h\"\n+#include \"libcamera/internal/ipa_manager.h\"\n+\n namespace libcamera {\n \n class Camera;\n class CameraConfiguration;\n-class CameraManager;\n class DeviceEnumerator;\n class DeviceMatch;\n class FrameBuffer;\n@@ -70,6 +72,13 @@ public:\n \n \tCameraManager *cameraManager() const { return manager_; }\n \n+\ttemplate<typename T>\n+\tstd::unique_ptr<T> createIPA(uint32_t minVersion, uint32_t maxVersion)\n+\t{\n+\t\tIPAManager *ipaManager = manager_->_d()->ipaManager();\n+\t\treturn ipaManager->createIPA<T>(this, minVersion, maxVersion);\n+\t}\n+\n protected:\n \tvoid registerCamera(std::shared_ptr<Camera> camera);\n \tvoid hotplugMediaDevice(std::shared_ptr<MediaDevice> media);\ndiff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\nindex 35171d097136..1e905e8b82e8 100644\n--- a/src/libcamera/ipa_manager.cpp\n+++ b/src/libcamera/ipa_manager.cpp\n@@ -105,6 +105,7 @@ LOG_DEFINE_CATEGORY(IPAManager)\n * CameraManager.\n */\n IPAManager::IPAManager(const GlobalConfiguration &configuration)\n+\t: configuration_(configuration)\n {\n #if HAVE_IPA_PUBKEY\n \tif (!pubKey_.isValid())\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex bac6f1c2ef40..bf4c2921f2e7 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -31,7 +31,6 @@\n #include \"libcamera/internal/delayed_controls.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/request.h\"\n@@ -1151,7 +1150,7 @@ int PipelineHandlerIPU3::registerCameras()\n \n int IPU3CameraData::loadIPA()\n {\n-\tipa_ = IPAManager::createIPA<ipa::ipu3::IPAProxyIPU3>(pipe(), 1, 1);\n+\tipa_ = pipe()->createIPA<ipa::ipu3::IPAProxyIPU3>(1, 1);\n \tif (!ipa_)\n \t\treturn -ENOENT;\n \ndiff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex c209b0b070b1..e39c8d5aea59 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -35,7 +35,6 @@\n #include \"libcamera/internal/delayed_controls.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/request.h\"\n@@ -382,7 +381,7 @@ int MaliC55CameraData::loadIPA()\n \tif (!sensor_)\n \t\treturn 0;\n \n-\tipa_ = IPAManager::createIPA<ipa::mali_c55::IPAProxyMaliC55>(pipe(), 1, 1);\n+\tipa_ = pipe()->createIPA<ipa::mali_c55::IPAProxyMaliC55>(1, 1);\n \tif (!ipa_)\n \t\treturn -ENOENT;\n \ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex faeeecd96692..a74ac8287199 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -40,7 +40,6 @@\n #include \"libcamera/internal/delayed_controls.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/media_pipeline.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n@@ -389,7 +388,7 @@ const PipelineHandlerRkISP1 *RkISP1CameraData::pipe() const\n \n int RkISP1CameraData::loadIPA(unsigned int hwRevision, uint32_t supportedBlocks)\n {\n-\tipa_ = IPAManager::createIPA<ipa::rkisp1::IPAProxyRkISP1>(pipe(), 1, 1);\n+\tipa_ = pipe()->createIPA<ipa::rkisp1::IPAProxyRkISP1>(1, 1);\n \tif (!ipa_)\n \t\treturn -ENOENT;\n \ndiff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\nindex 867ecf1bc1e3..6d2072e84da5 100644\n--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n@@ -20,7 +20,6 @@\n #include <libcamera/property_ids.h>\n \n #include \"libcamera/internal/camera_lens.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/v4l2_subdevice.h\"\n \n using namespace std::chrono_literals;\n@@ -1161,7 +1160,7 @@ int CameraData::loadIPA(ipa::RPi::InitResult *result)\n {\n \tint ret;\n \n-\tipa_ = IPAManager::createIPA<ipa::RPi::IPAProxyRPi>(pipe(), 1, 1);\n+\tipa_ = pipe()->createIPA<ipa::RPi::IPAProxyRPi>(1, 1);\n \n \tif (!ipa_)\n \t\treturn -ENOENT;\ndiff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\nindex 08b1007528f2..e915d5c2df23 100644\n--- a/src/libcamera/pipeline/vimc/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc/vimc.cpp\n@@ -35,7 +35,6 @@\n #include \"libcamera/internal/camera_sensor.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/request.h\"\n@@ -488,7 +487,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)\n \tif (data->init())\n \t\treturn false;\n \n-\tdata->ipa_ = IPAManager::createIPA<ipa::vimc::IPAProxyVimc>(this, 0, 0);\n+\tdata->ipa_ = createIPA<ipa::vimc::IPAProxyVimc>(0, 0);\n \tif (!data->ipa_) {\n \t\tLOG(VIMC, Error) << \"no matching IPA found\";\n \t\treturn false;\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 5c469e5bad24..e7145c1d4815 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -835,6 +835,16 @@ void PipelineHandler::disconnect()\n * \\return The CameraManager for this pipeline handler\n */\n \n+/**\n+ * \\fn PipelineHandler::createIPA()\n+ * \\brief Create an IPA proxy that matches this pipeline handler\n+ * \\param[in] minVersion Minimum acceptable version of IPA module\n+ * \\param[in] maxVersion Maximum acceptable version of IPA module\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 * \\class PipelineHandlerFactoryBase\n * \\brief Base class for pipeline handler factories\ndiff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\nindex 60228369fe2a..5b225c7cff93 100644\n--- a/src/libcamera/software_isp/software_isp.cpp\n+++ b/src/libcamera/software_isp/software_isp.cpp\n@@ -23,7 +23,6 @@\n \n #include \"libcamera/internal/bayer_format.h\"\n #include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/software_isp/debayer_params.h\"\n \n #include \"debayer_cpu.h\"\n@@ -127,7 +126,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n \tdebayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);\n \tdebayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);\n \n-\tipa_ = IPAManager::createIPA<ipa::soft::IPAProxySoft>(pipe, 0, 0);\n+\tipa_ = pipe->createIPA<ipa::soft::IPAProxySoft>(0, 0);\n \tif (!ipa_) {\n \t\tLOG(SoftwareIsp, Error)\n \t\t\t<< \"Creating IPA for software ISP failed\";\ndiff --git a/test/ipa/ipa_interface_test.cpp b/test/ipa/ipa_interface_test.cpp\nindex b81783664977..ccff6ac106c8 100644\n--- a/test/ipa/ipa_interface_test.cpp\n+++ b/test/ipa/ipa_interface_test.cpp\n@@ -22,7 +22,6 @@\n \n #include \"libcamera/internal/camera_manager.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n-#include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/ipa_module.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n \n@@ -99,7 +98,7 @@ protected:\n \t\tEventDispatcher *dispatcher = thread()->eventDispatcher();\n \t\tTimer timer;\n \n-\t\tipa_ = IPAManager::createIPA<ipa::vimc::IPAProxyVimc>(pipe_.get(), 0, 0);\n+\t\tipa_ = pipe_->createIPA<ipa::vimc::IPAProxyVimc>(0, 0);\n \t\tif (!ipa_) {\n \t\t\tcerr << \"Failed to create VIMC IPA interface\" << endl;\n \t\t\treturn TestFail;\n", "prefixes": [ "v2", "04/42" ] }