[{"id":27679,"web_url":"https://patchwork.libcamera.org/comment/27679/","msgid":"<169265306080.435850.6265288387452062312@ping.linuxembedded.co.uk>","date":"2023-08-21T21:24:20","subject":"Re: [libcamera-devel] [RFC PATCH v2 4/5] libcamera: pipeline:\n\tuvcvideo: Allocate metadata buffers","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Gabby George (2023-08-21 14:10:38)\n> Perform the allocation and mapping of metadata buffers into\n> libcamera's virtual address space.  UVC metadata buffers cannot be\n> exported as DMA buffer file descriptors, so use the MappedFrameBuffer\n> class to map them into memory directly.  This will give the UVC\n> pipeline access to buffer data to extract timestamp information.\n> \n> Metadata buffers are internal to the UVC pipeline, so buffer memory\n> should not be exposed to the user.\n> \n> Signed-off-by: Gabby George <gabbymg94@gmail.com>\n> ---\n>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 98 +++++++++++++++++++-\n>  1 file changed, 96 insertions(+), 2 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> index dbe0cc8c..c8d6633f 100644\n> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> @@ -24,6 +24,7 @@\n>  \n>  #include \"libcamera/internal/camera.h\"\n>  #include \"libcamera/internal/device_enumerator.h\"\n> +#include \"libcamera/internal/mapped_framebuffer.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n>  #include \"libcamera/internal/sysfs.h\"\n> @@ -51,6 +52,9 @@ public:\n>         std::unique_ptr<V4L2VideoDevice> video_;\n>         std::unique_ptr<V4L2VideoDevice> metadata_;\n>         Stream stream_;\n> +       std::vector<std::unique_ptr<FrameBuffer>> metadataBuffers_;\n> +       std::map<unsigned int, MappedFrameBuffer> mappedMetadataBuffers_;\n> +\n>         std::map<PixelFormat, std::vector<SizeRange>> formats_;\n>  \n>  private:\n> @@ -96,6 +100,10 @@ private:\n>                            const ControlValue &value);\n>         int processControls(UVCCameraData *data, Request *request);\n>  \n> +       int createMetadataBuffers(Camera *camera, unsigned int count);\n> +       int cleanupMetadataBuffers(Camera *camera);\n> +       int cleanup(Camera *camera);\n> +\n>         UVCCameraData *cameraData(Camera *camera)\n>         {\n>                 return static_cast<UVCCameraData *>(camera->_d());\n> @@ -225,10 +233,67 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config)\n>                 return -EINVAL;\n>  \n>         cfg.setStream(&data->stream_);\n> +       return 0;\n> +}\n> +\n> +int PipelineHandlerUVC::cleanupMetadataBuffers(Camera *camera)\n> +{\n> +       int ret = 0;\n\nYou set this and never use it except to return zero. You can just make\nboth this, and cleanup() 'void' return functions.\n\n\n> +       UVCCameraData *data = cameraData(camera);\n> +\n> +       if (data->metadata_)\n> +               data->metadata_->releaseBuffers();\n> +       data->metadataBuffers_.clear();\n> +       data->mappedMetadataBuffers_.clear();\n> +       data->metadata_ = nullptr;\n>  \n> +       return ret;\n> +}\n> +\n> +int PipelineHandlerUVC::cleanup(Camera *camera)\n> +{\n> +       UVCCameraData *data = cameraData(camera);\n> +       cleanupMetadataBuffers(camera);\n> +       data->video_->releaseBuffers();\n>         return 0;\n>  }\n>  \n> +/**\n> + * UVC Metadata stream does not support exporting buffers via EXPBUF,\n> + * so it is necessary to create and store mmap-ed addresses.\n> + * Metadata buffers are internal to libcamera. They are not, and\n> + * cannot be, exposed to the user.\n> + *\n> + * Returns the number of buffers allocated and mapped.\n> + *\n> + * \\return The number of buffers allocated, or a negative error code if\n> + * the number of buffers allocated was not equal to \"count\"\n> + * \\retval -EINVAL if \"count\" buffers were not successfully allocated.\n> + * \\retval MappedFrameBuffer::error()\n> + */\n> +int PipelineHandlerUVC::createMetadataBuffers(Camera *camera, unsigned int count)\n> +{\n> +       UVCCameraData *data = cameraData(camera);\n> +       int ret = data->metadata_->allocateBuffers(count, &data->metadataBuffers_);\n> +       if (ret < 0)\n> +               return -EINVAL;\n> +\n> +       for (unsigned int i = 0; i < count; i++) {\n> +               MappedFrameBuffer mappedBuffer(data->metadataBuffers_[i].get(),\n> +                                              MappedFrameBuffer::MapFlag::Read, true);\n> +               if (!mappedBuffer.isValid()) {\n> +                       LOG(UVC, Warning)\n> +                               << \"Failed to mmap metadata buffer: \"\n> +                               << strerror(mappedBuffer.error());\n> +                       return mappedBuffer.error();\n> +               }\n> +\n> +               data->mappedMetadataBuffers_.emplace(i, std::move(mappedBuffer));\n> +               data->metadataBuffers_[i]->setCookie(i);\n> +       }\n> +       return ret;\n> +}\n> +\n>  int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,\n>                                            std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n>  {\n> @@ -249,18 +314,47 @@ int PipelineHandlerUVC::start(Camera *camera, [[maybe_unused]] const ControlList\n>  \n>         ret = data->video_->streamOn();\n>         if (ret < 0) {\n> -               data->video_->releaseBuffers();\n> +               cleanup(camera);\n>                 return ret;\n>         }\n>  \n> +       /*\n> +        * If metadata allocation fails, exit this function but\n> +        * do not return a failure as video started successfully.\n> +        * Fall back on using driver timestamps.\n> +        */\n> +       if (data->metadata_) {\n\nShould metadata buffers be allocated and queued before calling streamOn\non the main video device so that it is capable of handling metadata for\nthe first frame? I think this section should all be above the\ndata->video_->streamOn() above.\n\n\n\n> +               if (createMetadataBuffers(camera, count) < 0 ||\n> +                   data->metadata_->streamOn()) {\n> +                       LOG(UVC, Warning)\n> +                               << \"Metadata stream unavailable.  Using driver timestamps.\";\n> +                       data->metadata_ = nullptr;\n> +                       return 0;\n> +               }\n> +\n> +               for (std::unique_ptr<FrameBuffer> &buf : data->metadataBuffers_) {\n> +                       ret = data->metadata_->queueBuffer(buf.get());\n> +                       if (ret < 0) {\n> +                               LOG(UVC, Warning)\n> +                                       << \"Metadata stream unavailable.  Using driver timestamps.\";\n> +                               cleanupMetadataBuffers(camera);\n> +                               return 0;\n> +                       }\n> +               }\n> +       }\n>         return 0;\n>  }\n>  \n>  void PipelineHandlerUVC::stopDevice(Camera *camera)\n>  {\n>         UVCCameraData *data = cameraData(camera);\n> +\n>         data->video_->streamOff();\n> -       data->video_->releaseBuffers();\n> +\n> +       if (data->metadata_)\n> +               data->metadata_->streamOff();\n> +\n> +       cleanup(camera);\n>  }\n>  \n>  int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,\n> -- \n> 2.34.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 DEB54BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 21 Aug 2023 21:24:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1CA8B61E09;\n\tMon, 21 Aug 2023 23:24:27 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C585761E09\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 21 Aug 2023 23:24:23 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(aztw-30-b2-v4wan-166917-cust845.vm26.cable.virginm.net\n\t[82.37.23.78])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 018BC83F;\n\tMon, 21 Aug 2023 23:23:06 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1692653067;\n\tbh=p4IYGA9C7cZcQyGVl4FL9reIgJ/DXkiSuTul5BDth1A=;\n\th=In-Reply-To:References:To:Date:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=F1PetLOox7Q77+MJ/0JQf+jYgSfl+qemb7FvX8dLUp6O014g/I87WMfKdKLSRLrr4\n\t2i6/xC3YPM2tDyd4GGe/XxWBDutN9pPknq7ASGRcnP5g6CSE7re9sFnTP5Z11gwODs\n\tRwlchFuPyzJHYPXObi7PACEgGm3TZreqJMYHwkhFa5qH3i3dZl3UllZvgOaz8hdkt/\n\txo5mwNJd9lKTco8KHofRjI9VOecBenRI30Y3k4oRVk2qbKKiZDtsUPY91Z/ZLQ0yin\n\t6xnkRobByp1QpE1cFRbpg1uJv3T/62hmuLW5a9DKObfbvun/e9ZIdG7BwDk5s/EVLb\n\tZdgOKdtlscOow==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1692652987;\n\tbh=p4IYGA9C7cZcQyGVl4FL9reIgJ/DXkiSuTul5BDth1A=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=edaT1wv3JWOGVEhhWhStV/RDdOE7FdjDTzN5EY5dCBJLlOTjhBQfNuBvMEQ3jAvGO\n\taxGwefYiSOGAZKTDrtK/sax90phGlTdObEJPqB0E5fKSpFKtkuNY0+N1a2/+mcfWdv\n\tJFLvbmynDmu4e7LP6xdKFQpupTStawhNOntwwef0="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"edaT1wv3\"; dkim-atps=neutral","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20230821131039.127370-5-gabbymg94@gmail.com>","References":"<20230821131039.127370-1-gabbymg94@gmail.com>\n\t<20230821131039.127370-5-gabbymg94@gmail.com>","To":"gabbymg94@gmail.com, libcamera-devel@lists.libcamera.org,\n\tvedantparanjape160201@gmail.com","Date":"Mon, 21 Aug 2023 22:24:20 +0100","Message-ID":"<169265306080.435850.6265288387452062312@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","Subject":"Re: [libcamera-devel] [RFC PATCH v2 4/5] libcamera: pipeline:\n\tuvcvideo: Allocate metadata buffers","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":"Kieran Bingham via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":27702,"web_url":"https://patchwork.libcamera.org/comment/27702/","msgid":"<20230828212601.GI17083@pendragon.ideasonboard.com>","date":"2023-08-28T21:26:01","subject":"Re: [libcamera-devel] [RFC PATCH v2 4/5] libcamera: pipeline:\n\tuvcvideo: Allocate metadata buffers","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Mon, Aug 21, 2023 at 10:24:20PM +0100, Kieran Bingham via libcamera-devel wrote:\n> Quoting Gabby George (2023-08-21 14:10:38)\n> > Perform the allocation and mapping of metadata buffers into\n> > libcamera's virtual address space.  UVC metadata buffers cannot be\n> > exported as DMA buffer file descriptors, so use the MappedFrameBuffer\n> > class to map them into memory directly.  This will give the UVC\n> > pipeline access to buffer data to extract timestamp information.\n> > \n> > Metadata buffers are internal to the UVC pipeline, so buffer memory\n> > should not be exposed to the user.\n> > \n> > Signed-off-by: Gabby George <gabbymg94@gmail.com>\n> > ---\n> >  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 98 +++++++++++++++++++-\n> >  1 file changed, 96 insertions(+), 2 deletions(-)\n> > \n> > diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> > index dbe0cc8c..c8d6633f 100644\n> > --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> > +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> > @@ -24,6 +24,7 @@\n> >  \n> >  #include \"libcamera/internal/camera.h\"\n> >  #include \"libcamera/internal/device_enumerator.h\"\n> > +#include \"libcamera/internal/mapped_framebuffer.h\"\n> >  #include \"libcamera/internal/media_device.h\"\n> >  #include \"libcamera/internal/pipeline_handler.h\"\n> >  #include \"libcamera/internal/sysfs.h\"\n> > @@ -51,6 +52,9 @@ public:\n> >         std::unique_ptr<V4L2VideoDevice> video_;\n> >         std::unique_ptr<V4L2VideoDevice> metadata_;\n> >         Stream stream_;\n> > +       std::vector<std::unique_ptr<FrameBuffer>> metadataBuffers_;\n> > +       std::map<unsigned int, MappedFrameBuffer> mappedMetadataBuffers_;\n> > +\n> >         std::map<PixelFormat, std::vector<SizeRange>> formats_;\n> >  \n> >  private:\n> > @@ -96,6 +100,10 @@ private:\n> >                            const ControlValue &value);\n> >         int processControls(UVCCameraData *data, Request *request);\n> >  \n> > +       int createMetadataBuffers(Camera *camera, unsigned int count);\n> > +       int cleanupMetadataBuffers(Camera *camera);\n> > +       int cleanup(Camera *camera);\n> > +\n> >         UVCCameraData *cameraData(Camera *camera)\n> >         {\n> >                 return static_cast<UVCCameraData *>(camera->_d());\n> > @@ -225,10 +233,67 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config)\n> >                 return -EINVAL;\n> >  \n> >         cfg.setStream(&data->stream_);\n> > +       return 0;\n> > +}\n> > +\n> > +int PipelineHandlerUVC::cleanupMetadataBuffers(Camera *camera)\n> > +{\n> > +       int ret = 0;\n> \n> You set this and never use it except to return zero. You can just make\n> both this, and cleanup() 'void' return functions.\n> \n> \n> > +       UVCCameraData *data = cameraData(camera);\n> > +\n> > +       if (data->metadata_)\n> > +               data->metadata_->releaseBuffers();\n> > +       data->metadataBuffers_.clear();\n> > +       data->mappedMetadataBuffers_.clear();\n> > +       data->metadata_ = nullptr;\n> >  \n> > +       return ret;\n> > +}\n> > +\n> > +int PipelineHandlerUVC::cleanup(Camera *camera)\n\n\"cleanup\" is an ambiguous name. It perform some cleanups associated with\nstopping capture, but it could also be understood as cleaning up the\nwhole pipeline handler. releaseBuffers() could be a better name.\nSimilarly, you could name the previous function\nreleaseMetadataBuffers().\n\n> > +{\n> > +       UVCCameraData *data = cameraData(camera);\n> > +       cleanupMetadataBuffers(camera);\n> > +       data->video_->releaseBuffers();\n> >         return 0;\n> >  }\n> >  \n> > +/**\n> > + * UVC Metadata stream does not support exporting buffers via EXPBUF,\n> > + * so it is necessary to create and store mmap-ed addresses.\n> > + * Metadata buffers are internal to libcamera. They are not, and\n> > + * cannot be, exposed to the user.\n> > + *\n> > + * Returns the number of buffers allocated and mapped.\n> > + *\n> > + * \\return The number of buffers allocated, or a negative error code if\n> > + * the number of buffers allocated was not equal to \"count\"\n> > + * \\retval -EINVAL if \"count\" buffers were not successfully allocated.\n> > + * \\retval MappedFrameBuffer::error()\n> > + */\n> > +int PipelineHandlerUVC::createMetadataBuffers(Camera *camera, unsigned int count)\n> > +{\n> > +       UVCCameraData *data = cameraData(camera);\n> > +       int ret = data->metadata_->allocateBuffers(count, &data->metadataBuffers_);\n> > +       if (ret < 0)\n> > +               return -EINVAL;\n> > +\n> > +       for (unsigned int i = 0; i < count; i++) {\n> > +               MappedFrameBuffer mappedBuffer(data->metadataBuffers_[i].get(),\n> > +                                              MappedFrameBuffer::MapFlag::Read, true);\n> > +               if (!mappedBuffer.isValid()) {\n> > +                       LOG(UVC, Warning)\n> > +                               << \"Failed to mmap metadata buffer: \"\n> > +                               << strerror(mappedBuffer.error());\n> > +                       return mappedBuffer.error();\n> > +               }\n> > +\n> > +               data->mappedMetadataBuffers_.emplace(i, std::move(mappedBuffer));\n\nThis map key is the index in the metadataBuffers_ vector, is there a\nreason to use a map instead of a vector ?\n\n> > +               data->metadataBuffers_[i]->setCookie(i);\n> > +       }\n> > +       return ret;\n> > +}\n> > +\n> >  int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,\n> >                                            std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n> >  {\n> > @@ -249,18 +314,47 @@ int PipelineHandlerUVC::start(Camera *camera, [[maybe_unused]] const ControlList\n> >  \n> >         ret = data->video_->streamOn();\n> >         if (ret < 0) {\n> > -               data->video_->releaseBuffers();\n> > +               cleanup(camera);\n> >                 return ret;\n> >         }\n> >  \n> > +       /*\n> > +        * If metadata allocation fails, exit this function but\n> > +        * do not return a failure as video started successfully.\n> > +        * Fall back on using driver timestamps.\n> > +        */\n> > +       if (data->metadata_) {\n> \n> Should metadata buffers be allocated and queued before calling streamOn\n> on the main video device so that it is capable of handling metadata for\n> the first frame? I think this section should all be above the\n> data->video_->streamOn() above.\n\nThat sounds like a good idea.\n\n> > +               if (createMetadataBuffers(camera, count) < 0 ||\n> > +                   data->metadata_->streamOn()) {\n> > +                       LOG(UVC, Warning)\n> > +                               << \"Metadata stream unavailable.  Using driver timestamps.\";\n> > +                       data->metadata_ = nullptr;\n> > +                       return 0;\n> > +               }\n> > +\n> > +               for (std::unique_ptr<FrameBuffer> &buf : data->metadataBuffers_) {\n> > +                       ret = data->metadata_->queueBuffer(buf.get());\n> > +                       if (ret < 0) {\n> > +                               LOG(UVC, Warning)\n> > +                                       << \"Metadata stream unavailable.  Using driver timestamps.\";\n> > +                               cleanupMetadataBuffers(camera);\n> > +                               return 0;\n> > +                       }\n> > +               }\n> > +       }\n\nMissing blank line.\n\n> >         return 0;\n> >  }\n> >  \n> >  void PipelineHandlerUVC::stopDevice(Camera *camera)\n> >  {\n> >         UVCCameraData *data = cameraData(camera);\n> > +\n> >         data->video_->streamOff();\n> > -       data->video_->releaseBuffers();\n> > +\n> > +       if (data->metadata_)\n> > +               data->metadata_->streamOff();\n> > +\n> > +       cleanup(camera);\n> >  }\n> >  \n> >  int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,","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 9F492BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 28 Aug 2023 21:25:54 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F3F67627D6;\n\tMon, 28 Aug 2023 23:25:53 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9040661F18\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 28 Aug 2023 23:25:52 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(117.145-247-81.adsl-dyn.isp.belgacom.be [81.247.145.117])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EA3ABE51;\n\tMon, 28 Aug 2023 23:24:30 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1693257954;\n\tbh=9EmqTEddnAi1RV9kkdtsDabwjefhS7xvTrNvxV6zPyI=;\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=VZLgF+gZUgBvPQWLnsRuvKJsfi7sOXzwe46U0L7NUR+/SW/7l/2ii7G1P0bFqf9Tx\n\t8FPgny2TIU3Dq3iaOP1JhqSswk20gRszCrNpQhnSiEGQ8We5WVAubATXG0vs5EaH+f\n\t3gWBNOLuV9mU3aVC2w/kElR2L6NxSusYC+kQXpYX3uup0ZDQMntTl9eYp1xKKmNMII\n\tmRYEik2at7d4hKWaWmA1OFA3GV3poNIBM3JjRZKWpIaT6E+HlZqG3Hyz8PknEm85j+\n\taWQpp6unCZcjQ792jwQixfu6Bgf9COQYPgTCS8Vxxn98Zj3MSKVDyyu0I6bZywAhMc\n\t2XZGvBSxz5kPQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1693257871;\n\tbh=9EmqTEddnAi1RV9kkdtsDabwjefhS7xvTrNvxV6zPyI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=kL/Gh2agGsGpgOuLcBm0qxkT0tTZd50hRv6R4gpyo7aA0XVMQbHglBVLesJ/bjOnU\n\tUYZqPJrxghK8eAMITeWbJHDJb2RnxyiDBjxD9idoyDmVrf+BqI2VVXQa+y4eQQLqcd\n\t+TockopzWdAjCEJfd7WEJbxtYEuj+I/ewrUFUS+s="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"kL/Gh2ag\"; dkim-atps=neutral","Date":"Tue, 29 Aug 2023 00:26:01 +0300","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Message-ID":"<20230828212601.GI17083@pendragon.ideasonboard.com>","References":"<20230821131039.127370-1-gabbymg94@gmail.com>\n\t<20230821131039.127370-5-gabbymg94@gmail.com>\n\t<169265306080.435850.6265288387452062312@ping.linuxembedded.co.uk>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<169265306080.435850.6265288387452062312@ping.linuxembedded.co.uk>","Subject":"Re: [libcamera-devel] [RFC PATCH v2 4/5] libcamera: pipeline:\n\tuvcvideo: Allocate metadata buffers","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, vedantparanjape160201@gmail.com","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]