[{"id":30209,"web_url":"https://patchwork.libcamera.org/comment/30209/","msgid":"<ZoPp6ml3k70xPCip@pyrite.rasen.tech>","date":"2024-07-02T11:52:10","subject":"Re: [PATCH v4 4/4] libcamera: converter: Replace usage of stream\n\tindex by Stream pointer","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"On Mon, Jun 24, 2024 at 07:18:59PM +0530, Umang Jain wrote:\n> The converter interface uses the unsigned int output stream index to map\n> to the output frame buffers. This is cumbersome to implement new\n> converters because one has to keep around additional book keeping\n> to track the streams with their correct indexes.\n> \n> The v4l2_converter_m2m and simple pipeline handler are adapted to\n> use the new interface. This work roped in software ISP as well,\n> which also seems to use indexes (although it doesn't implement converter\n> interface) because of a common conversionQueue_ queue used for\n> converter_ and swIsp_.\n> \n> The logPrefix is no longer able to generate an index from a stream, and\n> is updated to be more expressive by reporting the stream configuration\n> instead, for example, reporting \"1920x1080-MJPEG\" in place of\n> \"stream0\".\n> \n> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  include/libcamera/internal/converter.h        |  5 ++-\n>  .../internal/converter/converter_v4l2_m2m.h   | 11 ++---\n>  .../internal/software_isp/software_isp.h      |  5 ++-\n>  src/libcamera/converter.cpp                   |  6 +--\n>  .../converter/converter_v4l2_m2m.cpp          | 42 ++++++++++---------\n>  src/libcamera/pipeline/simple/simple.cpp      | 14 +++----\n>  src/libcamera/software_isp/software_isp.cpp   | 17 ++++----\n>  7 files changed, 52 insertions(+), 48 deletions(-)\n> \n> diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h\n> index 5d74db6b..b51563d7 100644\n> --- a/include/libcamera/internal/converter.h\n> +++ b/include/libcamera/internal/converter.h\n> @@ -26,6 +26,7 @@ namespace libcamera {\n>  class FrameBuffer;\n>  class MediaDevice;\n>  class PixelFormat;\n> +class Stream;\n>  struct StreamConfiguration;\n>  \n>  class Converter\n> @@ -46,14 +47,14 @@ public:\n>  \n>  \tvirtual int configure(const StreamConfiguration &inputCfg,\n>  \t\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0;\n> -\tvirtual int exportBuffers(unsigned int output, unsigned int count,\n> +\tvirtual int exportBuffers(const Stream *stream, unsigned int count,\n>  \t\t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;\n>  \n>  \tvirtual int start() = 0;\n>  \tvirtual void stop() = 0;\n>  \n>  \tvirtual int queueBuffers(FrameBuffer *input,\n> -\t\t\t\t const std::map<unsigned int, FrameBuffer *> &outputs) = 0;\n> +\t\t\t\t const std::map<const Stream *, FrameBuffer *> &outputs) = 0;\n>  \n>  \tSignal<FrameBuffer *> inputBufferReady;\n>  \tSignal<FrameBuffer *> outputBufferReady;\n> diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h\n> index 0da62290..b9e59899 100644\n> --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h\n> +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h\n> @@ -28,6 +28,7 @@ class FrameBuffer;\n>  class MediaDevice;\n>  class Size;\n>  class SizeRange;\n> +class Stream;\n>  struct StreamConfiguration;\n>  class V4L2M2MDevice;\n>  \n> @@ -47,20 +48,20 @@ public:\n>  \n>  \tint configure(const StreamConfiguration &inputCfg,\n>  \t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfg);\n> -\tint exportBuffers(unsigned int output, unsigned int count,\n> +\tint exportBuffers(const Stream *stream, unsigned int count,\n>  \t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n>  \n>  \tint start();\n>  \tvoid stop();\n>  \n>  \tint queueBuffers(FrameBuffer *input,\n> -\t\t\t const std::map<unsigned int, FrameBuffer *> &outputs);\n> +\t\t\t const std::map<const Stream *, FrameBuffer *> &outputs);\n>  \n>  private:\n>  \tclass V4L2M2MStream : protected Loggable\n>  \t{\n>  \tpublic:\n> -\t\tV4L2M2MStream(V4L2M2MConverter *converter, unsigned int index);\n> +\t\tV4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream);\n>  \n>  \t\tbool isValid() const { return m2m_ != nullptr; }\n>  \n> @@ -82,7 +83,7 @@ private:\n>  \t\tvoid outputBufferReady(FrameBuffer *buffer);\n>  \n>  \t\tV4L2M2MConverter *converter_;\n> -\t\tunsigned int index_;\n> +\t\tconst Stream *stream_;\n>  \t\tstd::unique_ptr<V4L2M2MDevice> m2m_;\n>  \n>  \t\tunsigned int inputBufferCount_;\n> @@ -91,7 +92,7 @@ private:\n>  \n>  \tstd::unique_ptr<V4L2M2MDevice> m2m_;\n>  \n> -\tstd::vector<V4L2M2MStream> streams_;\n> +\tstd::map<const Stream *, std::unique_ptr<V4L2M2MStream>> streams_;\n>  \tstd::map<FrameBuffer *, unsigned int> queue_;\n>  };\n>  \n> diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h\n> index c5338c05..f8e00003 100644\n> --- a/include/libcamera/internal/software_isp/software_isp.h\n> +++ b/include/libcamera/internal/software_isp/software_isp.h\n> @@ -37,6 +37,7 @@ namespace libcamera {\n>  class DebayerCpu;\n>  class FrameBuffer;\n>  class PixelFormat;\n> +class Stream;\n>  struct StreamConfiguration;\n>  \n>  LOG_DECLARE_CATEGORY(SoftwareIsp)\n> @@ -62,7 +63,7 @@ public:\n>  \t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n>  \t\t      const ControlInfoMap &sensorControls);\n>  \n> -\tint exportBuffers(unsigned int output, unsigned int count,\n> +\tint exportBuffers(const Stream *stream, unsigned int count,\n>  \t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n>  \n>  \tvoid processStats(const ControlList &sensorControls);\n> @@ -71,7 +72,7 @@ public:\n>  \tvoid stop();\n>  \n>  \tint queueBuffers(FrameBuffer *input,\n> -\t\t\t const std::map<unsigned int, FrameBuffer *> &outputs);\n> +\t\t\t const std::map<const Stream *, FrameBuffer *> &outputs);\n>  \n>  \tvoid process(FrameBuffer *input, FrameBuffer *output);\n>  \n> diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp\n> index d3d38c1b..c5e38937 100644\n> --- a/src/libcamera/converter.cpp\n> +++ b/src/libcamera/converter.cpp\n> @@ -111,12 +111,12 @@ Converter::~Converter()\n>  /**\n>   * \\fn Converter::exportBuffers()\n>   * \\brief Export buffers from the converter device\n> - * \\param[in] output Output stream index exporting the buffers\n> + * \\param[in] stream Output stream pointer exporting the buffers\n>   * \\param[in] count Number of buffers to allocate\n>   * \\param[out] buffers Vector to store allocated buffers\n>   *\n>   * This function operates similarly to V4L2VideoDevice::exportBuffers() on the\n> - * output stream indicated by the \\a output index.\n> + * output stream indicated by the \\a output.\n>   *\n>   * \\return The number of allocated buffers on success or a negative error code\n>   * otherwise\n> @@ -137,7 +137,7 @@ Converter::~Converter()\n>   * \\fn Converter::queueBuffers()\n>   * \\brief Queue buffers to converter device\n>   * \\param[in] input The frame buffer to apply the conversion\n> - * \\param[out] outputs The container holding the output stream indexes and\n> + * \\param[out] outputs The container holding the output stream pointer and\n\ns/pointer/pointers/\n\n>   * their respective frame buffer outputs.\n>   *\n>   * This function queues the \\a input frame buffer on the output streams of the\n> diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp\n> index 6309a0c0..2e77872e 100644\n> --- a/src/libcamera/converter/converter_v4l2_m2m.cpp\n> +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp\n> @@ -35,8 +35,8 @@ LOG_DECLARE_CATEGORY(Converter)\n>   * V4L2M2MConverter::V4L2M2MStream\n>   */\n>  \n> -V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, unsigned int index)\n> -\t: converter_(converter), index_(index)\n> +V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream)\n> +\t: converter_(converter), stream_(stream)\n>  {\n>  \tm2m_ = std::make_unique<V4L2M2MDevice>(converter->deviceNode());\n>  \n> @@ -157,7 +157,7 @@ int V4L2M2MConverter::V4L2M2MStream::queueBuffers(FrameBuffer *input, FrameBuffe\n>  \n>  std::string V4L2M2MConverter::V4L2M2MStream::logPrefix() const\n>  {\n> -\treturn \"stream\" + std::to_string(index_);\n> +\treturn stream_->configuration().toString();\n>  }\n>  \n>  void V4L2M2MConverter::V4L2M2MStream::outputBufferReady(FrameBuffer *buffer)\n> @@ -333,21 +333,24 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg,\n>  \tint ret = 0;\n>  \n>  \tstreams_.clear();\n> -\tstreams_.reserve(outputCfgs.size());\n>  \n>  \tfor (unsigned int i = 0; i < outputCfgs.size(); ++i) {\n> -\t\tV4L2M2MStream &stream = streams_.emplace_back(this, i);\n> +\t\tconst StreamConfiguration &cfg = outputCfgs[i];\n> +\t\tstd::unique_ptr<V4L2M2MStream> stream =\n> +\t\t\tstd::make_unique<V4L2M2MStream>(this, cfg.stream());\n>  \n> -\t\tif (!stream.isValid()) {\n> +\t\tif (!stream->isValid()) {\n>  \t\t\tLOG(Converter, Error)\n>  \t\t\t\t<< \"Failed to create stream \" << i;\n>  \t\t\tret = -EINVAL;\n>  \t\t\tbreak;\n>  \t\t}\n>  \n> -\t\tret = stream.configure(inputCfg, outputCfgs[i]);\n> +\t\tret = stream->configure(inputCfg, cfg);\n>  \t\tif (ret < 0)\n>  \t\t\tbreak;\n> +\n> +\t\tstreams_.emplace(cfg.stream(), std::move(stream));\n>  \t}\n>  \n>  \tif (ret < 0) {\n> @@ -361,13 +364,14 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg,\n>  /**\n>   * \\copydoc libcamera::Converter::exportBuffers\n>   */\n> -int V4L2M2MConverter::exportBuffers(unsigned int output, unsigned int count,\n> +int V4L2M2MConverter::exportBuffers(const Stream *stream, unsigned int count,\n>  \t\t\t\t    std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n>  {\n> -\tif (output >= streams_.size())\n> +\tauto iter = streams_.find(stream);\n> +\tif (iter == streams_.end())\n>  \t\treturn -EINVAL;\n>  \n> -\treturn streams_[output].exportBuffers(count, buffers);\n> +\treturn iter->second->exportBuffers(count, buffers);\n>  }\n>  \n>  /**\n> @@ -377,8 +381,8 @@ int V4L2M2MConverter::start()\n>  {\n>  \tint ret;\n>  \n> -\tfor (V4L2M2MStream &stream : streams_) {\n> -\t\tret = stream.start();\n> +\tfor (auto &iter : streams_) {\n> +\t\tret = iter.second->start();\n>  \t\tif (ret < 0) {\n>  \t\t\tstop();\n>  \t\t\treturn ret;\n> @@ -393,15 +397,15 @@ int V4L2M2MConverter::start()\n>   */\n>  void V4L2M2MConverter::stop()\n>  {\n> -\tfor (V4L2M2MStream &stream : utils::reverse(streams_))\n> -\t\tstream.stop();\n> +\tfor (auto &iter : streams_)\n> +\t\titer.second->stop();\n>  }\n>  \n>  /**\n>   * \\copydoc libcamera::Converter::queueBuffers\n>   */\n>  int V4L2M2MConverter::queueBuffers(FrameBuffer *input,\n> -\t\t\t\t   const std::map<unsigned int, FrameBuffer *> &outputs)\n> +\t\t\t\t   const std::map<const Stream *, FrameBuffer *> &outputs)\n>  {\n>  \tstd::set<FrameBuffer *> outputBufs;\n>  \tint ret;\n> @@ -414,11 +418,9 @@ int V4L2M2MConverter::queueBuffers(FrameBuffer *input,\n>  \tif (outputs.empty())\n>  \t\treturn -EINVAL;\n>  \n> -\tfor (auto [index, buffer] : outputs) {\n> +\tfor (auto [stream, buffer] : outputs) {\n>  \t\tif (!buffer)\n>  \t\t\treturn -EINVAL;\n> -\t\tif (index >= streams_.size())\n> -\t\t\treturn -EINVAL;\n>  \n>  \t\toutputBufs.insert(buffer);\n>  \t}\n> @@ -427,8 +429,8 @@ int V4L2M2MConverter::queueBuffers(FrameBuffer *input,\n>  \t\treturn -EINVAL;\n>  \n>  \t/* Queue the input and output buffers to all the streams. */\n> -\tfor (auto [index, buffer] : outputs) {\n> -\t\tret = streams_[index].queueBuffers(input, buffer);\n> +\tfor (auto [stream, buffer] : outputs) {\n> +\t\tret = streams_.at(stream)->queueBuffers(input, buffer);\n>  \t\tif (ret < 0)\n>  \t\t\treturn ret;\n>  \t}\n> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> index eb36578e..5eb1dd21 100644\n> --- a/src/libcamera/pipeline/simple/simple.cpp\n> +++ b/src/libcamera/pipeline/simple/simple.cpp\n> @@ -277,7 +277,7 @@ public:\n>  \tstd::map<PixelFormat, std::vector<const Configuration *>> formats_;\n>  \n>  \tstd::vector<std::unique_ptr<FrameBuffer>> conversionBuffers_;\n> -\tstd::queue<std::map<unsigned int, FrameBuffer *>> conversionQueue_;\n> +\tstd::queue<std::map<const Stream *, FrameBuffer *>> conversionQueue_;\n>  \tbool useConversion_;\n>  \n>  \tstd::unique_ptr<Converter> converter_;\n> @@ -836,7 +836,7 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer)\n>  \tRequest *request = buffer->request();\n>  \n>  \tif (useConversion_ && !conversionQueue_.empty()) {\n> -\t\tconst std::map<unsigned int, FrameBuffer *> &outputs =\n> +\t\tconst std::map<const Stream *, FrameBuffer *> &outputs =\n>  \t\t\tconversionQueue_.front();\n>  \t\tif (!outputs.empty()) {\n>  \t\t\tFrameBuffer *outputBuffer = outputs.begin()->second;\n> @@ -1303,10 +1303,8 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,\n>  \t */\n>  \tif (data->useConversion_)\n>  \t\treturn data->converter_\n> -\t\t\t       ? data->converter_->exportBuffers(data->streamIndex(stream),\n> -\t\t\t\t\t\t\t\t count, buffers)\n> -\t\t\t       : data->swIsp_->exportBuffers(data->streamIndex(stream),\n> -\t\t\t\t\t\t\t     count, buffers);\n> +\t\t\t       ? data->converter_->exportBuffers(stream, count, buffers)\n> +\t\t\t       : data->swIsp_->exportBuffers(stream, count, buffers);\n>  \telse\n>  \t\treturn data->video_->exportBuffers(count, buffers);\n>  }\n> @@ -1398,7 +1396,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request)\n>  \tSimpleCameraData *data = cameraData(camera);\n>  \tint ret;\n>  \n> -\tstd::map<unsigned int, FrameBuffer *> buffers;\n> +\tstd::map<const Stream *, FrameBuffer *> buffers;\n>  \n>  \tfor (auto &[stream, buffer] : request->buffers()) {\n>  \t\t/*\n> @@ -1407,7 +1405,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request)\n>  \t\t * completion handler.\n>  \t\t */\n>  \t\tif (data->useConversion_) {\n> -\t\t\tbuffers.emplace(data->streamIndex(stream), buffer);\n> +\t\t\tbuffers.emplace(stream, buffer);\n>  \t\t} else {\n>  \t\t\tret = data->video_->queueBuffer(buffer);\n>  \t\t\tif (ret < 0)\n> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n> index 3fb7ec8c..f7a518c0 100644\n> --- a/src/libcamera/software_isp/software_isp.cpp\n> +++ b/src/libcamera/software_isp/software_isp.cpp\n> @@ -241,19 +241,19 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg,\n>  \n>  /**\n>   * \\brief Export the buffers from the Software ISP\n> - * \\param[in] output Output stream index exporting the buffers\n> + * \\param[in] stream Output stream  exporting the buffers\n\ns/  / /\n\n>   * \\param[in] count Number of buffers to allocate\n>   * \\param[out] buffers Vector to store the allocated buffers\n>   * \\return The number of allocated buffers on success or a negative error code\n>   * otherwise\n>   */\n> -int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count,\n> +int SoftwareIsp::exportBuffers(const Stream *stream, unsigned int count,\n>  \t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n>  {\n>  \tASSERT(debayer_ != nullptr);\n>  \n>  \t/* single output for now */\n> -\tif (output >= 1)\n> +\tif (stream == nullptr)\n>  \t\treturn -EINVAL;\n>  \n>  \tfor (unsigned int i = 0; i < count; i++) {\n> @@ -280,12 +280,12 @@ int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count,\n>  /**\n>   * \\brief Queue buffers to Software ISP\n>   * \\param[in] input The input framebuffer\n> - * \\param[in] outputs The container holding the output stream indexes and\n> + * \\param[in] outputs The container holding the output stream pointer and\n\ns/pointer/pointers/\n\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n>   * their respective frame buffer outputs\n>   * \\return 0 on success, a negative errno on failure\n>   */\n>  int SoftwareIsp::queueBuffers(FrameBuffer *input,\n> -\t\t\t      const std::map<unsigned int, FrameBuffer *> &outputs)\n> +\t\t\t      const std::map<const Stream *, FrameBuffer *> &outputs)\n>  {\n>  \t/*\n>  \t * Validate the outputs as a sanity check: at least one output is\n> @@ -294,14 +294,15 @@ int SoftwareIsp::queueBuffers(FrameBuffer *input,\n>  \tif (outputs.empty())\n>  \t\treturn -EINVAL;\n>  \n> -\tfor (auto [index, buffer] : outputs) {\n> +\tfor (auto [stream, buffer] : outputs) {\n>  \t\tif (!buffer)\n>  \t\t\treturn -EINVAL;\n> -\t\tif (index >= 1) /* only single stream atm */\n> +\t\tif (outputs.size() != 1) /* only single stream atm */\n>  \t\t\treturn -EINVAL;\n>  \t}\n>  \n> -\tprocess(input, outputs.at(0));\n> +\tfor (auto iter = outputs.begin(); iter != outputs.end(); iter++)\n> +\t\tprocess(input, iter->second);\n>  \n>  \treturn 0;\n>  }\n> -- \n> 2.44.0\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 C2BBABEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  2 Jul 2024 11:52:18 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DEF3262E23;\n\tTue,  2 Jul 2024 13:52:17 +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 0AA2762C96\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  2 Jul 2024 13:52:17 +0200 (CEST)","from pyrite.rasen.tech (h175-177-049-156.catv02.itscom.jp\n\t[175.177.49.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8136A664;\n\tTue,  2 Jul 2024 13:51:48 +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=\"bidl8NdL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1719921109;\n\tbh=Jm1vf+F/YT1RZRv+48JgqGpVolf2kELvZ+4Tnn/4i/E=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=bidl8NdLOpcLJ3UU6cEdqag+4LGneE58SZPRb53bruAanbiD/YdlWCUvTQ4TO+2R6\n\tkpiVY0CqkE9GvvOINv3Pfpjbqb/GGMWm5v1meW3O4VfIkBUo92Fx98IIXcfRAUZX8m\n\tgdYr+QHtFEbqRfDH1bsFR3smZnE3z17XTD+g+nmY=","Date":"Tue, 2 Jul 2024 20:52:10 +0900","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"Umang Jain <umang.jain@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v4 4/4] libcamera: converter: Replace usage of stream\n\tindex by Stream pointer","Message-ID":"<ZoPp6ml3k70xPCip@pyrite.rasen.tech>","References":"<20240624134859.171969-1-umang.jain@ideasonboard.com>\n\t<20240624134859.171969-5-umang.jain@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20240624134859.171969-5-umang.jain@ideasonboard.com>","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>"}}]