[PATCH 1/1] libcamera: Add request API support for media controller device
Harvey Yang
chenghaoyang at chromium.org
Mon Sep 23 08:02:35 CEST 2024
From: Han-Lin Chen <hanlinchen at chromium.org>
This patch adds `allocateRequests` with MEDIA_IOC_REQUEST_ALLOC
, `queueRequest` with MEDIA_REQUEST_IOC_QUEUE, and `reInitRequest`
with MEDIA_REQUEST_IOC_REINIT.
Signed-off-by: Han-Lin Chen <hanlinchen at chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang at chromium.org>
---
include/libcamera/internal/media_device.h | 4 ++
src/libcamera/media_device.cpp | 87 +++++++++++++++++++++++
2 files changed, 91 insertions(+)
diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h
index e412d3a0..8f54dd12 100644
--- a/include/libcamera/internal/media_device.h
+++ b/include/libcamera/internal/media_device.h
@@ -53,6 +53,10 @@ public:
MediaLink *link(const MediaPad *source, const MediaPad *sink);
int disableLinks();
+ int allocateRequests(unsigned int count, std::vector<UniqueFD> &requests);
+ int queueRequest(int requestFd);
+ int reInitRequest(int requestFd);
+
Signal<> disconnected;
protected:
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index bd054552..47b75809 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -9,6 +9,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <stdint.h>
#include <string>
#include <string.h>
@@ -836,4 +837,90 @@ int MediaDevice::setupLink(const MediaLink *link, unsigned int flags)
return 0;
}
+/**
+ * \brief Allocate \a count requests with ioctl
+ * \param[in] count The number of requests to be allocated
+ * \param[out] requests The request file descriptors to be returned
+ *
+ * This function returns request file descriptors if the MediaDevice supports
+ * requests. The file descriptors can then be queued and re-inited afterwards.
+ *
+ * \sa queueRequest(int requestFd)
+ * \sa reInitRequest(int requestFd)
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int MediaDevice::allocateRequests(unsigned int count, std::vector<UniqueFD> &requests)
+{
+ for (unsigned int i = 0; i < count; i++) {
+ int fd;
+ int ret = ioctl(fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &fd);
+ if (ret) {
+ LOG(MediaDevice, Error) << "Allocate request failed "
+ << strerror(-ret);
+ return -EBUSY;
+ }
+ requests.emplace_back(fd);
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Queue a request with ioctl
+ * \param[in] requestFd The request file descriptor
+ *
+ * This function queues a request that was allocated before.
+ *
+ * \sa allocateRequests(unsigned int count, std::vector<UniqueFD> &requests)
+ * \sa reInitRequest(int requestFd)
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int MediaDevice::queueRequest(int requestFd)
+{
+ int ret = ioctl(requestFd, MEDIA_REQUEST_IOC_QUEUE, NULL);
+ if (ret)
+ LOG(MediaDevice, Error) << "QueueRequest fd " << requestFd
+ << "failed: " << strerror(-ret);
+ return ret;
+}
+
+/**
+ * \brief Re-init a request with ioctl
+ * \param[in] requestFd The request file descriptor
+ *
+ * This function recycles a request that was allocated and queued before. It
+ * polls on \a requestFd to ensure the request is completed, and reinits the
+ * request.
+ *
+ * \sa allocateRequests(unsigned int count, std::vector<UniqueFD> &requests)
+ * \sa queueRequest(int requestFd)
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int MediaDevice::reInitRequest(int requestFd)
+{
+ struct pollfd pfd;
+
+ pfd.fd = requestFd;
+ pfd.events = POLLPRI;
+
+ int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, 300));
+ if (ret < 0)
+ LOG(MediaDevice, Error) << "The request " << requestFd
+ << " polled failed: " << strerror(-ret);
+ else if (ret == 0)
+ LOG(MediaDevice, Error) << "The request " << requestFd
+ << " polled timeout: " << strerror(-ret);
+
+ ret = ::ioctl(requestFd, MEDIA_REQUEST_IOC_REINIT, NULL);
+ if (ret)
+ LOG(MediaDevice, Error) << "The request " << requestFd
+ << " is queued but not yet completed: "
+ << strerror(-ret);
+
+ return ret;
+}
+
} /* namespace libcamera */
--
2.46.0.792.g87dc391469-goog
More information about the libcamera-devel
mailing list