Message ID | 20221031114522.14215-7-naush@raspberrypi.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
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@raspberrypi.com> > Reviewed-by: David Plowman <david.plowman@raspberrypi.com> > Tested-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@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 >
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);