[v3,10/11] pipeline: simple: Report the software ISP's maximum crop
diff mbox series

Message ID 20261016202818.1405645-11-halfline@gmail.com
State New
Headers show
Series
  • software-isp: Align crops, statistics and metadata
Related show

Commit Message

Ray Strode Oct. 16, 2026, 8:28 p.m. UTC
From: Ray Strode <rstrode@redhat.com>

This commit reports the software ISP's configured image region through the
ScalerCropMaximum camera property.

The simple pipeline currently exposes sensor properties without identifying
the region retained by software processing. CPU debayering crops to the
output dimensions, while EGL also scales the image, so the visible region
can be smaller than the analogue sensor crop.

The reported rectangle uses native sensor coordinates relative to the
active array. Reporting is limited to capture paths that preserve the
sensor output, since intermediate cropping or scaling requires an
additional mapping. Reconfiguration restores the sensor properties so
raw-only configurations do not retain an earlier processed-image crop.

Based on Kieran Bingham's ScalerCropMaximum reporting patch, extended to
account for the software ISP's selected image region.

Link: https://patchwork.libcamera.org/patch/26678/
Signed-off-by: Ray Strode <rstrode@redhat.com>
---
 src/libcamera/pipeline/simple/simple.cpp | 54 +++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 35c29cec..91b149d1 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -30,6 +30,7 @@ 
 #include <libcamera/control_ids.h>
 #include <libcamera/geometry.h>
 #include <libcamera/pixel_format.h>
+#include <libcamera/property_ids.h>
 #include <libcamera/stream.h>
 
 #include "libcamera/internal/camera.h"
@@ -44,6 +45,7 @@ 
 #include "libcamera/internal/media_device.h"
 #include "libcamera/internal/pipeline_handler.h"
 #include "libcamera/internal/request.h"
+#include "libcamera/internal/software_isp/debayer_geometry.h"
 #include "libcamera/internal/software_isp/software_isp.h"
 #include "libcamera/internal/v4l2_subdevice.h"
 #include "libcamera/internal/v4l2_videodevice.h"
@@ -292,6 +294,7 @@  public:
 			 Transform transform = Transform::Identity);
 	void imageBufferReady(FrameBuffer *buffer);
 	void clearIncompleteRequests();
+	void updateScalerCrop(const Size &inputSize, Transform transform);
 
 	unsigned int streamIndex(const Stream *stream) const
 	{
@@ -983,6 +986,48 @@  void SimpleCameraData::clearIncompleteRequests()
 	}
 }
 
+void SimpleCameraData::updateScalerCrop(const Size &inputSize, Transform transform)
+{
+	IPACameraSensorInfo sensorInfo;
+	if (sensor_->sensorInfo(&sensorInfo))
+		return;
+
+	/*
+	 * The buffer-to-sensor mapping requires a capture path that preserves
+	 * the sensor output. Intermediate cropping or scaling needs a separate
+	 * mapping; do not report the analogue crop as if it included that work.
+	 */
+	if (sensorInfo.outputSize != inputSize)
+		return;
+
+	for (const Entity &entity : entities_) {
+		if (!entity.sink || !entity.source)
+			continue;
+
+		V4L2Subdevice *subdev = pipe()->subdev(entity.entity);
+		for (const MediaPad *pad : { entity.sink, entity.source }) {
+			V4L2SubdeviceFormat format{};
+			if (subdev->getFormat(pad->index(), &format) ||
+			    format.size != inputSize)
+				return;
+
+			for (unsigned int target : { V4L2_SEL_TGT_CROP, V4L2_SEL_TGT_COMPOSE }) {
+				Rectangle selection;
+				int ret = subdev->getSelection(pad->index(), target, &selection, true);
+				if (!ret && selection != Rectangle(inputSize))
+					return;
+				if (ret && ret != -ENOTTY && ret != -EINVAL)
+					return;
+			}
+		}
+	}
+
+	Rectangle crop = debayerCropToSensor(swIsp_->inputCrop(), inputSize,
+					     sensorInfo.analogCrop, sensorInfo.activeArea,
+					     transform);
+	properties_.set(properties::ScalerCropMaximum, crop);
+}
+
 void SimpleCameraData::tryCompleteRequest(Request *request)
 {
 	if (request->hasPendingBuffers())
@@ -1505,6 +1550,8 @@  int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
 	V4L2VideoDevice *video = data->video_;
 	int ret;
 
+	data->properties_ = data->sensor_->properties();
+
 	/*
 	 * Configure links on the pipeline and propagate formats from the
 	 * sensor to the video node.
@@ -1605,7 +1652,12 @@  int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
 	} else {
 		ipa::softisp::IPAConfigInfo configInfo;
 		configInfo.sensorControls = data->sensor_->controls();
-		return data->swIsp_->configure(inputCfg, outputCfgs, configInfo, &data->controlInfo_);
+		ret = data->swIsp_->configure(inputCfg, outputCfgs, configInfo, &data->controlInfo_);
+		if (ret)
+			return ret;
+
+		data->updateScalerCrop(inputCfg.size, config->combinedTransform());
+		return 0;
 	}
 }