summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/ipa/raspberrypi.mojom6
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp42
-rw-r--r--src/libcamera/pipeline/raspberrypi/raspberrypi.cpp16
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);