[v3,05/11] software-isp: Expose the configured image crop
diff mbox series

Message ID 20261016202818.1405645-6-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 makes the image region selected by the debayer available to the
pipeline handler, so ScalerCrop metadata can describe the processed output.

The CPU and EGL backends crop input differently. CPU debayering keeps an
output-sized window whose origin depends on the Bayer pattern and output
channel order, while EGL scales a centered crop to fill the output. The
pipeline currently cannot retrieve the region chosen by either backend.

Each backend returns its actual configured image crop in input-buffer
coordinates. The EGL crop is retained before statistics alignment, so the
returned rectangle describes the image rather than its metering samples.

Signed-off-by: Ray Strode <rstrode@redhat.com>
---
 .../libcamera/internal/software_isp/software_isp.h |  1 +
 src/libcamera/software_isp/debayer.cpp             | 11 +++++++++++
 src/libcamera/software_isp/debayer.h               |  1 +
 src/libcamera/software_isp/debayer_cpu.h           |  4 ++++
 src/libcamera/software_isp/debayer_egl.cpp         |  3 ++-
 src/libcamera/software_isp/debayer_egl.h           |  2 ++
 src/libcamera/software_isp/software_isp.cpp        | 14 ++++++++++++++
 7 files changed, 35 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
index b8b24bb1..1e54a4fe 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -67,6 +67,7 @@  public:
 		      const std::vector<std::reference_wrapper<const StreamConfiguration>> &outputCfgs,
 		      const ipa::softisp::IPAConfigInfo &configInfo,
 		      ControlInfoMap *ipaControls);
+	Rectangle inputCrop() const;
 
 	int exportBuffers(const Stream *stream, unsigned int count,
 			  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp
index a4854e51..14b09937 100644
--- a/src/libcamera/software_isp/debayer.cpp
+++ b/src/libcamera/software_isp/debayer.cpp
@@ -66,6 +66,17 @@  Debayer::~Debayer()
 }
 
 /**
+ * \fn Rectangle Debayer::inputCrop() const
+ * \brief Retrieve the input region visible in the configured output
+ *
+ * The rectangle is in input-buffer coordinates and excludes any additional
+ * alignment performed for statistics sampling. It is valid after a successful
+ * configure() call.
+ *
+ * \return The configured image crop
+ */
+
+/**
  * \fn int Debayer::configure()
  * \brief Configure the debayer object according to the passed in parameters
  * \param[in] inputCfg The input configuration
diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h
index 55685226..7ffdaea1 100644
--- a/src/libcamera/software_isp/debayer.h
+++ b/src/libcamera/software_isp/debayer.h
@@ -53,6 +53,7 @@  public:
 	virtual void stop() {}
 
 	virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0;
+	virtual Rectangle inputCrop() const = 0;
 
 	virtual const SharedFD &getStatsFD() = 0;
 
diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h
index 2c88c9e1..1e037a79 100644
--- a/src/libcamera/software_isp/debayer_cpu.h
+++ b/src/libcamera/software_isp/debayer_cpu.h
@@ -46,6 +46,10 @@  public:
 	int start() override;
 	void stop() override;
 	SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override;
+	Rectangle inputCrop() const override
+	{
+		return window_.translatedBy({ static_cast<int>(xShift_), 0 });
+	}
 	const SharedFD &getStatsFD() override { return stats_->getStatsFD(); }
 
 private:
diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
index 9f3dc752..cd9ad888 100644
--- a/src/libcamera/software_isp/debayer_egl.cpp
+++ b/src/libcamera/software_isp/debayer_egl.cpp
@@ -327,7 +327,8 @@  int DebayerEGL::configure(const StreamConfiguration &inputCfg,
 	 * The GPU scales the visible sensor crop to outputSize_. Statistics
 	 * consume the original input buffer, so use sensor coordinates here.
 	 */
-	stats_->setWindow(debayerCrop(inputCfg.size, nativeOutputSize_, outputSize_));
+	inputCrop_ = debayerCrop(inputCfg.size, nativeOutputSize_, outputSize_);
+	stats_->setWindow(inputCrop_);
 
 	inputBufferCount_ = inputCfg.bufferCount;
 	outputBufferCount_ = outputCfg.bufferCount;
diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h
index 52b8aa07..5a4cd2d8 100644
--- a/src/libcamera/software_isp/debayer_egl.h
+++ b/src/libcamera/software_isp/debayer_egl.h
@@ -60,6 +60,7 @@  public:
 	const SharedFD &getStatsFD() override { return stats_->getStatsFD(); }
 
 	SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override;
+	Rectangle inputCrop() const override { return inputCrop_; }
 
 private:
 	static int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config);
@@ -111,6 +112,7 @@  private:
 	GLint contrastExpUniformDataIn_;
 
 	Size nativeOutputSize_;
+	Rectangle inputCrop_;
 	std::unique_ptr<SwStatsCpu> stats_;
 	eGL egl_;
 	uint32_t width_;
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index a4097605..c0c55fbf 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -306,6 +306,20 @@  int SoftwareIsp::configure(const StreamConfiguration &inputCfg,
 }
 
 /**
+ * \brief Retrieve the input region used to produce the configured output
+ *
+ * The rectangle is expressed in input-buffer pixels, before any Bayer
+ * alignment applied by the statistics engine. It is valid after configure()
+ * succeeds and describes the selected CPU or EGL debayer backend.
+ *
+ * \return The configured input crop
+ */
+Rectangle SoftwareIsp::inputCrop() const
+{
+	return debayer_->inputCrop();
+}
+
+/**
  * \brief Export the buffers from the Software ISP
  * \param[in] stream Output stream exporting the buffers
  * \param[in] count Number of buffers to allocate