summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicholas Roth <nicholas@rothemail.net>2022-10-30 18:04:57 -0500
committerJacopo Mondi <jacopo@jmondi.org>2022-11-23 18:44:36 +0100
commit1d8fb317593680a539435dc2cfbb67676894d4c9 (patch)
treed3769e60194af62054e9f6fcdc45ed3cda978f5a /src
parent13d85e632a507d68d0c04f6329078a40b79c7afd (diff)
ipa: rkisp1: add FrameDurationLimits control
Currently, the Android HAL does not work on rkisp1-based devices because required FrameDurationLimits metadata is missing from the IPA implementation. This change sets FrameDurationLimits for rkisp1 based on the existing ipu3 implementation, using the sensor's reported range of vertical blanking intervals with the minimum reported horizontal blanking interval. Signed-off-by: Nicholas Roth <nicholas@rothemail.net> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src')
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp57
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp17
2 files changed, 63 insertions, 11 deletions
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 50039b11..4658aa31 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -49,12 +49,15 @@ public:
IPARkISP1();
int init(const IPASettings &settings, unsigned int hwRevision,
+ const IPACameraSensorInfo &sensorInfo,
+ const ControlInfoMap &sensorControls,
ControlInfoMap *ipaControls) override;
int start() override;
void stop() override;
int configure(const IPAConfigInfo &ipaConfig,
- const std::map<uint32_t, IPAStream> &streamConfig) override;
+ const std::map<uint32_t, IPAStream> &streamConfig,
+ ControlInfoMap *ipaControls) override;
void mapBuffers(const std::vector<IPABuffer> &buffers) override;
void unmapBuffers(const std::vector<unsigned int> &ids) override;
@@ -67,6 +70,9 @@ protected:
std::string logPrefix() const override;
private:
+ void updateControls(const IPACameraSensorInfo &sensorInfo,
+ const ControlInfoMap &sensorControls,
+ ControlInfoMap *ipaControls);
void setControls(unsigned int frame);
std::map<unsigned int, FrameBuffer> buffers_;
@@ -114,6 +120,8 @@ std::string IPARkISP1::logPrefix() const
}
int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
+ const IPACameraSensorInfo &sensorInfo,
+ const ControlInfoMap &sensorControls,
ControlInfoMap *ipaControls)
{
/* \todo Add support for other revisions */
@@ -179,9 +187,8 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
if (ret)
return ret;
- /* Return the controls handled by the IPA. */
- ControlInfoMap::Map ctrlMap = rkisp1Controls;
- *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
+ /* Initialize controls. */
+ updateControls(sensorInfo, sensorControls, ipaControls);
return 0;
}
@@ -199,7 +206,8 @@ void IPARkISP1::stop()
}
int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
- [[maybe_unused]] const std::map<uint32_t, IPAStream> &streamConfig)
+ [[maybe_unused]] const std::map<uint32_t, IPAStream> &streamConfig,
+ ControlInfoMap *ipaControls)
{
sensorControls_ = ipaConfig.sensorControls;
@@ -229,6 +237,9 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
context_.configuration.sensor.size = info.outputSize;
context_.configuration.sensor.lineDuration = info.minLineLength * 1.0s / info.pixelRate;
+ /* Update the camera controls using the new sensor settings. */
+ updateControls(info, sensorControls_, ipaControls);
+
/*
* When the AGC computes the new exposure values for a frame, it needs
* to know the limits for shutter speed and analogue gain.
@@ -331,6 +342,42 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId
metadataReady.emit(frame, metadata);
}
+void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
+ const ControlInfoMap &sensorControls,
+ ControlInfoMap *ipaControls)
+{
+ ControlInfoMap::Map ctrlMap = rkisp1Controls;
+
+ /*
+ * 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);
+ }
+
+ ctrlMap[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0],
+ frameDurations[1],
+ frameDurations[2]);
+
+ *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);
+}
+
void IPARkISP1::setControls(unsigned int frame)
{
/*
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index e946ccc4..231b16ec 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -347,8 +347,15 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision)
ipaTuningFile = std::string(configFromEnv);
}
- int ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision,
- &controlInfo_);
+ IPACameraSensorInfo sensorInfo{};
+ int ret = sensor_->sensorInfo(&sensorInfo);
+ if (ret) {
+ LOG(RkISP1, Error) << "Camera sensor information not available";
+ return ret;
+ }
+
+ ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision,
+ sensorInfo, sensor_->controls(), &controlInfo_);
if (ret < 0) {
LOG(RkISP1, Error) << "IPA initialization failure";
return ret;
@@ -718,14 +725,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
ipa::rkisp1::IPAConfigInfo ipaConfig{};
ret = data->sensor_->sensorInfo(&ipaConfig.sensorInfo);
- if (ret) {
- LOG(RkISP1, Error) << "Camera sensor information not available";
+ if (ret)
return ret;
- }
ipaConfig.sensorControls = data->sensor_->controls();
- ret = data->ipa_->configure(ipaConfig, streamConfig);
+ ret = data->ipa_->configure(ipaConfig, streamConfig, &data->controlInfo_);
if (ret) {
LOG(RkISP1, Error) << "failed configuring IPA (" << ret << ")";
return ret;