Message ID | 20190711185047.11671-6-paul.elder@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Paul, Thank you for the patch. On Fri, Jul 12, 2019 at 03:50:44AM +0900, Paul Elder wrote: > Add a skeletal default linux IPA proxy. It currently lacks the IPA proxy > protocol itself. > > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > --- > This patch depends on "libcamera: logging: add logging API for > applications" > > Changes in v4: > - use logging API to set the log file in the proxy worker > > Changes in v3: > - better logging (both main proxy and proxy worker) > - renamed ProxyLinuxDefault to IPAProxyLinux > - initialize listeners for IPC > > New in v2 > - replaces the dummy/linux default shim > > src/libcamera/meson.build | 7 +- > src/libcamera/proxy/ipa_proxy_linux.cpp | 96 +++++++++++++++++++ > src/libcamera/proxy/meson.build | 3 + > .../proxy/worker/ipa_proxy_linux_worker.cpp | 86 +++++++++++++++++ > src/libcamera/proxy/worker/meson.build | 16 ++++ > 5 files changed, 204 insertions(+), 4 deletions(-) > create mode 100644 src/libcamera/proxy/ipa_proxy_linux.cpp > create mode 100644 src/libcamera/proxy/meson.build > create mode 100644 src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp > create mode 100644 src/libcamera/proxy/worker/meson.build > > diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build > index 3e86edb..6a9d270 100644 > --- a/src/libcamera/meson.build > +++ b/src/libcamera/meson.build > @@ -68,10 +68,7 @@ includes = [ > ] > > subdir('pipeline') > - > -proxy_install_dir = join_paths(get_option('libdir'), 'libcamera', 'proxy') > -config_h.set('IPA_PROXY_DIR', > - '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"') > +subdir('proxy') > > libudev = dependency('libudev', required : false) > > @@ -116,3 +113,5 @@ libcamera = shared_library('camera', > libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h], > include_directories : libcamera_includes, > link_with : libcamera) > + > +subdir('proxy/worker') > diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp > new file mode 100644 > index 0000000..2b3f187 > --- /dev/null > +++ b/src/libcamera/proxy/ipa_proxy_linux.cpp > @@ -0,0 +1,96 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2019, Google Inc. > + * > + * ipa_proxy_linux.cpp - Default Image Processing Algorithm proxy for Linux > + */ > + > +#include <vector> > + > +#include <libcamera/ipa/ipa_interface.h> > +#include <libcamera/ipa/ipa_module_info.h> > + > +#include "ipa_module.h" > +#include "ipa_proxy.h" > +#include "ipc_unixsocket.h" > +#include "log.h" > +#include "process.h" > + > +namespace libcamera { > + > +LOG_DECLARE_CATEGORY(IPAProxy) > + > +class IPAProxyLinux : public IPAProxy > +{ > +public: > + IPAProxyLinux(IPAModule *ipam); > + ~IPAProxyLinux(); > + > + int init(); > + > +private: > + void readyRead(IPCUnixSocket *ipc); > + > + Process *proc_; > + > + IPCUnixSocket *socket_; > +}; > + > +int IPAProxyLinux::init() > +{ > + LOG(IPAProxy, Debug) << "initializing IPA via dummy proxy!"; > + > + return 0; > +} > + > +IPAProxyLinux::IPAProxyLinux(IPAModule *ipam) > +{ > + LOG(IPAProxy, Debug) > + << "initializing dummy proxy: loading IPA from " > + << ipam->path(); > + > + std::vector<int> fds; > + std::vector<std::string> args; > + args.push_back(ipam->path()); > + const std::string path = resolvePath("ipa_proxy_linux"); > + if (path.empty()) { > + LOG(IPAProxy, Error) > + << "Failed to get proxy worker path"; > + return; > + } > + > + socket_ = new IPCUnixSocket(); > + int fd = socket_->create(); > + if (fd < 0) { > + LOG(IPAProxy, Error) > + << "Failed to create socket"; > + return; > + } > + socket_->readyRead.connect(this, &IPAProxyLinux::readyRead); > + args.push_back(std::to_string(fd)); > + fds.push_back(fd); > + > + proc_ = new Process(); > + int ret = proc_->start(path, args, fds); > + if (ret) { > + LOG(IPAProxy, Error) > + << "Failed to start IPAProxyLinux worker process"; s/IPAProxyLinux/proxy/ > + return; > + } > + > + valid_ = true; > +} > + > +IPAProxyLinux::~IPAProxyLinux() > +{ > + delete proc_; > + delete socket_; > +} > + > +void IPAProxyLinux::readyRead(IPCUnixSocket *ipc) > +{ > +} > + > +REGISTER_IPA_PROXY(IPAProxyLinux) > + > +}; /* namespace libcamera */ > diff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build > new file mode 100644 > index 0000000..efc1132 > --- /dev/null > +++ b/src/libcamera/proxy/meson.build > @@ -0,0 +1,3 @@ > +libcamera_sources += files([ > + 'ipa_proxy_linux.cpp', > +]) > diff --git a/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp b/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp > new file mode 100644 > index 0000000..8b7aa74 > --- /dev/null > +++ b/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp > @@ -0,0 +1,86 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Copyright (C) 2019, Google Inc. > + * > + * ipa_proxy_linux_worker.cpp - Default Image Processing Algorithm proxy worker for Linux > + */ > + > +#include <iostream> > +#include <sys/types.h> > +#include <unistd.h> > + > +#include <libcamera/camera_manager.h> > +#include <libcamera/event_dispatcher.h> > +#include <libcamera/ipa/ipa_interface.h> > +#include <libcamera/logging.h> > + > +#include "ipa_module.h" > +#include "ipc_unixsocket.h" > +#include "log.h" > +#include "utils.h" > + > +using namespace libcamera; > + > +LOG_DEFINE_CATEGORY(IPAProxyLinuxWorker) > + > +void readyRead(IPCUnixSocket *ipc) > +{ > + IPCUnixSocket::Payload message; > + int ret; > + > + ret = ipc->receive(&message); > + if (ret) { > + LOG(IPAProxyLinuxWorker, Error) > + << "Receive message failed: " << ret; > + return; > + } > + > + LOG(IPAProxyLinuxWorker, Debug) << "Received a message!"; > +} > + > +int main(int argc, char **argv) > +{ > + std::string logPath = "/tmp/libcamera.process." + s/process/worker/ > + std::to_string(getpid()) + ".log"; > + logSetFile(logPath.c_str()); > + > + if (argc < 3) { > + LOG(IPAProxyLinuxWorker, Debug) > + << "Tried to start worker with no args"; > + return EXIT_FAILURE; > + } > + > + int fd = std::stoi(argv[2]); > + LOG(IPAProxyLinuxWorker, Debug) > + << "Starting worker for IPA module " << argv[1] > + << " with IPC fd = " << fd; > + > + std::unique_ptr<IPAModule> ipam = utils::make_unique<IPAModule>(argv[1]); > + if (!ipam->isValid() || !ipam->load()) { > + LOG(IPAProxyLinuxWorker, Error) > + << "IPAModule " << argv[1] << " should be valid but isn't"; > + return EXIT_FAILURE; > + } > + > + IPCUnixSocket socket; > + if (socket.bind(fd) < 0) { > + LOG(IPAProxyLinuxWorker, Error) << "IPC socket binding failed"; > + return EXIT_FAILURE; > + } > + socket.readyRead.connect(&readyRead); > + > + std::unique_ptr<IPAInterface> ipa = ipam->createInstance(); > + if (!ipa) { > + LOG(IPAProxyLinuxWorker, Error) << "Failed to create IPA interface"; > + return EXIT_FAILURE; > + } > + > + LOG(IPAProxyLinuxWorker, Debug) << "Proxy worker successfully started"; > + > + /* \todo upgrade listening loop */ > + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); > + while (1) > + dispatcher->processEvents(); > + > + return 0; > +} > diff --git a/src/libcamera/proxy/worker/meson.build b/src/libcamera/proxy/worker/meson.build > new file mode 100644 > index 0000000..839156f > --- /dev/null > +++ b/src/libcamera/proxy/worker/meson.build > @@ -0,0 +1,16 @@ > +ipa_proxy_sources = [ > + ['ipa_proxy_linux', 'ipa_proxy_linux_worker.cpp'] > +] > + > +proxy_install_dir = join_paths(get_option('libexecdir'), 'libcamera') > + > +foreach t : ipa_proxy_sources > + proxy = executable(t[0], t[1], > + include_directories : libcamera_internal_includes, > + install : true, > + install_dir : proxy_install_dir, > + dependencies : libcamera_dep) > +endforeach > + > +config_h.set('IPA_PROXY_DIR', > + '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"')
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 3e86edb..6a9d270 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -68,10 +68,7 @@ includes = [ ] subdir('pipeline') - -proxy_install_dir = join_paths(get_option('libdir'), 'libcamera', 'proxy') -config_h.set('IPA_PROXY_DIR', - '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"') +subdir('proxy') libudev = dependency('libudev', required : false) @@ -116,3 +113,5 @@ libcamera = shared_library('camera', libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h], include_directories : libcamera_includes, link_with : libcamera) + +subdir('proxy/worker') diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp new file mode 100644 index 0000000..2b3f187 --- /dev/null +++ b/src/libcamera/proxy/ipa_proxy_linux.cpp @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipa_proxy_linux.cpp - Default Image Processing Algorithm proxy for Linux + */ + +#include <vector> + +#include <libcamera/ipa/ipa_interface.h> +#include <libcamera/ipa/ipa_module_info.h> + +#include "ipa_module.h" +#include "ipa_proxy.h" +#include "ipc_unixsocket.h" +#include "log.h" +#include "process.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(IPAProxy) + +class IPAProxyLinux : public IPAProxy +{ +public: + IPAProxyLinux(IPAModule *ipam); + ~IPAProxyLinux(); + + int init(); + +private: + void readyRead(IPCUnixSocket *ipc); + + Process *proc_; + + IPCUnixSocket *socket_; +}; + +int IPAProxyLinux::init() +{ + LOG(IPAProxy, Debug) << "initializing IPA via dummy proxy!"; + + return 0; +} + +IPAProxyLinux::IPAProxyLinux(IPAModule *ipam) +{ + LOG(IPAProxy, Debug) + << "initializing dummy proxy: loading IPA from " + << ipam->path(); + + std::vector<int> fds; + std::vector<std::string> args; + args.push_back(ipam->path()); + const std::string path = resolvePath("ipa_proxy_linux"); + if (path.empty()) { + LOG(IPAProxy, Error) + << "Failed to get proxy worker path"; + return; + } + + socket_ = new IPCUnixSocket(); + int fd = socket_->create(); + if (fd < 0) { + LOG(IPAProxy, Error) + << "Failed to create socket"; + return; + } + socket_->readyRead.connect(this, &IPAProxyLinux::readyRead); + args.push_back(std::to_string(fd)); + fds.push_back(fd); + + proc_ = new Process(); + int ret = proc_->start(path, args, fds); + if (ret) { + LOG(IPAProxy, Error) + << "Failed to start IPAProxyLinux worker process"; + return; + } + + valid_ = true; +} + +IPAProxyLinux::~IPAProxyLinux() +{ + delete proc_; + delete socket_; +} + +void IPAProxyLinux::readyRead(IPCUnixSocket *ipc) +{ +} + +REGISTER_IPA_PROXY(IPAProxyLinux) + +}; /* namespace libcamera */ diff --git a/src/libcamera/proxy/meson.build b/src/libcamera/proxy/meson.build new file mode 100644 index 0000000..efc1132 --- /dev/null +++ b/src/libcamera/proxy/meson.build @@ -0,0 +1,3 @@ +libcamera_sources += files([ + 'ipa_proxy_linux.cpp', +]) diff --git a/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp b/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp new file mode 100644 index 0000000..8b7aa74 --- /dev/null +++ b/src/libcamera/proxy/worker/ipa_proxy_linux_worker.cpp @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ipa_proxy_linux_worker.cpp - Default Image Processing Algorithm proxy worker for Linux + */ + +#include <iostream> +#include <sys/types.h> +#include <unistd.h> + +#include <libcamera/camera_manager.h> +#include <libcamera/event_dispatcher.h> +#include <libcamera/ipa/ipa_interface.h> +#include <libcamera/logging.h> + +#include "ipa_module.h" +#include "ipc_unixsocket.h" +#include "log.h" +#include "utils.h" + +using namespace libcamera; + +LOG_DEFINE_CATEGORY(IPAProxyLinuxWorker) + +void readyRead(IPCUnixSocket *ipc) +{ + IPCUnixSocket::Payload message; + int ret; + + ret = ipc->receive(&message); + if (ret) { + LOG(IPAProxyLinuxWorker, Error) + << "Receive message failed: " << ret; + return; + } + + LOG(IPAProxyLinuxWorker, Debug) << "Received a message!"; +} + +int main(int argc, char **argv) +{ + std::string logPath = "/tmp/libcamera.process." + + std::to_string(getpid()) + ".log"; + logSetFile(logPath.c_str()); + + if (argc < 3) { + LOG(IPAProxyLinuxWorker, Debug) + << "Tried to start worker with no args"; + return EXIT_FAILURE; + } + + int fd = std::stoi(argv[2]); + LOG(IPAProxyLinuxWorker, Debug) + << "Starting worker for IPA module " << argv[1] + << " with IPC fd = " << fd; + + std::unique_ptr<IPAModule> ipam = utils::make_unique<IPAModule>(argv[1]); + if (!ipam->isValid() || !ipam->load()) { + LOG(IPAProxyLinuxWorker, Error) + << "IPAModule " << argv[1] << " should be valid but isn't"; + return EXIT_FAILURE; + } + + IPCUnixSocket socket; + if (socket.bind(fd) < 0) { + LOG(IPAProxyLinuxWorker, Error) << "IPC socket binding failed"; + return EXIT_FAILURE; + } + socket.readyRead.connect(&readyRead); + + std::unique_ptr<IPAInterface> ipa = ipam->createInstance(); + if (!ipa) { + LOG(IPAProxyLinuxWorker, Error) << "Failed to create IPA interface"; + return EXIT_FAILURE; + } + + LOG(IPAProxyLinuxWorker, Debug) << "Proxy worker successfully started"; + + /* \todo upgrade listening loop */ + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + while (1) + dispatcher->processEvents(); + + return 0; +} diff --git a/src/libcamera/proxy/worker/meson.build b/src/libcamera/proxy/worker/meson.build new file mode 100644 index 0000000..839156f --- /dev/null +++ b/src/libcamera/proxy/worker/meson.build @@ -0,0 +1,16 @@ +ipa_proxy_sources = [ + ['ipa_proxy_linux', 'ipa_proxy_linux_worker.cpp'] +] + +proxy_install_dir = join_paths(get_option('libexecdir'), 'libcamera') + +foreach t : ipa_proxy_sources + proxy = executable(t[0], t[1], + include_directories : libcamera_internal_includes, + install : true, + install_dir : proxy_install_dir, + dependencies : libcamera_dep) +endforeach + +config_h.set('IPA_PROXY_DIR', + '"' + join_paths(get_option('prefix'), proxy_install_dir) + '"')