[{"id":23647,"web_url":"https://patchwork.libcamera.org/comment/23647/","msgid":"<9873281e9494f29b942e6267807b5fea45713640.camel@collabora.com>","date":"2022-06-28T13:26:13","subject":"Re: [libcamera-devel] [PATCH 11/13] gstreamer: Split request\n\tcreation to a separate function","submitter":{"id":31,"url":"https://patchwork.libcamera.org/api/people/31/","name":"Nicolas Dufresne","email":"nicolas.dufresne@collabora.com"},"content":"Hi Laurent,\n\nLe vendredi 24 juin 2022 à 02:22 +0300, Laurent Pinchart a écrit :\n> In order to prepare for creation and queuing of multiple requests, move\n> the request creation and queueing code to a separate function. No\n> functional change intended.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/gstreamer/gstlibcamerasrc.cpp | 76 +++++++++++++++++--------------\n>  1 file changed, 42 insertions(+), 34 deletions(-)\n> \n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> index 58a322b251c7..fb39d6093a3f 100644\n> --- a/src/gstreamer/gstlibcamerasrc.cpp\n> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> @@ -123,6 +123,7 @@ struct GstLibcameraSrcState {\n>  \n>  \tguint group_id_;\n>  \n> +\tint queueRequest();\n>  \tvoid requestCompleted(Request *request);\n>  };\n>  \n> @@ -160,6 +161,44 @@ GstStaticPadTemplate request_src_template = {\n>  \t\"src_%u\", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS\n>  };\n>  \n> +int GstLibcameraSrcState::queueRequest()\n\nThis function must be called with stream lock held, please comment above the\nfunction.\n\n> +{\n> +\tstd::unique_ptr<Request> request = cam_->createRequest();\n> +\tif (!request)\n> +\t\treturn -ENOMEM;\n> +\n> +\tstd::unique_ptr<RequestWrap> wrap =\n> +\t\tstd::make_unique<RequestWrap>(std::move(request));\n> +\n> +\tfor (GstPad *srcpad : srcpads_) {\n> +\t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n> +\t\tGstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad);\n> +\t\tGstBuffer *buffer;\n> +\t\tGstFlowReturn ret;\n> +\n> +\t\tret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool),\n> +\t\t\t\t\t\t     &buffer, nullptr);\n> +\t\tif (ret != GST_FLOW_OK) {\n> +\t\t\t/*\n> +\t\t\t * RequestWrap has ownership of the request, and we\n> +\t\t\t * won't be queueing this one due to lack of buffers.\n> +\t\t\t */\n> +\t\t\treturn -ENOBUFS;\n> +\t\t}\n> +\n> +\t\twrap->attachBuffer(stream, buffer);\n> +\t}\n> +\n> +\tGST_TRACE_OBJECT(src_, \"Requesting buffers\");\n> +\tcam_->queueRequest(wrap->request_.get());\n> +\n> +\tMutexLocker locker(lock_);\n> +\tqueuedRequests_.push(std::move(wrap));\n\nPossible maintenance trap, add a scope around the locker perhaps ?\n\n> +\n> +\t/* The RequestWrap will be deleted in the completion handler. */\n> +\treturn 0;\n> +}\n> +\n>  void\n>  GstLibcameraSrcState::requestCompleted(Request *request)\n>  {\n> @@ -269,8 +308,8 @@ gst_libcamera_src_task_run(gpointer user_data)\n>  \tGstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);\n>  \tGstLibcameraSrcState *state = self->state;\n>  \n> -\tstd::unique_ptr<Request> request = state->cam_->createRequest();\n> -\tif (!request) {\n> +\tint err = state->queueRequest();\n> +\tif (err == -ENOMEM) {\n>  \t\tGST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT,\n>  \t\t\t\t  (\"Failed to allocate request for camera '%s'.\",\n>  \t\t\t\t   state->cam_->id().c_str()),\n> @@ -279,38 +318,7 @@ gst_libcamera_src_task_run(gpointer user_data)\n>  \t\treturn;\n>  \t}\n>  \n> -\tstd::unique_ptr<RequestWrap> wrap =\n> -\t\tstd::make_unique<RequestWrap>(std::move(request));\n> -\n> -\tfor (GstPad *srcpad : state->srcpads_) {\n> -\t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n> -\t\tGstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad);\n> -\t\tGstBuffer *buffer;\n> -\t\tGstFlowReturn ret;\n> -\n> -\t\tret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool),\n> -\t\t\t\t\t\t     &buffer, nullptr);\n> -\t\tif (ret != GST_FLOW_OK) {\n> -\t\t\t/*\n> -\t\t\t * RequestWrap has ownership of the request, and we\n> -\t\t\t * won't be queueing this one due to lack of buffers.\n> -\t\t\t */\n> -\t\t\twrap.release();\n> -\t\t\tbreak;\n> -\t\t}\n> -\n> -\t\twrap->attachBuffer(stream, buffer);\n> -\t}\n> -\n> -\tif (wrap) {\n> -\t\tGST_TRACE_OBJECT(self, \"Requesting buffers\");\n> -\t\tstate->cam_->queueRequest(wrap->request_.get());\n> -\n> -\t\tMutexLocker locker(state->lock_);\n> -\t\tstate->queuedRequests_.push(std::move(wrap));\n> -\n> -\t\t/* The RequestWrap will be deleted in the completion handler. */\n> -\t}\n> +\tstd::unique_ptr<RequestWrap> wrap;\n>  \n>  \t{\n>  \t\tMutexLocker locker(state->lock_);\n\nNothing major here:\n\nReviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>","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 AB470BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jun 2022 13:26:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C217365635;\n\tTue, 28 Jun 2022 15:26:23 +0200 (CEST)","from madras.collabora.co.uk (madras.collabora.co.uk\n\t[IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C99BB6059D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 15:26:22 +0200 (CEST)","from nicolas-tpx395.localdomain (192-222-136-102.qc.cable.ebox.net\n\t[192.222.136.102])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (4096 bits)\n\tserver-digest SHA256)\n\t(No client certificate requested) (Authenticated sender: nicolas)\n\tby madras.collabora.co.uk (Postfix) with ESMTPSA id E1C9A66015C5;\n\tTue, 28 Jun 2022 14:26:21 +0100 (BST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656422783;\n\tbh=wQAWFhAXMMtODnIsAg2ud/U3lQOoi8Zj1SHJhzlvpP8=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=Q4/+4Z90tzlQSxSOROuEM9fKJ0h6SHpYOjxMDWBt08N5OQgfTjSDjw6gP9ZGVCftg\n\t0pMCxPM84zpy+oWuNpjtcs5sYjlNA791QbvLvniM6VOuARgOK6094D5TeNlNX29c87\n\tnJFdQ5MnU8RDyltV9Hyjgb8CRxjVaCt2WT1TWxqvNrfEVl0S+cz9mNLhzXekUQLroX\n\tZUdWqIFlU0eYfKcWbL1VODGNi5dHaLVLtxwFDsZbFFyqHbAV9NUM1UD7bN++fhc1CK\n\t/FIyFEyVZl+XTFC0VehigAtFEpL8/ulp0xtUK3r2dXc3x+uFHBQq/kYwMrerCmKg1V\n\thFfbmM6xAOnHg==","v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com;\n\ts=mail; t=1656422782;\n\tbh=wQAWFhAXMMtODnIsAg2ud/U3lQOoi8Zj1SHJhzlvpP8=;\n\th=Subject:From:To:Cc:Date:In-Reply-To:References:From;\n\tb=dtaPNkcVAfTpQD43Lj3y3L2+Q+RLlqF7iVO+ujX0te/ivJbTevA0vw/f/v/9uTOWt\n\tI/GfZzC+XntflbT/vtLmzvTOaNsZYy40JO0FKbY/i1E83AyjIhZoQulUVHovbWldEs\n\tDIaJH6dgN2d8Qj7RjgTQAXljsTsRxpJAauY1Selo5RlF8HXhOVjpz+j+aZwbPtNCd8\n\t2DZK61Gd7oCpQxL6Ahbk+2EDXmGXJh1PjmJQjisXU6APfHVcTtNpcjQLdRd5PNz8iT\n\titKIB21IFo3qyDR/9xlN3uD8G4lzfkICrFyaAlBbLaNy9TymU51+Oeawv0nvVrSTm9\n\tA5zH4ChDxmq3w=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=collabora.com\n\theader.i=@collabora.com\n\theader.b=\"dtaPNkcV\"; dkim-atps=neutral","Message-ID":"<9873281e9494f29b942e6267807b5fea45713640.camel@collabora.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org","Date":"Tue, 28 Jun 2022 09:26:13 -0400","In-Reply-To":"<20220623232210.18742-12-laurent.pinchart@ideasonboard.com>","References":"<20220623232210.18742-1-laurent.pinchart@ideasonboard.com>\n\t<20220623232210.18742-12-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","User-Agent":"Evolution 3.44.2 (3.44.2-1.fc36) ","MIME-Version":"1.0","Subject":"Re: [libcamera-devel] [PATCH 11/13] gstreamer: Split request\n\tcreation to a separate function","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>","From":"Nicolas Dufresne via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Nicolas Dufresne <nicolas.dufresne@collabora.com>","Cc":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23653,"web_url":"https://patchwork.libcamera.org/comment/23653/","msgid":"<YrtCQOSkL+tGrLiZ@pendragon.ideasonboard.com>","date":"2022-06-28T18:02:40","subject":"Re: [libcamera-devel] [PATCH 11/13] gstreamer: Split request\n\tcreation to a separate function","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Nicolas,\n\nOn Tue, Jun 28, 2022 at 09:26:13AM -0400, Nicolas Dufresne wrote:\n> Le vendredi 24 juin 2022 à 02:22 +0300, Laurent Pinchart a écrit :\n> > In order to prepare for creation and queuing of multiple requests, move\n> > the request creation and queueing code to a separate function. No\n> > functional change intended.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  src/gstreamer/gstlibcamerasrc.cpp | 76 +++++++++++++++++--------------\n> >  1 file changed, 42 insertions(+), 34 deletions(-)\n> > \n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > index 58a322b251c7..fb39d6093a3f 100644\n> > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > @@ -123,6 +123,7 @@ struct GstLibcameraSrcState {\n> >  \n> >  \tguint group_id_;\n> >  \n> > +\tint queueRequest();\n> >  \tvoid requestCompleted(Request *request);\n> >  };\n> >  \n> > @@ -160,6 +161,44 @@ GstStaticPadTemplate request_src_template = {\n> >  \t\"src_%u\", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS\n> >  };\n> >  \n> > +int GstLibcameraSrcState::queueRequest()\n> \n> This function must be called with stream lock held, please comment above the\n> function.\n> \n> > +{\n> > +\tstd::unique_ptr<Request> request = cam_->createRequest();\n> > +\tif (!request)\n> > +\t\treturn -ENOMEM;\n> > +\n> > +\tstd::unique_ptr<RequestWrap> wrap =\n> > +\t\tstd::make_unique<RequestWrap>(std::move(request));\n> > +\n> > +\tfor (GstPad *srcpad : srcpads_) {\n> > +\t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n> > +\t\tGstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad);\n> > +\t\tGstBuffer *buffer;\n> > +\t\tGstFlowReturn ret;\n> > +\n> > +\t\tret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool),\n> > +\t\t\t\t\t\t     &buffer, nullptr);\n> > +\t\tif (ret != GST_FLOW_OK) {\n> > +\t\t\t/*\n> > +\t\t\t * RequestWrap has ownership of the request, and we\n> > +\t\t\t * won't be queueing this one due to lack of buffers.\n> > +\t\t\t */\n> > +\t\t\treturn -ENOBUFS;\n> > +\t\t}\n> > +\n> > +\t\twrap->attachBuffer(stream, buffer);\n> > +\t}\n> > +\n> > +\tGST_TRACE_OBJECT(src_, \"Requesting buffers\");\n> > +\tcam_->queueRequest(wrap->request_.get());\n> > +\n> > +\tMutexLocker locker(lock_);\n> > +\tqueuedRequests_.push(std::move(wrap));\n> \n> Possible maintenance trap, add a scope around the locker perhaps ?\n\nBoth are good points, I'll fix that.\n\n> > +\n> > +\t/* The RequestWrap will be deleted in the completion handler. */\n> > +\treturn 0;\n> > +}\n> > +\n> >  void\n> >  GstLibcameraSrcState::requestCompleted(Request *request)\n> >  {\n> > @@ -269,8 +308,8 @@ gst_libcamera_src_task_run(gpointer user_data)\n> >  \tGstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);\n> >  \tGstLibcameraSrcState *state = self->state;\n> >  \n> > -\tstd::unique_ptr<Request> request = state->cam_->createRequest();\n> > -\tif (!request) {\n> > +\tint err = state->queueRequest();\n> > +\tif (err == -ENOMEM) {\n> >  \t\tGST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT,\n> >  \t\t\t\t  (\"Failed to allocate request for camera '%s'.\",\n> >  \t\t\t\t   state->cam_->id().c_str()),\n> > @@ -279,38 +318,7 @@ gst_libcamera_src_task_run(gpointer user_data)\n> >  \t\treturn;\n> >  \t}\n> >  \n> > -\tstd::unique_ptr<RequestWrap> wrap =\n> > -\t\tstd::make_unique<RequestWrap>(std::move(request));\n> > -\n> > -\tfor (GstPad *srcpad : state->srcpads_) {\n> > -\t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n> > -\t\tGstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad);\n> > -\t\tGstBuffer *buffer;\n> > -\t\tGstFlowReturn ret;\n> > -\n> > -\t\tret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool),\n> > -\t\t\t\t\t\t     &buffer, nullptr);\n> > -\t\tif (ret != GST_FLOW_OK) {\n> > -\t\t\t/*\n> > -\t\t\t * RequestWrap has ownership of the request, and we\n> > -\t\t\t * won't be queueing this one due to lack of buffers.\n> > -\t\t\t */\n> > -\t\t\twrap.release();\n> > -\t\t\tbreak;\n> > -\t\t}\n> > -\n> > -\t\twrap->attachBuffer(stream, buffer);\n> > -\t}\n> > -\n> > -\tif (wrap) {\n> > -\t\tGST_TRACE_OBJECT(self, \"Requesting buffers\");\n> > -\t\tstate->cam_->queueRequest(wrap->request_.get());\n> > -\n> > -\t\tMutexLocker locker(state->lock_);\n> > -\t\tstate->queuedRequests_.push(std::move(wrap));\n> > -\n> > -\t\t/* The RequestWrap will be deleted in the completion handler. */\n> > -\t}\n> > +\tstd::unique_ptr<RequestWrap> wrap;\n> >  \n> >  \t{\n> >  \t\tMutexLocker locker(state->lock_);\n> \n> Nothing major here:\n> \n> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>","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 D5BE4BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jun 2022 18:03:00 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 94D1865635;\n\tTue, 28 Jun 2022 20:03:00 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E9D766059D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 20:02:59 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 841324A8;\n\tTue, 28 Jun 2022 20:02:59 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656439380;\n\tbh=vvvPpGpntFNhcuuIeV7VxOjepAN+wTX3zWd4ayimSn4=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=PhNJA9lfluaSg1Afux/eZEtkvRUaTX4uMtySZPPadrVtKVwT9gvJEsdERwHvFcpZA\n\twnBcu2BEWX0b+o/woeRwwNMqsN3QexY2j7fG4jStI47kDmMg2Y4dRPchEhK3Sm67K/\n\ttA0UnNnCg6fbmsQj/tGwq+sepArCN54UAyohxiHgsuKr8tzssqwNabOmjdnrRqEowh\n\teWV20Lnff3Rpv92mGA9ewOoXdwloS7dwKCuB1y/I74pBWdwMzY8WtPdGcEevIoz56n\n\tBqPB913FXLaTiH3pcViEKRsWZfPUJjOOyE6uOxcJh8Gp9IlDtVBeF+vxO/+tHJl5gj\n\tyGNtx3V83EKMw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656439379;\n\tbh=vvvPpGpntFNhcuuIeV7VxOjepAN+wTX3zWd4ayimSn4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=PE4RmtkPSry9iA2nYJ4lme3lHH4Hszlw35BJ46sHh4qAA5EafEe50l84EBREjF//D\n\tzFSzLKyOHJ39ebVwbinedb3I7RVAxoGkyiKSS1JLo2R/uae2479+ZjWh4isCFxvgZa\n\ttIyUc9YWjjxIqtdLfL3CeCm+ru6vcOblzvnANMX8="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"PE4RmtkP\"; dkim-atps=neutral","Date":"Tue, 28 Jun 2022 21:02:40 +0300","To":"Nicolas Dufresne <nicolas.dufresne@collabora.com>","Message-ID":"<YrtCQOSkL+tGrLiZ@pendragon.ideasonboard.com>","References":"<20220623232210.18742-1-laurent.pinchart@ideasonboard.com>\n\t<20220623232210.18742-12-laurent.pinchart@ideasonboard.com>\n\t<9873281e9494f29b942e6267807b5fea45713640.camel@collabora.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<9873281e9494f29b942e6267807b5fea45713640.camel@collabora.com>","Subject":"Re: [libcamera-devel] [PATCH 11/13] gstreamer: Split request\n\tcreation to a separate function","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tVedant Paranjape <vedantparanjape160201@gmail.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]