Patch Detail
Show a patch.
GET /api/patches/19512/?format=api
{ "id": 19512, "url": "https://patchwork.libcamera.org/api/patches/19512/?format=api", "web_url": "https://patchwork.libcamera.org/patch/19512/", "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-2-dan.scally@ideasonboard.com>", "date": "2024-02-20T16:43:11", "name": "[v2,1/7] libcamera: request: Introduce internal buffers", "commit_ref": null, "pull_url": null, "state": "rejected", "archived": true, "hash": "98b6bc3eb4f6698bf1c530b6858a22427c4333cc", "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/19512/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/19512/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/19512/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 F10F9C3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 20 Feb 2024 16:43:28 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6EFFE6281C;\n\tTue, 20 Feb 2024 17:43:26 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E6D8E61CAA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 20 Feb 2024 17:43:23 +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 87B7C14B0;\n\tTue, 20 Feb 2024 17:43:16 +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=\"dLh35uea\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1708447396;\n\tbh=W49fGUKG1FUnRBidXbw5IYfpuQeRo7bpjnz3RT9D1SI=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=dLh35ueaagZ2j4fkDgRb1Jz9Tndp1JUICunH4RFkn5LdNeyYIq99+rWnTClnShkl0\n\tk4ppDPbmeC1LTmL6jFT0m4aI6R8i3NJNJG0gvNrpwaryhs4SybJXKI9X8bfHyAdMwj\n\tWqLm+sgavUOk10CBGJdGZ7fhccwLOgyBG5QZP2X0=", "From": "Daniel Scally <dan.scally@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[PATCH v2 1/7] libcamera: request: Introduce internal buffers", "Date": "Tue, 20 Feb 2024 16:43:11 +0000", "Message-Id": "<20240220164317.998477-2-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": "To simplify Pipeline Handler code designed to track whether a\nRequest is ready to be returned to the application or not, extend\nRequest::Private with the concept of internal buffers. These can\nbe added to a Request::Private and associated with a role, for which\na new enumeration holds descriptors. Internal buffers added to a\nRequest in this way count towards pending buffers and so will cause\nhasPendingBuffers() to return false until they are also completed.\n\nThis necessitates a checks before emiting the bufferCompleted signal\nto confirm that the buffer under consideration is associated with a\nStream rather than a purely-internal buffer.\n\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n---\nChanges in v2:\n\n\t- New patch, previously this was just done via the inFlightStatsBuffers\n\t map in the RkISP1 pipeline handler.\n\n include/libcamera/internal/request.h | 12 ++++\n src/libcamera/pipeline_handler.cpp | 9 ++-\n src/libcamera/request.cpp | 93 +++++++++++++++++++++++++++-\n 3 files changed, 112 insertions(+), 2 deletions(-)", "diff": "diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h\nindex 3454cf5a..03ccc7e5 100644\n--- a/include/libcamera/internal/request.h\n+++ b/include/libcamera/internal/request.h\n@@ -31,9 +31,20 @@ public:\n \tPrivate(Camera *camera);\n \t~Private();\n \n+\tenum InternalStream {\n+\t\tParameters,\n+\t\tStatistics,\n+\t\tMem2Mem,\n+\t};\n+\n+\tusing InternalBufferMap = std::map<InternalStream, FrameBuffer *>;\n+\n \tCamera *camera() const { return camera_; }\n \tbool hasPendingBuffers() const;\n \n+\tconst InternalBufferMap &internalBuffers() const { return internalBufferMap_; }\n+\tint addInternalBuffer(InternalStream stream, FrameBuffer *buffer);\n+\tFrameBuffer *findInternalBuffer(InternalStream stream);\n \tbool completeBuffer(FrameBuffer *buffer);\n \tvoid complete();\n \tvoid cancel();\n@@ -59,6 +70,7 @@ private:\n \tstd::unordered_set<FrameBuffer *> pending_;\n \tstd::map<FrameBuffer *, std::unique_ptr<EventNotifier>> notifiers_;\n \tstd::unique_ptr<Timer> timer_;\n+\tInternalBufferMap internalBufferMap_;\n };\n \n } /* namespace libcamera */\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 29e0c98a..343804e9 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -499,7 +499,14 @@ void PipelineHandler::doQueueRequests()\n bool PipelineHandler::completeBuffer(Request *request, FrameBuffer *buffer)\n {\n \tCamera *camera = request->_d()->camera();\n-\tcamera->bufferCompleted.emit(request, buffer);\n+\n+\tfor (auto pair : request->buffers()) {\n+\t\tif (pair.second == buffer) {\n+\t\t\tcamera->bufferCompleted.emit(request, buffer);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \treturn request->_d()->completeBuffer(buffer);\n }\n \ndiff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\nindex 949c556f..3b852f7b 100644\n--- a/src/libcamera/request.cpp\n+++ b/src/libcamera/request.cpp\n@@ -57,6 +57,22 @@ Request::Private::~Private()\n \tdoCancelRequest();\n }\n \n+/**\n+ * \\enum Request::Private::InternalStream\n+ * Internal stream identifiers\n+ * \\var Request::Private::Parameters\n+ * The stream relates to ISP parameters\n+ * \\var Request::Private::Statistics\n+ * The stream relates to ISP statistics\n+ * \\var Request::Private::Mem2Mem\n+ * The stream relates to memory-to-memory mode operation\n+ */\n+\n+/**\n+ * \\typedef Request::Private::InternalBufferMap\n+ * \\brief A map of InternalStream to FrameBuffer pointers\n+ */\n+\n /**\n * \\fn Request::Private::camera()\n * \\brief Retrieve the camera this request has been queued to\n@@ -75,6 +91,72 @@ bool Request::Private::hasPendingBuffers() const\n \treturn !pending_.empty();\n }\n \n+/**\n+ * \\fn Request::Private::internalBuffers\n+ * \\brief Retrieve the Request::Private's InternalStreams to buffers map\n+ *\n+ * Return a reference to the map that associates each InternalStream to the\n+ * FrameBuffer it uses.\n+ *\n+ * \\return The map of InternalStream to FrameBuffer\n+ */\n+\n+/**\n+ * \\brief Add a FrameBuffer to a Request for an InternalStream\n+ * \\param[in] stream The InternalStream the buffer is used for\n+ * \\param[in] buffer The FrameBuffer to add to the request\n+ *\n+ * A reference to the buffer is stored in the request. The caller is responsible\n+ * for ensuring that the buffer will remain valid until the request complete\n+ * callback is called.\n+ *\n+ * A request can only contain one buffer per InternalStream. If a buffer has\n+ * already been added to the request for the same InternalStream, this function\n+ * returns -EEXIST.\n+ *\n+ * \\return 0 on success or a negative error code otherwise\n+ * \\retval -EEXIST The request already contains a buffer for the stream\n+ */\n+int Request::Private::addInternalBuffer(InternalStream stream, FrameBuffer *buffer)\n+{\n+\tauto it = internalBufferMap_.find(stream);\n+\tif (it != internalBufferMap_.end()) {\n+\t\tLOG(Request, Error)\n+\t\t\t<< \"FrameBuffer already set for internal stream\";\n+\t\treturn -EEXIST;\n+\t}\n+\n+\tbuffer->_d()->setRequest(_o<Request>());\n+\tpending_.insert(buffer);\n+\tinternalBufferMap_[stream] = buffer;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * \\var Request::Private::internalBufferMap_\n+ * \\brief Mapping of private buffer streams to buffers for this request\n+ *\n+ * The internalBufferMap_ tracks the buffers associated with each internal\n+ * buffer stream. If a stream is not utilised in this request there will be no\n+ * buffer for that stream in the map.\n+ */\n+\n+/**\n+ * \\brief Return the buffer associated with a stream\n+ * \\param[in] stream The \\ref InternalStream the buffer is associated to\n+ * \\return The buffer associated with the stream, or nullptr if the stream is\n+ * not part of this request\n+ */\n+FrameBuffer *Request::Private::findInternalBuffer(InternalStream stream)\n+{\n+\tauto it = internalBufferMap_.find(stream);\n+\tif (it == internalBufferMap_.end())\n+\t\treturn nullptr;\n+\n+\treturn it->second;\n+}\n+\n /**\n * \\brief Complete a buffer for the request\n * \\param[in] buffer The buffer that has completed\n@@ -130,7 +212,14 @@ void Request::Private::doCancelRequest()\n \n \tfor (FrameBuffer *buffer : pending_) {\n \t\tbuffer->_d()->cancel();\n-\t\tcamera_->bufferCompleted.emit(request, buffer);\n+\n+\t\tfor (auto pair : request->bufferMap_) {\n+\t\t\tif (pair.second == buffer) {\n+\t\t\t\tcamera_->bufferCompleted.emit(request, buffer);\n+\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n \t}\n \n \tcancelled_ = true;\n@@ -395,6 +484,8 @@ void Request::reuse(ReuseFlag flags)\n \t\tbufferMap_.clear();\n \t}\n \n+\t_d()->internalBufferMap_.clear();\n+\n \tstatus_ = RequestPending;\n \n \tcontrols_->clear();\n", "prefixes": [ "v2", "1/7" ] }