From patchwork Thu Oct 23 14:48:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24737 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E86C3C32CE for ; Thu, 23 Oct 2025 14:49:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 90B3B607FF; Thu, 23 Oct 2025 16:49:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="KcEQqh4p"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4110D607F3 for ; Thu, 23 Oct 2025 16:49:13 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:7328:357b:4ce1:72b6]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 52FFA1D2B; Thu, 23 Oct 2025 16:47:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761230848; bh=D4qT+SNg9hd+BYvSKgmM0erFPZxmbrAtSDyfQm6udVw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KcEQqh4pkTnZbFsA560AglxRhQgpyuJ1UKltR1Y0IkmZxTm7jihvNeYx7bhN103PR /UWW1DXSRMV6wNnH8TUPB6v1Cr3LrrHF/STBQmbrR5Zf7mHYQySGqr3Z36tLCXmJr+ vsEm15+s3AVaOXNREVC442LVukBtXxwJDIxu40rQ= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v2 09/35] pipeline: rkisp1: Use V4L2 requests for the dewarper Date: Thu, 23 Oct 2025 16:48:10 +0200 Message-ID: <20251023144841.403689-10-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20251023144841.403689-1-stefan.klug@ideasonboard.com> References: <20251023144841.403689-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the V4L2 requests API if the dewarper supports it. Signed-off-by: Stefan Klug --- Changes in v2: - Replace strerrorname_np() by strerror() because the former is not supported on all our targets --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 59 ++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 0e2a210e1e80..dd3907e2fb5f 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> mainPathBuffers_; std::queue availableMainPathBuffers_; + std::vector> dewarpRequests_; + std::queue availableDewarpRequests_; + std::vector> paramBuffers_; std::vector> statBuffers_; std::queue availableParamBuffers_; @@ -1034,6 +1039,18 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) for (std::unique_ptr &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 &request : dewarpRequests_) { + request->requestDone.connect(this, &PipelineHandlerRkISP1::dewarpRequestReady); + availableDewarpRequests_.push(request.get()); + } } auto pushBuffers = [&](const std::vector> &buffers, @@ -1075,6 +1092,11 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) statBuffers_.clear(); mainPathBuffers_.clear(); + while (!availableDewarpRequests_.empty()) + availableDewarpRequests_.pop(); + + dewarpRequests_.clear(); + std::vector ids; for (IPABuffer &ipabuf : data->ipaBuffers_) ids.push_back(ipabuf.id); @@ -1560,6 +1582,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) { @@ -1597,14 +1627,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: " + int ret = dewarper_->queueBuffers(buffer, request->buffers(), dewarpRequest); + if (ret < 0) { + LOG(RkISP1, Error) << "Failed to queue buffers to dewarper: -" << strerror(-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: -" + << strerror(-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_);