summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2021-07-15 16:27:43 +0200
committerJacopo Mondi <jacopo@jmondi.org>2021-08-12 10:08:32 +0200
commit11fe4333c54d6ffd69b6911520ab5aa47893b58d (patch)
tree8249d2b18521701716c797fef64470aa95b9920b /src/ipa
parent62c82ab93ff5fb07d581d3a78bc52a621a2a9c8f (diff)
libcamera: ipu3: Initialize controls in the IPA
All the IPU3 Camera controls are currently initialized by the pipeline handler which initializes them using the camera sensor configuration and platform specific requirements. However, some controls are better initialized by the IPA, which might, in example, cap the exposure times and frame duration to the constraints of its algorithms implementation. Also, moving forward, the IPA should register controls to report its capabilities, in example the ability to enable/disable 3A algorithms on request. Move the existing controls initialization to the IPA, by providing the sensor configuration and its controls to the IPU3IPA::init() function, which initializes controls and returns them to the pipeline through an output parameter. The existing controls initialization has been copied verbatim from the pipeline handler to the IPA, if not a for few line breaks adjustments and the resulting Camera controls values are not changed. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/ipu3/ipu3.cpp72
1 files changed, 69 insertions, 3 deletions
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index c903f751..36a06966 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -5,7 +5,9 @@
* ipu3.cpp - IPU3 Image Processing Algorithms
*/
+#include <array>
#include <stdint.h>
+#include <utility>
#include <linux/intel-ipu3.h>
#include <linux/v4l2-controls.h>
@@ -37,7 +39,11 @@ namespace ipa::ipu3 {
class IPAIPU3 : public IPAIPU3Interface
{
public:
- int init(const IPASettings &settings) override;
+ int init(const IPASettings &settings,
+ const IPACameraSensorInfo &sensorInfo,
+ const ControlInfoMap &sensorControls,
+ ControlInfoMap *ipaControls) override;
+
int start() override;
void stop() override {}
@@ -85,14 +91,74 @@ private:
struct ipu3_uapi_grid_config bdsGrid_;
};
-int IPAIPU3::init(const IPASettings &settings)
+/**
+ * Initialize the IPA module and its controls.
+ *
+ * This function receives the camera sensor information from the pipeline
+ * handler, computes the limits of the controls it handles and returns
+ * them in the \a ipaControls output parameter.
+ */
+int IPAIPU3::init(const IPASettings &settings,
+ const IPACameraSensorInfo &sensorInfo,
+ const ControlInfoMap &sensorControls,
+ ControlInfoMap *ipaControls)
{
camHelper_ = CameraSensorHelperFactory::create(settings.sensorModel);
if (camHelper_ == nullptr) {
- LOG(IPAIPU3, Error) << "Failed to create camera sensor helper for " << settings.sensorModel;
+ LOG(IPAIPU3, Error)
+ << "Failed to create camera sensor helper for "
+ << settings.sensorModel;
return -ENODEV;
}
+ /* Initialize Controls. */
+ ControlInfoMap::Map controls{};
+
+ /*
+ * Compute exposure time limits.
+ *
+ * Initialize the control using the line length and pixel rate of the
+ * current configuration converted to microseconds. Use the
+ * V4L2_CID_EXPOSURE control to get exposure min, max and default and
+ * convert it from lines to microseconds.
+ */
+ double lineDuration = sensorInfo.lineLength / (sensorInfo.pixelRate / 1e6);
+ const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
+ int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
+ int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
+ int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;
+ controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,
+ defExposure);
+
+ /*
+ * Compute the frame duration limits.
+ *
+ * The frame length is computed assuming a fixed line length combined
+ * with the vertical frame sizes.
+ */
+ const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second;
+ uint32_t hblank = v4l2HBlank.def().get<int32_t>();
+ uint32_t lineLength = sensorInfo.outputSize.width + hblank;
+
+ const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
+ std::array<uint32_t, 3> frameHeights{
+ v4l2VBlank.min().get<int32_t>() + sensorInfo.outputSize.height,
+ v4l2VBlank.max().get<int32_t>() + sensorInfo.outputSize.height,
+ v4l2VBlank.def().get<int32_t>() + sensorInfo.outputSize.height,
+ };
+
+ std::array<int64_t, 3> frameDurations;
+ for (unsigned int i = 0; i < frameHeights.size(); ++i) {
+ uint64_t frameSize = lineLength * frameHeights[i];
+ frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U);
+ }
+
+ controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0],
+ frameDurations[1],
+ frameDurations[2]);
+
+ *ipaControls = ControlInfoMap(std::move(controls), controls::controls);
+
return 0;
}