aboutsummaryrefslogtreecommitdiff
path: root/hsm-cam/FFI
diff options
context:
space:
mode:
Diffstat (limited to 'hsm-cam/FFI')
-rw-r--r--hsm-cam/FFI/Cam.cpp145
-rw-r--r--hsm-cam/FFI/Cam.hpp39
2 files changed, 184 insertions, 0 deletions
diff --git a/hsm-cam/FFI/Cam.cpp b/hsm-cam/FFI/Cam.cpp
new file mode 100644
index 0000000..4c21e7f
--- /dev/null
+++ b/hsm-cam/FFI/Cam.cpp
@@ -0,0 +1,145 @@
+#include "Cam.hpp"
+
+#include <libcamera/libcamera.h>
+
+#include <format>
+
+using namespace libcamera;
+using namespace std;
+
+HsLogger g_logger;
+HsRequestCallback g_request_callback;
+unique_ptr<CameraManager> g_manager;
+shared_ptr<Camera> g_camera;
+unique_ptr<CameraConfiguration> g_config;
+unique_ptr<FrameBufferAllocator> g_allocator;
+unique_ptr<Request> g_request;
+
+template<class... Args>
+void
+logMsg(Severity severity, const format_string<Args...> fmt, const Args &...args)
+{
+ g_logger(severity, vformat(fmt.get(), make_format_args(args...)).c_str());
+}
+
+void
+internal_request_callback(Request *request)
+{
+ int sequence = request->buffers().begin()->second->metadata().sequence;
+ logMsg(Trace, "Completed request #{}", sequence);
+ g_request_callback();
+}
+
+extern "C" void
+register_logger(HsLogger hs_logger)
+{
+ g_logger = hs_logger;
+ logMsg(Info, "Registered FFI logger");
+}
+
+extern "C" void
+register_request_callback(HsRequestCallback hs_request_callback)
+{
+ g_request_callback = hs_request_callback;
+ logMsg(Info, "Registered FFI request callback");
+}
+
+extern "C" void
+start_camera_manager()
+{
+ logMsg(Info, "Starting camera manager");
+ g_manager = make_unique<CameraManager>();
+ g_manager->start();
+}
+
+extern "C" void
+stop_camera_manager()
+{
+ logMsg(Info, "Stopping camera manager");
+ g_manager->stop();
+}
+
+extern "C" void
+acquire_camera()
+{
+ logMsg(Info, "Acquiring camera");
+ g_camera = g_manager->cameras()[0];
+ g_camera->acquire();
+ logMsg(Info, "Acquired camera: {}", g_camera->id());
+}
+
+extern "C" void
+release_camera()
+{
+ logMsg(Info, "Releasing camera");
+ g_camera->release();
+ g_camera.reset();
+}
+
+extern "C" void
+allocate_frame_buffer()
+{
+ logMsg(Info, "Generating camera configuration");
+ g_config = g_camera->generateConfiguration({ StreamRole::StillCapture });
+ g_config->at(0).size.width = FRAME_WIDTH;
+ g_config->at(0).size.height = FRAME_HEIGHT;
+ g_config->at(0).pixelFormat = formats::BGR888;
+ logMsg(Info, "Generated camera configuration: {}", g_config->at(0).toString());
+ g_camera->configure(g_config.get());
+
+ logMsg(Info, "Generating frame buffer allocator");
+ g_allocator = make_unique<FrameBufferAllocator>(g_camera);
+ g_allocator->allocate(g_config->at(0).stream());
+
+ logMsg(Info, "Registering internal request callback");
+ g_camera->requestCompleted.connect(internal_request_callback);
+}
+
+extern "C" void
+free_frame_buffer()
+{
+ logMsg(Info, "Freeing frame buffer allocator");
+ g_allocator->free(g_config->at(0).stream());
+ g_allocator.reset();
+}
+
+extern "C" void
+start_camera()
+{
+ logMsg(Info, "Starting camera");
+ g_camera->start();
+}
+
+extern "C" void
+stop_camera()
+{
+ logMsg(Info, "Stopping camera");
+ g_camera->stop();
+}
+
+extern "C" void
+create_request()
+{
+ logMsg(Info, "Creating request");
+ g_request = g_camera->createRequest();
+
+ logMsg(Info, "Setting buffer for request");
+ Stream *stream = g_config->at(0).stream();
+ g_request->addBuffer(stream, g_allocator->buffers(stream)[0].get());
+}
+
+extern "C" int
+get_dma_buffer_fd()
+{
+ int fd = g_request->buffers().begin()->second->planes()[0].fd.get();
+ logMsg(Info, "DMA buffer available in FD {}", fd);
+ return fd;
+}
+
+extern "C" void
+request_frame()
+{
+ logMsg(Trace, "Requested frame");
+ g_request->reuse(Request::ReuseBuffers);
+ g_camera->queueRequest(g_request.get());
+}
diff --git a/hsm-cam/FFI/Cam.hpp b/hsm-cam/FFI/Cam.hpp
new file mode 100644
index 0000000..eeea814
--- /dev/null
+++ b/hsm-cam/FFI/Cam.hpp
@@ -0,0 +1,39 @@
+#ifndef CAM_HPP
+#define CAM_HPP
+
+#define FRAME_WIDTH (800)
+#define FRAME_HEIGHT (600)
+
+enum Severity
+{
+ Attention = 0,
+ Info = 1,
+ Trace = 2,
+};
+
+typedef void (*HsLogger)(enum Severity, const char *);
+typedef void (*HsRequestCallback)();
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ void register_logger(HsLogger hs_logger);
+ void register_request_callback(HsRequestCallback hs_request_callback);
+ void start_camera_manager();
+ void stop_camera_manager();
+ void acquire_camera();
+ void release_camera();
+ void allocate_frame_buffer();
+ void free_frame_buffer();
+ void start_camera();
+ void stop_camera();
+ void create_request();
+
+ int get_dma_buffer_fd();
+ void request_frame();
+#ifdef __cplusplus
+}
+#endif
+
+#endif