summaryrefslogtreecommitdiff
path: root/src/ipa/rpi
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa/rpi')
-rw-r--r--src/ipa/rpi/common/ipa_base.cpp27
-rw-r--r--src/ipa/rpi/controller/controller.cpp20
-rw-r--r--src/ipa/rpi/controller/controller.h2
3 files changed, 49 insertions, 0 deletions
diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
index 6ac9d5de..6ec91575 100644
--- a/src/ipa/rpi/common/ipa_base.cpp
+++ b/src/ipa/rpi/common/ipa_base.cpp
@@ -532,6 +532,33 @@ void IpaBase::setMode(const IPACameraSensorInfo &sensorInfo)
mode_.maxLineLength = sensorInfo.maxLineLength * (1.0s / sensorInfo.pixelRate);
/*
+ * Ensure that the maximum pixel processing rate does not exceed the ISP
+ * hardware capabilities. If it does, try adjusting the minimum line
+ * length to compensate if possible.
+ */
+ Duration minPixelTime = controller_.getHardwareConfig().minPixelProcessingTime;
+ Duration pixelTime = mode_.minLineLength / mode_.width;
+ if (minPixelTime && pixelTime < minPixelTime) {
+ Duration adjustedLineLength = minPixelTime * mode_.width;
+ if (adjustedLineLength <= mode_.maxLineLength) {
+ LOG(IPARPI, Info)
+ << "Adjusting mode minimum line length from " << mode_.minLineLength
+ << " to " << adjustedLineLength << " because of ISP constraints.";
+ mode_.minLineLength = adjustedLineLength;
+ } else {
+ LOG(IPARPI, Error)
+ << "Sensor minimum line length of " << pixelTime * mode_.width
+ << " (" << 1us / pixelTime << " MPix/s)"
+ << " is below the minimum allowable ISP limit of "
+ << adjustedLineLength
+ << " (" << 1us / minPixelTime << " MPix/s) ";
+ LOG(IPARPI, Error)
+ << "THIS WILL CAUSE IMAGE CORRUPTION!!! "
+ << "Please update the camera sensor driver to allow more horizontal blanking control.";
+ }
+ }
+
+ /*
* Set the frame length limits for the mode to ensure exposure and
* framerate calculations are clipped appropriately.
*/
diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp
index e62becd8..5ca98b98 100644
--- a/src/ipa/rpi/controller/controller.cpp
+++ b/src/ipa/rpi/controller/controller.cpp
@@ -17,6 +17,7 @@
using namespace RPiController;
using namespace libcamera;
+using namespace std::literals::chrono_literals;
LOG_DEFINE_CATEGORY(RPiController)
@@ -37,6 +38,7 @@ static const std::map<std::string, Controller::HardwareConfig> HardwareConfigMap
.numGammaPoints = 33,
.pipelineWidth = 13,
.statsInline = false,
+ .minPixelProcessingTime = 0s,
}
},
{
@@ -51,6 +53,24 @@ static const std::map<std::string, Controller::HardwareConfig> HardwareConfigMap
.numGammaPoints = 64,
.pipelineWidth = 16,
.statsInline = true,
+
+ /*
+ * The constraint below is on the rate of pixels going
+ * from CSI2 peripheral to ISP-FE (400Mpix/s, plus tiny
+ * overheads per scanline, for which 380Mpix/s is a
+ * conservative bound).
+ *
+ * There is a 64kbit data FIFO before the bottleneck,
+ * which means that in all reasonable cases the
+ * constraint applies at a timescale >= 1 scanline, so
+ * adding horizontal blanking can prevent loss.
+ *
+ * If the backlog were to grow beyond 64kbit during a
+ * single scanline, there could still be loss. This
+ * could happen using 4 lanes at 1.5Gbps at 10bpp with
+ * frames wider than ~16,000 pixels.
+ */
+ .minPixelProcessingTime = 1.0us / 380,
}
},
};
diff --git a/src/ipa/rpi/controller/controller.h b/src/ipa/rpi/controller/controller.h
index 6e5f5952..170aea74 100644
--- a/src/ipa/rpi/controller/controller.h
+++ b/src/ipa/rpi/controller/controller.h
@@ -15,6 +15,7 @@
#include <vector>
#include <string>
+#include <libcamera/base/utils.h>
#include "libcamera/internal/yaml_parser.h"
#include "camera_mode.h"
@@ -47,6 +48,7 @@ public:
unsigned int numGammaPoints;
unsigned int pipelineWidth;
bool statsInline;
+ libcamera::utils::Duration minPixelProcessingTime;
};
Controller();