[PATCH 1/1] libcamera: Camera: Add signals for completion of metadata as a partial result
Harvey Yang
chenghaoyang at chromium.org
Thu Sep 12 06:52:48 CEST 2024
From: Han-Lin Chen <hanlinchen at chromium.org>
Allows pipeline handler to signal metadata completion by adding the
following signals to Camera:
Signal<Request *, const ControlList &> metadataCompleted;
Together with the bufferCompleted signal, the pipeline handler is allowed to
return buffers and partial metadata at any stage of processing.
Signed-off-by: Han-Lin Chen <hanlinchen at chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang at chromium.org>
---
include/libcamera/camera.h | 1 +
include/libcamera/internal/pipeline_handler.h | 1 +
include/libcamera/request.h | 5 +++
src/libcamera/camera.cpp | 6 +++
src/libcamera/pipeline_handler.cpp | 37 +++++++++++++++++++
src/libcamera/request.cpp | 20 ++++++++++
6 files changed, 70 insertions(+)
diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 94cee7bd..08c5c58c 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -122,6 +122,7 @@ public:
const std::string &id() const;
+ Signal<Request *, const ControlList &> metadataCompleted;
Signal<Request *, FrameBuffer *> bufferCompleted;
Signal<Request *> requestCompleted;
Signal<> disconnected;
diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
index 0d380803..1af63a23 100644
--- a/include/libcamera/internal/pipeline_handler.h
+++ b/include/libcamera/internal/pipeline_handler.h
@@ -58,6 +58,7 @@ public:
void registerRequest(Request *request);
void queueRequest(Request *request);
+ void completeMetadata(Request *request, const ControlList &metadata);
bool completeBuffer(Request *request, FrameBuffer *buffer);
void completeRequest(Request *request);
diff --git a/include/libcamera/request.h b/include/libcamera/request.h
index e214a9d1..0200f4a1 100644
--- a/include/libcamera/request.h
+++ b/include/libcamera/request.h
@@ -12,6 +12,7 @@
#include <ostream>
#include <stdint.h>
#include <string>
+#include <unordered_set>
#include <libcamera/base/class.h>
#include <libcamera/base/signal.h>
@@ -64,6 +65,8 @@ public:
std::string toString() const;
+ ControlList addCompletedMetadata(const ControlList &metadata);
+
private:
LIBCAMERA_DISABLE_COPY(Request)
@@ -73,6 +76,8 @@ private:
const uint64_t cookie_;
Status status_;
+
+ std::unordered_set<unsigned int> completedMetadata_;
};
std::ostream &operator<<(std::ostream &out, const Request &r);
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index a86f552a..5ffae23e 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -892,6 +892,12 @@ const std::string &Camera::id() const
* completed
*/
+/**
+ * \var Camera::metadataCompleted
+ * \brief Signal emitted when some metadata for a request is completed as a
+ * partial result
+ */
+
/**
* \var Camera::requestCompleted
* \brief Signal emitted when a request queued to the camera has completed
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index e5940469..5d2999cb 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -535,6 +535,28 @@ bool PipelineHandler::completeBuffer(Request *request, FrameBuffer *buffer)
return request->_d()->completeBuffer(buffer);
}
+/**
+ * \brief Complete part of metadata for a request
+ * \param[in] request The request the buffer belongs to
+ * \param[in] metadata The partial metadata that has completed
+ *
+ * This function could be called by pipeline handlers to signal completion of
+ * the \a metadata part of the \a request. It notifies applications of metadata
+ * completion.
+ *
+ * \context This function shall be called from the CameraManager thread.
+ */
+void PipelineHandler::completeMetadata(Request *request, const ControlList &metadata)
+{
+ const ControlList &validMetadata = request->addCompletedMetadata(metadata);
+ if (!validMetadata.empty()) {
+ request->metadata().merge(validMetadata);
+
+ Camera *camera = request->_d()->camera();
+ camera->metadataCompleted.emit(request, validMetadata);
+ }
+}
+
/**
* \brief Signal request completion
* \param[in] request The request that has completed
@@ -557,6 +579,21 @@ void PipelineHandler::completeRequest(Request *request)
Camera::Private *data = camera->_d();
+ /*
+ * Collect metadata which is not yet completed by the Camera, and
+ * create one partial result to cover the missing metadata before
+ * completing the whole request. This guarantees the aggregation of
+ * metadata in completed partial results equals to the global metadata
+ * in the request.
+ *
+ * \todo: Forbid merging metadata into request.metadata() directly and
+ * force calling completeMetadata() to report metadata.
+ */
+ const ControlList &validMetadata = request->addCompletedMetadata(
+ request->metadata());
+ if (!validMetadata.empty())
+ camera->metadataCompleted.emit(request, validMetadata);
+
while (!data->queuedRequests_.empty()) {
Request *req = data->queuedRequests_.front();
if (req->status() == Request::RequestPending)
diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
index 8c56ed30..3ce23a8e 100644
--- a/src/libcamera/request.cpp
+++ b/src/libcamera/request.cpp
@@ -598,6 +598,26 @@ std::string Request::toString() const
return ss.str();
}
+/**
+ * \brief Add completed metadata, as a partial result
+ * \param[in] metadata The metadata completed
+ *
+ * Request will record the entries that has been sent to the application, to
+ * prevent duplicated controls.
+ *
+ * \return ControlList that hasn't been completed before
+ */
+ControlList Request::addCompletedMetadata(const ControlList &metadata)
+{
+ ControlList resultMetadata;
+ for (auto &[id, value] : metadata) {
+ if (!completedMetadata_.count(id))
+ resultMetadata.set(id, value);
+ }
+
+ return resultMetadata;
+}
+
/**
* \brief Insert a text representation of a Request into an output stream
* \param[in] out The output stream
--
2.46.0.598.g6f2099f65c-goog
More information about the libcamera-devel
mailing list