Make libcamera
to work?
This commit is contained in:
parent
a08904688e
commit
aa0f7276bf
@ -3,7 +3,7 @@
|
|||||||
int libcamera_buffer_open(buffer_t *buf)
|
int libcamera_buffer_open(buffer_t *buf)
|
||||||
{
|
{
|
||||||
buf->libcamera = new buffer_libcamera_t{};
|
buf->libcamera = new buffer_libcamera_t{};
|
||||||
buf->libcamera->request = buf->buf_list->dev->libcamera->camera->createRequest();
|
buf->libcamera->request = buf->buf_list->dev->libcamera->camera->createRequest(buf->index);
|
||||||
if (!buf->libcamera->request) {
|
if (!buf->libcamera->request) {
|
||||||
E_LOG_ERROR(buf, "Can't create request");
|
E_LOG_ERROR(buf, "Can't create request");
|
||||||
}
|
}
|
||||||
@ -53,15 +53,72 @@ void libcamera_buffer_close(buffer_t *buf)
|
|||||||
|
|
||||||
int libcamera_buffer_enqueue(buffer_t *buf, const char *who)
|
int libcamera_buffer_enqueue(buffer_t *buf, const char *who)
|
||||||
{
|
{
|
||||||
|
auto &request = buf->libcamera->request;
|
||||||
|
auto const &camera = buf->buf_list->dev->libcamera->camera;
|
||||||
|
|
||||||
|
request->reuse(libcamera::Request::ReuseBuffers);
|
||||||
|
|
||||||
|
// TODO: assign timestamps
|
||||||
|
// for (auto const &pair : request->buffers()) {
|
||||||
|
// v4l2_buf.timestamp.tv_sec = buf->captured_time_us / (1000LL * 1000LL);
|
||||||
|
// v4l2_buf.timestamp.tv_usec = buf->captured_time_us % (1000LL * 1000LL);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (buf->buf_list->dev->libcamera->camera->queueRequest(buf->libcamera->request.get()) < 0) {
|
||||||
|
E_LOG_ERROR(buf, "Can't queue buffer.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void buffer_list_libcamera_t::libcamera_buffer_list_dequeued(libcamera::Request *request)
|
||||||
|
{
|
||||||
|
E_LOG_INFO(buf_list, "Dequeued: index=%d, status=%d", request->cookie(), request->status());
|
||||||
|
|
||||||
|
if (request->status() == libcamera::Request::RequestComplete) {
|
||||||
|
unsigned index = request->cookie();
|
||||||
|
if (write(buf_list->libcamera->fds[1], &index, sizeof(index)) == sizeof(index)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// put back into queue, as it failed
|
||||||
|
buf_list->dev->libcamera->camera->queueRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
int libcamera_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp)
|
int libcamera_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp)
|
||||||
{
|
{
|
||||||
return -1;
|
unsigned index = 0;
|
||||||
|
int n = read(buf_list->libcamera->fds[0], &index, sizeof(index));
|
||||||
|
if (n != sizeof(index)) {
|
||||||
|
E_LOG_INFO(buf_list, "Received invalid result from `read`: %d", n);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= buf_list->nbufs) {
|
||||||
|
E_LOG_INFO(buf_list, "Received invalid index from `read`: %d >= %d", index, buf_list->nbufs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bufp = buf_list->bufs[index];
|
||||||
|
|
||||||
|
// TODO: fix timestamps
|
||||||
|
// buf->v4l2->flags = v4l2_buf.flags;
|
||||||
|
// buf->flags.is_keyframe = (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0;
|
||||||
|
// buf->captured_time_us = get_time_us(CLOCK_FROM_PARAMS, NULL, &v4l2_buf.timestamp, 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int libcamera_buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue)
|
int libcamera_buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue)
|
||||||
{
|
{
|
||||||
return -1;
|
int count_enqueued = buffer_list_count_enqueued(buf_list);
|
||||||
|
pollfd->fd = buf_list->libcamera->fds[0]; // write end
|
||||||
|
pollfd->events = POLLHUP;
|
||||||
|
if (can_dequeue && count_enqueued > 0) {
|
||||||
|
pollfd->events |= POLLIN;
|
||||||
|
}
|
||||||
|
pollfd->revents = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,18 @@ int libcamera_buffer_list_open(buffer_list_t *buf_list, unsigned width, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf_list->libcamera = new buffer_list_libcamera_t{};
|
buf_list->libcamera = new buffer_list_libcamera_t{};
|
||||||
|
buf_list->libcamera->buf_list = buf_list;
|
||||||
|
buf_list->libcamera->fds[0] = -1;
|
||||||
|
buf_list->libcamera->fds[1] = -1;
|
||||||
|
|
||||||
|
if (pipe2(buf_list->libcamera->fds, O_DIRECT|O_CLOEXEC) < 0) {
|
||||||
|
E_LOG_INFO(buf_list, "Cannot open `pipe2`.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
buf_list->libcamera->configuration = buf_list->dev->libcamera->camera->generateConfiguration(
|
buf_list->libcamera->configuration = buf_list->dev->libcamera->camera->generateConfiguration(
|
||||||
{ libcamera::StreamRole::Viewfinder });
|
{ libcamera::StreamRole::Viewfinder });
|
||||||
|
|
||||||
auto &configuration = buf_list->libcamera->configuration->at(0);
|
auto &configuration = buf_list->libcamera->configuration->at(0);
|
||||||
configuration.size = libcamera::Size(width, height);
|
configuration.size = libcamera::Size(width, height);
|
||||||
configuration.pixelFormat = libcamera::PixelFormat(format);
|
configuration.pixelFormat = libcamera::PixelFormat(format);
|
||||||
@ -64,6 +73,9 @@ error:
|
|||||||
void libcamera_buffer_list_close(buffer_list_t *buf_list)
|
void libcamera_buffer_list_close(buffer_list_t *buf_list)
|
||||||
{
|
{
|
||||||
if (buf_list->libcamera) {
|
if (buf_list->libcamera) {
|
||||||
|
close(buf_list->libcamera->fds[0]);
|
||||||
|
close(buf_list->libcamera->fds[1]);
|
||||||
|
|
||||||
delete buf_list->libcamera;
|
delete buf_list->libcamera;
|
||||||
buf_list->libcamera = NULL;
|
buf_list->libcamera = NULL;
|
||||||
}
|
}
|
||||||
@ -72,10 +84,16 @@ void libcamera_buffer_list_close(buffer_list_t *buf_list)
|
|||||||
int libcamera_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on)
|
int libcamera_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on)
|
||||||
{
|
{
|
||||||
if (do_on) {
|
if (do_on) {
|
||||||
|
buf_list->dev->libcamera->camera->requestCompleted.connect(
|
||||||
|
buf_list->libcamera, &buffer_list_libcamera_t::libcamera_buffer_list_dequeued);
|
||||||
|
|
||||||
if (buf_list->dev->libcamera->camera->start() < 0) {
|
if (buf_list->dev->libcamera->camera->start() < 0) {
|
||||||
E_LOG_ERROR(buf_list, "Failed to start camera.");
|
E_LOG_ERROR(buf_list, "Failed to start camera.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
buf_list->dev->libcamera->camera->requestCompleted.disconnect(
|
||||||
|
buf_list->libcamera, &buffer_list_libcamera_t::libcamera_buffer_list_dequeued);
|
||||||
|
|
||||||
if (buf_list->dev->libcamera->camera->stop() < 0) {
|
if (buf_list->dev->libcamera->camera->stop() < 0) {
|
||||||
E_LOG_ERROR(buf_list, "Failed to stop camera.");
|
E_LOG_ERROR(buf_list, "Failed to stop camera.");
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,10 @@ typedef struct device_libcamera_s {
|
|||||||
typedef struct buffer_list_libcamera_s {
|
typedef struct buffer_list_libcamera_s {
|
||||||
std::shared_ptr<libcamera::CameraConfiguration> configuration;
|
std::shared_ptr<libcamera::CameraConfiguration> configuration;
|
||||||
std::shared_ptr<libcamera::FrameBufferAllocator> allocator;
|
std::shared_ptr<libcamera::FrameBufferAllocator> allocator;
|
||||||
|
buffer_list_t *buf_list;
|
||||||
|
int fds[2];
|
||||||
|
|
||||||
|
void libcamera_buffer_list_dequeued(libcamera::Request *request);
|
||||||
} buffer_list_libcamera_t;
|
} buffer_list_libcamera_t;
|
||||||
|
|
||||||
typedef struct buffer_libcamera_s {
|
typedef struct buffer_libcamera_s {
|
||||||
@ -58,6 +62,7 @@ int libcamera_device_set_option(device_t *dev, const char *key, const char *valu
|
|||||||
int libcamera_buffer_open(buffer_t *buf);
|
int libcamera_buffer_open(buffer_t *buf);
|
||||||
void libcamera_buffer_close(buffer_t *buf);
|
void libcamera_buffer_close(buffer_t *buf);
|
||||||
int libcamera_buffer_enqueue(buffer_t *buf, const char *who);
|
int libcamera_buffer_enqueue(buffer_t *buf, const char *who);
|
||||||
|
void libcamera_buffer_list_dequeued(buffer_list_t *buf_list, libcamera::Request *request);
|
||||||
int libcamera_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp);
|
int libcamera_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp);
|
||||||
int libcamera_buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue);
|
int libcamera_buffer_list_pollfd(buffer_list_t *buf_list, struct pollfd *pollfd, bool can_dequeue);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user