From patchwork Thu Feb 4 23:26:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 11172 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 8A7E8BD162 for ; Thu, 4 Feb 2021 23:27:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 651F3614A7; Fri, 5 Feb 2021 00:27:18 +0100 (CET) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3A8EA614B3 for ; Fri, 5 Feb 2021 00:27:16 +0100 (CET) X-Halon-ID: 83a07858-6740-11eb-b73f-0050569116f7 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de [79.202.36.88]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 83a07858-6740-11eb-b73f-0050569116f7; Fri, 05 Feb 2021 00:27:15 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 5 Feb 2021 00:26:12 +0100 Message-Id: <20210204232613.494121-11-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210204232613.494121-1-niklas.soderlund@ragnatech.se> References: <20210204232613.494121-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 10/11] libcamera: ipu3: Add helper for parameter and statistic buffers 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" Add a helper class to aid in associating a parameter and statistic buffer with each request queued to the pipeline. The helper helps with tracking the state of the extra buffers and in completing the request once all extra processing is done. This change only adds the helper more work is needed to integrate it with the pipeline and an IPA. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- * Changes since v1 - Move mapping of buffers to IPA to the pipeline handler and a separate patch. - Move all pipeline interactions out of helper. * Changes since v2 - Add todo to remove dynamic memory allocation. - Remove unused find(Request *request). * Changes since v3 - s/IPU3Frames::Info/Info/ for tryComplete() in header file. - Add a remove() interface to reduce code duplication when removing an entry that is should be removed rather then completed. For example in error paths. - Add LOG(Error) prints if the info structure can't be find(). --- src/libcamera/pipeline/ipu3/frames.cpp | 136 ++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/frames.h | 62 +++++++++++ src/libcamera/pipeline/ipu3/meson.build | 1 + 3 files changed, 199 insertions(+) create mode 100644 src/libcamera/pipeline/ipu3/frames.cpp create mode 100644 src/libcamera/pipeline/ipu3/frames.h diff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp new file mode 100644 index 0000000000000000..37932dc779a5a112 --- /dev/null +++ b/src/libcamera/pipeline/ipu3/frames.cpp @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * frames.cpp - Intel IPU3 Frames helper + */ + +#include "frames.h" + +#include +#include + +#include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/v4l2_videodevice.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(IPU3) + +IPU3Frames::IPU3Frames() + : nextId_(0) +{ +} + +void IPU3Frames::init(const std::vector> ¶mBuffers, + const std::vector> &statBuffers) +{ + for (const std::unique_ptr &buffer : paramBuffers) + availableParamBuffers_.push(buffer.get()); + + for (const std::unique_ptr &buffer : statBuffers) + availableStatBuffers_.push(buffer.get()); + + nextId_ = 0; + frameInfo_.clear(); +} + +void IPU3Frames::clear() +{ + availableParamBuffers_ = {}; + availableStatBuffers_ = {}; +} + +IPU3Frames::Info *IPU3Frames::create(Request *request) +{ + unsigned int id = nextId_++; + + if (availableParamBuffers_.empty()) { + LOG(IPU3, Error) << "Parameters buffer underrun"; + return nullptr; + } + FrameBuffer *paramBuffer = availableParamBuffers_.front(); + + if (availableStatBuffers_.empty()) { + LOG(IPU3, Error) << "Statisitc buffer underrun"; + return nullptr; + } + FrameBuffer *statBuffer = availableStatBuffers_.front(); + + availableParamBuffers_.pop(); + availableStatBuffers_.pop(); + + /* \todo Remove the dynamic allocation of Info */ + std::unique_ptr info = std::make_unique(); + + info->id = id; + info->request = request; + info->rawBuffer = nullptr; + info->paramBuffer = paramBuffer; + info->statBuffer = statBuffer; + info->paramDequeued = false; + info->metadataProcessed = false; + + frameInfo_[id] = std::move(info); + + return frameInfo_[id].get(); +} + +void IPU3Frames::remove(IPU3Frames::Info *info) +{ + /* Return params and stat buffer for reuse. */ + availableParamBuffers_.push(info->paramBuffer); + availableStatBuffers_.push(info->statBuffer); + + /* Delete the extended frame information. */ + frameInfo_.erase(info->id); +} + +bool IPU3Frames::tryComplete(IPU3Frames::Info *info) +{ + Request *request = info->request; + + if (request->hasPendingBuffers()) + return false; + + if (!info->metadataProcessed) + return false; + + if (!info->paramDequeued) + return false; + + remove(info); + + return true; +} + +IPU3Frames::Info *IPU3Frames::find(unsigned int id) +{ + const auto &itInfo = frameInfo_.find(id); + + if (itInfo != frameInfo_.end()) + return itInfo->second.get(); + + LOG(IPU3, Error) << "Can't find tracking informaton for frame " << id; + return nullptr; +} + +IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer) +{ + for (auto const &itInfo : frameInfo_) { + Info *info = itInfo.second.get(); + + for (auto const itBuffers : info->request->buffers()) + if (itBuffers.second == buffer) + return info; + + if (info->rawBuffer == buffer || info->paramBuffer == buffer || + info->statBuffer == buffer) + return info; + } + + LOG(IPU3, Error) << "Can't find tracking informaton from buffer"; + return nullptr; +} + +} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h new file mode 100644 index 0000000000000000..106e5c15cc7aea9b --- /dev/null +++ b/src/libcamera/pipeline/ipu3/frames.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * frames.h - Intel IPU3 Frames helper + */ +#ifndef __LIBCAMERA_PIPELINE_IPU3_FRAMES_H__ +#define __LIBCAMERA_PIPELINE_IPU3_FRAMES_H__ + +#include +#include +#include +#include + +namespace libcamera { + +class FrameBuffer; +class IPAProxy; +class PipelineHandler; +class Request; +class V4L2VideoDevice; +struct IPABuffer; + +class IPU3Frames +{ +public: + struct Info { + unsigned int id; + Request *request; + + FrameBuffer *rawBuffer; + FrameBuffer *paramBuffer; + FrameBuffer *statBuffer; + + bool paramDequeued; + bool metadataProcessed; + }; + + IPU3Frames(); + + void init(const std::vector> ¶mBuffers, + const std::vector> &statBuffers); + void clear(); + + Info *create(Request *request); + void remove(Info *info); + bool tryComplete(Info *info); + + Info *find(unsigned int id); + Info *find(FrameBuffer *buffer); + +private: + std::queue availableParamBuffers_; + std::queue availableStatBuffers_; + + unsigned int nextId_; + std::map> frameInfo_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_PIPELINE_IPU3_FRAMES_H__ */ diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build index d60e07ae6ccac2bc..a1b0b31ac5bcf864 100644 --- a/src/libcamera/pipeline/ipu3/meson.build +++ b/src/libcamera/pipeline/ipu3/meson.build @@ -2,6 +2,7 @@ libcamera_sources += files([ 'cio2.cpp', + 'frames.cpp', 'imgu.cpp', 'ipu3.cpp', ])