[PATCH 1/1] libcamera: Camera: Add signals for completion of metadata as a partial result
Cheng-Hao Yang
chenghaoyang at chromium.org
Wed Nov 13 08:00:52 CET 2024
Gentle ping: May we review this patch recently, so that I can continue
uploading the corresponding patches in Android Adapter?
Thanks :)
BR,
Harvey
On Thu, Sep 12, 2024 at 12:57 PM Harvey Yang <chenghaoyang at chromium.org> wrote:
>
> 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