{"id":20116,"url":"https://patchwork.libcamera.org/api/1.1/patches/20116/?format=json","web_url":"https://patchwork.libcamera.org/patch/20116/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20240529070248.12186-5-umang.jain@ideasonboard.com>","date":"2024-05-29T07:02:48","name":"[v2,4/4] libcamera: converter: Replace usage of stream index by Stream pointer","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"a0540fed65a9104c1eaf68987e6afe5f363e95b8","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/1.1/people/86/?format=json","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/20116/mbox/","series":[{"id":4331,"url":"https://patchwork.libcamera.org/api/1.1/series/4331/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=4331","date":"2024-05-29T07:02:44","name":"libcamera: converter: Replace usage of stream index by Stream pointer","version":2,"mbox":"https://patchwork.libcamera.org/series/4331/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/20116/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/20116/checks/","tags":{},"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 8A69CBD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 May 2024 07:03:12 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2A0E2634B0;\n\tWed, 29 May 2024 09:03:12 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 539C1634BC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 May 2024 09:03:07 +0200 (CEST)","from fedora.local (unknown\n\t[IPv6:2409:4055:4e99:4251:f523:b915:4362:f847])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1083E2D60;\n\tWed, 29 May 2024 09:03:01 +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=\"uhBQS2VT\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1716966184;\n\tbh=6LKurF2mZkY/gARw692VbVg3T+pnV7uNVeSUEMZeG3I=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=uhBQS2VTztq1p+uj5EaRlehOsMfEmEjNnF9+HqlhynRdTrc/XoAliAlLs4edcwKUI\n\tJSgX/L30jz9/0LeuA97iZ5vl5/d2OJGnB/4/pQKsxhNLUUfBvp3ZtHElwhsGiEnFVL\n\tSxyXLlK93aNe87Hd79bnOHPYi3VZLJkR2x34XjXk=","From":"Umang Jain <umang.jain@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Milan Zamazal <mzamazal@redhat.com>,\n\tAndrey Konovalov <andrey.konovalov@linaro.org>,\n\tUmang Jain <umang.jain@ideasonboard.com>","Subject":"[PATCH v2 4/4] libcamera: converter: Replace usage of stream index\n\tby Stream pointer","Date":"Wed, 29 May 2024 12:32:48 +0530","Message-ID":"<20240529070248.12186-5-umang.jain@ideasonboard.com>","X-Mailer":"git-send-email 2.44.0","In-Reply-To":"<20240529070248.12186-1-umang.jain@ideasonboard.com>","References":"<20240529070248.12186-1-umang.jain@ideasonboard.com>","MIME-Version":"1.0","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>"},"content":"The converter interface uses the unsigned int output stream index to map\nto the output frame buffers. This is cumbersome to implement new\nconverters because one has to keep around additional book keeping\nto track the streams with their correct indexes.\n\nThe v4l2_converter_m2m and simple pipeline handler are adapted to\nuse the new interface. This work roped in software ISP as well,\nwhich also seems to use indexes (although it doesn't implement converter\ninterface) because of a common conversionQueue_ queue used for\nconverter_ and swIsp_.\n\nSigned-off-by: Umang Jain <umang.jain@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 .../converter/converter_v4l2_m2m.cpp          | 40 ++++++++++---------\n src/libcamera/pipeline/simple/simple.cpp      | 14 +++----\n src/libcamera/software_isp/software_isp.cpp   | 13 +++---\n 6 files changed, 46 insertions(+), 42 deletions(-)","diff":"diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h\nindex 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;\ndiff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h\nindex 0da62290..58fd19db 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 *, V4L2M2MStream> streams_;\n \tstd::map<FrameBuffer *, unsigned int> queue_;\n };\n \ndiff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h\nindex 7e9fae6a..09cc0f6f 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 \ndiff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp\nindex 6309a0c0..a48b2a87 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,10 +333,13 @@ 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\tstreams_.emplace(cfg.stream(),\n+\t\t\t\t V4L2M2MStream(this, cfg.stream()));\n+\n+\t\tV4L2M2MStream &stream = streams_.at(cfg.stream());\n \n \t\tif (!stream.isValid()) {\n \t\t\tLOG(Converter, Error)\n@@ -345,7 +348,7 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg,\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 \t}\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}\ndiff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex db3575c3..01ad91a7 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -278,7 +278,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@@ -837,7 +837,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@@ -1304,10 +1304,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@@ -1399,7 +1397,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@@ -1408,7 +1406,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)\ndiff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\nindex ac10d82d..7cadd585 100644\n--- a/src/libcamera/software_isp/software_isp.cpp\n+++ b/src/libcamera/software_isp/software_isp.cpp\n@@ -227,13 +227,13 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg,\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@@ -265,7 +265,7 @@ int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count,\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@@ -274,14 +274,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","prefixes":["v2","4/4"]}