[{"id":12589,"web_url":"https://patchwork.libcamera.org/comment/12589/","msgid":"<20200919124358.GV1850958@oden.dyn.berto.se>","date":"2020-09-19T12:43:58","subject":"Re: [libcamera-devel] [PATCH 20/23] libcamera: proxy: Remove\n\tIPAProxyLinux and IPAProxyThread","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Paul,\n\nThanks for your work.\n\nOn 2020-09-15 23:20:35 +0900, Paul Elder wrote:\n> We have now changed the proxy from per-IPC mechanism to per-pipeline.\n> The per-IPC mechanism proxies are thus no longer needed; remove them.\n> \n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\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        |   3 -\n>  5 files changed, 373 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\n> \n> diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp\n> deleted file mode 100644\n> index 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 */\n> diff --git a/src/libcamera/proxy/ipa_proxy_thread.cpp b/src/libcamera/proxy/ipa_proxy_thread.cpp\n> deleted file mode 100644\n> index 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 */\n> diff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build\n> index b0d35646..cfec0567 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>  ipa_proxy_sources = []\n>  \n> diff --git a/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp b/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp\n> deleted file mode 100644\n> index 0c4687f7..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/event_dispatcher.h>\n> -#include <libcamera/ipa/ipa_interface.h>\n> -#include <libcamera/logging.h>\n> -\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> -}\n> diff --git a/src/libcamera/proxy/worker/meson.build b/src/libcamera/proxy/worker/meson.build\n> index c35be70c..db463065 100644\n> --- a/src/libcamera/proxy/worker/meson.build\n> +++ b/src/libcamera/proxy/worker/meson.build\n> @@ -1,8 +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>  # generate ipa_proxy_{pipeline}_worker.cpp\n>  ipa_proxy_sources = {}\n> -- \n> 2.27.0\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","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 1848FBF01C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 19 Sep 2020 12:44:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DD9A362FBC;\n\tSat, 19 Sep 2020 14:44:00 +0200 (CEST)","from mail-lf1-x143.google.com (mail-lf1-x143.google.com\n\t[IPv6:2a00:1450:4864:20::143])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B87E360367\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 19 Sep 2020 14:43:59 +0200 (CEST)","by mail-lf1-x143.google.com with SMTP id y2so9029137lfy.10\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 19 Sep 2020 05:43:59 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tq13sm1265172lfa.286.2020.09.19.05.43.58\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSat, 19 Sep 2020 05:43:58 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"kbnMEzCl\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=XoOnulZQCZZrisau4wCoYV8PIm16EW6+Pk/BD+GpPkA=;\n\tb=kbnMEzClT/6IeCjicAm0sSBTAARxtGnfUb2+IK1s0CkMkSjibecAO/Z15NBstB6hhv\n\tR+YkBNf+cuTT9T6J4IB3l3dW4mfQYBRXDwMzgiEvWBSIx8t+MJb0LMS2HV7x4V4WfsK2\n\t3Af8njPvaWH7bIb7kiXC+o7mydEwS4tdhc+r8Ub5Yht+4AozL5xHVBDUuYyhpJcyLMJK\n\txx21srJijMyA3qFXC/nJaqYoYZM9SwqBuR1OkIVr2iuujvJg0sdbAxWdhSX37dlNpuBg\n\tZLgzbCq4XKoz/E3tXiycil0b+Enwcgm3E3q1IcRmFfCBs4oIissO2ddG8lkyvLoOpldt\n\tAK/Q==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=XoOnulZQCZZrisau4wCoYV8PIm16EW6+Pk/BD+GpPkA=;\n\tb=OjqwwYbp0fYL+S0arYmwIUv9Ls1LCStdEVv3eG/8GVi07bhew7lDy1XivgUWEzu1ZG\n\tQDEnUnV88C6Pr752ZykGsDSxF1UvLh1oTyBsbMuMRfZhXHWIvtIr8n+OBVNV6yEFY7qK\n\t080/dUbpn9FtY9/t24l4Ss3cUkOYixOMIj4vQMkIT4Wz2Z4GcWEt96lMQECXX0OZvhSi\n\tOUQC+eJK5ifXHUPmGiRzyVeR6o8x4DBFo0iXfKUwEAVSaF6BuWnrSOnWefa3TkHfrP2F\n\tnaFaowPRU8lOsIIyWAMiJmcra3bPvJbJ8mL8bMqRlQ3wscIgMMoYrNSTjhNqsdEBd7px\n\tTYIw==","X-Gm-Message-State":"AOAM531hwxS7wYXcXHEq9loO/+zVo4KBH/ZzSXqxV8ILGHbTZWlaHGTu\n\tDiipAjZXNCCz+/snTojDfC22uw==","X-Google-Smtp-Source":"ABdhPJzmcFNSrSDT8YvhsF3lrnb6TEgKCcyG6fPDYBc/QWzwHqHHOyE4dWPLG62GlWyFhUZ8jxElNA==","X-Received":"by 2002:a19:85c4:: with SMTP id\n\th187mr9904860lfd.320.1600519439009; \n\tSat, 19 Sep 2020 05:43:59 -0700 (PDT)","Date":"Sat, 19 Sep 2020 14:43:58 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Paul Elder <paul.elder@ideasonboard.com>","Message-ID":"<20200919124358.GV1850958@oden.dyn.berto.se>","References":"<20200915142038.28757-1-paul.elder@ideasonboard.com>\n\t<20200915142038.28757-21-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200915142038.28757-21-paul.elder@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 20/23] libcamera: proxy: Remove\n\tIPAProxyLinux and IPAProxyThread","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]