diff options
-rw-r--r-- | include/libcamera/ipa/raspberrypi.mojom | 6 | ||||
-rw-r--r-- | src/ipa/raspberrypi/raspberrypi.cpp | 42 | ||||
-rw-r--r-- | src/libcamera/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 d53644fe..189f978a 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -29,6 +29,8 @@ struct ISPConfig { uint32 bayerBufferId; bool embeddedBufferPresent; libcamera.ControlList controls; + uint32 ipaContext; + uint32 delayContext; }; struct IPAConfig { @@ -119,7 +121,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); }; @@ -129,5 +131,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 ea3e90a3..3157805c 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, libcameraMetadata_); } @@ -540,9 +542,9 @@ void IPARPi::signalIspPrepare(const ISPConfig &data) runIsp.emit(data.bayerBufferId); } -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); /* @@ -1011,12 +1013,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) { /* @@ -1048,7 +1050,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; } @@ -1107,7 +1111,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 = {}; @@ -1123,12 +1127,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()) { @@ -1147,7 +1151,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 164a65b7..8569df17 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_; @@ -1800,9 +1801,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(); } @@ -1875,13 +1876,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); } @@ -1931,7 +1932,8 @@ void RPiCameraData::ispOutputDequeue(FrameBuffer *buffer) * application until after the IPA signals so. */ if (stream == &isp_[Isp::Stats]) { - ipa_->signalStatReady(RPi::MaskStats | static_cast<unsigned int>(index)); + ipa_->signalStatReady(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); @@ -2176,6 +2178,8 @@ void RPiCameraData::tryRunPipeline() ipa::RPi::ISPConfig ispPrepare; ispPrepare.bayerBufferId = 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); |