Patch Detail
Show a patch.
GET /api/patches/10576/?format=api
{ "id": 10576, "url": "https://patchwork.libcamera.org/api/patches/10576/?format=api", "web_url": "https://patchwork.libcamera.org/patch/10576/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/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": "<20201205103106.242080-14-paul.elder@ideasonboard.com>", "date": "2020-12-05T10:30:56", "name": "[libcamera-devel,v5,13/23] libcamera: IPAProxy, IPAManager: Switch to one-proxy-per-pipeline scheme", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "ee6fbee2672f6dc35bf1fd33ba7ba9e08746ad76", "submitter": { "id": 17, "url": "https://patchwork.libcamera.org/api/people/17/?format=api", "name": "Paul Elder", "email": "paul.elder@ideasonboard.com" }, "delegate": { "id": 17, "url": "https://patchwork.libcamera.org/api/users/17/?format=api", "username": "epaul", "first_name": "Paul", "last_name": "Elder", "email": "paul.elder@ideasonboard.com" }, "mbox": "https://patchwork.libcamera.org/patch/10576/mbox/", "series": [ { "id": 1506, "url": "https://patchwork.libcamera.org/api/series/1506/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1506", "date": "2020-12-05T10:30:43", "name": "IPA isolation implementation", "version": 5, "mbox": "https://patchwork.libcamera.org/series/1506/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/10576/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/10576/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 3C4FEBDB20\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 5 Dec 2020 10:31:48 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 08C3F6360F;\n\tSat, 5 Dec 2020 11:31:48 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C2D11635F0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 5 Dec 2020 11:31:46 +0100 (CET)", "from pyrite.rasen.tech (unknown\n\t[IPv6:2400:4051:61:600:2c71:1b79:d06d:5032])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6E68E2A4;\n\tSat, 5 Dec 2020 11:31:44 +0100 (CET)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"n/C8EgtO\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1607164306;\n\tbh=EtNH7PZMfA/JHREhAkHthp1FSY+sCW7FCCBbIK+/2u0=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=n/C8EgtOv15ma0Gk+ilLB40KBmSCPAGA/W/JBHX3nIdP2G7oQOn/GLRyKK1KARhyP\n\tvyKtXrxZjnj06zYUGFldfgStFlMTOFhVRAKK0JNVxWRL7VKRykT2elm0s9iiLUhAt/\n\tQMk/1EnqYZKVCB7FqIcvVaIqasK6njaP486oK2TQ=", "From": "Paul Elder <paul.elder@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Sat, 5 Dec 2020 19:30:56 +0900", "Message-Id": "<20201205103106.242080-14-paul.elder@ideasonboard.com>", "X-Mailer": "git-send-email 2.27.0", "In-Reply-To": "<20201205103106.242080-1-paul.elder@ideasonboard.com>", "References": "<20201205103106.242080-1-paul.elder@ideasonboard.com>", "MIME-Version": "1.0", "Subject": "[libcamera-devel] [PATCH v5 13/23] libcamera: IPAProxy,\n\tIPAManager: Switch to one-proxy-per-pipeline scheme", "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>", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "IPAProxy is changed in two major ways:\n- Every pipeline has its own proxy, to support each pipeline's IPA\n interface\n- IPAProxy implementations always encapsulate IPA modules, and switch\n internally for isolation or threaded\n\nThe IPAProxy registration mechanism is removed, as each pipeline will\nhave its own proxy, so the pipeline can pass the specialized class name\nof the IPAProxy to the IPAManager for construction.\n\nIPAManager is changed accordingly to support these changes:\n- createIPA is a template function that takes an IPAProxy class, and\n always returns an IPAProxy\n- IPAManager no longer decides on isolation, and simply creates an\n IPAProxy instance while passing the isolation flag\n\nConsequently, the old IPAProxy classes (IPAProxyThread and\nIPAProxyLinux) are removed. The IPAInterfaceTest is updated to use\nthe new IPAManager interface, and to construct a ProcessManager as no\nsingle global instance is created anymore.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n\n---\n\nSquashed in v5\n\nChanges in v4\n- rename libcamera_generated_headers to libcamera_generated_ipa_headers\n\nChanges in v3:\n- declare ProcessManager\n- add libcamera_generated_headers as dependency to meson\n - otherwise test might build before the generated IPA headers and\n #include will fail\n\nChanges in v2:\n- document isolate argument\n- remove documentation\n\n---\n\nThis is a combination of 7 commits:\n\n---\n\nlibcamera: IPAProxy: Add isolate parameter to create()\n\nSince IPAProxy implementations now always encapsulate IPA modules, add a\nparameter to create() to signal if the proxy should isolate the IPA or not.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n---\n\nlibcamera: IPAManager: Fetch IPAProxy corresponding to pipeline\n\nNow that each pipeline handler has its own IPAProxy implementation, make\nthe IPAManager fetch the IPAProxy based on the pipeline handler name.\nAlso, since the IPAProxy is used regardless of isolation or no\nisolation, remove the isolation check from the proxy selection.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\n---\n\nlibcamera: IPAManager: add isolation flag to proxy creation\n\nWhen the IPA proxy is created, it needs to know whether to isolate or\nnot. Feed the flag at creation of the IPA proxy.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n---\n\nlibcamera: IPAManager: Make createIPA return proxy directly\n\nSince every pipeline knows the type of the proxy that it needs, and\nsince all IPAs are to be wrapped in a proxy, IPAManager no longer needs\nto search in the factory list to fetch the proxy factory to construct a\nfactory. Instead, we define createIPA as a template function, and the\npipeline handler can declare the proxy type when it calls createIPA.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n---\n\nlibcamera: IPAProxy: Remove registration mechanism\n\nImplementations of IPA proxies use a registration mechanism to register\nthemselves with the main IPA proxy factory. This registration declares\nstatic objects, causing a risk of things being constructed before the\nproper libcamera facilities are ready. Since each pipeline handler has\nits own IPA proxy and knows the type, it isn't necessary to have a proxy\nfactory. Remove it to alleviate the risk of early construction.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n---\n\nlibcamera: proxy: Remove IPAProxyLinux and IPAProxyThread\n\nWe have now changed the proxy from per-IPC mechanism to per-pipeline.\nThe per-IPC mechanism proxies are thus no longer needed; remove them.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n---\n\ntests: ipa_interface_test: Update to use new createIPA\n\nUpdate the IPA interface test to use the new createIPA function from\nIPAManager. Also create an instance of ProcessManager, as no single\nglobal instance is created automatically anymore. Update meson.build to\nto depend on the generated IPA interface headers.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n Documentation/Doxyfile.in | 1 -\n include/libcamera/internal/ipa_manager.h | 31 +++-\n include/libcamera/internal/ipa_proxy.h | 29 ---\n src/libcamera/ipa_manager.cpp | 47 +----\n src/libcamera/ipa_proxy.cpp | 91 ---------\n src/libcamera/proxy/ipa_proxy_linux.cpp | 103 -----------\n src/libcamera/proxy/ipa_proxy_thread.cpp | 172 ------------------\n src/libcamera/proxy/meson.build | 5 -\n .../proxy/worker/ipa_proxy_linux_worker.cpp | 90 ---------\n src/libcamera/proxy/worker/meson.build | 4 -\n test/ipa/ipa_interface_test.cpp | 8 +-\n test/ipa/meson.build | 2 +-\n 12 files changed, 36 insertions(+), 547 deletions(-)\n delete mode 100644 src/libcamera/proxy/ipa_proxy_linux.cpp\n delete mode 100644 src/libcamera/proxy/ipa_proxy_thread.cpp\n delete mode 100644 src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp", "diff": "diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in\nindex 36a0cef3..9126a11d 100644\n--- a/Documentation/Doxyfile.in\n+++ b/Documentation/Doxyfile.in\n@@ -842,7 +842,6 @@ EXCLUDE = @TOP_SRCDIR@/include/libcamera/span.h \\\n \t\t\t @TOP_SRCDIR@/src/libcamera/device_enumerator_udev.cpp \\\n \t\t\t @TOP_SRCDIR@/src/libcamera/ipc_pipe_unixsocket.cpp \\\n \t\t\t @TOP_SRCDIR@/src/libcamera/pipeline/ \\\n-\t\t\t @TOP_SRCDIR@/src/libcamera/proxy/ \\\n \t\t\t @TOP_SRCDIR@/src/libcamera/tracepoints.cpp \\\n \t\t\t @TOP_BUILDDIR@/include/libcamera/internal/tracepoints.h \\\n \t\t\t @TOP_BUILDDIR@/include/libcamera/ipa/ \\\ndiff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\nindex 4a143b6a..e904a2be 100644\n--- a/include/libcamera/internal/ipa_manager.h\n+++ b/include/libcamera/internal/ipa_manager.h\n@@ -14,20 +14,45 @@\n #include <libcamera/ipa/ipa_module_info.h>\n \n #include \"libcamera/internal/ipa_module.h\"\n+#include \"libcamera/internal/log.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 IPAManager\n {\n public:\n \tIPAManager();\n \t~IPAManager();\n \n-\tstatic std::unique_ptr<IPAProxy> createIPA(PipelineHandler *pipe,\n-\t\t\t\t\t\t uint32_t maxVersion,\n-\t\t\t\t\t\t uint32_t minVersion);\n+\ttemplate<typename T>\n+\tstatic std::unique_ptr<T> createIPA(PipelineHandler *pipe,\n+\t\t\t\t\t uint32_t maxVersion,\n+\t\t\t\t\t uint32_t minVersion)\n+\t{\n+\t\tIPAModule *m = nullptr;\n+\n+\t\tfor (IPAModule *module : self_->modules_) {\n+\t\t\tif (module->match(pipe, minVersion, maxVersion)) {\n+\t\t\t\tm = module;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!m)\n+\t\t\treturn nullptr;\n+\n+\t\tstd::unique_ptr<T> proxy = std::make_unique<T>(m, !self_->isSignatureValid(m));\n+\t\tif (!proxy->isValid()) {\n+\t\t\tLOG(IPAManager, Error) << \"Failed to load proxy\";\n+\t\t\treturn nullptr;\n+\t\t}\n+\n+\t\treturn proxy;\n+\t}\n \n private:\n \tstatic IPAManager *self_;\ndiff --git a/include/libcamera/internal/ipa_proxy.h b/include/libcamera/internal/ipa_proxy.h\nindex 59a5b841..f651a3ae 100644\n--- a/include/libcamera/internal/ipa_proxy.h\n+++ b/include/libcamera/internal/ipa_proxy.h\n@@ -36,35 +36,6 @@ private:\n \tIPAModule *ipam_;\n };\n \n-class IPAProxyFactory\n-{\n-public:\n-\tIPAProxyFactory(const char *name);\n-\tvirtual ~IPAProxyFactory() = default;\n-\n-\tvirtual std::unique_ptr<IPAProxy> create(IPAModule *ipam) = 0;\n-\n-\tconst std::string &name() const { return name_; }\n-\n-\tstatic void registerType(IPAProxyFactory *factory);\n-\tstatic std::vector<IPAProxyFactory *> &factories();\n-\n-private:\n-\tstd::string name_;\n-};\n-\n-#define REGISTER_IPA_PROXY(proxy)\t\t\t\\\n-class proxy##Factory final : public IPAProxyFactory\t\\\n-{\t\t\t\t\t\t\t\\\n-public:\t\t\t\t\t\t\t\\\n-\tproxy##Factory() : IPAProxyFactory(#proxy) {}\t\\\n-\tstd::unique_ptr<IPAProxy> create(IPAModule *ipam)\t\\\n-\t{\t\t\t\t\t\t\\\n-\t\treturn std::make_unique<proxy>(ipam);\t\\\n-\t}\t\t\t\t\t\t\\\n-};\t\t\t\t\t\t\t\\\n-static proxy##Factory global_##proxy##Factory;\n-\n } /* namespace libcamera */\n \n #endif /* __LIBCAMERA_INTERNAL_IPA_PROXY_H__ */\ndiff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\nindex ad05b9c9..93d02d94 100644\n--- a/src/libcamera/ipa_manager.cpp\n+++ b/src/libcamera/ipa_manager.cpp\n@@ -245,6 +245,7 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\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 * \\param[in] minVersion Minimum acceptable version of IPA module\n@@ -253,52 +254,6 @@ unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth)\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-std::unique_ptr<IPAProxy> IPAManager::createIPA(PipelineHandler *pipe,\n-\t\t\t\t\t\tuint32_t maxVersion,\n-\t\t\t\t\t\tuint32_t minVersion)\n-{\n-\tIPAModule *m = nullptr;\n-\n-\tfor (IPAModule *module : self_->modules_) {\n-\t\tif (module->match(pipe, minVersion, maxVersion)) {\n-\t\t\tm = module;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\tif (!m)\n-\t\treturn nullptr;\n-\n-\t/*\n-\t * Load and run the IPA module in a thread if it has a valid signature,\n-\t * or isolate it in a separate process otherwise.\n-\t *\n-\t * \\todo Implement a better proxy selection\n-\t */\n-\tconst char *proxyName = self_->isSignatureValid(m)\n-\t\t\t ? \"IPAProxyThread\" : \"IPAProxyLinux\";\n-\tIPAProxyFactory *pf = nullptr;\n-\n-\tfor (IPAProxyFactory *factory : IPAProxyFactory::factories()) {\n-\t\tif (!strcmp(factory->name().c_str(), proxyName)) {\n-\t\t\tpf = factory;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\tif (!pf) {\n-\t\tLOG(IPAManager, Error) << \"Failed to get proxy factory\";\n-\t\treturn nullptr;\n-\t}\n-\n-\tstd::unique_ptr<IPAProxy> proxy = pf->create(m);\n-\tif (!proxy->isValid()) {\n-\t\tLOG(IPAManager, Error) << \"Failed to load proxy\";\n-\t\treturn nullptr;\n-\t}\n-\n-\treturn proxy;\n-}\n \n bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const\n {\ndiff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp\nindex 23be24ad..29c0e9e0 100644\n--- a/src/libcamera/ipa_proxy.cpp\n+++ b/src/libcamera/ipa_proxy.cpp\n@@ -30,17 +30,11 @@ LOG_DEFINE_CATEGORY(IPAProxy)\n * \\brief IPA Proxy\n *\n * Isolate IPA into separate process.\n- *\n- * Every subclass of proxy shall be registered with libcamera using\n- * the REGISTER_IPA_PROXY() macro.\n */\n \n /**\n * \\brief Construct an IPAProxy instance\n * \\param[in] ipam The IPA module\n- *\n- * IPAProxy instances shall be constructed through the IPAProxyFactory::create()\n- * method implemented by the respective factories.\n */\n IPAProxy::IPAProxy(IPAModule *ipam)\n \t: valid_(false), ipam_(ipam)\n@@ -219,89 +213,4 @@ std::string IPAProxy::resolvePath(const std::string &file) const\n * construction.\n */\n \n-/**\n- * \\class IPAProxyFactory\n- * \\brief Registration of IPAProxy classes and creation of instances\n- *\n- * To facilitate discovery and instantiation of IPAProxy classes, the\n- * IPAProxyFactory class maintains a registry of IPAProxy classes. Each\n- * IPAProxy subclass shall register itself using the REGISTER_IPA_PROXY()\n- * macro, which will create a corresponding instance of a IPAProxyFactory\n- * subclass and register it with the static list of factories.\n- */\n-\n-/**\n- * \\brief Construct a IPAProxy factory\n- * \\param[in] name Name of the IPAProxy class\n- *\n- * Creating an instance of the factory registers is with the global list of\n- * factories, accessible through the factories() function.\n- *\n- * The factory \\a name is used for debugging and IPAProxy matching purposes\n- * and shall be unique.\n- */\n-IPAProxyFactory::IPAProxyFactory(const char *name)\n-\t: name_(name)\n-{\n-\tregisterType(this);\n-}\n-\n-/**\n- * \\fn IPAProxyFactory::create()\n- * \\brief Create an instance of the IPAProxy corresponding to the factory\n- * \\param[in] ipam The IPA module\n- *\n- * This virtual function is implemented by the REGISTER_IPA_PROXY() macro.\n- * It creates a IPAProxy instance that isolates an IPA interface designated\n- * by the IPA module \\a ipam.\n- *\n- * \\return A pointer to a newly constructed instance of the IPAProxy subclass\n- * corresponding to the factory\n- */\n-\n-/**\n- * \\fn IPAProxyFactory::name()\n- * \\brief Retrieve the factory name\n- * \\return The factory name\n- */\n-\n-/**\n- * \\brief Add a IPAProxy class to the registry\n- * \\param[in] factory Factory to use to construct the IPAProxy\n- *\n- * The caller is responsible to guarantee the uniqueness of the IPAProxy name.\n- */\n-void IPAProxyFactory::registerType(IPAProxyFactory *factory)\n-{\n-\tstd::vector<IPAProxyFactory *> &factories = IPAProxyFactory::factories();\n-\n-\tfactories.push_back(factory);\n-\n-\tLOG(IPAProxy, Debug)\n-\t\t<< \"Registered proxy \\\"\" << factory->name() << \"\\\"\";\n-}\n-\n-/**\n- * \\brief Retrieve the list of all IPAProxy factories\n- *\n- * The static factories map is defined inside the function to ensure it gets\n- * initialized on first use, without any dependency on link order.\n- *\n- * \\return The list of pipeline handler factories\n- */\n-std::vector<IPAProxyFactory *> &IPAProxyFactory::factories()\n-{\n-\tstatic std::vector<IPAProxyFactory *> factories;\n-\treturn factories;\n-}\n-\n-/**\n- * \\def REGISTER_IPA_PROXY\n- * \\brief Register a IPAProxy with the IPAProxy factory\n- * \\param[in] proxy Class name of IPAProxy derived class to register\n- *\n- * Register a proxy subclass with the factory and make it available to\n- * isolate IPA modules.\n- */\n-\n } /* namespace libcamera */\ndiff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp\ndeleted file mode 100644\nindex b78a0e45..00000000\n--- a/src/libcamera/proxy/ipa_proxy_linux.cpp\n+++ /dev/null\n@@ -1,103 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2019, Google Inc.\n- *\n- * ipa_proxy_linux.cpp - Default Image Processing Algorithm proxy for Linux\n- */\n-\n-#include <vector>\n-\n-#include <libcamera/ipa/ipa_interface.h>\n-#include <libcamera/ipa/ipa_module_info.h>\n-\n-#include \"libcamera/internal/ipa_module.h\"\n-#include \"libcamera/internal/ipa_proxy.h\"\n-#include \"libcamera/internal/ipc_unixsocket.h\"\n-#include \"libcamera/internal/log.h\"\n-#include \"libcamera/internal/process.h\"\n-\n-namespace libcamera {\n-\n-LOG_DECLARE_CATEGORY(IPAProxy)\n-\n-class IPAProxyLinux : public IPAProxy\n-{\n-public:\n-\tIPAProxyLinux(IPAModule *ipam);\n-\t~IPAProxyLinux();\n-\n-\tint init([[maybe_unused]] const IPASettings &settings) override\n-\t{\n-\t\treturn 0;\n-\t}\n-\tint start() override { return 0; }\n-\tvoid stop() override {}\n-\tvoid configure([[maybe_unused]] const CameraSensorInfo &sensorInfo,\n-\t\t [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig,\n-\t\t [[maybe_unused]] const std::map<unsigned int, const ControlInfoMap &> &entityControls,\n-\t\t [[maybe_unused]] const IPAOperationData &ipaConfig,\n-\t\t [[maybe_unused]] IPAOperationData *result) override {}\n-\tvoid mapBuffers([[maybe_unused]] const std::vector<IPABuffer> &buffers) override {}\n-\tvoid unmapBuffers([[maybe_unused]] const std::vector<unsigned int> &ids) override {}\n-\tvoid processEvent([[maybe_unused]] const IPAOperationData &event) override {}\n-\n-private:\n-\tvoid readyRead(IPCUnixSocket *ipc);\n-\n-\tProcess *proc_;\n-\n-\tIPCUnixSocket *socket_;\n-};\n-\n-IPAProxyLinux::IPAProxyLinux(IPAModule *ipam)\n-\t: IPAProxy(ipam), proc_(nullptr), socket_(nullptr)\n-{\n-\tLOG(IPAProxy, Debug)\n-\t\t<< \"initializing dummy proxy: loading IPA from \"\n-\t\t<< ipam->path();\n-\n-\tstd::vector<int> fds;\n-\tstd::vector<std::string> args;\n-\targs.push_back(ipam->path());\n-\tconst std::string path = resolvePath(\"ipa_proxy_linux\");\n-\tif (path.empty()) {\n-\t\tLOG(IPAProxy, Error)\n-\t\t\t<< \"Failed to get proxy worker path\";\n-\t\treturn;\n-\t}\n-\n-\tsocket_ = new IPCUnixSocket();\n-\tint fd = socket_->create();\n-\tif (fd < 0) {\n-\t\tLOG(IPAProxy, Error)\n-\t\t\t<< \"Failed to create socket\";\n-\t\treturn;\n-\t}\n-\tsocket_->readyRead.connect(this, &IPAProxyLinux::readyRead);\n-\targs.push_back(std::to_string(fd));\n-\tfds.push_back(fd);\n-\n-\tproc_ = new Process();\n-\tint ret = proc_->start(path, args, fds);\n-\tif (ret) {\n-\t\tLOG(IPAProxy, Error)\n-\t\t\t<< \"Failed to start proxy worker process\";\n-\t\treturn;\n-\t}\n-\n-\tvalid_ = true;\n-}\n-\n-IPAProxyLinux::~IPAProxyLinux()\n-{\n-\tdelete proc_;\n-\tdelete socket_;\n-}\n-\n-void IPAProxyLinux::readyRead([[maybe_unused]] IPCUnixSocket *ipc)\n-{\n-}\n-\n-REGISTER_IPA_PROXY(IPAProxyLinux)\n-\n-} /* namespace libcamera */\ndiff --git a/src/libcamera/proxy/ipa_proxy_thread.cpp b/src/libcamera/proxy/ipa_proxy_thread.cpp\ndeleted file mode 100644\nindex eead2883..00000000\n--- a/src/libcamera/proxy/ipa_proxy_thread.cpp\n+++ /dev/null\n@@ -1,172 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2020, Google Inc.\n- *\n- * ipa_proxy_thread.cpp - Proxy running an Image Processing Algorithm in a thread\n- */\n-\n-#include <memory>\n-\n-#include <libcamera/ipa/ipa_interface.h>\n-#include <libcamera/ipa/ipa_module_info.h>\n-\n-#include \"libcamera/internal/ipa_context_wrapper.h\"\n-#include \"libcamera/internal/ipa_module.h\"\n-#include \"libcamera/internal/ipa_proxy.h\"\n-#include \"libcamera/internal/log.h\"\n-#include \"libcamera/internal/thread.h\"\n-\n-namespace libcamera {\n-\n-LOG_DECLARE_CATEGORY(IPAProxy)\n-\n-class IPAProxyThread : public IPAProxy, public Object\n-{\n-public:\n-\tIPAProxyThread(IPAModule *ipam);\n-\n-\tint init(const IPASettings &settings) override;\n-\tint start() override;\n-\tvoid stop() override;\n-\n-\tvoid configure(const CameraSensorInfo &sensorInfo,\n-\t\t const std::map<unsigned int, IPAStream> &streamConfig,\n-\t\t const std::map<unsigned int, const ControlInfoMap &> &entityControls,\n-\t\t const IPAOperationData &ipaConfig,\n-\t\t IPAOperationData *result) override;\n-\tvoid mapBuffers(const std::vector<IPABuffer> &buffers) override;\n-\tvoid unmapBuffers(const std::vector<unsigned int> &ids) override;\n-\tvoid processEvent(const IPAOperationData &event) override;\n-\n-private:\n-\tvoid queueFrameAction(unsigned int frame, const IPAOperationData &data);\n-\n-\t/* Helper class to invoke processEvent() in another thread. */\n-\tclass ThreadProxy : public Object\n-\t{\n-\tpublic:\n-\t\tvoid setIPA(IPAInterface *ipa)\n-\t\t{\n-\t\t\tipa_ = ipa;\n-\t\t}\n-\n-\t\tint start()\n-\t\t{\n-\t\t\treturn ipa_->start();\n-\t\t}\n-\n-\t\tvoid stop()\n-\t\t{\n-\t\t\tipa_->stop();\n-\t\t}\n-\n-\t\tvoid processEvent(const IPAOperationData &event)\n-\t\t{\n-\t\t\tipa_->processEvent(event);\n-\t\t}\n-\n-\tprivate:\n-\t\tIPAInterface *ipa_;\n-\t};\n-\n-\tbool running_;\n-\tThread thread_;\n-\tThreadProxy proxy_;\n-\tstd::unique_ptr<IPAInterface> ipa_;\n-};\n-\n-IPAProxyThread::IPAProxyThread(IPAModule *ipam)\n-\t: IPAProxy(ipam), running_(false)\n-{\n-\tif (!ipam->load())\n-\t\treturn;\n-\n-\tstruct ipa_context *ctx = ipam->createContext();\n-\tif (!ctx) {\n-\t\tLOG(IPAProxy, Error)\n-\t\t\t<< \"Failed to create IPA context for \" << ipam->path();\n-\t\treturn;\n-\t}\n-\n-\tipa_ = std::make_unique<IPAContextWrapper>(ctx);\n-\tproxy_.setIPA(ipa_.get());\n-\n-\t/*\n-\t * Proxy the queueFrameAction signal to dispatch it in the caller's\n-\t * thread.\n-\t */\n-\tipa_->queueFrameAction.connect(this, &IPAProxyThread::queueFrameAction);\n-\n-\tvalid_ = true;\n-}\n-\n-int IPAProxyThread::init(const IPASettings &settings)\n-{\n-\tint ret = ipa_->init(settings);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tproxy_.moveToThread(&thread_);\n-\n-\treturn 0;\n-}\n-\n-int IPAProxyThread::start()\n-{\n-\trunning_ = true;\n-\tthread_.start();\n-\n-\treturn proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking);\n-}\n-\n-void IPAProxyThread::stop()\n-{\n-\tif (!running_)\n-\t\treturn;\n-\n-\trunning_ = false;\n-\n-\tproxy_.invokeMethod(&ThreadProxy::stop, ConnectionTypeBlocking);\n-\n-\tthread_.exit();\n-\tthread_.wait();\n-}\n-\n-void IPAProxyThread::configure(const CameraSensorInfo &sensorInfo,\n-\t\t\t const std::map<unsigned int, IPAStream> &streamConfig,\n-\t\t\t const std::map<unsigned int, const ControlInfoMap &> &entityControls,\n-\t\t\t const IPAOperationData &ipaConfig,\n-\t\t\t IPAOperationData *result)\n-{\n-\tipa_->configure(sensorInfo, streamConfig, entityControls, ipaConfig,\n-\t\t\tresult);\n-}\n-\n-void IPAProxyThread::mapBuffers(const std::vector<IPABuffer> &buffers)\n-{\n-\tipa_->mapBuffers(buffers);\n-}\n-\n-void IPAProxyThread::unmapBuffers(const std::vector<unsigned int> &ids)\n-{\n-\tipa_->unmapBuffers(ids);\n-}\n-\n-void IPAProxyThread::processEvent(const IPAOperationData &event)\n-{\n-\tif (!running_)\n-\t\treturn;\n-\n-\t/* Dispatch the processEvent() call to the thread. */\n-\tproxy_.invokeMethod(&ThreadProxy::processEvent, ConnectionTypeQueued,\n-\t\t\t event);\n-}\n-\n-void IPAProxyThread::queueFrameAction(unsigned int frame, const IPAOperationData &data)\n-{\n-\tIPAInterface::queueFrameAction.emit(frame, data);\n-}\n-\n-REGISTER_IPA_PROXY(IPAProxyThread)\n-\n-} /* namespace libcamera */\ndiff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build\nindex ac68ad08..5965589f 100644\n--- a/src/libcamera/proxy/meson.build\n+++ b/src/libcamera/proxy/meson.build\n@@ -1,10 +1,5 @@\n # SPDX-License-Identifier: CC0-1.0\n \n-libcamera_sources += files([\n- 'ipa_proxy_linux.cpp',\n- 'ipa_proxy_thread.cpp',\n-])\n-\n # generate ipa_proxy_{pipeline}.cpp\n foreach mojom : ipa_mojoms\n proxy = custom_target(mojom['name'] + '_proxy_cpp',\ndiff --git a/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp b/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp\ndeleted file mode 100644\nindex bdbac988..00000000\n--- a/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp\n+++ /dev/null\n@@ -1,90 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2019, Google Inc.\n- *\n- * ipa_proxy_linux_worker.cpp - Default Image Processing Algorithm proxy worker for Linux\n- */\n-\n-#include <iostream>\n-#include <sys/types.h>\n-#include <unistd.h>\n-\n-#include <libcamera/ipa/ipa_interface.h>\n-#include <libcamera/logging.h>\n-\n-#include \"libcamera/internal/event_dispatcher.h\"\n-#include \"libcamera/internal/ipa_module.h\"\n-#include \"libcamera/internal/ipc_unixsocket.h\"\n-#include \"libcamera/internal/log.h\"\n-#include \"libcamera/internal/thread.h\"\n-\n-using namespace libcamera;\n-\n-LOG_DEFINE_CATEGORY(IPAProxyLinuxWorker)\n-\n-void readyRead(IPCUnixSocket *ipc)\n-{\n-\tIPCUnixSocket::Payload message;\n-\tint ret;\n-\n-\tret = ipc->receive(&message);\n-\tif (ret) {\n-\t\tLOG(IPAProxyLinuxWorker, Error)\n-\t\t\t<< \"Receive message failed: \" << ret;\n-\t\treturn;\n-\t}\n-\n-\tLOG(IPAProxyLinuxWorker, Debug) << \"Received a message!\";\n-}\n-\n-int main(int argc, char **argv)\n-{\n-\t/* Uncomment this for debugging. */\n-#if 0\n-\tstd::string logPath = \"/tmp/libcamera.worker.\" +\n-\t\t\t std::to_string(getpid()) + \".log\";\n-\tlogSetFile(logPath.c_str());\n-#endif\n-\n-\tif (argc < 3) {\n-\t\tLOG(IPAProxyLinuxWorker, Debug)\n-\t\t\t<< \"Tried to start worker with no args\";\n-\t\treturn EXIT_FAILURE;\n-\t}\n-\n-\tint fd = std::stoi(argv[2]);\n-\tLOG(IPAProxyLinuxWorker, Debug)\n-\t\t<< \"Starting worker for IPA module \" << argv[1]\n-\t\t<< \" with IPC fd = \" << fd;\n-\n-\tstd::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]);\n-\tif (!ipam->isValid() || !ipam->load()) {\n-\t\tLOG(IPAProxyLinuxWorker, Error)\n-\t\t\t<< \"IPAModule \" << argv[1] << \" should be valid but isn't\";\n-\t\treturn EXIT_FAILURE;\n-\t}\n-\n-\tIPCUnixSocket socket;\n-\tif (socket.bind(fd) < 0) {\n-\t\tLOG(IPAProxyLinuxWorker, Error) << \"IPC socket binding failed\";\n-\t\treturn EXIT_FAILURE;\n-\t}\n-\tsocket.readyRead.connect(&readyRead);\n-\n-\tstruct ipa_context *ipac = ipam->createContext();\n-\tif (!ipac) {\n-\t\tLOG(IPAProxyLinuxWorker, Error) << \"Failed to create IPA context\";\n-\t\treturn EXIT_FAILURE;\n-\t}\n-\n-\tLOG(IPAProxyLinuxWorker, Debug) << \"Proxy worker successfully started\";\n-\n-\t/* \\todo upgrade listening loop */\n-\tEventDispatcher *dispatcher = Thread::current()->eventDispatcher();\n-\twhile (1)\n-\t\tdispatcher->processEvents();\n-\n-\tipac->ops->destroy(ipac);\n-\n-\treturn 0;\n-}\ndiff --git a/src/libcamera/proxy/worker/meson.build b/src/libcamera/proxy/worker/meson.build\nindex 8e0b978a..f3129b76 100644\n--- a/src/libcamera/proxy/worker/meson.build\n+++ b/src/libcamera/proxy/worker/meson.build\n@@ -1,9 +1,5 @@\n # SPDX-License-Identifier: CC0-1.0\n \n-ipa_proxy_sources = [\n- ['ipa_proxy_linux', 'ipa_proxy_linux_worker.cpp']\n-]\n-\n proxy_install_dir = join_paths(get_option('libexecdir'), 'libcamera')\n \n # generate ipa_proxy_{pipeline}_worker.cpp\ndiff --git a/test/ipa/ipa_interface_test.cpp b/test/ipa/ipa_interface_test.cpp\nindex 9f575f93..45d322f4 100644\n--- a/test/ipa/ipa_interface_test.cpp\n+++ b/test/ipa/ipa_interface_test.cpp\n@@ -13,6 +13,7 @@\n #include <unistd.h>\n \n #include <libcamera/ipa/vimc.h>\n+#include <libcamera/ipa/vimc_ipa_proxy.h>\n \n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/event_dispatcher.h\"\n@@ -20,6 +21,7 @@\n #include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/ipa_module.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n+#include \"libcamera/internal/process.h\"\n #include \"libcamera/internal/thread.h\"\n #include \"libcamera/internal/timer.h\"\n \n@@ -95,7 +97,7 @@ protected:\n \t\tEventDispatcher *dispatcher = thread()->eventDispatcher();\n \t\tTimer timer;\n \n-\t\tipa_ = IPAManager::createIPA(pipe_.get(), 0, 0);\n+\t\tipa_ = IPAManager::createIPA<IPAProxyVimc>(pipe_.get(), 0, 0);\n \t\tif (!ipa_) {\n \t\t\tcerr << \"Failed to create VIMC IPA interface\" << endl;\n \t\t\treturn TestFail;\n@@ -163,8 +165,10 @@ private:\n \t\t}\n \t}\n \n+\tProcessManager processManager_;\n+\n \tstd::shared_ptr<PipelineHandler> pipe_;\n-\tstd::unique_ptr<IPAProxy> ipa_;\n+\tstd::unique_ptr<IPAProxyVimc> ipa_;\n \tstd::unique_ptr<IPAManager> ipaManager_;\n \tenum IPAOperationCode trace_;\n \tEventNotifier *notifier_;\ndiff --git a/test/ipa/meson.build b/test/ipa/meson.build\nindex e4f0818a..e8a041b5 100644\n--- a/test/ipa/meson.build\n+++ b/test/ipa/meson.build\n@@ -6,7 +6,7 @@ ipa_test = [\n ]\n \n foreach t : ipa_test\n- exe = executable(t[0], t[1],\n+ exe = executable(t[0], [t[1], libcamera_generated_ipa_headers],\n dependencies : libcamera_dep,\n link_with : [libipa, test_libraries],\n include_directories : [libipa_includes, test_includes_internal])\n", "prefixes": [ "libcamera-devel", "v5", "13/23" ] }