Patch Detail
Show a patch.
GET /api/patches/19518/?format=api
{ "id": 19518, "url": "https://patchwork.libcamera.org/api/patches/19518/?format=api", "web_url": "https://patchwork.libcamera.org/patch/19518/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20240220164317.998477-8-dan.scally@ideasonboard.com>", "date": "2024-02-20T16:43:17", "name": "[v2,7/7] libcamera: ipu3: Remove IPU3Frames", "commit_ref": null, "pull_url": null, "state": "rejected", "archived": true, "hash": "3ca8e0633612275dd575599e719f25ff7efb0d0b", "submitter": { "id": 156, "url": "https://patchwork.libcamera.org/api/people/156/?format=api", "name": "Dan Scally", "email": "dan.scally@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/19518/mbox/", "series": [ { "id": 4172, "url": "https://patchwork.libcamera.org/api/series/4172/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4172", "date": "2024-02-20T16:43:10", "name": "Remove RkISP1FrameInfo and IPU3Frames classes", "version": 2, "mbox": "https://patchwork.libcamera.org/series/4172/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/19518/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/19518/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 A1C68C32C3\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 20 Feb 2024 16:43:39 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 52C906281A;\n\tTue, 20 Feb 2024 17:43:39 +0100 (CET)", "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 A140F6281E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 20 Feb 2024 17:43:26 +0100 (CET)", "from mail.ideasonboard.com\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3416E230E;\n\tTue, 20 Feb 2024 17:43:19 +0100 (CET)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"r+AdyMdM\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1708447399;\n\tbh=ULueQp8rIcDhjqodhbddJkkr9uqRqkkH+A1iuuLNJk0=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=r+AdyMdMHcbag+g/7zlFWZV8lH+CWozCDaSyXeICZnBcPgJLWcy+p4okfXbtu1NXN\n\tNZGEPgvFu0/O5KobRu48UWvQaG6w6lGL6n+Sxg9it01yClg8h6KBzspkfsyR76NvbR\n\tewtbNfjhGAZvJwO9M7yyZQA7i2d62FAthi7FxPIo=", "From": "Daniel Scally <dan.scally@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[PATCH v2 7/7] libcamera: ipu3: Remove IPU3Frames", "Date": "Tue, 20 Feb 2024 16:43:17 +0000", "Message-Id": "<20240220164317.998477-8-dan.scally@ideasonboard.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20240220164317.998477-1-dan.scally@ideasonboard.com>", "References": "<20240220164317.998477-1-dan.scally@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 IPU3Frames class existed to track whether or not a request is ok\nto complete yet or not - that can now be done through internal buffer\ntracking within a Request::Private, so switch to that method and drop\nthe dedicated class.\n\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n---\nChanges in v2:\n\n\t- New patch\n\n src/libcamera/pipeline/ipu3/cio2.cpp | 3 +-\n src/libcamera/pipeline/ipu3/cio2.h | 2 +-\n src/libcamera/pipeline/ipu3/frames.cpp | 143 -----------------\n src/libcamera/pipeline/ipu3/frames.h | 67 --------\n src/libcamera/pipeline/ipu3/ipu3.cpp | 203 ++++++++++++++----------\n src/libcamera/pipeline/ipu3/meson.build | 1 -\n 6 files changed, 122 insertions(+), 297 deletions(-)\n delete mode 100644 src/libcamera/pipeline/ipu3/frames.cpp\n delete mode 100644 src/libcamera/pipeline/ipu3/frames.h", "diff": "diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\nindex 7400cb0b..e0b0d3d1 100644\n--- a/src/libcamera/pipeline/ipu3/cio2.cpp\n+++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n@@ -379,7 +379,7 @@ int CIO2Device::stop()\n \treturn ret;\n }\n \n-FrameBuffer *CIO2Device::queueBuffer(Request *request, FrameBuffer *rawBuffer)\n+FrameBuffer *CIO2Device::queueBuffer(FrameBuffer *rawBuffer)\n {\n \tFrameBuffer *buffer = rawBuffer;\n \n@@ -392,7 +392,6 @@ FrameBuffer *CIO2Device::queueBuffer(Request *request, FrameBuffer *rawBuffer)\n \n \t\tbuffer = availableBuffers_.front();\n \t\tavailableBuffers_.pop();\n-\t\tbuffer->_d()->setRequest(request);\n \t}\n \n \tint ret = output_->queueBuffer(buffer);\ndiff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\nindex bbd87eb8..42bb28b7 100644\n--- a/src/libcamera/pipeline/ipu3/cio2.h\n+++ b/src/libcamera/pipeline/ipu3/cio2.h\n@@ -56,7 +56,7 @@ public:\n \tCameraSensor *sensor() { return sensor_.get(); }\n \tconst CameraSensor *sensor() const { return sensor_.get(); }\n \n-\tFrameBuffer *queueBuffer(Request *request, FrameBuffer *rawBuffer);\n+\tFrameBuffer *queueBuffer(FrameBuffer *rawBuffer);\n \tvoid tryReturnBuffer(FrameBuffer *buffer);\n \tSignal<FrameBuffer *> &bufferReady() { return output_->bufferReady; }\n \tSignal<uint32_t> &frameStart() { return csi2_->frameStart; }\ndiff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp\ndeleted file mode 100644\nindex a4c3477c..00000000\n--- a/src/libcamera/pipeline/ipu3/frames.cpp\n+++ /dev/null\n@@ -1,143 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2020, Google Inc.\n- *\n- * frames.cpp - Intel IPU3 Frames helper\n- */\n-\n-#include \"frames.h\"\n-\n-#include <libcamera/framebuffer.h>\n-#include <libcamera/request.h>\n-\n-#include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/pipeline_handler.h\"\n-#include \"libcamera/internal/v4l2_videodevice.h\"\n-\n-namespace libcamera {\n-\n-LOG_DECLARE_CATEGORY(IPU3)\n-\n-IPU3Frames::IPU3Frames()\n-{\n-}\n-\n-void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers,\n-\t\t const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers)\n-{\n-\tfor (const std::unique_ptr<FrameBuffer> &buffer : paramBuffers)\n-\t\tavailableParamBuffers_.push(buffer.get());\n-\n-\tfor (const std::unique_ptr<FrameBuffer> &buffer : statBuffers)\n-\t\tavailableStatBuffers_.push(buffer.get());\n-\n-\tframeInfo_.clear();\n-}\n-\n-void IPU3Frames::clear()\n-{\n-\tavailableParamBuffers_ = {};\n-\tavailableStatBuffers_ = {};\n-}\n-\n-IPU3Frames::Info *IPU3Frames::create(Request *request)\n-{\n-\tunsigned int id = request->sequence();\n-\n-\tif (availableParamBuffers_.empty()) {\n-\t\tLOG(IPU3, Debug) << \"Parameters buffer underrun\";\n-\t\treturn nullptr;\n-\t}\n-\n-\tif (availableStatBuffers_.empty()) {\n-\t\tLOG(IPU3, Debug) << \"Statistics buffer underrun\";\n-\t\treturn nullptr;\n-\t}\n-\n-\tFrameBuffer *paramBuffer = availableParamBuffers_.front();\n-\tFrameBuffer *statBuffer = availableStatBuffers_.front();\n-\n-\tparamBuffer->_d()->setRequest(request);\n-\tstatBuffer->_d()->setRequest(request);\n-\n-\tavailableParamBuffers_.pop();\n-\tavailableStatBuffers_.pop();\n-\n-\t/* \\todo Remove the dynamic allocation of Info */\n-\tstd::unique_ptr<Info> info = std::make_unique<Info>();\n-\n-\tinfo->id = id;\n-\tinfo->request = request;\n-\tinfo->rawBuffer = nullptr;\n-\tinfo->paramBuffer = paramBuffer;\n-\tinfo->statBuffer = statBuffer;\n-\tinfo->paramDequeued = false;\n-\tinfo->metadataProcessed = false;\n-\n-\tframeInfo_[id] = std::move(info);\n-\n-\treturn frameInfo_[id].get();\n-}\n-\n-void IPU3Frames::remove(IPU3Frames::Info *info)\n-{\n-\t/* Return params and stat buffer for reuse. */\n-\tavailableParamBuffers_.push(info->paramBuffer);\n-\tavailableStatBuffers_.push(info->statBuffer);\n-\n-\t/* Delete the extended frame information. */\n-\tframeInfo_.erase(info->id);\n-}\n-\n-bool IPU3Frames::tryComplete(IPU3Frames::Info *info)\n-{\n-\tRequest *request = info->request;\n-\n-\tif (request->hasPendingBuffers())\n-\t\treturn false;\n-\n-\tif (!info->metadataProcessed)\n-\t\treturn false;\n-\n-\tif (!info->paramDequeued)\n-\t\treturn false;\n-\n-\tremove(info);\n-\n-\tbufferAvailable.emit();\n-\n-\treturn true;\n-}\n-\n-IPU3Frames::Info *IPU3Frames::find(unsigned int id)\n-{\n-\tconst auto &itInfo = frameInfo_.find(id);\n-\n-\tif (itInfo != frameInfo_.end())\n-\t\treturn itInfo->second.get();\n-\n-\tLOG(IPU3, Fatal) << \"Can't find tracking information for frame \" << id;\n-\n-\treturn nullptr;\n-}\n-\n-IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer)\n-{\n-\tfor (auto const &itInfo : frameInfo_) {\n-\t\tInfo *info = itInfo.second.get();\n-\n-\t\tfor (auto const itBuffers : info->request->buffers())\n-\t\t\tif (itBuffers.second == buffer)\n-\t\t\t\treturn info;\n-\n-\t\tif (info->rawBuffer == buffer || info->paramBuffer == buffer ||\n-\t\t info->statBuffer == buffer)\n-\t\t\treturn info;\n-\t}\n-\n-\tLOG(IPU3, Fatal) << \"Can't find tracking information from buffer\";\n-\n-\treturn nullptr;\n-}\n-\n-} /* namespace libcamera */\ndiff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h\ndeleted file mode 100644\nindex 6e3cb915..00000000\n--- a/src/libcamera/pipeline/ipu3/frames.h\n+++ /dev/null\n@@ -1,67 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2020, Google Inc.\n- *\n- * frames.h - Intel IPU3 Frames helper\n- */\n-\n-#pragma once\n-\n-#include <map>\n-#include <memory>\n-#include <queue>\n-#include <vector>\n-\n-#include <libcamera/base/signal.h>\n-\n-#include <libcamera/controls.h>\n-\n-namespace libcamera {\n-\n-class FrameBuffer;\n-class IPAProxy;\n-class PipelineHandler;\n-class Request;\n-class V4L2VideoDevice;\n-struct IPABuffer;\n-\n-class IPU3Frames\n-{\n-public:\n-\tstruct Info {\n-\t\tunsigned int id;\n-\t\tRequest *request;\n-\n-\t\tFrameBuffer *rawBuffer;\n-\t\tFrameBuffer *paramBuffer;\n-\t\tFrameBuffer *statBuffer;\n-\n-\t\tControlList effectiveSensorControls;\n-\n-\t\tbool paramDequeued;\n-\t\tbool metadataProcessed;\n-\t};\n-\n-\tIPU3Frames();\n-\n-\tvoid init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers,\n-\t\t const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers);\n-\tvoid clear();\n-\n-\tInfo *create(Request *request);\n-\tvoid remove(Info *info);\n-\tbool tryComplete(Info *info);\n-\n-\tInfo *find(unsigned int id);\n-\tInfo *find(FrameBuffer *buffer);\n-\n-\tSignal<> bufferAvailable;\n-\n-private:\n-\tstd::queue<FrameBuffer *> availableParamBuffers_;\n-\tstd::queue<FrameBuffer *> availableStatBuffers_;\n-\n-\tstd::map<unsigned int, std::unique_ptr<Info>> frameInfo_;\n-};\n-\n-} /* namespace libcamera */\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex fa4bd0bb..a8e59dea 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -34,15 +34,17 @@\n #include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n+#include \"libcamera/internal/request.h\"\n \n #include \"cio2.h\"\n-#include \"frames.h\"\n #include \"imgu.h\"\n \n namespace libcamera {\n \n LOG_DEFINE_CATEGORY(IPU3)\n \n+using InternalStream = Request::Private::InternalStream;\n+\n static const ControlInfoMap::Map IPU3Controls = {\n \t{ &controls::draft::PipelineDepth, ControlInfo(2, 3) },\n };\n@@ -58,6 +60,7 @@ public:\n \tint loadIPA();\n \n \tvoid imguOutputBufferReady(FrameBuffer *buffer);\n+\tvoid imguInputBufferReady(FrameBuffer *buffer);\n \tvoid cio2BufferReady(FrameBuffer *buffer);\n \tvoid paramBufferReady(FrameBuffer *buffer);\n \tvoid statBufferReady(FrameBuffer *buffer);\n@@ -75,7 +78,6 @@ public:\n \tRectangle cropRegion_;\n \n \tstd::unique_ptr<DelayedControls> delayedCtrls_;\n-\tIPU3Frames frameInfos_;\n \n \tstd::unique_ptr<ipa::ipu3::IPAProxyIPU3> ipa_;\n \n@@ -86,11 +88,14 @@ public:\n \n \tControlInfoMap ipaControls_;\n \n+\tstd::queue<FrameBuffer *> availableParamBuffers_;\n+\tstd::queue<FrameBuffer *> availableStatBuffers_;\n private:\n \tvoid metadataReady(unsigned int id, const ControlList &metadata);\n \tvoid paramsBufferReady(unsigned int id);\n \tvoid setSensorControls(unsigned int id, const ControlList &sensorControls,\n \t\t\t const ControlList &lensControls);\n+\tvoid tryCompleteRequest(Request *request);\n };\n \n class IPU3CameraConfiguration : public CameraConfiguration\n@@ -680,19 +685,17 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera)\n \tfor (const std::unique_ptr<FrameBuffer> &buffer : imgu->paramBuffers_) {\n \t\tbuffer->setCookie(ipaBufferId++);\n \t\tipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());\n+\t\tdata->availableParamBuffers_.push(buffer.get());\n \t}\n \n \tfor (const std::unique_ptr<FrameBuffer> &buffer : imgu->statBuffers_) {\n \t\tbuffer->setCookie(ipaBufferId++);\n \t\tipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());\n+\t\tdata->availableStatBuffers_.push(buffer.get());\n \t}\n \n \tdata->ipa_->mapBuffers(ipaBuffers_);\n \n-\tdata->frameInfos_.init(imgu->paramBuffers_, imgu->statBuffers_);\n-\tdata->frameInfos_.bufferAvailable.connect(\n-\t\tdata, &IPU3CameraData::queuePendingRequests);\n-\n \treturn 0;\n }\n \n@@ -700,7 +703,11 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera)\n {\n \tIPU3CameraData *data = cameraData(camera);\n \n-\tdata->frameInfos_.clear();\n+\twhile (!data->availableStatBuffers_.empty())\n+\t\tdata->availableStatBuffers_.pop();\n+\n+\twhile (!data->availableParamBuffers_.empty())\n+\t\tdata->availableParamBuffers_.pop();\n \n \tstd::vector<unsigned int> ids;\n \tfor (IPABuffer &ipabuf : ipaBuffers_)\n@@ -792,6 +799,12 @@ void IPU3CameraData::cancelPendingRequests()\n \t\t\tpipe()->completeBuffer(request, buffer);\n \t\t}\n \n+\t\tfor (auto it : request->_d()->internalBuffers()) {\n+\t\t\tFrameBuffer *b = it.second;\n+\t\t\tb->_d()->cancel();\n+\t\t\tpipe()->completeBuffer(request, b);\n+\t\t}\n+\n \t\tpipe()->completeRequest(request);\n \t\tpendingRequests_.pop();\n \t}\n@@ -802,31 +815,23 @@ void IPU3CameraData::queuePendingRequests()\n \twhile (!pendingRequests_.empty()) {\n \t\tRequest *request = pendingRequests_.front();\n \n-\t\tIPU3Frames::Info *info = frameInfos_.create(request);\n-\t\tif (!info)\n-\t\t\tbreak;\n-\n \t\t/*\n \t\t * Queue a buffer on the CIO2, using the raw stream buffer\n \t\t * provided in the request, if any, or a CIO2 internal buffer\n \t\t * otherwise.\n \t\t */\n \t\tFrameBuffer *reqRawBuffer = request->findBuffer(&rawStream_);\n-\t\tFrameBuffer *rawBuffer = cio2_.queueBuffer(request, reqRawBuffer);\n+\t\tFrameBuffer *rawBuffer = cio2_.queueBuffer(reqRawBuffer);\n \t\t/*\n \t\t * \\todo If queueBuffer fails in queuing a buffer to the device,\n \t\t * report the request as error by cancelling the request and\n \t\t * calling PipelineHandler::completeRequest().\n \t\t */\n-\t\tif (!rawBuffer) {\n-\t\t\tframeInfos_.remove(info);\n+\t\tif (!rawBuffer)\n \t\t\tbreak;\n-\t\t}\n-\n-\t\tinfo->rawBuffer = rawBuffer;\n-\n-\t\tipa_->queueRequest(info->id, request->controls());\n \n+\t\trequest->_d()->addInternalBuffer(InternalStream::Mem2Mem, rawBuffer);\n+\t\tipa_->queueRequest(request->sequence(), request->controls());\n \t\tpendingRequests_.pop();\n \t\tprocessingRequests_.push(request);\n \t}\n@@ -1120,8 +1125,8 @@ int PipelineHandlerIPU3::registerCameras()\n \t\t\t\t\t&IPU3CameraData::cio2BufferReady);\n \t\tdata->cio2_.bufferAvailable.connect(\n \t\t\tdata.get(), &IPU3CameraData::queuePendingRequests);\n-\t\tdata->imgu_->input_->bufferReady.connect(&data->cio2_,\n-\t\t\t\t\t&CIO2Device::tryReturnBuffer);\n+\t\tdata->imgu_->input_->bufferReady.connect(data.get(),\n+\t\t\t\t\t&IPU3CameraData::imguInputBufferReady);\n \t\tdata->imgu_->output_->bufferReady.connect(data.get(),\n \t\t\t\t\t&IPU3CameraData::imguOutputBufferReady);\n \t\tdata->imgu_->viewfinder_->bufferReady.connect(data.get(),\n@@ -1200,6 +1205,17 @@ int IPU3CameraData::loadIPA()\n \treturn 0;\n }\n \n+void IPU3CameraData::tryCompleteRequest(Request *request)\n+{\n+\tif (request->hasPendingBuffers())\n+\t\treturn;\n+\n+\tpipe()->completeRequest(request);\n+\n+\t/* Try queue another request now that this one has completed. */\n+\tqueuePendingRequests();\n+}\n+\n void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id,\n \t\t\t\t const ControlList &sensorControls,\n \t\t\t\t const ControlList &lensControls)\n@@ -1220,12 +1236,11 @@ void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id,\n \n void IPU3CameraData::paramsBufferReady(unsigned int id)\n {\n-\tIPU3Frames::Info *info = frameInfos_.find(id);\n-\tif (!info)\n-\t\treturn;\n+\tRequest *request = queuedRequests_[id];\n+\tASSERT(request);\n \n \t/* Queue all buffers from the request aimed for the ImgU. */\n-\tfor (auto it : info->request->buffers()) {\n+\tfor (auto it : request->buffers()) {\n \t\tconst Stream *stream = it.first;\n \t\tFrameBuffer *outbuffer = it.second;\n \n@@ -1235,25 +1250,41 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)\n \t\t\timgu_->viewfinder_->queueBuffer(outbuffer);\n \t}\n \n-\tinfo->paramBuffer->_d()->metadata().planes()[0].bytesused =\n+\tFrameBuffer *paramBuffer = request->_d()->findInternalBuffer(InternalStream::Parameters);\n+\tparamBuffer->_d()->metadata().planes()[0].bytesused =\n \t\tsizeof(struct ipu3_uapi_params);\n-\timgu_->param_->queueBuffer(info->paramBuffer);\n-\timgu_->stat_->queueBuffer(info->statBuffer);\n-\timgu_->input_->queueBuffer(info->rawBuffer);\n+\n+\tif (availableStatBuffers_.empty()) {\n+\t\tLOG(IPU3, Error) << \"Statistics buffer underrun\";\n+\t\treturn;\n+\t}\n+\n+\tFrameBuffer *statBuffer = availableStatBuffers_.front();\n+\tavailableStatBuffers_.pop();\n+\trequest->_d()->addInternalBuffer(InternalStream::Statistics, statBuffer);\n+\n+\timgu_->param_->queueBuffer(paramBuffer);\n+\timgu_->stat_->queueBuffer(statBuffer);\n+\n+\tFrameBuffer *rawBuffer = request->_d()->findInternalBuffer(InternalStream::Mem2Mem);\n+\tASSERT(rawBuffer);\n+\n+\timgu_->input_->queueBuffer(rawBuffer);\n }\n \n void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)\n {\n-\tIPU3Frames::Info *info = frameInfos_.find(id);\n-\tif (!info)\n-\t\treturn;\n+\tRequest *request = queuedRequests_[id];\n+\tASSERT(request);\n+\n+\tFrameBuffer *statBuffer = request->_d()->findInternalBuffer(InternalStream::Statistics);\n+\tASSERT(statBuffer);\n \n-\tRequest *request = info->request;\n \trequest->metadata().merge(metadata);\n+\tavailableStatBuffers_.push(statBuffer);\n \n-\tinfo->metadataProcessed = true;\n-\tif (frameInfos_.tryComplete(info))\n-\t\tpipe()->completeRequest(request);\n+\tpipe()->completeBuffer(request, statBuffer);\n+\ttryCompleteRequest(request);\n }\n \n /* -----------------------------------------------------------------------------\n@@ -1268,13 +1299,7 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)\n */\n void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n {\n-\tIPU3Frames::Info *info = frameInfos_.find(buffer);\n-\tif (!info)\n-\t\treturn;\n-\n-\tRequest *request = info->request;\n-\n-\tpipe()->completeBuffer(request, buffer);\n+\tRequest *request = buffer->request();\n \n \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n \t/* \\todo Actually apply the scaler crop region to the ImgU. */\n@@ -1283,8 +1308,25 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n \t\tcropRegion_ = *scalerCrop;\n \trequest->metadata().set(controls::ScalerCrop, cropRegion_);\n \n-\tif (frameInfos_.tryComplete(info))\n-\t\tpipe()->completeRequest(request);\n+\tpipe()->completeBuffer(request, buffer);\n+\ttryCompleteRequest(request);\n+}\n+\n+void IPU3CameraData::imguInputBufferReady(FrameBuffer *buffer)\n+{\n+\tRequest *request = buffer->request();\n+\n+\t/*\n+\t * If the Request has a Mem2Mem buffer and it's **this** buffer, then\n+\t * give it back to the CIO2Device to return it to its internal queue and\n+\t * flag it as completed for the purposes of the Request\n+\t*/\n+\tFrameBuffer *reqBuffer = request->_d()->findInternalBuffer(InternalStream::Mem2Mem);\n+\tif (reqBuffer && reqBuffer == buffer) {\n+\t\tpipe()->completeBuffer(request, buffer);\n+\t\ttryCompleteRequest(request);\n+\t\tcio2_.tryReturnBuffer(buffer);\n+\t}\n }\n \n /**\n@@ -1296,11 +1338,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n */\n void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)\n {\n-\tIPU3Frames::Info *info = frameInfos_.find(buffer);\n-\tif (!info)\n-\t\treturn;\n-\n-\tRequest *request = info->request;\n+\tRequest *request = buffer->request();\n \n \t/* If the buffer is cancelled force a complete of the whole request. */\n \tif (buffer->metadata().status == FrameMetadata::FrameCancelled) {\n@@ -1310,7 +1348,12 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)\n \t\t\tpipe()->completeBuffer(request, b);\n \t\t}\n \n-\t\tframeInfos_.remove(info);\n+\t\tfor (auto it : request->_d()->internalBuffers()) {\n+\t\t\tFrameBuffer *b = it.second;\n+\t\t\tb->_d()->cancel();\n+\t\t\tpipe()->completeBuffer(request, b);\n+\t\t}\n+\n \t\tpipe()->completeRequest(request);\n \t\treturn;\n \t}\n@@ -1324,57 +1367,51 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)\n \trequest->metadata().set(controls::SensorTimestamp,\n \t\t\t\tbuffer->metadata().timestamp);\n \n-\tinfo->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence);\n-\n \tif (request->findBuffer(&rawStream_))\n \t\tpipe()->completeBuffer(request, buffer);\n \n-\tipa_->fillParamsBuffer(info->id, info->paramBuffer->cookie());\n+\tif (availableParamBuffers_.empty()) {\n+\t\tLOG(IPU3, Error) << \"Parameters buffer underrun\";\n+\t\treturn;\n+\t}\n+\n+\tFrameBuffer *paramBuffer = availableParamBuffers_.front();\n+\tavailableParamBuffers_.pop();\n+\trequest->_d()->addInternalBuffer(InternalStream::Parameters, paramBuffer);\n+\n+\tipa_->fillParamsBuffer(request->sequence(), paramBuffer->cookie());\n }\n \n void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)\n {\n-\tIPU3Frames::Info *info = frameInfos_.find(buffer);\n-\tif (!info)\n-\t\treturn;\n-\n-\tinfo->paramDequeued = true;\n+\tRequest *request = buffer->request();\n \n-\t/*\n-\t * tryComplete() will delete info if it completes the IPU3Frame.\n-\t * In that event, we must have obtained the Request before hand.\n-\t *\n-\t * \\todo Improve the FrameInfo API to avoid this type of issue\n-\t */\n-\tRequest *request = info->request;\n+\tpipe()->completeBuffer(request, buffer);\n+\ttryCompleteRequest(request);\n \n-\tif (frameInfos_.tryComplete(info))\n-\t\tpipe()->completeRequest(request);\n+\tavailableParamBuffers_.push(buffer);\n }\n \n void IPU3CameraData::statBufferReady(FrameBuffer *buffer)\n {\n-\tIPU3Frames::Info *info = frameInfos_.find(buffer);\n-\tif (!info)\n-\t\treturn;\n-\n-\tRequest *request = info->request;\n+\tRequest *request = buffer->request();\n \n \tif (buffer->metadata().status == FrameMetadata::FrameCancelled) {\n-\t\tinfo->metadataProcessed = true;\n-\n-\t\t/*\n-\t\t * tryComplete() will delete info if it completes the IPU3Frame.\n-\t\t * In that event, we must have obtained the Request before hand.\n-\t\t */\n-\t\tif (frameInfos_.tryComplete(info))\n-\t\t\tpipe()->completeRequest(request);\n+\t\tpipe()->completeBuffer(request, buffer);\n+\t\ttryCompleteRequest(request);\n \n \t\treturn;\n \t}\n \n-\tipa_->processStatsBuffer(info->id, request->metadata().get(controls::SensorTimestamp).value_or(0),\n-\t\t\t\t info->statBuffer->cookie(), info->effectiveSensorControls);\n+\t/*\n+\t * We **must** use the sequence reported by the CIO2 when fetching the\n+\t * applied sensor controls.\n+\t */\n+\tFrameBuffer *rawBuffer = request->_d()->findInternalBuffer(InternalStream::Mem2Mem);\n+\tASSERT(rawBuffer);\n+\n+\tipa_->processStatsBuffer(request->sequence(), request->metadata().get(controls::SensorTimestamp).value_or(0),\n+\t\t\t\t buffer->cookie(), delayedCtrls_->get(rawBuffer->metadata().sequence));\n }\n \n /*\ndiff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build\nindex a1b0b31a..d60e07ae 100644\n--- a/src/libcamera/pipeline/ipu3/meson.build\n+++ b/src/libcamera/pipeline/ipu3/meson.build\n@@ -2,7 +2,6 @@\n \n libcamera_sources += files([\n 'cio2.cpp',\n- 'frames.cpp',\n 'imgu.cpp',\n 'ipu3.cpp',\n ])\n", "prefixes": [ "v2", "7/7" ] }