summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi/cam_helper.cpp
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2022-10-06 14:17:43 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-18 03:10:08 +0300
commitcb4c5f3e44d41b646c6c7b74689af6d9584e62fa (patch)
treef657b5f98433f943e9b550754535e2049f1b5670 /src/ipa/raspberrypi/cam_helper.cpp
parentdd667e38646928f25c7614bd41b168667f223722 (diff)
ipa: raspberrypi: Allow full line length control
Rename CamHelper::getVBlanking to CamHelper::getBlanking, and update the calculations in that function to return both horizontal and vertical blanking values for a given exposure time and frame duration limits. The calculations are setup such that vertical blanking is extended to the maximum allowable value, and any remainder gets put into horizontal blanking. The calculated horizontal blanking value is now returned to the pipeline handler to pass into DelayedControls to program into the sensor. Update the IPA to now specify the maximum frame duration from the maximum horizontal + vertical blanking values provided by the sensor mode. Additionally, the IPA now uses the frame specific horizontal blanking value (as returned by DelayedControls) in all instances. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Tested-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/ipa/raspberrypi/cam_helper.cpp')
-rw-r--r--src/ipa/raspberrypi/cam_helper.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/src/ipa/raspberrypi/cam_helper.cpp b/src/ipa/raspberrypi/cam_helper.cpp
index bc3f66a5..afbc03d3 100644
--- a/src/ipa/raspberrypi/cam_helper.cpp
+++ b/src/ipa/raspberrypi/cam_helper.cpp
@@ -7,6 +7,7 @@
#include <linux/videodev2.h>
+#include <limits>
#include <map>
#include <string.h>
@@ -70,31 +71,56 @@ Duration CamHelper::exposure(uint32_t exposureLines, const Duration lineLength)
return exposureLines * lineLength;
}
-uint32_t CamHelper::getVBlanking(Duration &exposure,
- Duration minFrameDuration,
- Duration maxFrameDuration) const
+std::pair<uint32_t, uint32_t> CamHelper::getBlanking(Duration &exposure,
+ Duration minFrameDuration,
+ Duration maxFrameDuration) const
{
- uint32_t frameLengthMin, frameLengthMax, vblank;
- uint32_t exposureLines = CamHelper::exposureLines(exposure, mode_.minLineLength);
+ uint32_t frameLengthMin, frameLengthMax, vblank, hblank;
+ Duration lineLength = mode_.minLineLength;
/*
* minFrameDuration and maxFrameDuration are clamped by the caller
* based on the limits for the active sensor mode.
+ *
+ * frameLengthMax gets calculated on the smallest line length as we do
+ * not want to extend that unless absolutely necessary.
*/
frameLengthMin = minFrameDuration / mode_.minLineLength;
frameLengthMax = maxFrameDuration / mode_.minLineLength;
/*
+ * Watch out for (exposureLines + frameIntegrationDiff_) overflowing a
+ * uint32_t in the std::clamp() below when the exposure time is
+ * extremely (extremely!) long - as happens when the IPA calculates the
+ * maximum possible exposure time.
+ */
+ uint32_t exposureLines = std::min(CamHelper::exposureLines(exposure, lineLength),
+ std::numeric_limits<uint32_t>::max() - frameIntegrationDiff_);
+ uint32_t frameLengthLines = std::clamp(exposureLines + frameIntegrationDiff_,
+ frameLengthMin, frameLengthMax);
+
+ /*
+ * If our frame length lines is above the maximum allowed, see if we can
+ * extend the line length to accommodate the requested frame length.
+ */
+ if (frameLengthLines > mode_.maxFrameLength) {
+ Duration lineLengthAdjusted = lineLength * frameLengthLines / mode_.maxFrameLength;
+ lineLength = std::min(mode_.maxLineLength, lineLengthAdjusted);
+ frameLengthLines = mode_.maxFrameLength;
+ }
+
+ hblank = lineLengthToHblank(lineLength);
+ vblank = frameLengthLines - mode_.height;
+
+ /*
* Limit the exposure to the maximum frame duration requested, and
* re-calculate if it has been clipped.
*/
- exposureLines = std::min(frameLengthMax - frameIntegrationDiff_, exposureLines);
- exposure = CamHelper::exposure(exposureLines, mode_.minLineLength);
+ exposureLines = std::min(frameLengthLines - frameIntegrationDiff_,
+ CamHelper::exposureLines(exposure, lineLength));
+ exposure = CamHelper::exposure(exposureLines, lineLength);
- /* Limit the vblank to the range allowed by the frame length limits. */
- vblank = std::clamp(exposureLines + frameIntegrationDiff_,
- frameLengthMin, frameLengthMax) - mode_.height;
- return vblank;
+ return { vblank, hblank };
}
Duration CamHelper::hblankToLineLength(uint32_t hblank) const