The libcamera
starts
This commit is contained in:
@ -3,7 +3,44 @@
|
||||
int libcamera_buffer_open(buffer_t *buf)
|
||||
{
|
||||
buf->libcamera = new buffer_libcamera_t{};
|
||||
buf->libcamera->request = buf->buf_list->dev->libcamera->camera->createRequest();
|
||||
if (!buf->libcamera->request) {
|
||||
E_LOG_ERROR(buf, "Can't create request");
|
||||
}
|
||||
|
||||
for (libcamera::StreamConfiguration &stream_cfg : *buf->buf_list->libcamera->configuration) {
|
||||
auto stream = stream_cfg.stream();
|
||||
const std::vector<std::unique_ptr<libcamera::FrameBuffer>> &buffers =
|
||||
buf->buf_list->libcamera->allocator->buffers(stream);
|
||||
auto const &buffer = buffers[buf->index];
|
||||
|
||||
if (buf->libcamera->request->addBuffer(stream, buffer.get()) < 0) {
|
||||
E_LOG_ERROR(buf, "Can't set buffer for request");
|
||||
}
|
||||
|
||||
for (auto const &plane : buffer->planes()) {
|
||||
if (buf->start) {
|
||||
E_LOG_ERROR(buf, "Too many planes open.");
|
||||
}
|
||||
|
||||
buf->start = mmap(NULL, plane.length, PROT_READ | PROT_WRITE, MAP_SHARED, plane.fd.get(), 0);
|
||||
buf->length = plane.length;
|
||||
buf->used = 0;
|
||||
buf->dma_fd = plane.fd.get();
|
||||
|
||||
if (!buf->start) {
|
||||
E_LOG_ERROR(buf, "Failed to mmap DMA buffer");
|
||||
}
|
||||
|
||||
E_LOG_DEBUG(buf, "Mapped buffer: start=%p, length=%d, fd=%d",
|
||||
buf->start, buf->length, buf->dma_fd);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void libcamera_buffer_close(buffer_t *buf)
|
||||
|
@ -2,13 +2,63 @@
|
||||
|
||||
int libcamera_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned height, unsigned format, unsigned bytesperline, int nbufs)
|
||||
{
|
||||
int got_bufs = 0;
|
||||
|
||||
if (!buf_list->do_capture) {
|
||||
E_LOG_INFO(buf_list, "Only capture mode is supported.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!buf_list->do_mmap) {
|
||||
E_LOG_INFO(buf_list, "Only mmap buffers are supported.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf_list->libcamera = new buffer_list_libcamera_t{};
|
||||
return 0;
|
||||
buf_list->libcamera->configuration = buf_list->dev->libcamera->camera->generateConfiguration(
|
||||
{ libcamera::StreamRole::Viewfinder });
|
||||
|
||||
auto &configuration = buf_list->libcamera->configuration->at(0);
|
||||
configuration.size = libcamera::Size(width, height);
|
||||
configuration.pixelFormat = libcamera::PixelFormat(format);
|
||||
if (bytesperline > 0) {
|
||||
configuration.stride = bytesperline;
|
||||
}
|
||||
if (nbufs > 0) {
|
||||
configuration.bufferCount = nbufs;
|
||||
}
|
||||
if (buf_list->libcamera->configuration->validate() == libcamera::CameraConfiguration::Invalid) {
|
||||
E_LOG_ERROR(buf_list, "Camera configuration invalid");
|
||||
}
|
||||
|
||||
if (buf_list->dev->libcamera->camera->configure(buf_list->libcamera->configuration.get()) < 0) {
|
||||
E_LOG_ERROR(buf_list, "Failed to configure camera");
|
||||
}
|
||||
|
||||
buf_list->fmt_width = configuration.size.width;
|
||||
buf_list->fmt_height = configuration.size.height;
|
||||
buf_list->fmt_format = configuration.pixelFormat.fourcc();
|
||||
buf_list->fmt_bytesperline = configuration.stride;
|
||||
|
||||
buf_list->libcamera->allocator = std::make_shared<libcamera::FrameBufferAllocator>(
|
||||
buf_list->dev->libcamera->camera);
|
||||
|
||||
got_bufs = configuration.bufferCount;
|
||||
|
||||
for (libcamera::StreamConfiguration &stream_config : *buf_list->libcamera->configuration) {
|
||||
if (buf_list->libcamera->allocator->allocate(stream_config.stream()) < 0) {
|
||||
E_LOG_ERROR(buf_list, "Can't allocate buffers");
|
||||
}
|
||||
|
||||
int allocated = buf_list->libcamera->allocator->buffers(
|
||||
stream_config.stream()).size();
|
||||
got_bufs = std::min(got_bufs, allocated);
|
||||
}
|
||||
|
||||
return got_bufs;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void libcamera_buffer_list_close(buffer_list_t *buf_list)
|
||||
@ -21,5 +71,18 @@ void libcamera_buffer_list_close(buffer_list_t *buf_list)
|
||||
|
||||
int libcamera_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on)
|
||||
{
|
||||
if (do_on) {
|
||||
if (buf_list->dev->libcamera->camera->start() < 0) {
|
||||
E_LOG_ERROR(buf_list, "Failed to start camera.");
|
||||
}
|
||||
} else {
|
||||
if (buf_list->dev->libcamera->camera->stop() < 0) {
|
||||
E_LOG_ERROR(buf_list, "Failed to stop camera.");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
@ -4,18 +4,43 @@ int libcamera_device_open(device_t *dev)
|
||||
{
|
||||
dev->libcamera = new device_libcamera_t{};
|
||||
|
||||
auto camera_manager = std::make_unique<libcamera::CameraManager>();
|
||||
int ret = camera_manager->start();
|
||||
dev->libcamera->camera_manager = std::make_shared<libcamera::CameraManager>();
|
||||
int ret = dev->libcamera->camera_manager->start();
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
E_LOG_ERROR(dev, "Cannot start camera_manager.");
|
||||
}
|
||||
|
||||
dev->libcamera->camera = dev->libcamera->camera_manager->get(dev->path);
|
||||
if (!dev->libcamera->camera) {
|
||||
if (dev->libcamera->camera_manager->cameras().size()) {
|
||||
for(auto const &camera : dev->libcamera->camera_manager->cameras()) {
|
||||
E_LOG_INFO(dev, "Available Camera: %s", camera->id().c_str());
|
||||
}
|
||||
} else {
|
||||
E_LOG_INFO(dev, "No available cameras");
|
||||
}
|
||||
E_LOG_ERROR(dev, "Camera `%s` was not found.", dev->path);
|
||||
}
|
||||
|
||||
if (dev->libcamera->camera->acquire()) {
|
||||
E_LOG_ERROR(dev, "Failed to acquire `%s` camera.", dev->path);
|
||||
}
|
||||
|
||||
printf("camera manager started, and camera was found: %s\n", dev->libcamera->camera->id().c_str());
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void libcamera_device_close(device_t *dev)
|
||||
{
|
||||
if (dev->libcamera) {
|
||||
if (dev->libcamera->camera) {
|
||||
dev->libcamera->camera->stop();
|
||||
dev->libcamera->camera->release();
|
||||
}
|
||||
|
||||
delete dev->libcamera;
|
||||
dev->libcamera = NULL;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ extern "C" {
|
||||
#include "device/buffer_list.h"
|
||||
#include "device/buffer.h"
|
||||
#include "opts/log.h"
|
||||
#include "opts/fourcc.h"
|
||||
};
|
||||
|
||||
#include <optional>
|
||||
@ -34,12 +35,17 @@ typedef struct device_s device_t;
|
||||
struct pollfd;
|
||||
|
||||
typedef struct device_libcamera_s {
|
||||
std::shared_ptr<libcamera::CameraManager> camera_manager;
|
||||
std::shared_ptr<libcamera::Camera> camera;
|
||||
} device_libcamera_t;
|
||||
|
||||
typedef struct buffer_list_libcamera_s {
|
||||
std::shared_ptr<libcamera::CameraConfiguration> configuration;
|
||||
std::shared_ptr<libcamera::FrameBufferAllocator> allocator;
|
||||
} buffer_list_libcamera_t;
|
||||
|
||||
typedef struct buffer_libcamera_s {
|
||||
std::shared_ptr<libcamera::Request> request;
|
||||
} buffer_libcamera_t;
|
||||
|
||||
int libcamera_device_open(device_t *dev);
|
||||
|
Reference in New Issue
Block a user