From patchwork Thu Nov 5 00:15:44 2020 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: 10346 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 15A82BDB89 for ; Thu, 5 Nov 2020 00:16:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E6F9662CD4; Thu, 5 Nov 2020 01:16:24 +0100 (CET) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D475E62C8E for ; Thu, 5 Nov 2020 01:16:21 +0100 (CET) X-Halon-ID: 6eaba91e-1efa-11eb-8a9c-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de [79.202.36.88]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6eaba91e-1efa-11eb-8a9c-005056917a89; Thu, 05 Nov 2020 01:04:11 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Nov 2020 01:15:44 +0100 Message-Id: <20201105001546.1690179-10-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201105001546.1690179-1-niklas.soderlund@ragnatech.se> References: <20201105001546.1690179-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/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 --- src/libcamera/pipeline/ipu3/frames.cpp | 164 ++++++++++++++++++++++++ src/libcamera/pipeline/ipu3/frames.h | 68 ++++++++++ src/libcamera/pipeline/ipu3/meson.build | 1 + 3 files changed, 233 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..824844e345e13679 --- /dev/null +++ b/src/libcamera/pipeline/ipu3/frames.cpp @@ -0,0 +1,164 @@ +/* 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 + +#include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/v4l2_videodevice.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(IPU3) + +IPU3Frames::IPU3Frames(PipelineHandler *pipe, IPAProxy *ipa) + : pipe_(pipe), ipa_(ipa), nextId_(0) +{ +} + +void IPU3Frames::mapBuffers(const std::vector> ¶mBuffers, + const std::vector> &statBuffers) +{ + unsigned int ipaBufferId = 1; + + for (const std::unique_ptr &buffer : paramBuffers) { + buffer->setCookie(ipaBufferId++); + ipaBuffers_.push_back({ .id = buffer->cookie(), + .planes = buffer->planes() }); + availableParamBuffers_.push(buffer.get()); + } + + for (const std::unique_ptr &buffer : statBuffers) { + buffer->setCookie(ipaBufferId++); + ipaBuffers_.push_back({ .id = buffer->cookie(), + .planes = buffer->planes() }); + availableStatBuffers_.push(buffer.get()); + } + + ipa_->mapBuffers(ipaBuffers_); + + nextId_ = 0; + frameInfo_.clear(); +} + +void IPU3Frames::unmapBuffers() +{ + availableParamBuffers_ = {}; + availableStatBuffers_ = {}; + + std::vector ids; + for (IPABuffer &ipabuf : ipaBuffers_) + ids.push_back(ipabuf.id); + + ipa_->unmapBuffers(ids); + ipaBuffers_.clear(); +} + +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(); + + std::unique_ptr info = std::make_unique(); + + info->id = id; + info->request = request; + info->rawBuffer = nullptr; + info->paramBuffer = paramBuffer; + info->statBuffer = statBuffer; + info->paramFilled = false; + info->paramDequeued = false; + info->metadataProcessed = false; + + frameInfo_[id] = std::move(info); + + return frameInfo_[id].get(); +} + +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; + + /* Return params and stat buffer for reuse. */ + availableParamBuffers_.push(info->paramBuffer); + availableStatBuffers_.push(info->statBuffer); + + /* Delete the extended frame information. */ + frameInfo_.erase(info->id); + + pipe_->completeRequest(request); + + return true; +} + +IPU3Frames::Info *IPU3Frames::find(unsigned int id) +{ + const auto &itInfo = frameInfo_.find(id); + + if (itInfo != frameInfo_.end()) + return itInfo->second.get(); + + 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; + } + + return nullptr; +} + +IPU3Frames::Info *IPU3Frames::find(Request *request) +{ + for (auto const &itInfo : frameInfo_) { + Info *info = itInfo.second.get(); + + if (info->request == request) + return info; + } + + 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..5c072f8ddbc9660f --- /dev/null +++ b/src/libcamera/pipeline/ipu3/frames.h @@ -0,0 +1,68 @@ +/* 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 paramFilled; + bool paramDequeued; + bool metadataProcessed; + }; + + IPU3Frames(PipelineHandler *pipe, IPAProxy *ipa); + + void mapBuffers(const std::vector> ¶mBuffers, + const std::vector> &statBuffers); + void unmapBuffers(); + + Info *create(Request *request); + bool tryComplete(IPU3Frames::Info *info); + + Info *find(unsigned int id); + Info *find(FrameBuffer *buffer); + Info *find(Request *request); + +private: + PipelineHandler *pipe_; + IPAProxy *ipa_; + + std::queue availableParamBuffers_; + std::queue availableStatBuffers_; + + std::vector ipaBuffers_; + + 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', ])