[v1,10/33] pipeline: rkisp1: Use V4L2 requests for the dewarper
diff mbox series

Message ID 20250930122726.1837524-11-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • Full dewarper support on imx8mp
Related show

Commit Message

Stefan Klug Sept. 30, 2025, 12:26 p.m. UTC
Use the V4L2 requests API if the dewarper supports it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 61 ++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 4 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index b52d1ff736cd..6048f028000a 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -44,6 +44,7 @@ 
 #include "libcamera/internal/media_device.h"
 #include "libcamera/internal/media_pipeline.h"
 #include "libcamera/internal/pipeline_handler.h"
+#include "libcamera/internal/v4l2_request.h"
 #include "libcamera/internal/v4l2_subdevice.h"
 #include "libcamera/internal/v4l2_videodevice.h"
 
@@ -210,6 +211,7 @@  private:
 	void imageBufferReady(FrameBuffer *buffer);
 	void paramBufferReady(FrameBuffer *buffer);
 	void statBufferReady(FrameBuffer *buffer);
+	void dewarpRequestReady(V4L2Request *request);
 	void dewarpBufferReady(FrameBuffer *buffer);
 	void frameStart(uint32_t sequence);
 
@@ -239,6 +241,9 @@  private:
 	std::vector<std::unique_ptr<FrameBuffer>> mainPathBuffers_;
 	std::queue<FrameBuffer *> availableMainPathBuffers_;
 
+	std::vector<std::unique_ptr<V4L2Request>> dewarpRequests_;
+	std::queue<V4L2Request *> availableDewarpRequests_;
+
 	std::vector<std::unique_ptr<FrameBuffer>> paramBuffers_;
 	std::vector<std::unique_ptr<FrameBuffer>> statBuffers_;
 	std::queue<FrameBuffer *> availableParamBuffers_;
@@ -1034,6 +1039,18 @@  int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
 
 		for (std::unique_ptr<FrameBuffer> &buffer : mainPathBuffers_)
 			availableMainPathBuffers_.push(buffer.get());
+
+		if (dewarper_->supportsRequests()) {
+			ret = dewarper_->allocateRequests(kRkISP1MinBufferCount,
+							  &dewarpRequests_);
+			if (ret < 0)
+				LOG(RkISP1, Error) << "Failed to allocate requests.";
+		}
+
+		for (std::unique_ptr<V4L2Request> &request : dewarpRequests_) {
+			request->requestDone.connect(this, &PipelineHandlerRkISP1::dewarpRequestReady);
+			availableDewarpRequests_.push(request.get());
+		}
 	}
 
 	auto pushBuffers = [&](const std::vector<std::unique_ptr<FrameBuffer>> &buffers,
@@ -1075,6 +1092,11 @@  int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
 	statBuffers_.clear();
 	mainPathBuffers_.clear();
 
+	while (!availableDewarpRequests_.empty())
+		availableDewarpRequests_.pop();
+
+	dewarpRequests_.clear();
+
 	std::vector<unsigned int> ids;
 	for (IPABuffer &ipabuf : data->ipaBuffers_)
 		ids.push_back(ipabuf.id);
@@ -1565,6 +1587,14 @@  void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)
 		return;
 	}
 
+	V4L2Request *dewarpRequest = nullptr;
+	if (!dewarpRequests_.empty()) {
+		/* If we have requests support, there must be one available */
+		ASSERT(!availableDewarpRequests_.empty());
+		dewarpRequest = availableDewarpRequests_.front();
+		availableDewarpRequests_.pop();
+	}
+
 	/* Handle scaler crop control. */
 	const auto &crop = request->controls().get(controls::ScalerCrop);
 	if (crop) {
@@ -1602,14 +1632,37 @@  void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)
 	 * buffers for the dewarper are the buffers of the request, supplied
 	 * by the application.
 	 */
-	int ret = dewarper_->queueBuffers(buffer, request->buffers());
-	if (ret < 0)
-		LOG(RkISP1, Error) << "Cannot queue buffers to dewarper: "
-				   << strerror(-ret);
+	int ret = dewarper_->queueBuffers(buffer, request->buffers(), dewarpRequest);
+	if (ret < 0) {
+		LOG(RkISP1, Error) << "Failed to queue buffers to dewarper: -"
+				   << strerrorname_np(-ret);
+
+		/* Push it back into the queue. */
+		if (dewarpRequest)
+			dewarpRequestReady(dewarpRequest);
+
+		return;
+	}
+
+	if (dewarpRequest) {
+		ret = dewarpRequest->queue();
+		if (ret < 0) {
+			LOG(RkISP1, Error) << "Failed to queue dewarp request: -"
+					   << strerrorname_np(-ret);
+			/* Push it back into the queue. */
+			dewarpRequestReady(dewarpRequest);
+		}
+	}
 
 	request->metadata().set(controls::ScalerCrop, activeCrop_.value());
 }
 
+void PipelineHandlerRkISP1::dewarpRequestReady(V4L2Request *request)
+{
+	request->reinit();
+	availableDewarpRequests_.push(request);
+}
+
 void PipelineHandlerRkISP1::dewarpBufferReady(FrameBuffer *buffer)
 {
 	ASSERT(activeCamera_);