From patchwork Tue Jan 6 16:57:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 25644 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 B30D1C3213 for ; Tue, 6 Jan 2026 16:58:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9464462001; Tue, 6 Jan 2026 17:58:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Yt0b3l+a"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7D89161FC0 for ; Tue, 6 Jan 2026 17:58:01 +0100 (CET) Received: from pb-laptop.local (185.221.143.114.nat.pool.zt.hu [185.221.143.114]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 69990581; Tue, 6 Jan 2026 17:57:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1767718660; bh=MzC4wpVJD9DyEjqljKdnn3f8t8g71dRuRgLZqKSdLNI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Yt0b3l+a/z5qtSvBYjnvP+nMNaFp2+MQ11Cu6XEIzXCdKmHX+IbMNTL4A3+nHNB8e i7g4vXo27x5S8iWAt7SMbLr0RjPFMY0aSOSLc3cVChG4MtSwmZ2BFCL0PPBYAJ1Izu EduijfKg4bs3p8Za0Wvc/sdl/qp3ZqsIYCD9LBPs= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Paul Elder , Kieran Bingham Subject: [PATCH v4 14/22] libcamera: camera: Introduce metadataAvailable signal Date: Tue, 6 Jan 2026 17:57:46 +0100 Message-ID: <20260106165754.1759831-15-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260106165754.1759831-1-barnabas.pocze@ideasonboard.com> References: <20260106165754.1759831-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" From: Jacopo Mondi Add a new signal to the Camera class that allows applications to receive notifications for early completion of metadata results. To avoid expensive copies of the metadata results the signal transports a view object of metadata items that are ready. The signal is an opt-in feature for applications and the sum of all metadata results notified through this signal is available in Request::metadata() at request completion time. Signed-off-by: Jacopo Mondi [Use `MetadataList::Diff`, change documentation accordingly.] Signed-off-by: Barnabás Pőcze Reviewed-by: Paul Elder Reviewed-by: Kieran Bingham --- Original: https://patchwork.libcamera.org/patch/22227/ --- Documentation/design/metadata-list.rst | 2 +- include/libcamera/camera.h | 2 + src/libcamera/camera.cpp | 54 ++++++++++++++++++++++++++ src/libcamera/metadata_list.cpp | 1 + 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Documentation/design/metadata-list.rst b/Documentation/design/metadata-list.rst index f535db008..299e30a4a 100644 --- a/Documentation/design/metadata-list.rst +++ b/Documentation/design/metadata-list.rst @@ -20,7 +20,7 @@ extra processing on the image, etc. using certain metadata items. For such an application it is likely best if the value of each metadata item is reported as soon as possible, thus allowing it to start processing as soon as possible. -For this reason, libcamera provides the ``Camera::metadataAvailable`` signal. +For this reason, libcamera provides the :doxy-int:`Camera::metadataAvailable` signal. This signal is dispatched whenever new metadata items become available for a queued request. This mechanism is completely optional, only interested applications need to subscribe, others are free to ignore it completely. :doxy-int:`Request::metadata` diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 53089282a..51aee7ee4 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -123,6 +124,7 @@ public: const std::string &id() const; + Signal metadataAvailable; Signal bufferCompleted; Signal requestCompleted; Signal<> disconnected; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 88990c3c0..6fb916400 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -911,6 +911,60 @@ const std::string &Camera::id() const return _d()->id_; } +/** + * \var Camera::metadataAvailable + * \brief Signal emitted when metadata for a request is available + * + * The metadataAvailable signal notifies applications about the availability + * of metadata for a request before the request completes. + * + * As metadata results could be large in size, the signal transports only a view + * object via which the newly completed metadata items can be accessed. Similarly + * to the metadata list itself, this object is thread-safe, and can be sent to other + * threads for deferred processing. The view object is valid until the request is + * destroyed or reused, whichever happens first. + * + * Applications can access the value of the newly available metadata results as follows: + * + * \code + + void metadataAvailableHandler(Request *request, MetadataList::Diff update) + { + // The object can be iterated... + for (auto &&[id, data] : update) { + // `id` is the numeric identifier + // `data` is a `ControlValueView` object + } + + // ...or individual items can be looked up. + if (auto x = update.get(controls::SensorTimestamp)) { + // `SensorTimestamp` will only be found if it is part of this + // particular update; metadata items completed earlier will + // not be found. + } + } + \endcode + * + * This signal is emitted multiple times for the same request, it is in fact + * emitted by libcamera every time a new set of metadata is made available + * by the Camera to the application. + * + * The sum of all metadata reported through this signal is equal to + * Request::metadata() list when the Request completes. + * + * Applications can opt-in to handle this signal to receive fast notifications + * of metadata availability or can equally access the full metadata list + * at Request completion time through Request::metadata() if they have no interest + * in early metadata notification. + * + * \note The received MetadataList::Diff object is merely a view, it is only valid until + * the associated Request is destroyed or \ref Request::reuse() "reused". However, + * during its valid lifetime, an application is free to create copies and access the + * completed metadata items from separate threads by iteration or MetadataList::Diff::get(). + * + * \sa ControlValueView + */ + /** * \var Camera::bufferCompleted * \brief Signal emitted when a buffer for a request queued to the camera has diff --git a/src/libcamera/metadata_list.cpp b/src/libcamera/metadata_list.cpp index 5b0a47cb4..5a5114fc7 100644 --- a/src/libcamera/metadata_list.cpp +++ b/src/libcamera/metadata_list.cpp @@ -526,6 +526,7 @@ MetadataList::set(const Entry &e, ControlValueView v, State &s) * a series of consecutively added metadata items. Its main purposes is to * enable applications to receive a list of changes made to a MetadataList. * + * \sa Camera::metadataAvailable * \internal * \sa MetadataList::Checkpoint::diffSince() */