Patch Detail
Show a patch.
GET /api/1.1/patches/22112/?format=api
{ "id": 22112, "url": "https://patchwork.libcamera.org/api/1.1/patches/22112/?format=api", "web_url": "https://patchwork.libcamera.org/patch/22112/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20241127092632.3145984-2-chenghaoyang@chromium.org>", "date": "2024-11-27T09:25:51", "name": "[v2,1/9] libcamera: Camera: Add signals for completion of metadata as a partial result", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "e42565ed4afeb64f14c08d2bb6f3b41512036676", "submitter": { "id": 117, "url": "https://patchwork.libcamera.org/api/1.1/people/117/?format=api", "name": "Cheng-Hao Yang", "email": "chenghaoyang@chromium.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/22112/mbox/", "series": [ { "id": 4828, "url": "https://patchwork.libcamera.org/api/1.1/series/4828/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4828", "date": "2024-11-27T09:25:50", "name": "Signal metadataAvailable and Android partial result", "version": 2, "mbox": "https://patchwork.libcamera.org/series/4828/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/22112/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/22112/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 712C5C3213\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 27 Nov 2024 09:26:46 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D6C0B660C3;\n\tWed, 27 Nov 2024 10:26:45 +0100 (CET)", "from mail-ot1-x335.google.com (mail-ot1-x335.google.com\n\t[IPv6:2607:f8b0:4864:20::335])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 14DAE660AD\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Nov 2024 10:26:41 +0100 (CET)", "by mail-ot1-x335.google.com with SMTP id\n\t46e09a7af769-71d42a79a14so1652478a34.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Nov 2024 01:26:41 -0800 (PST)", "from chenghaoyang-low.c.googlers.com.com\n\t(27.247.221.35.bc.googleusercontent.com. [35.221.247.27])\n\tby smtp.gmail.com with ESMTPSA id\n\t41be03b00d2f7-7fbcbfc41f9sm8693027a12.8.2024.11.27.01.26.37\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 27 Nov 2024 01:26:38 -0800 (PST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"jBFo3plp\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=chromium.org; s=google; t=1732699599; x=1733304399;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=W9hw/h8DkwpQ2JaAwAse5GJuP66gmF3X+z6FR3Gk7gc=;\n\tb=jBFo3plpHI1hVtllOfs4k5J8lyHGdWlfJe8vG3PYZQ7jOg1d4ooyVX47FQD4UZ0Les\n\tbf6yOP0sxEhnlAvQL9j/bppbvl+jNTHVEcY9qxg8bhqG33EasY6p0d8IRJdXY1nJXKeK\n\tEzlsnW4Ow1/meumLAn958CK4Zg66GDnG2iA4Y=", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1732699599; x=1733304399;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=W9hw/h8DkwpQ2JaAwAse5GJuP66gmF3X+z6FR3Gk7gc=;\n\tb=TH2DpyrLu06StJiVOtJYJu28iQRlsR6OHsZYbfnpXfWbwOdky+yxl1kMKl3vILc1X+\n\tWusim/j1mQlCJRahOFDlgkH6oLx+268EFlD4Zgw5NeVYlA1jPsnkw2syVkZdmfVbfVkb\n\tGIQIMMtltGz7fB7ZY5yCzm15aogw4eXlpicJvyajLuWRRPnfCA0kAKNG6QkTwFCyjigQ\n\tTSmXDWXT/FOwBF6SzMrzkqTGPyRuKs5jW4katJEWs5P9b6yM3lF2GJtWjECFoE0Ydyon\n\t2p47R6htjmuecZSmayN7xmqLZbyFYXkKottH84RqfzMIhZ2rOW6xV4bKJpHZX68kT+Ny\n\tn75w==", "X-Gm-Message-State": "AOJu0YydG6Zk9YbUEnErEq5Mi78UMydWzJYNNfOhxay+zIt0JYxUUQFh\n\tcV7D/jjbbRXFZXXDvibjLc54Wytd8OG5G0dTsNEUZuKBX5ekJiZmeWI/1afQavonf+JzHtBTPR8\n\t=", "X-Gm-Gg": "ASbGncvFY50wSq1HfIhX+3UUyZn1mirC/BmvKVYPWsNDOUtcj1WTtjPT73FvquH6NOf\n\tB0J+rAGD03Uz6ONzGmXSx3AGLhBHmK65OTKfs1uhcdtuosRYejV6euRl5TnMZ/AoLNmX3U402H3\n\tf6+OW6v/FqsjjsQaj8X6MKXvYsTn0I67YIxCj51XVjGirTfh1B9hkeNTW2LVm2VnxNdi9OpLCVz\n\txiC+gl8ivMrQdXO5C5TEDSQJhXuMWpgE1UZFpJSp7GBTQCGwVdP+7VoNTq3NX6tDhyvXPAO9qlu\n\t/MNiJAUbL4RWVS72EBlBjkUBz0IIUSpXF3GYsJy0jil2REmehg/FnA==", "X-Google-Smtp-Source": "AGHT+IGX39X0MMD9q3e5WIa5y/wqcLhDtSLtr/WxnTf/+Ultwg7Caumei5Wdr09Df7d+iUNRbB17qw==", "X-Received": "by 2002:a05:6830:6dc6:b0:718:17b6:56f5 with SMTP id\n\t46e09a7af769-71d65d01867mr2225754a34.29.1732699599128; \n\tWed, 27 Nov 2024 01:26:39 -0800 (PST)", "From": "Harvey Yang <chenghaoyang@chromium.org>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Han-Lin Chen <hanlinchen@chromium.org>,\n\tHarvey Yang <chenghaoyang@chromium.org>", "Subject": "[PATCH v2 1/9] libcamera: Camera: Add signals for completion of\n\tmetadata as a partial result", "Date": "Wed, 27 Nov 2024 09:25:51 +0000", "Message-ID": "<20241127092632.3145984-2-chenghaoyang@chromium.org>", "X-Mailer": "git-send-email 2.47.0.338.g60cca15819-goog", "In-Reply-To": "<20241127092632.3145984-1-chenghaoyang@chromium.org>", "References": "<20241127092632.3145984-1-chenghaoyang@chromium.org>", "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": "From: Han-Lin Chen <hanlinchen@chromium.org>\n\nAllows pipeline handler to signal metadata completion by adding the\nfollowing signals to Camera:\n\nSignal<Request *, const ControlList &> metadataAvailable;\n\nTogether with the bufferCompleted signal, the pipeline handler is allowed to\nreturn buffers and partial metadata at any stage of processing.\n\nSigned-off-by: Han-Lin Chen <hanlinchen@chromium.org>\nCo-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n---\n include/libcamera/camera.h | 1 +\n include/libcamera/internal/pipeline_handler.h | 1 +\n include/libcamera/internal/request.h | 4 ++\n include/libcamera/request.h | 1 +\n src/libcamera/camera.cpp | 6 +++\n src/libcamera/pipeline_handler.cpp | 41 +++++++++++++++++++\n src/libcamera/request.cpp | 21 ++++++++++\n 7 files changed, 75 insertions(+)", "diff": "diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex 94cee7bd8..eb7cdf81b 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -122,6 +122,7 @@ public:\n \n \tconst std::string &id() const;\n \n+\tSignal<Request *, const ControlList &> metadataAvailable;\n \tSignal<Request *, FrameBuffer *> bufferCompleted;\n \tSignal<Request *> requestCompleted;\n \tSignal<> disconnected;\ndiff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex fb28a18d0..6c6cad66f 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -58,6 +58,7 @@ public:\n \tvoid registerRequest(Request *request);\n \tvoid queueRequest(Request *request);\n \n+\tvoid completeMetadata(Request *request, const ControlList &metadata);\n \tbool completeBuffer(Request *request, FrameBuffer *buffer);\n \tvoid completeRequest(Request *request);\n \tvoid cancelRequest(Request *request);\ndiff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h\nindex 4e7d05b1e..286cd9d76 100644\n--- a/include/libcamera/internal/request.h\n+++ b/include/libcamera/internal/request.h\n@@ -43,6 +43,8 @@ public:\n \tvoid prepare(std::chrono::milliseconds timeout = 0ms);\n \tSignal<> prepared;\n \n+\tControlList addCompletedMetadata(const ControlList &metadata);\n+\n private:\n \tfriend class PipelineHandler;\n \tfriend std::ostream &operator<<(std::ostream &out, const Request &r);\n@@ -60,6 +62,8 @@ private:\n \tstd::unordered_set<FrameBuffer *> pending_;\n \tstd::map<FrameBuffer *, std::unique_ptr<EventNotifier>> notifiers_;\n \tstd::unique_ptr<Timer> timer_;\n+\n+\tstd::unordered_set<unsigned int> completedMetadata_;\n };\n \n } /* namespace libcamera */\ndiff --git a/include/libcamera/request.h b/include/libcamera/request.h\nindex e214a9d13..2c78d9bb4 100644\n--- a/include/libcamera/request.h\n+++ b/include/libcamera/request.h\n@@ -12,6 +12,7 @@\n #include <ostream>\n #include <stdint.h>\n #include <string>\n+#include <unordered_set>\n \n #include <libcamera/base/class.h>\n #include <libcamera/base/signal.h>\ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex 7507e9dda..22484721a 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -892,6 +892,12 @@ const std::string &Camera::id() const\n * completed\n */\n \n+/**\n+ * \\var Camera::metadataAvailable\n+ * \\brief Signal emitted when some metadata for a request is available as a\n+ * partial result\n+ */\n+\n /**\n * \\var Camera::requestCompleted\n * \\brief Signal emitted when a request queued to the camera has completed\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 991b06f26..4ba96cfa2 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -531,6 +531,32 @@ bool PipelineHandler::completeBuffer(Request *request, FrameBuffer *buffer)\n \treturn request->_d()->completeBuffer(buffer);\n }\n \n+/**\n+ * \\brief Complete part of metadata for a request\n+ * \\param[in] request The request the metadata belongs to\n+ * \\param[in] metadata The partial metadata that has completed\n+ *\n+ * This function could be called by pipeline handlers to signal availability of\n+ * \\a metadata before \\a request completes. Early metadata completion allows to\n+ * notify applications about the availability of a partial metadata buffer\n+ * before the associated Request has completed.\n+ *\n+ * A metadata key is expected to be completed at most once. If it's completed\n+ * more than once, the key will be dropped since the second time.\n+ *\n+ * \\context This function shall be called from the CameraManager thread.\n+ */\n+void PipelineHandler::completeMetadata(Request *request, const ControlList &metadata)\n+{\n+\tconst ControlList validMetadata = request->_d()->addCompletedMetadata(metadata);\n+\tif (!validMetadata.empty()) {\n+\t\trequest->metadata().merge(validMetadata);\n+\n+\t\tCamera *camera = request->_d()->camera();\n+\t\tcamera->metadataAvailable.emit(request, validMetadata);\n+\t}\n+}\n+\n /**\n * \\brief Signal request completion\n * \\param[in] request The request that has completed\n@@ -553,6 +579,21 @@ void PipelineHandler::completeRequest(Request *request)\n \n \tCamera::Private *data = camera->_d();\n \n+\t/*\n+\t * Collect metadata which is not yet completed by the Camera, and\n+\t * create one partial result to cover the missing metadata before\n+\t * completing the whole request. This guarantees the aggregation of\n+\t * metadata in completed partial results equals to the global metadata\n+\t * in the request.\n+\t *\n+\t * \\todo: Forbid merging metadata into request.metadata() directly and\n+\t * force calling completeMetadata() to report metadata.\n+\t */\n+\tconst ControlList validMetadata = request->_d()->addCompletedMetadata(\n+\t\trequest->metadata());\n+\tif (!validMetadata.empty())\n+\t\tcamera->metadataAvailable.emit(request, validMetadata);\n+\n \twhile (!data->queuedRequests_.empty()) {\n \t\tRequest *req = data->queuedRequests_.front();\n \t\tif (req->status() == Request::RequestPending)\ndiff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\nindex 8c56ed30d..ae5cdeb19 100644\n--- a/src/libcamera/request.cpp\n+++ b/src/libcamera/request.cpp\n@@ -178,6 +178,7 @@ void Request::Private::reset()\n \tpending_.clear();\n \tnotifiers_.clear();\n \ttimer_.reset();\n+\tcompletedMetadata_.clear();\n }\n \n /*\n@@ -270,6 +271,26 @@ void Request::Private::prepare(std::chrono::milliseconds timeout)\n * if they have failed preparing.\n */\n \n+/**\n+ * \\brief Add completed metadata, as a partial result\n+ * \\param[in] metadata The metadata completed\n+ *\n+ * Request will record the entries that has been sent to the application, to\n+ * prevent duplicated controls.\n+ *\n+ * \\return ControlList that hasn't been completed before\n+ */\n+ControlList Request::Private::addCompletedMetadata(const ControlList &metadata)\n+{\n+\tControlList resultMetadata;\n+\tfor (auto &[id, value] : metadata) {\n+\t\tif (!completedMetadata_.count(id))\n+\t\t\tresultMetadata.set(id, value);\n+\t}\n+\n+\treturn resultMetadata;\n+}\n+\n void Request::Private::notifierActivated(FrameBuffer *buffer)\n {\n \t/* Close the fence if successfully signalled. */\n", "prefixes": [ "v2", "1/9" ] }