[{"id":36441,"web_url":"https://patchwork.libcamera.org/comment/36441/","msgid":"<33bad1b1-a503-447e-9c0a-14223582d1fe@ideasonboard.com>","date":"2025-10-24T14:32:14","subject":"Re: [PATCH v2 09/35] pipeline: rkisp1: Use V4L2 requests for the\n\tdewarper","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2025. 10. 23. 16:48 keltezéssel, Stefan Klug írta:\n> Use the V4L2 requests API if the dewarper supports it.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> \n> ---\n> \n> Changes in v2:\n> - Replace strerrorname_np() by strerror() because the former is not\n>    supported on all our targets\n> ---\n>   src/libcamera/pipeline/rkisp1/rkisp1.cpp | 59 ++++++++++++++++++++++--\n>   1 file changed, 56 insertions(+), 3 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 0e2a210e1e80..dd3907e2fb5f 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -44,6 +44,7 @@\n>   #include \"libcamera/internal/media_device.h\"\n>   #include \"libcamera/internal/media_pipeline.h\"\n>   #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/v4l2_request.h\"\n>   #include \"libcamera/internal/v4l2_subdevice.h\"\n>   #include \"libcamera/internal/v4l2_videodevice.h\"\n>   \n> @@ -210,6 +211,7 @@ private:\n>   \tvoid imageBufferReady(FrameBuffer *buffer);\n>   \tvoid paramBufferReady(FrameBuffer *buffer);\n>   \tvoid statBufferReady(FrameBuffer *buffer);\n> +\tvoid dewarpRequestReady(V4L2Request *request);\n>   \tvoid dewarpBufferReady(FrameBuffer *buffer);\n>   \tvoid frameStart(uint32_t sequence);\n>   \n> @@ -239,6 +241,9 @@ private:\n>   \tstd::vector<std::unique_ptr<FrameBuffer>> mainPathBuffers_;\n>   \tstd::queue<FrameBuffer *> availableMainPathBuffers_;\n>   \n> +\tstd::vector<std::unique_ptr<V4L2Request>> dewarpRequests_;\n> +\tstd::queue<V4L2Request *> availableDewarpRequests_;\n> +\n>   \tstd::vector<std::unique_ptr<FrameBuffer>> paramBuffers_;\n>   \tstd::vector<std::unique_ptr<FrameBuffer>> statBuffers_;\n>   \tstd::queue<FrameBuffer *> availableParamBuffers_;\n> @@ -1034,6 +1039,18 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)\n>   \n>   \t\tfor (std::unique_ptr<FrameBuffer> &buffer : mainPathBuffers_)\n>   \t\t\tavailableMainPathBuffers_.push(buffer.get());\n> +\n> +\t\tif (dewarper_->supportsRequests()) {\n> +\t\t\tret = dewarper_->allocateRequests(kRkISP1MinBufferCount,\n> +\t\t\t\t\t\t\t  &dewarpRequests_);\n> +\t\t\tif (ret < 0)\n> +\t\t\t\tLOG(RkISP1, Error) << \"Failed to allocate requests.\";\n> +\t\t}\n> +\n> +\t\tfor (std::unique_ptr<V4L2Request> &request : dewarpRequests_) {\n> +\t\t\trequest->requestDone.connect(this, &PipelineHandlerRkISP1::dewarpRequestReady);\n> +\t\t\tavailableDewarpRequests_.push(request.get());\n> +\t\t}\n\nI think `errorCleanup` should be updated with the following:\n\n   availableDewarpRequests_.clear();\n   dewarpRequests_.clear();\n\n\n>   \t}\n>   \n>   \tauto pushBuffers = [&](const std::vector<std::unique_ptr<FrameBuffer>> &buffers,\n> @@ -1075,6 +1092,11 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)\n>   \tstatBuffers_.clear();\n>   \tmainPathBuffers_.clear();\n>   \n> +\twhile (!availableDewarpRequests_.empty())\n> +\t\tavailableDewarpRequests_.pop();\n\n`std::queue` does not have `clear()`... maybe we should use `std::dequeue`\n(which is the default container of `std::queue` and it has `clear()`).\n\n\n> +\n> +\tdewarpRequests_.clear();\n> +\n>   \tstd::vector<unsigned int> ids;\n>   \tfor (IPABuffer &ipabuf : data->ipaBuffers_)\n>   \t\tids.push_back(ipabuf.id);\n> @@ -1560,6 +1582,14 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n>   \t\treturn;\n>   \t}\n>   \n> +\tV4L2Request *dewarpRequest = nullptr;\n> +\tif (!dewarpRequests_.empty()) {\n> +\t\t/* If we have requests support, there must be one available */\n> +\t\tASSERT(!availableDewarpRequests_.empty());\n> +\t\tdewarpRequest = availableDewarpRequests_.front();\n> +\t\tavailableDewarpRequests_.pop();\n> +\t}\n> +\n>   \t/* Handle scaler crop control. */\n>   \tconst auto &crop = request->controls().get(controls::ScalerCrop);\n>   \tif (crop) {\n> @@ -1597,14 +1627,37 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n>   \t * buffers for the dewarper are the buffers of the request, supplied\n>   \t * by the application.\n>   \t */\n> -\tint ret = dewarper_->queueBuffers(buffer, request->buffers());\n> -\tif (ret < 0)\n> -\t\tLOG(RkISP1, Error) << \"Cannot queue buffers to dewarper: \"\n> +\tint ret = dewarper_->queueBuffers(buffer, request->buffers(), dewarpRequest);\n> +\tif (ret < 0) {\n> +\t\tLOG(RkISP1, Error) << \"Failed to queue buffers to dewarper: -\"\n>   \t\t\t\t   << strerror(-ret);\n>   \n> +\t\t/* Push it back into the queue. */\n> +\t\tif (dewarpRequest)\n> +\t\t\tdewarpRequestReady(dewarpRequest);\n> +\n> +\t\treturn;\n> +\t}\n> +\n> +\tif (dewarpRequest) {\n> +\t\tret = dewarpRequest->queue();\n> +\t\tif (ret < 0) {\n> +\t\t\tLOG(RkISP1, Error) << \"Failed to queue dewarp request: -\"\n> +\t\t\t\t\t   << strerror(-ret);\n> +\t\t\t/* Push it back into the queue. */\n> +\t\t\tdewarpRequestReady(dewarpRequest);\n> +\t\t}\n> +\t}\n\nI feel the error handling is a bit on the more complicated side, i.e. easy to miss things.\nBut I don't have a simple idea on how it could be improved.\n\n\nRegards,\nBarnabás Pőcze\n\n\n> [...]","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2F834BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Oct 2025 14:32:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 606F760976;\n\tFri, 24 Oct 2025 16:32:22 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CF7CF60938\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Oct 2025 16:32:21 +0200 (CEST)","from [192.168.33.13] (185.221.141.231.nat.pool.zt.hu\n\t[185.221.141.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1F777EFF;\n\tFri, 24 Oct 2025 16:30:34 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"i3BdSsw2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761316236;\n\tbh=xYFcNMUdrYTEtAC+Gl+awd713AikFfxQUIDI5McyaQY=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=i3BdSsw20DHaJP2q1DPajQ6CIrytY6HXSetLcxtNw5ZHboqm0gTqlufkeBJD6MzU2\n\tlPnA/3l5ccgv3uBPj5QHnvRZyMTuLYs5duIaqaXGnRwrPARli02pbSevx2kBCqiEW3\n\tnZS1WYWwuE+tmei6sBcGgK1Y8M0dqxFiDKNZuDAI=","Message-ID":"<33bad1b1-a503-447e-9c0a-14223582d1fe@ideasonboard.com>","Date":"Fri, 24 Oct 2025 16:32:14 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2 09/35] pipeline: rkisp1: Use V4L2 requests for the\n\tdewarper","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20251023144841.403689-1-stefan.klug@ideasonboard.com>\n\t<20251023144841.403689-10-stefan.klug@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20251023144841.403689-10-stefan.klug@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":36710,"web_url":"https://patchwork.libcamera.org/comment/36710/","msgid":"<176236119689.2116251.12223903999011454476@neptunite.rasen.tech>","date":"2025-11-05T16:46:36","subject":"Re: [PATCH v2 09/35] pipeline: rkisp1: Use V4L2 requests for the\n\tdewarper","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Stefan Klug (2025-10-23 23:48:10)\n> Use the V4L2 requests API if the dewarper supports it.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> \n> ---\n> \n> Changes in v2:\n> - Replace strerrorname_np() by strerror() because the former is not\n>   supported on all our targets\n> ---\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 59 ++++++++++++++++++++++--\n>  1 file changed, 56 insertions(+), 3 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 0e2a210e1e80..dd3907e2fb5f 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -44,6 +44,7 @@\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/media_pipeline.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/v4l2_request.h\"\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n> @@ -210,6 +211,7 @@ private:\n>         void imageBufferReady(FrameBuffer *buffer);\n>         void paramBufferReady(FrameBuffer *buffer);\n>         void statBufferReady(FrameBuffer *buffer);\n> +       void dewarpRequestReady(V4L2Request *request);\n>         void dewarpBufferReady(FrameBuffer *buffer);\n>         void frameStart(uint32_t sequence);\n>  \n> @@ -239,6 +241,9 @@ private:\n>         std::vector<std::unique_ptr<FrameBuffer>> mainPathBuffers_;\n>         std::queue<FrameBuffer *> availableMainPathBuffers_;\n>  \n> +       std::vector<std::unique_ptr<V4L2Request>> dewarpRequests_;\n> +       std::queue<V4L2Request *> availableDewarpRequests_;\n> +\n>         std::vector<std::unique_ptr<FrameBuffer>> paramBuffers_;\n>         std::vector<std::unique_ptr<FrameBuffer>> statBuffers_;\n>         std::queue<FrameBuffer *> availableParamBuffers_;\n> @@ -1034,6 +1039,18 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)\n>  \n>                 for (std::unique_ptr<FrameBuffer> &buffer : mainPathBuffers_)\n>                         availableMainPathBuffers_.push(buffer.get());\n> +\n> +               if (dewarper_->supportsRequests()) {\n> +                       ret = dewarper_->allocateRequests(kRkISP1MinBufferCount,\n> +                                                         &dewarpRequests_);\n> +                       if (ret < 0)\n> +                               LOG(RkISP1, Error) << \"Failed to allocate requests.\";\n> +               }\n> +\n> +               for (std::unique_ptr<V4L2Request> &request : dewarpRequests_) {\n> +                       request->requestDone.connect(this, &PipelineHandlerRkISP1::dewarpRequestReady);\n> +                       availableDewarpRequests_.push(request.get());\n> +               }\n>         }\n>  \n>         auto pushBuffers = [&](const std::vector<std::unique_ptr<FrameBuffer>> &buffers,\n> @@ -1075,6 +1092,11 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)\n>         statBuffers_.clear();\n>         mainPathBuffers_.clear();\n>  \n> +       while (!availableDewarpRequests_.empty())\n> +               availableDewarpRequests_.pop();\n> +\n> +       dewarpRequests_.clear();\n> +\n>         std::vector<unsigned int> ids;\n>         for (IPABuffer &ipabuf : data->ipaBuffers_)\n>                 ids.push_back(ipabuf.id);\n> @@ -1560,6 +1582,14 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n>                 return;\n>         }\n>  \n> +       V4L2Request *dewarpRequest = nullptr;\n> +       if (!dewarpRequests_.empty()) {\n\nTo me it feels more correct to check availableDewarpRequests_ since that's what\nwe're dequeueing from, or supportsRequests() if you want to check capability.\n\n> +               /* If we have requests support, there must be one available */\n> +               ASSERT(!availableDewarpRequests_.empty());\n> +               dewarpRequest = availableDewarpRequests_.front();\n> +               availableDewarpRequests_.pop();\n> +       }\n> +\n>         /* Handle scaler crop control. */\n>         const auto &crop = request->controls().get(controls::ScalerCrop);\n>         if (crop) {\n> @@ -1597,14 +1627,37 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n>          * buffers for the dewarper are the buffers of the request, supplied\n>          * by the application.\n>          */\n> -       int ret = dewarper_->queueBuffers(buffer, request->buffers());\n> -       if (ret < 0)\n> -               LOG(RkISP1, Error) << \"Cannot queue buffers to dewarper: \"\n> +       int ret = dewarper_->queueBuffers(buffer, request->buffers(), dewarpRequest);\n> +       if (ret < 0) {\n> +               LOG(RkISP1, Error) << \"Failed to queue buffers to dewarper: -\"\n>                                    << strerror(-ret);\n>  \n> +               /* Push it back into the queue. */\n> +               if (dewarpRequest)\n> +                       dewarpRequestReady(dewarpRequest);\n> +\n> +               return;\n> +       }\n> +\n> +       if (dewarpRequest) {\n> +               ret = dewarpRequest->queue();\n\nIs it possible for this to fail while queueBuffers() succeeds? Maybe ENOMEM if\nnot EIO? Should we assert or warn?\n\n\nThanks,\n\nPaul\n\n> +               if (ret < 0) {\n> +                       LOG(RkISP1, Error) << \"Failed to queue dewarp request: -\"\n> +                                          << strerror(-ret);\n> +                       /* Push it back into the queue. */\n> +                       dewarpRequestReady(dewarpRequest);\n> +               }\n> +       }\n> +\n>         request->metadata().set(controls::ScalerCrop, activeCrop_.value());\n>  }\n>  \n> +void PipelineHandlerRkISP1::dewarpRequestReady(V4L2Request *request)\n> +{\n> +       request->reinit();\n> +       availableDewarpRequests_.push(request);\n> +}\n> +\n>  void PipelineHandlerRkISP1::dewarpBufferReady(FrameBuffer *buffer)\n>  {\n>         ASSERT(activeCamera_);\n> -- \n> 2.48.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id DE0A6BDE4C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  5 Nov 2025 16:46:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A6D6860AA2;\n\tWed,  5 Nov 2025 17:46:44 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0EF66609DE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  5 Nov 2025 17:46:43 +0100 (CET)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:d4d0:27ea:7a74:8a9e])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 3A9F8E45;\n\tWed,  5 Nov 2025 17:44:47 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"SwhdHvYg\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1762361088;\n\tbh=7xMUA1XGzgYQpq4PnLMBNtL7ucPdYHCWeIYsDJe1mYg=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=SwhdHvYgBgnGVyg36H+y2zTri+AC5/RkuQBJIQCgje2wnK55Jfg2uGCAWwQl5kjCk\n\tWgwNIF1p4SInrrYFdqGHCjnDHe90ahu87gxegrvFC9LoDuyeJcLXtU8U99xkH91K4y\n\tAVLQ4POBy+PPDYHpNDlPwvCl1JiLRgHUFHB7rHVw=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251023144841.403689-10-stefan.klug@ideasonboard.com>","References":"<20251023144841.403689-1-stefan.klug@ideasonboard.com>\n\t<20251023144841.403689-10-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v2 09/35] pipeline: rkisp1: Use V4L2 requests for the\n\tdewarper","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 06 Nov 2025 01:46:36 +0900","Message-ID":"<176236119689.2116251.12223903999011454476@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]