[{"id":34916,"web_url":"https://patchwork.libcamera.org/comment/34916/","msgid":"<175275744808.1641235.6498869986711737104@ping.linuxembedded.co.uk>","date":"2025-07-17T13:04:08","subject":"Re: [PATCH v3 4/5] pipeline: rkisp1: Properly handle the bufferCount\n\tset in the stream configuration","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2025-07-17 13:59:24)\n> The StreamConfiguration::bufferCount is reset to a hardcoded value of 4\n> in RkISP1Path::validate(). Keep the minimum value of 4 but do not reset\n> it, if it was set to a larger value.  This allows the user to set\n> bufferCount to an arbitrary number of buffers which then can be\n> allocated for example by the FrameBufferAllocator. If the bufferCount is\n> set to a smaller value it gets reset to 4 again and the configuation is\n> market as adjusted.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> Tested-By: Sven Püschel<s.pueschel@pengutronix.de>\n> \n> ---\n> \n> Changes in v3:\n> - Introduced a new constant kRkISP1MinBufferCount\n> - Ensure that bufferCount is at least 4 in validate\n> - Use the stream bufferCount for the number of import buffers, so that\n>   we don't issue cache flushes due to more buffers circulating than\n> imported in V4L2\n\nThanks.\n\n\n> \n> Changes in v1:\n> - Removed todo comment that was solved by this change\n> ---\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp      | 13 +++++++++++--\n>  src/libcamera/pipeline/rkisp1/rkisp1_path.cpp |  7 ++-----\n>  src/libcamera/pipeline/rkisp1/rkisp1_path.h   |  4 +---\n>  3 files changed, 14 insertions(+), 10 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 7954ea82fd0d..aee267a90f4b 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -164,6 +164,8 @@ namespace {\n>   */\n>  static constexpr unsigned int kRkISP1MaxQueuedRequests = 4;\n>  \n> +static constexpr unsigned int kRkISP1MinBufferCount = 4;\n> +\n>  } // namespace\n>  \n>  class PipelineHandlerRkISP1 : public PipelineHandler\n> @@ -607,6 +609,12 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()\n>                                 return false;\n>                 }\n>  \n> +               if (tryCfg.bufferCount < kRkISP1MinBufferCount) {\n> +                       tryCfg.bufferCount = kRkISP1MinBufferCount;\n> +                       if (expectedStatus == Valid)\n> +                               return false;\n> +               }\n> +\n>                 cfg = tryCfg;\n>                 cfg.setStream(stream);\n>                 return true;\n> @@ -796,6 +804,7 @@ PipelineHandlerRkISP1::generateConfiguration(Camera *camera,\n>                         return nullptr;\n>  \n>                 cfg.colorSpace = colorSpace;\n> +               cfg.bufferCount = kRkISP1MinBufferCount;\n>                 config->addConfiguration(cfg);\n>         }\n>  \n> @@ -1129,14 +1138,14 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL\n>         }\n>  \n>         if (data->mainPath_->isEnabled()) {\n> -               ret = mainPath_.start();\n> +               ret = mainPath_.start(data->mainPathStream_.configuration().bufferCount);\n>                 if (ret)\n>                         return ret;\n>                 actions += [&]() { mainPath_.stop(); };\n>         }\n>  \n>         if (hasSelfPath_ && data->selfPath_->isEnabled()) {\n> -               ret = selfPath_.start();\n> +               ret = selfPath_.start(data->selfPathStream_.configuration().bufferCount);\n>                 if (ret)\n>                         return ret;\n\nGreat, that solves my concerns.\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n>         }\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> index 64018dc5b2f4..8ea5500d4080 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> @@ -249,7 +249,6 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size,\n>         StreamConfiguration cfg(formats);\n>         cfg.pixelFormat = format;\n>         cfg.size = streamSize;\n> -       cfg.bufferCount = RKISP1_BUFFER_COUNT;\n>  \n>         return cfg;\n>  }\n> @@ -383,7 +382,6 @@ RkISP1Path::validate(const CameraSensor *sensor,\n>  \n>         cfg->size.boundTo(maxResolution);\n>         cfg->size.expandTo(minResolution);\n> -       cfg->bufferCount = RKISP1_BUFFER_COUNT;\n>  \n>         V4L2DeviceFormat format;\n>         format.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat);\n> @@ -480,15 +478,14 @@ int RkISP1Path::configure(const StreamConfiguration &config,\n>         return 0;\n>  }\n>  \n> -int RkISP1Path::start()\n> +int RkISP1Path::start(unsigned int bufferCount)\n>  {\n>         int ret;\n>  \n>         if (running_)\n>                 return -EBUSY;\n>  \n> -       /* \\todo Make buffer count user configurable. */\n> -       ret = video_->importBuffers(RKISP1_BUFFER_COUNT);\n> +       ret = video_->importBuffers(bufferCount);\n>         if (ret)\n>                 return ret;\n>  \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> index 430181d371a7..0b60c499ac64 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> @@ -58,7 +58,7 @@ public:\n>                 return video_->exportBuffers(bufferCount, buffers);\n>         }\n>  \n> -       int start();\n> +       int start(unsigned int bufferCount);\n>         void stop();\n>  \n>         int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); }\n> @@ -69,8 +69,6 @@ private:\n>         void populateFormats();\n>         Size filterSensorResolution(const CameraSensor *sensor);\n>  \n> -       static constexpr unsigned int RKISP1_BUFFER_COUNT = 4;\n> -\n>         const char *name_;\n>         bool running_;\n>  \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 9885BBE175\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 17 Jul 2025 13:04:13 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CB63A68F7D;\n\tThu, 17 Jul 2025 15:04:12 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8572661517\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 17 Jul 2025 15:04:11 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6AAFBE92;\n\tThu, 17 Jul 2025 15:03:37 +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=\"YhKZ25Ou\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1752757417;\n\tbh=P3Yh85iX7+BWvJ6DzGHaYKnh1VuAkp9yaLQL40dqQ6w=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=YhKZ25OugonaDjcrWFmbFglJaGicGexyPMKe4s+gLyV3qspOtsQO0vDSxvd5ZFePy\n\tVOytn4f9clcFlPZesQiXWGxfTJQFHEJz2j7jl5WDN4HXzweKXiJ8OTbkElvO0W5oJU\n\t8+ONqNTlRDvTD49qWXXv3CWEHtOKYcBYNM9Dll3E=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250717125931.2848300-5-stefan.klug@ideasonboard.com>","References":"<20250717125931.2848300-1-stefan.klug@ideasonboard.com>\n\t<20250717125931.2848300-5-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v3 4/5] pipeline: rkisp1: Properly handle the bufferCount\n\tset in the stream configuration","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>, Sven =?utf-8?q?P=C3=BCsche?=\n\t=?utf-8?q?l?= <s.pueschel@pengutronix.de>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 17 Jul 2025 14:04:08 +0100","Message-ID":"<175275744808.1641235.6498869986711737104@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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":34922,"web_url":"https://patchwork.libcamera.org/comment/34922/","msgid":"<74kym4qubvzhlkdqxwolr652xds7jwepn6iifkvs37x5mege2j@dj6marzmuhsx>","date":"2025-07-18T05:41:52","subject":"Re: [PATCH v3 4/5] pipeline: rkisp1: Properly handle the bufferCount\n\tset in the stream configuration","submitter":{"id":232,"url":"https://patchwork.libcamera.org/api/people/232/","name":"Umang Jain","email":"uajain@igalia.com"},"content":"On Thu, Jul 17, 2025 at 02:59:24PM +0200, Stefan Klug wrote:\n> The StreamConfiguration::bufferCount is reset to a hardcoded value of 4\n> in RkISP1Path::validate(). Keep the minimum value of 4 but do not reset\n> it, if it was set to a larger value.  This allows the user to set\n> bufferCount to an arbitrary number of buffers which then can be\n> allocated for example by the FrameBufferAllocator. If the bufferCount is\n> set to a smaller value it gets reset to 4 again and the configuation is\n\ns/4/kRkISP1MinBufferCount/\n\ns/configuation/configuration\n\n> market as adjusted.\n\ns/market/marked/\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> Tested-By: Sven Püschel<s.pueschel@pengutronix.de>\n> \n> ---\n> \n> Changes in v3:\n> - Introduced a new constant kRkISP1MinBufferCount\n> - Ensure that bufferCount is at least 4 in validate\n> - Use the stream bufferCount for the number of import buffers, so that\n>   we don't issue cache flushes due to more buffers circulating than\n> imported in V4L2\n> \n> Changes in v1:\n> - Removed todo comment that was solved by this change\n> ---\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp      | 13 +++++++++++--\n>  src/libcamera/pipeline/rkisp1/rkisp1_path.cpp |  7 ++-----\n>  src/libcamera/pipeline/rkisp1/rkisp1_path.h   |  4 +---\n>  3 files changed, 14 insertions(+), 10 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 7954ea82fd0d..aee267a90f4b 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -164,6 +164,8 @@ namespace {\n>   */\n>  static constexpr unsigned int kRkISP1MaxQueuedRequests = 4;\n>  \n> +static constexpr unsigned int kRkISP1MinBufferCount = 4;\n> +\n>  } // namespace\n>  \n>  class PipelineHandlerRkISP1 : public PipelineHandler\n> @@ -607,6 +609,12 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()\n>  \t\t\t\treturn false;\n>  \t\t}\n>  \n> +\t\tif (tryCfg.bufferCount < kRkISP1MinBufferCount) {\n> +\t\t\ttryCfg.bufferCount = kRkISP1MinBufferCount;\n> +\t\t\tif (expectedStatus == Valid)\n> +\t\t\t\treturn false;\n> +\t\t}\n> +\n\nI would prefer moving the tryCfg.bufferCount = kRkISP1MinBufferCount; after\nthe expectedStatus == Valid check.\n\nReviewed-by: Umang Jain <uajain@igalia.com>\n\n>  \t\tcfg = tryCfg;\n>  \t\tcfg.setStream(stream);\n>  \t\treturn true;\n> @@ -796,6 +804,7 @@ PipelineHandlerRkISP1::generateConfiguration(Camera *camera,\n>  \t\t\treturn nullptr;\n>  \n>  \t\tcfg.colorSpace = colorSpace;\n> +\t\tcfg.bufferCount = kRkISP1MinBufferCount;\n>  \t\tconfig->addConfiguration(cfg);\n>  \t}\n>  \n> @@ -1129,14 +1138,14 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL\n>  \t}\n>  \n>  \tif (data->mainPath_->isEnabled()) {\n> -\t\tret = mainPath_.start();\n> +\t\tret = mainPath_.start(data->mainPathStream_.configuration().bufferCount);\n>  \t\tif (ret)\n>  \t\t\treturn ret;\n>  \t\tactions += [&]() { mainPath_.stop(); };\n>  \t}\n>  \n>  \tif (hasSelfPath_ && data->selfPath_->isEnabled()) {\n> -\t\tret = selfPath_.start();\n> +\t\tret = selfPath_.start(data->selfPathStream_.configuration().bufferCount);\n>  \t\tif (ret)\n>  \t\t\treturn ret;\n>  \t}\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> index 64018dc5b2f4..8ea5500d4080 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp\n> @@ -249,7 +249,6 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size,\n>  \tStreamConfiguration cfg(formats);\n>  \tcfg.pixelFormat = format;\n>  \tcfg.size = streamSize;\n> -\tcfg.bufferCount = RKISP1_BUFFER_COUNT;\n>  \n>  \treturn cfg;\n>  }\n> @@ -383,7 +382,6 @@ RkISP1Path::validate(const CameraSensor *sensor,\n>  \n>  \tcfg->size.boundTo(maxResolution);\n>  \tcfg->size.expandTo(minResolution);\n> -\tcfg->bufferCount = RKISP1_BUFFER_COUNT;\n>  \n>  \tV4L2DeviceFormat format;\n>  \tformat.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat);\n> @@ -480,15 +478,14 @@ int RkISP1Path::configure(const StreamConfiguration &config,\n>  \treturn 0;\n>  }\n>  \n> -int RkISP1Path::start()\n> +int RkISP1Path::start(unsigned int bufferCount)\n>  {\n>  \tint ret;\n>  \n>  \tif (running_)\n>  \t\treturn -EBUSY;\n>  \n> -\t/* \\todo Make buffer count user configurable. */\n> -\tret = video_->importBuffers(RKISP1_BUFFER_COUNT);\n> +\tret = video_->importBuffers(bufferCount);\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> index 430181d371a7..0b60c499ac64 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h\n> @@ -58,7 +58,7 @@ public:\n>  \t\treturn video_->exportBuffers(bufferCount, buffers);\n>  \t}\n>  \n> -\tint start();\n> +\tint start(unsigned int bufferCount);\n>  \tvoid stop();\n>  \n>  \tint queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); }\n> @@ -69,8 +69,6 @@ private:\n>  \tvoid populateFormats();\n>  \tSize filterSensorResolution(const CameraSensor *sensor);\n>  \n> -\tstatic constexpr unsigned int RKISP1_BUFFER_COUNT = 4;\n> -\n>  \tconst char *name_;\n>  \tbool running_;\n>  \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 A4CB1C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 18 Jul 2025 05:41:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C099568F8E;\n\tFri, 18 Jul 2025 07:41:49 +0200 (CEST)","from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 20CA561508\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 18 Jul 2025 07:41:48 +0200 (CEST)","from [49.36.71.87] (helo=uajain) by fanzine2.igalia.com with\n\tesmtpsa \n\t(Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)\n\t(Exim) id 1ucdqs-000ROR-9p; Fri, 18 Jul 2025 07:41:46 +0200"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=igalia.com header.i=@igalia.com\n\theader.b=\"fY/rocXH\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com;\n\ts=20170329;\n\th=In-Reply-To:Content-Transfer-Encoding:Content-Type:MIME-Version\n\t:References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To:Content-ID:\n\tContent-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc\n\t:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe:\n\tList-Post:List-Owner:List-Archive;\n\tbh=LwDLFAUagI4Kz426vlyjrOK/TE/gKyxHEOO1vadC7m8=;\n\tb=fY/rocXHi07/aQ/X3qF8HG2yZ1\n\t+jY62AOuNf+fAKRF/AHdfiz6PhvAaunP/f8QBqlGmLmr4qdRZpB3Qtmyk8Gu45WNflqVthtXCVTIe\n\t5izMiNQH7OVOiFwfSb4RaQpeSIl+y3a5RZ74ly3re2YKBnAe+90uSAtj4ciXrvonc+xZIjUZby8wq\n\t3u1SThmnqnNlg2Oe9o97bEJt9IEFTSiEUPu+NOF/13o2f/b97G78C5+zImdzcOaTMf88fogUTkAWI\n\tTk8Pm9Ekb92HC35AIr63QmAzaXVzbIPYw9htN2YrJQ4aqTDgRBa+pIeFJpf8voT9IEQD/WjCplFA6\n\t/cIO7qFA==;","Date":"Fri, 18 Jul 2025 11:11:52 +0530","From":"Umang Jain <uajain@igalia.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  Sven =?utf-8?q?P=C3=BCschel?=\n\t<s.pueschel@pengutronix.de>","Subject":"Re: [PATCH v3 4/5] pipeline: rkisp1: Properly handle the bufferCount\n\tset in the stream configuration","Message-ID":"<74kym4qubvzhlkdqxwolr652xds7jwepn6iifkvs37x5mege2j@dj6marzmuhsx>","References":"<20250717125931.2848300-1-stefan.klug@ideasonboard.com>\n\t<20250717125931.2848300-5-stefan.klug@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20250717125931.2848300-5-stefan.klug@ideasonboard.com>","User-Agent":"NeoMutt/20250510-dirty","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>"}}]