diff options
-rw-r--r-- | include/libcamera/ipa/core.mojom | 21 | ||||
-rw-r--r-- | src/ipa/ipu3/ipu3.cpp | 6 | ||||
-rw-r--r-- | src/ipa/raspberrypi/raspberrypi.cpp | 2 | ||||
-rw-r--r-- | src/ipa/rkisp1/rkisp1.cpp | 2 | ||||
-rw-r--r-- | src/libcamera/camera_sensor.cpp | 32 |
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>(); |