aboutsummaryrefslogtreecommitdiff
path: root/hsm-cam/FFI/Cam.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hsm-cam/FFI/Cam.cpp')
-rw-r--r--hsm-cam/FFI/Cam.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/hsm-cam/FFI/Cam.cpp b/hsm-cam/FFI/Cam.cpp
new file mode 100644
index 0000000..5f2ca1f
--- /dev/null
+++ b/hsm-cam/FFI/Cam.cpp
@@ -0,0 +1,85 @@
+#include <format>
+
+#include <libcamera/libcamera.h>
+
+#include "Cam.hpp"
+
+using namespace libcamera;
+using namespace std;
+
+HsLogger g_logger;
+HsCallback g_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 request_complete(Request *request) {
+ logMsg(Trace, "Completed request");
+ g_callback(request->buffers().begin()->second->planes()[0].fd.get());
+}
+
+extern "C" void register_logger(HsLogger hs_logger) {
+ g_logger = hs_logger;
+ logMsg(Info, "Registered FFI logger");
+}
+
+extern "C" void register_callback(HsCallback hs_callback) {
+ g_callback = hs_callback;
+ logMsg(Info, "Registered FFI callback");
+}
+
+extern "C" void initialize_ffi() {
+ logMsg(Info, "Starting camera manager");
+ g_manager = make_unique<CameraManager>();
+ g_manager->start();
+
+ logMsg(Info, "Acquiring camera");
+ g_camera = g_manager->cameras()[0];
+ g_camera->acquire();
+
+ logMsg(Info, "Generating still capture configuration");
+ g_config = g_camera->generateConfiguration({StreamRole::StillCapture});
+ g_camera->configure(g_config.get());
+
+ logMsg(Info, "Allocating buffer");
+ g_allocator = make_unique<FrameBufferAllocator>(g_camera);
+ g_allocator->allocate((*g_config)[0].stream());
+
+ logMsg(Info, "Registering request complete callback");
+ g_camera->requestCompleted.connect(request_complete);
+
+ logMsg(Info, "Starting camera");
+ g_camera->start();
+}
+
+extern "C" void shutdown_ffi() {
+ logMsg(Info, "Stopping camera");
+ g_camera->stop();
+
+ logMsg(Info, "Freeing frame buffer allocator");
+ g_allocator->free((*g_config)[0].stream());
+ g_allocator.reset();
+
+ logMsg(Info, "Releasing camera");
+ g_camera->release();
+ g_camera.reset();
+
+ logMsg(Info, "Stopping camera manager");
+ g_manager->stop();
+}
+
+extern "C" void request_capture() {
+ logMsg(Trace, "Requesting still capture");
+
+ Stream *stream = (*g_config)[0].stream();
+ g_request = g_camera->createRequest();
+ g_request->addBuffer(stream, g_allocator->buffers(stream)[0].get());
+ g_camera->queueRequest(g_request.get());
+}