diff options
Diffstat (limited to 'src/ipa')
-rw-r--r-- | src/ipa/rpi/common/ipa_base.cpp | 27 | ||||
-rw-r--r-- | src/ipa/rpi/controller/controller.cpp | 20 | ||||
-rw-r--r-- | src/ipa/rpi/controller/controller.h | 2 |
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(); |