diff --git a/spa/plugins/libcamera/libcamera-source.cpp b/spa/plugins/libcamera/libcamera-source.cpp index 3e5715b2a..5588f9828 100644 --- a/spa/plugins/libcamera/libcamera-source.cpp +++ b/spa/plugins/libcamera/libcamera-source.cpp @@ -279,18 +279,42 @@ int spa_libcamera_buffer_recycle(struct impl *impl, struct port *port, uint32_t return 0; } +void freeBuffers(struct impl *impl, struct port *port) +{ + impl->requestPool.clear(); + std::ignore = impl->allocator->free(port->streamConfig.stream()); +} + +[[nodiscard]] +std::size_t count_unique_fds(libcamera::Span planes) +{ + std::size_t c = 0; + int fd = -1; + + for (const auto& plane : planes) { + const int current_fd = plane.fd.get(); + if (current_fd >= 0 && current_fd != fd) { + c += 1; + fd = current_fd; + } + } + + return c; +} + int allocBuffers(struct impl *impl, struct port *port, unsigned int count) { + libcamera::Stream *stream = port->streamConfig.stream(); int res; - if ((res = impl->allocator->allocate(port->streamConfig.stream())) < 0) + if ((res = impl->allocator->allocate(stream)) < 0) return res; for (unsigned int i = 0; i < count; i++) { std::unique_ptr request = impl->camera->createRequest(i); if (!request) { - impl->requestPool.clear(); - return -ENOMEM; + res = -ENOMEM; + goto err; } impl->requestPool.push_back(std::move(request)); } @@ -300,33 +324,20 @@ int allocBuffers(struct impl *impl, struct port *port, unsigned int count) * video frame has to be addressed using more than one memory. * address. Therefore, need calculate the number of discontiguous * memory and allocate the specified amount of memory */ - Stream *stream = impl->config->at(0).stream(); - const std::vector> &bufs = - impl->allocator->buffers(stream); - const std::vector &planes = bufs[0]->planes(); - int fd = -1; - uint32_t buffers_blocks = 0; - - for (const FrameBuffer::Plane &plane : planes) { - const int current_fd = plane.fd.get(); - if (current_fd >= 0 && current_fd != fd) { - buffers_blocks += 1; - fd = current_fd; - } + port->buffers_blocks = count_unique_fds(impl->allocator->buffers(stream).front()->planes()); + if (port->buffers_blocks <= 0) { + res = -ENOBUFS; + goto err; } - if (buffers_blocks > 0) { - port->buffers_blocks = buffers_blocks; - } + return 0; + +err: + freeBuffers(impl, port); + return res; } -void freeBuffers(struct impl *impl, struct port *port) -{ - impl->requestPool.clear(); - impl->allocator->free(port->streamConfig.stream()); -} - int spa_libcamera_clear_buffers(struct impl *impl, struct port *port) { uint32_t i;