#include "Cam.hpp" #include #include using namespace libcamera; using namespace std; HsLogger g_logger; HsRequestCallback g_request_callback; unique_ptr g_manager; shared_ptr g_camera; unique_ptr g_config; unique_ptr g_allocator; unique_ptr g_request; template void logMsg(Severity severity, const format_string 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(); 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::RGB888; 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(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()); }