[v5,11/11] pipeline: simple: Include the software ISP crop in request metadata
diff mbox series

Message ID 20261029152058.896209-12-halfline@gmail.com
State Rejected
Headers show
Series
  • software-isp: Align metering and report the configured crop
Related show

Commit Message

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

This commit includes the software ISP's configured image region in
completed requests as ScalerCrop metadata.

The simple pipeline exposes the fixed region through ScalerCropMaximum,
but completed requests still omit the sensor rectangle visible in their
processed output.

The crop is cached when the software ISP is configured and reported when
each request completes. Successful reconfiguration replaces or clears the
cached region so raw-only requests do not inherit an earlier
processed-image crop.

Based on Kieran Bingham's ScalerCrop metadata reporting patch, extended to
use the software ISP's selected image region.

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

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 3e6a3a50..4196ad4b 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -1045,60 +1045,63 @@  void SimpleCameraData::updateScalerCrop(std::optional<Rectangle> crop)
 		properties_.set(properties::ScalerCropMaximum, *crop);
 		return;
 	}
 
 	if (!properties_.contains(properties::ScalerCropMaximum.id()))
 		return;
 
 	ControlList updatedProperties = properties_;
 	updatedProperties.clear();
 	for (const auto &[id, value] : properties_) {
 		if (id != properties::ScalerCropMaximum.id())
 			updatedProperties.set(id, value);
 	}
 	properties_ = std::move(updatedProperties);
 }
 
 void SimpleCameraData::tryCompleteRequest(Request *request)
 {
 	if (request->hasPendingBuffers())
 		return;
 
 	SimpleFrameInfo *info = frameInfo_.find(request->sequence());
 	if (!info) {
 		/* Something is really wrong, let's return. */
 		return;
 	}
 
 	if (info->metadataRequired && !info->metadataProcessed)
 		return;
 
+	if (scalerCrop_)
+		request->_d()->metadata().set(controls::ScalerCrop, *scalerCrop_);
+
 	frameInfo_.destroy(info->frame);
 	pipe()->completeRequest(request);
 }
 
 void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)
 {
 	if (rawStream_) {
 		/* Complete the input buffer as with raw-only processing. */
 		Request *request = buffer->request();
 		if (pipe()->completeBuffer(request, buffer))
 			tryCompleteRequest(request);
 	} else {
 		/* Queue the input buffer back for capture. */
 		video_->queueBuffer(buffer);
 	}
 }
 
 void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
 {
 	SimplePipelineHandler *pipe = SimpleCameraData::pipe();
 
 	/* Complete the buffer and the request. */
 	Request *request = buffer->request();
 	if (pipe->completeBuffer(request, buffer))
 		tryCompleteRequest(request);
 }
 
 void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)
 {
 	swIsp_->processStats(frame, bufferId,