[libcamera-devel] [PATCH 07/12] libcamera: ipu3: Register ScalerCrop control
Jacopo Mondi
jacopo at jmondi.org
Tue Jan 5 20:05:17 CET 2021
Register the ScalerCrop control in the ImgU pipeline handler computed
by using the Viewfinder [1280x720] pipeline output configuration and
the sensor resolution as parameters.
The ScalerCrop control limits should be updated everytime a new
configuration is applied to the sensor.
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
src/libcamera/pipeline/ipu3/ipu3.cpp | 53 ++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 2 deletions(-)
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 418301b33a5e..f1329ffb0463 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -41,6 +41,7 @@ static constexpr unsigned int IMGU_OUTPUT_WIDTH_ALIGN = 64;
static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4;
static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64;
static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32;
+static constexpr Size IPU3ViewfinderSize(1280, 720);
static const ControlInfoMap::Map IPU3Controls = {
{ &controls::draft::PipelineDepth, ControlInfo(2, 3) },
@@ -378,7 +379,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
* capped to the maximum sensor resolution and aligned
* to the ImgU output constraints.
*/
- size = sensorResolution.boundedTo({ 1280, 720 })
+ size = sensorResolution.boundedTo(IPU3ViewfinderSize)
.alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN,
IMGU_OUTPUT_HEIGHT_ALIGN);
pixelFormat = formats::NV12;
@@ -785,7 +786,7 @@ int PipelineHandlerIPU3::initProperties(IPU3CameraData *data)
*/
int PipelineHandlerIPU3::initControls(IPU3CameraData *data)
{
- const CameraSensor *sensor = data->cio2_.sensor();
+ CameraSensor *sensor = data->cio2_.sensor();
CameraSensorInfo sensorInfo{};
int ret = sensor->sensorInfo(&sensorInfo);
@@ -822,6 +823,54 @@ int PipelineHandlerIPU3::initControls(IPU3CameraData *data)
controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,
defExposure);
+ /*
+ * Compute the scaler crop limits.
+ *
+ * \todo The scaler crop limits depend on the sensor configuration. It
+ * should be updated when a new configuration is applied. To initialize
+ * the control use the 'Viewfinder' configuration (1280x720) as the
+ * pipeline output resolution and the full sensor size as input frame
+ * (see the todo note in the validation function).
+ */
+
+ /*
+ * The maximum scaler crop rectangle is the analogue crop used to
+ * produce the maximum frame size.
+ */
+ V4L2SubdeviceFormat sensorFormat;
+ sensorFormat.size = sensor->resolution();
+ ret = sensor->setFormat(&sensorFormat);
+ if (ret)
+ return ret;
+
+ /* Re-fetch the sensor info updated to use the largest resolution. */
+ ret = sensor->sensorInfo(&sensorInfo);
+ if (ret)
+ return ret;
+
+ const Rectangle &analogueCrop = sensorInfo.analogCrop;
+ Rectangle maxCrop = analogueCrop;
+
+ /*
+ * The minimum crop rectangle is the default viewfinder configuration
+ * (or the sensor resolution, if smaller) re-scaled in the sensor's pixel
+ * array coordinates. As the ImgU cannot up-scale, the minimum selection
+ * rectangle has to be as large as the desired pipeline output size.
+ *
+ * The top-left corner position is not relevant as the minimum crop
+ * rectangle can be placed anywhere inside the analogue crop region.
+ */
+ const Size &sensorOutput = sensorInfo.outputSize;
+ Size minCropSize = sensorOutput.boundedTo(IPU3ViewfinderSize)
+ .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN,
+ IMGU_OUTPUT_HEIGHT_ALIGN);
+ Rectangle minCrop(minCropSize);
+ minCrop.scaledBy(analogueCrop.size(), sensorOutput);
+ minCrop.x = analogueCrop.x;
+ minCrop.y = analogueCrop.y;
+
+ controls[&controls::ScalerCrop] = ControlInfo(minCrop, maxCrop, maxCrop);
+
data->controlInfo_ = std::move(controls);
return 0;
--
2.29.2
More information about the libcamera-devel
mailing list