summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/ipa/core.mojom21
-rw-r--r--src/ipa/ipu3/ipu3.cpp6
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp2
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp2
-rw-r--r--src/libcamera/camera_sensor.cpp32
5 files changed, 51 insertions, 12 deletions
diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom
index 74f3339e..2bc3028c 100644
--- a/include/libcamera/ipa/core.mojom
+++ b/include/libcamera/ipa/core.mojom
@@ -172,10 +172,17 @@ module libcamera;
*/
/**
- * \var IPACameraSensorInfo::lineLength
- * \brief Total line length in pixels
+ * \var IPACameraSensorInfo::minLineLength
+ * \brief The minimum line length in pixels
*
- * The total line length in pixel clock periods, including blanking.
+ * The minimum allowable line length in pixel clock periods, including blanking.
+ */
+
+/**
+ * \var IPACameraSensorInfo::maxLineLength
+ * \brief The maximum line length in pixels
+ *
+ * The maximum allowable line length in pixel clock periods, including blanking.
*/
/**
@@ -189,7 +196,7 @@ module libcamera;
* To obtain the minimum frame duration:
*
* \verbatim
- frameDuration(s) = minFrameLength(lines) * lineLength(pixels) / pixelRate(pixels per second)
+ frameDuration(s) = minFrameLength(lines) * minLineLength(pixels) / pixelRate(pixels per second)
\endverbatim
*/
@@ -204,7 +211,7 @@ module libcamera;
* To obtain the maximum frame duration:
*
* \verbatim
- frameDuration(s) = maxFrameLength(lines) * lineLength(pixels) / pixelRate(pixels per second)
+ frameDuration(s) = maxFrameLength(lines) * maxLineLength(pixels) / pixelRate(pixels per second)
\endverbatim
*/
struct IPACameraSensorInfo {
@@ -217,7 +224,9 @@ struct IPACameraSensorInfo {
Size outputSize;
uint64 pixelRate;
- uint32 lineLength;
+
+ uint32 minLineLength;
+ uint32 maxLineLength;
uint32 minFrameLength;
uint32 maxFrameLength;
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 852deb71..891643e0 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -336,7 +336,8 @@ int IPAIPU3::init(const IPASettings &settings,
/* Clean context */
context_.configuration = {};
- context_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate;
+ context_.configuration.sensor.lineDuration = sensorInfo.minLineLength
+ * 1.0s / sensorInfo.pixelRate;
/* Load the tuning data file. */
File file(settings.configurationFile);
@@ -499,7 +500,8 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo,
context_.frameContexts.clear();
/* Initialise the sensor configuration. */
- context_.configuration.sensor.lineDuration = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate;
+ context_.configuration.sensor.lineDuration = sensorInfo_.minLineLength
+ * 1.0s / sensorInfo_.pixelRate;
/*
* Compute the sensor V4L2 controls to be used by the algorithms and
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 14b06a4f..ec495a37 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -356,7 +356,7 @@ void IPARPi::setMode(const IPACameraSensorInfo &sensorInfo)
* Calculate the line length as the ratio between the line length in
* pixels and the pixel rate.
*/
- mode_.lineLength = sensorInfo.lineLength * (1.0s / sensorInfo.pixelRate);
+ mode_.lineLength = sensorInfo.minLineLength * (1.0s / sensorInfo.pixelRate);
/*
* Set the frame length limits for the mode to ensure exposure and
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 022595f3..3f5c1a58 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -246,7 +246,7 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info,
context_.configuration.hw.revision = hwRevision_;
context_.configuration.sensor.size = info.outputSize;
- context_.configuration.sensor.lineDuration = info.lineLength * 1.0s / info.pixelRate;
+ context_.configuration.sensor.lineDuration = info.minLineLength * 1.0s / info.pixelRate;
/*
* When the AGC computes the new exposure values for a frame, it needs
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 911fd0be..572a313a 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -176,6 +176,32 @@ int CameraSensor::init()
if (ret)
return ret;
+ /*
+ * Set HBLANK to the minimum to start with a well-defined line length,
+ * allowing IPA modules that do not modify HBLANK to use the sensor
+ * minimum line length in their calculations.
+ *
+ * At present, there is no way of knowing if a control is read-only.
+ * As a workaround, assume that if the minimum and maximum values of
+ * the V4L2_CID_HBLANK control are the same, it implies the control
+ * is read-only.
+ *
+ * \todo The control API ought to have a flag to specify if a control
+ * is read-only which could be used below.
+ */
+ const ControlInfo hblank = ctrls.infoMap()->at(V4L2_CID_HBLANK);
+ const int32_t hblankMin = hblank.min().get<int32_t>();
+ const int32_t hblankMax = hblank.max().get<int32_t>();
+
+ if (hblankMin != hblankMax) {
+ ControlList ctrl(subdev_->controls());
+
+ ctrl.set(V4L2_CID_HBLANK, hblankMin);
+ ret = subdev_->setControls(&ctrl);
+ if (ret)
+ return ret;
+ }
+
return applyTestPatternMode(controls::draft::TestPatternModeEnum::TestPatternModeOff);
}
@@ -883,10 +909,12 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const
return -EINVAL;
}
- int32_t hblank = ctrls.get(V4L2_CID_HBLANK).get<int32_t>();
- info->lineLength = info->outputSize.width + hblank;
info->pixelRate = ctrls.get(V4L2_CID_PIXEL_RATE).get<int64_t>();
+ const ControlInfo hblank = ctrls.infoMap()->at(V4L2_CID_HBLANK);
+ info->minLineLength = info->outputSize.width + hblank.min().get<int32_t>();
+ info->maxLineLength = info->outputSize.width + hblank.max().get<int32_t>();
+
const ControlInfo vblank = ctrls.infoMap()->at(V4L2_CID_VBLANK);
info->minFrameLength = info->outputSize.height + vblank.min().get<int32_t>();
info->maxFrameLength = info->outputSize.height + vblank.max().get<int32_t>();