diff options
Diffstat (limited to 'hsm-cam/FFI/Cam.cpp')
-rw-r--r-- | hsm-cam/FFI/Cam.cpp | 145 |
1 files changed, 145 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()); +} |