[libcamera-devel] [PATCH v5 6/7] pipeline: ipa: raspberrypi: Use IPA cookies
Kieran Bingham
kieran.bingham at ideasonboard.com
Tue Nov 8 18:40:34 CET 2022
Quoting Naushir Patuck via libcamera-devel (2022-10-31 11:45:21)
> Pass an IPA cookie from the pipeline handler to the IPA and eventually back to
> the pipeline handler through the setDelayedControls signal. This cookie is used
> to index the RPiController::Metadata object to be used for the frame.
>
> The IPA cookie is then returned from DelayedControls when the frame with the
> applied controls has been returned from the sensor, and eventually passed back
> to the IPA from the signalIspPrepare signal.
>
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> Reviewed-by: David Plowman <david.plowman at raspberrypi.com>
> Tested-by: David Plowman <david.plowman at raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> ---
> include/libcamera/ipa/raspberrypi.mojom | 6 ++-
> src/ipa/raspberrypi/raspberrypi.cpp | 42 ++++++++++---------
> .../pipeline/raspberrypi/raspberrypi.cpp | 16 ++++---
> 3 files changed, 37 insertions(+), 27 deletions(-)
>
> diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom
> index 40f78d9e3b3f..325d2d855bc0 100644
> --- a/include/libcamera/ipa/raspberrypi.mojom
> +++ b/include/libcamera/ipa/raspberrypi.mojom
> @@ -37,6 +37,8 @@ struct ISPConfig {
> uint32 bayerBufferId;
> bool embeddedBufferPresent;
> libcamera.ControlList controls;
> + uint32 ipaContext;
> + uint32 delayContext;
> };
>
> struct IPAConfig {
> @@ -127,7 +129,7 @@ interface IPARPiInterface {
> */
> unmapBuffers(array<uint32> ids);
>
> - [async] signalStatReady(uint32 bufferId);
> + [async] signalStatReady(uint32 bufferId, uint32 ipaContext);
> [async] signalQueueRequest(libcamera.ControlList controls);
> [async] signalIspPrepare(ISPConfig data);
> };
> @@ -137,5 +139,5 @@ interface IPARPiEventInterface {
> runIsp(uint32 bufferId);
> embeddedComplete(uint32 bufferId);
> setIspControls(libcamera.ControlList controls);
> - setDelayedControls(libcamera.ControlList controls);
> + setDelayedControls(libcamera.ControlList controls, uint32 delayContext);
> };
> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
> index 799a4fe70000..194171a8bc96 100644
> --- a/src/ipa/raspberrypi/raspberrypi.cpp
> +++ b/src/ipa/raspberrypi/raspberrypi.cpp
> @@ -126,7 +126,7 @@ public:
> ControlList *controls, IPAConfigResult *result) override;
> void mapBuffers(const std::vector<IPABuffer> &buffers) override;
> void unmapBuffers(const std::vector<unsigned int> &ids) override;
> - void signalStatReady(const uint32_t bufferId) override;
> + void signalStatReady(const uint32_t bufferId, uint32_t ipaContext) override;
> void signalQueueRequest(const ControlList &controls) override;
> void signalIspPrepare(const ISPConfig &data) override;
>
> @@ -137,9 +137,9 @@ private:
> void queueRequest(const ControlList &controls);
> void returnEmbeddedBuffer(unsigned int bufferId);
> void prepareISP(const ISPConfig &data);
> - void reportMetadata();
> - void fillDeviceStatus(const ControlList &sensorControls);
> - void processStats(unsigned int bufferId);
> + void reportMetadata(unsigned int ipaContext);
> + void fillDeviceStatus(const ControlList &sensorControls, unsigned int ipaContext);
> + void processStats(unsigned int bufferId, unsigned int ipaContext);
> void applyFrameDurations(Duration minFrameDuration, Duration maxFrameDuration);
> void applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls);
> void applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls);
> @@ -509,14 +509,16 @@ void IPARPi::unmapBuffers(const std::vector<unsigned int> &ids)
> }
> }
>
> -void IPARPi::signalStatReady(uint32_t bufferId)
> +void IPARPi::signalStatReady(uint32_t bufferId, uint32_t ipaContext)
> {
> + unsigned int context = ipaContext % rpiMetadata_.size();
> +
> if (++checkCount_ != frameCount_) /* assert here? */
> LOG(IPARPI, Error) << "WARNING: Prepare/Process mismatch!!!";
> if (processPending_ && frameCount_ > mistrustCount_)
> - processStats(bufferId);
> + processStats(bufferId, context);
>
> - reportMetadata();
> + reportMetadata(context);
>
> statsMetadataComplete.emit(bufferId & MaskID, libcameraMetadata_);
> }
> @@ -540,9 +542,9 @@ void IPARPi::signalIspPrepare(const ISPConfig &data)
> runIsp.emit(data.bayerBufferId & MaskID);
> }
>
> -void IPARPi::reportMetadata()
> +void IPARPi::reportMetadata(unsigned int ipaContext)
> {
> - RPiController::Metadata &rpiMetadata = rpiMetadata_[0];
> + RPiController::Metadata &rpiMetadata = rpiMetadata_[ipaContext];
> std::unique_lock<RPiController::Metadata> lock(rpiMetadata);
>
> /*
> @@ -1009,12 +1011,12 @@ void IPARPi::returnEmbeddedBuffer(unsigned int bufferId)
> void IPARPi::prepareISP(const ISPConfig &data)
> {
> int64_t frameTimestamp = data.controls.get(controls::SensorTimestamp).value_or(0);
> - RPiController::Metadata lastMetadata;
> - RPiController::Metadata &rpiMetadata = rpiMetadata_[0];
> + unsigned int ipaContext = data.ipaContext % rpiMetadata_.size();
> + RPiController::Metadata &rpiMetadata = rpiMetadata_[ipaContext];
> Span<uint8_t> embeddedBuffer;
>
> - lastMetadata = std::move(rpiMetadata);
> - fillDeviceStatus(data.controls);
> + rpiMetadata.clear();
> + fillDeviceStatus(data.controls, ipaContext);
>
> if (data.embeddedBufferPresent) {
> /*
> @@ -1046,7 +1048,9 @@ void IPARPi::prepareISP(const ISPConfig &data)
> * current frame, or any other bits of metadata that were added
> * in helper_->Prepare().
> */
> - rpiMetadata.merge(lastMetadata);
> + RPiController::Metadata &lastMetadata =
> + rpiMetadata_[ipaContext ? ipaContext : rpiMetadata_.size()];
> + rpiMetadata.mergeCopy(lastMetadata);
> processPending_ = false;
> return;
> }
> @@ -1105,7 +1109,7 @@ void IPARPi::prepareISP(const ISPConfig &data)
> setIspControls.emit(ctrls);
> }
>
> -void IPARPi::fillDeviceStatus(const ControlList &sensorControls)
> +void IPARPi::fillDeviceStatus(const ControlList &sensorControls, unsigned int ipaContext)
> {
> DeviceStatus deviceStatus = {};
>
> @@ -1121,12 +1125,12 @@ void IPARPi::fillDeviceStatus(const ControlList &sensorControls)
>
> LOG(IPARPI, Debug) << "Metadata - " << deviceStatus;
>
> - rpiMetadata_[0].set("device.status", deviceStatus);
> + rpiMetadata_[ipaContext].set("device.status", deviceStatus);
> }
>
> -void IPARPi::processStats(unsigned int bufferId)
> +void IPARPi::processStats(unsigned int bufferId, unsigned int ipaContext)
> {
> - RPiController::Metadata &rpiMetadata = rpiMetadata_[0];
> + RPiController::Metadata &rpiMetadata = rpiMetadata_[ipaContext];
>
> auto it = buffers_.find(bufferId);
> if (it == buffers_.end()) {
> @@ -1145,7 +1149,7 @@ void IPARPi::processStats(unsigned int bufferId)
> ControlList ctrls(sensorCtrls_);
> applyAGC(&agcStatus, ctrls);
>
> - setDelayedControls.emit(ctrls);
> + setDelayedControls.emit(ctrls, ipaContext);
> }
> }
>
> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> index 29626c0ef14e..cae1f7b9aea3 100644
> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> @@ -206,7 +206,7 @@ public:
> void runIsp(uint32_t bufferId);
> void embeddedComplete(uint32_t bufferId);
> void setIspControls(const ControlList &controls);
> - void setDelayedControls(const ControlList &controls);
> + void setDelayedControls(const ControlList &controls, uint32_t delayContext);
> void setSensorControls(ControlList &controls);
> void unicamTimeout();
>
> @@ -262,6 +262,7 @@ public:
> struct BayerFrame {
> FrameBuffer *buffer;
> ControlList controls;
> + unsigned int delayContext;
> };
>
> std::queue<BayerFrame> bayerQueue_;
> @@ -1792,9 +1793,9 @@ void RPiCameraData::setIspControls(const ControlList &controls)
> handleState();
> }
>
> -void RPiCameraData::setDelayedControls(const ControlList &controls)
> +void RPiCameraData::setDelayedControls(const ControlList &controls, uint32_t delayContext)
> {
> - if (!delayedCtrls_->push(controls, 0))
> + if (!delayedCtrls_->push(controls, delayContext))
> LOG(RPI, Error) << "V4L2 DelayedControl set failed";
> handleState();
> }
> @@ -1867,13 +1868,13 @@ void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer)
> * Lookup the sensor controls used for this frame sequence from
> * DelayedControl and queue them along with the frame buffer.
> */
> - auto [ctrl, cookie] = delayedCtrls_->get(buffer->metadata().sequence);
> + auto [ctrl, delayContext] = delayedCtrls_->get(buffer->metadata().sequence);
> /*
> * Add the frame timestamp to the ControlList for the IPA to use
> * as it does not receive the FrameBuffer object.
> */
> ctrl.set(controls::SensorTimestamp, buffer->metadata().timestamp);
> - bayerQueue_.push({ buffer, std::move(ctrl) });
> + bayerQueue_.push({ buffer, std::move(ctrl), delayContext });
> } else {
> embeddedQueue_.push(buffer);
> }
> @@ -1923,7 +1924,8 @@ void RPiCameraData::ispOutputDequeue(FrameBuffer *buffer)
> * application until after the IPA signals so.
> */
> if (stream == &isp_[Isp::Stats]) {
> - ipa_->signalStatReady(ipa::RPi::MaskStats | static_cast<unsigned int>(index));
> + ipa_->signalStatReady(ipa::RPi::MaskStats | static_cast<unsigned int>(index),
> + requestQueue_.front()->sequence());
> } else {
> /* Any other ISP output can be handed back to the application now. */
> handleStreamBuffer(buffer, stream);
> @@ -2168,6 +2170,8 @@ void RPiCameraData::tryRunPipeline()
> ipa::RPi::ISPConfig ispPrepare;
> ispPrepare.bayerBufferId = ipa::RPi::MaskBayerData | bayerId;
> ispPrepare.controls = std::move(bayerFrame.controls);
> + ispPrepare.ipaContext = request->sequence();
> + ispPrepare.delayContext = bayerFrame.delayContext;
>
> if (embeddedBuffer) {
> unsigned int embeddedId = unicam_[Unicam::Embedded].getBufferId(embeddedBuffer);
> --
> 2.25.1
>
More information about the libcamera-devel
mailing list