From patchwork Thu Sep 4 13:46:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 24283 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 06F02C328C for ; Thu, 4 Sep 2025 13:47:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6FEBD69346; Thu, 4 Sep 2025 15:47:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Ig1bEfyS"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EB31C69338 for ; Thu, 4 Sep 2025 15:47:04 +0200 (CEST) Received: from pendragon.ideasonboard.com (230.215-178-91.adsl-dyn.isp.belgacom.be [91.178.215.230]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 8A2E6F09 for ; Thu, 4 Sep 2025 15:45:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1756993555; bh=yP8rwj88dPgAOL7ScJUho2LiEKWBFASC50mUAYHzzII=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Ig1bEfyS1VqMPifQF1wm32khliOPTKEI3rZc+gYKyyXLhahjGD42Qio0XMYZeoGbs AGavCizg6/wxlyt6FiIfypeF/yDUY1hsNF8y6rGSTytubBy1IhuXlq5Mm/+0/fQlMl MTPsRfU0g3MKEpX5TJzm4nI+rU6AHAmu/5tXsSro= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v3 1/2] pipelines: Use lambda functions to factor out buffer mapping code Date: Thu, 4 Sep 2025 15:46:40 +0200 Message-ID: <20250904134641.29597-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.49.1 In-Reply-To: <20250904134641.29597-1-laurent.pinchart@ideasonboard.com> References: <20250904134641.29597-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Multiple pipeline handlers duplicate code related to mapping params and stats buffers to IPA modules. Factor out the code to lambda functions to share it between the two buffer types. Signed-off-by: Laurent Pinchart Reviewed-by: Barnabás Pőcze Reviewed-by: Kieran Bingham --- Changes since v1: - Move for loop to pushBuffers() function - Drop unneeded lambda function arguments --- src/libcamera/pipeline/ipu3/ipu3.cpp | 16 ++++++------ src/libcamera/pipeline/mali-c55/mali-c55.cpp | 26 +++++++++++--------- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 23 +++++++++-------- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index ad20810e6a26..bfbc80af6a3c 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -678,15 +678,15 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) /* Map buffers to the IPA. */ unsigned int ipaBufferId = 1; - for (const std::unique_ptr &buffer : imgu->paramBuffers_) { - buffer->setCookie(ipaBufferId++); - ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); - } + auto pushBuffers = [&](const std::vector> &buffers) { + for (const std::unique_ptr &buffer : buffers) { + buffer->setCookie(ipaBufferId++); + ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + } + }; - for (const std::unique_ptr &buffer : imgu->statBuffers_) { - buffer->setCookie(ipaBufferId++); - ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); - } + pushBuffers(imgu->paramBuffers_); + pushBuffers(imgu->statBuffers_); data->ipa_->mapBuffers(ipaBuffers_); diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 76341ed3f363..97996399fc51 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1133,27 +1133,29 @@ int PipelineHandlerMaliC55::allocateBuffers(Camera *camera) data->dsStream_.configuration().bufferCount, }); + auto pushBuffers = [&](const std::vector> &buffers, + std::queue &queue, + std::vector &ipaBuffers) { + for (const std::unique_ptr &buffer : buffers) { + buffer->setCookie(ipaBufferId++); + ipaBuffers.emplace_back(buffer->cookie(), buffer->planes()); + queue.push(buffer.get()); + } + }; + ret = stats_->allocateBuffers(bufferCount, &statsBuffers_); if (ret < 0) return ret; - for (std::unique_ptr &buffer : statsBuffers_) { - buffer->setCookie(ipaBufferId++); - data->ipaStatBuffers_.emplace_back(buffer->cookie(), - buffer->planes()); - availableStatsBuffers_.push(buffer.get()); - } + pushBuffers(statsBuffers_, availableStatsBuffers_, + data->ipaStatBuffers_); ret = params_->allocateBuffers(bufferCount, ¶msBuffers_); if (ret < 0) return ret; - for (std::unique_ptr &buffer : paramsBuffers_) { - buffer->setCookie(ipaBufferId++); - data->ipaParamBuffers_.emplace_back(buffer->cookie(), - buffer->planes()); - availableParamsBuffers_.push(buffer.get()); - } + pushBuffers(paramsBuffers_, availableParamsBuffers_, + data->ipaParamBuffers_); if (data->ipa_) { data->ipa_->mapBuffers(data->ipaStatBuffers_, true); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 55d7d4442caf..291f96836c5e 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1028,19 +1028,18 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) availableMainPathBuffers_.push(buffer.get()); } - for (std::unique_ptr &buffer : paramBuffers_) { - buffer->setCookie(ipaBufferId++); - data->ipaBuffers_.emplace_back(buffer->cookie(), - buffer->planes()); - availableParamBuffers_.push(buffer.get()); - } + auto pushBuffers = [&](const std::vector> &buffers, + std::queue &queue) { + for (const std::unique_ptr &buffer : buffers) { + buffer->setCookie(ipaBufferId++); + data->ipaBuffers_.emplace_back(buffer->cookie(), + buffer->planes()); + queue.push(buffer.get()); + } + }; - for (std::unique_ptr &buffer : statBuffers_) { - buffer->setCookie(ipaBufferId++); - data->ipaBuffers_.emplace_back(buffer->cookie(), - buffer->planes()); - availableStatBuffers_.push(buffer.get()); - } + pushBuffers(paramBuffers_, availableParamBuffers_); + pushBuffers(statBuffers_, availableStatBuffers_); data->ipa_->mapBuffers(data->ipaBuffers_); From patchwork Thu Sep 4 13:46:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 24284 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0D9A2BDB13 for ; Thu, 4 Sep 2025 13:47:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9020969348; Thu, 4 Sep 2025 15:47:16 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UwNvOt73"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 63D4769341 for ; Thu, 4 Sep 2025 15:47:06 +0200 (CEST) Received: from pendragon.ideasonboard.com (230.215-178-91.adsl-dyn.isp.belgacom.be [91.178.215.230]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id C23E8F09 for ; Thu, 4 Sep 2025 15:45:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1756993556; bh=4AUIoFoRwu1kt0V02upo+RvHRe1aTcXr8Zj05zZBCY0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=UwNvOt73kpKEko4rTVIOaqJ7GQM0E2YTKU/1q3TU8YclDYl6JbgvjAF+kG//aP/nF s6/1BDbUiHGoGJ3vBahjXxdOBRy9Cr8/7LsTEStzPDN+bVoD8Jkvi+Z7bZBqk7+4Yn 8RGF79UPaCE+pNXTRRgzEAAk63gVk0zBh9APRX58= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v3 2/2] libcamera: framebuffer: Replace vector with span in constructor Date: Thu, 4 Sep 2025 15:46:41 +0200 Message-ID: <20250904134641.29597-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.49.1 In-Reply-To: <20250904134641.29597-1-laurent.pinchart@ideasonboard.com> References: <20250904134641.29597-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The FrameBuffer constructor takes a list of planes as an std::vector. The caller may stores the planes in a different type of container, resulting in the needless allocation of a temporary vector. Replace it with a span. Suggested-by: Daniel Rákos Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Barnabás Pőcze --- include/libcamera/framebuffer.h | 4 ++-- include/libcamera/internal/framebuffer.h | 3 ++- src/android/mm/cros_frame_buffer_allocator.cpp | 2 +- src/android/mm/generic_frame_buffer_allocator.cpp | 2 +- src/libcamera/framebuffer.cpp | 10 +++++----- src/libcamera/pipeline/ipu3/ipu3.cpp | 6 +++++- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 6 +++++- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 5 ++++- src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 6 ++++-- src/libcamera/pipeline/vimc/vimc.cpp | 5 ++++- src/libcamera/pipeline/virtual/virtual.cpp | 3 ++- src/libcamera/v4l2_videodevice.cpp | 6 +++--- 12 files changed, 38 insertions(+), 20 deletions(-) diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index e83825b466aa..723525d05294 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -58,11 +58,11 @@ public: unsigned int length; }; - FrameBuffer(const std::vector &planes, unsigned int cookie = 0); + FrameBuffer(Span planes, unsigned int cookie = 0); FrameBuffer(std::unique_ptr d); virtual ~FrameBuffer() {} - const std::vector &planes() const; + Span planes() const; Request *request() const; const FrameMetadata &metadata() const; diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index 97b49d42063f..67b090fc307f 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -23,7 +24,7 @@ class FrameBuffer::Private : public Extensible::Private LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) public: - Private(const std::vector &planes, uint64_t cookie = 0); + Private(Span planes, uint64_t cookie = 0); virtual ~Private(); void setRequest(Request *request) { request_ = request; } diff --git a/src/android/mm/cros_frame_buffer_allocator.cpp b/src/android/mm/cros_frame_buffer_allocator.cpp index 264c0d481272..7ec116e1500d 100644 --- a/src/android/mm/cros_frame_buffer_allocator.cpp +++ b/src/android/mm/cros_frame_buffer_allocator.cpp @@ -29,7 +29,7 @@ class CrosFrameBufferData : public FrameBuffer::Private public: CrosFrameBufferData(cros::ScopedBufferHandle scopedHandle, - const std::vector &planes) + Span planes) : FrameBuffer::Private(planes), scopedHandle_(std::move(scopedHandle)) { } diff --git a/src/android/mm/generic_frame_buffer_allocator.cpp b/src/android/mm/generic_frame_buffer_allocator.cpp index 79625a9a3c75..25ad6b035e73 100644 --- a/src/android/mm/generic_frame_buffer_allocator.cpp +++ b/src/android/mm/generic_frame_buffer_allocator.cpp @@ -35,7 +35,7 @@ class GenericFrameBufferData : public FrameBuffer::Private public: GenericFrameBufferData(struct alloc_device_t *allocDevice, buffer_handle_t handle, - const std::vector &planes) + Span planes) : FrameBuffer::Private(planes), allocDevice_(allocDevice), handle_(handle) { diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index 219db50d6527..765dab95a843 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -130,9 +130,9 @@ LOG_DEFINE_CATEGORY(Buffer) * \param[in] planes The frame memory planes * \param[in] cookie Cookie */ -FrameBuffer::Private::Private(const std::vector &planes, uint64_t cookie) - : planes_(planes), cookie_(cookie), request_(nullptr), - isContiguous_(true) +FrameBuffer::Private::Private(Span planes, uint64_t cookie) + : planes_(planes.begin(), planes.end()), cookie_(cookie), + request_(nullptr), isContiguous_(true) { metadata_.planes_.resize(planes_.size()); } @@ -315,7 +315,7 @@ ino_t fileDescriptorInode(const SharedFD &fd) * \param[in] planes The frame memory planes * \param[in] cookie Cookie */ -FrameBuffer::FrameBuffer(const std::vector &planes, unsigned int cookie) +FrameBuffer::FrameBuffer(Span planes, unsigned int cookie) : FrameBuffer(std::make_unique(planes, cookie)) { } @@ -365,7 +365,7 @@ FrameBuffer::FrameBuffer(std::unique_ptr d) * \brief Retrieve the static plane descriptors * \return Array of plane descriptors */ -const std::vector &FrameBuffer::planes() const +Span FrameBuffer::planes() const { return _d()->planes_; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index bfbc80af6a3c..d6b7edcb5a7f 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -680,8 +680,12 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) auto pushBuffers = [&](const std::vector> &buffers) { for (const std::unique_ptr &buffer : buffers) { + Span planes = buffer->planes(); + buffer->setCookie(ipaBufferId++); - ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + ipaBuffers_.emplace_back(buffer->cookie(), + std::vector{ planes.begin(), + planes.end() }); } }; diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 97996399fc51..38bdc6138ed1 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1137,8 +1137,12 @@ int PipelineHandlerMaliC55::allocateBuffers(Camera *camera) std::queue &queue, std::vector &ipaBuffers) { for (const std::unique_ptr &buffer : buffers) { + Span planes = buffer->planes(); + buffer->setCookie(ipaBufferId++); - ipaBuffers.emplace_back(buffer->cookie(), buffer->planes()); + ipaBuffers.emplace_back(buffer->cookie(), + std::vector{ planes.begin(), + planes.end() }); queue.push(buffer.get()); } }; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 291f96836c5e..cfcbb3b2590a 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1031,9 +1031,12 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) auto pushBuffers = [&](const std::vector> &buffers, std::queue &queue) { for (const std::unique_ptr &buffer : buffers) { + Span planes = buffer->planes(); + buffer->setCookie(ipaBufferId++); data->ipaBuffers_.emplace_back(buffer->cookie(), - buffer->planes()); + std::vector{ planes.begin(), + planes.end() }); queue.push(buffer.get()); } }; diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 09d30f34d9b7..c209aa596311 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -883,8 +883,10 @@ void PipelineHandlerBase::mapBuffers(Camera *camera, const BufferMap &buffers, u * handler and the IPA. */ for (auto const &[id, buffer] : buffers) { - bufferIds.push_back(IPABuffer(mask | id, - buffer.buffer->planes())); + Span planes = buffer.buffer->planes(); + + bufferIds.emplace_back(mask | id, + std::vector{ planes.begin(), planes.end() }); data->bufferIds_.insert(mask | id); } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 07273bd2b6c3..5022101505a1 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -363,8 +363,11 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] const ControlLis /* Map the mock IPA buffers to VIMC IPA to exercise IPC code paths. */ std::vector ipaBuffers; for (auto [i, buffer] : utils::enumerate(data->mockIPABufs_)) { + Span planes = buffer->planes(); + buffer->setCookie(i + 1); - ipaBuffers.emplace_back(buffer->cookie(), buffer->planes()); + ipaBuffers.emplace_back(buffer->cookie(), + std::vector{ planes.begin(), planes.end() }); } data->ipa_->mapBuffers(ipaBuffers); diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 049ebcba58ec..f9538129c956 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -315,7 +315,8 @@ int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera, fmd.sequence = streamConfig.seq++; fmd.timestamp = timestamp; - for (const auto [i, p] : utils::enumerate(buffer->planes())) + Span planes = buffer->planes(); + for (const auto [i, p] : utils::enumerate(planes)) fmd.planes()[i].bytesused = p.length; found = true; diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index ba1889a939cb..7b48d911db73 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -288,7 +288,7 @@ V4L2BufferCache::Entry::Entry(bool free, uint64_t lastUsed, const FrameBuffer &b bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const { - const std::vector &planes = buffer.planes(); + Span planes = buffer.planes(); if (planes_.size() != planes.size()) return false; @@ -1676,7 +1676,7 @@ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer) buf.field = V4L2_FIELD_NONE; bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type); - const std::vector &planes = buffer->planes(); + Span planes = buffer->planes(); const unsigned int numV4l2Planes = format_.planesCount; /* @@ -1909,7 +1909,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer() } metadata.sequence -= firstFrame_.value(); - const std::vector &framebufferPlanes = buffer->planes(); + Span framebufferPlanes = buffer->planes(); unsigned int numV4l2Planes = multiPlanar ? buf.length : 1; if (numV4l2Planes != framebufferPlanes.size()) {