libcamera: proxy: add default linux IPA proxy

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 commit is contained in:
Paul Elder
2019-07-10 03:18:38 +09:00
parent c2a8217df5
commit 131a88795e
5 changed files with 207 additions and 4 deletions
+3 -4
View File
@@ -67,10 +67,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)
@@ -115,3 +112,5 @@ libcamera = shared_library('camera',
libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
include_directories : libcamera_includes,
link_with : libcamera)
subdir('proxy/worker')
+96
View File
@@ -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 proxy worker process";
return;
}
valid_ = true;
}
IPAProxyLinux::~IPAProxyLinux()
{
delete proc_;
delete socket_;
}
void IPAProxyLinux::readyRead(IPCUnixSocket *ipc)
{
}
REGISTER_IPA_PROXY(IPAProxyLinux)
}; /* namespace libcamera */
+3
View File
@@ -0,0 +1,3 @@
libcamera_sources += files([
'ipa_proxy_linux.cpp',
])
@@ -0,0 +1,89 @@
/* 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)
{
/* Uncomment this for debugging. */
#if 0
std::string logPath = "/tmp/libcamera.worker." +
std::to_string(getpid()) + ".log";
logSetFile(logPath.c_str());
#endif
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;
}
+16
View File
@@ -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) + '"')