[1/1] pipeline: rpi: Handle buffers with offsets
diff mbox series

Message ID 20260629110240.3656-2-david.plowman@raspberrypi.com
State New
Headers show
Series
  • Make Raspberry Pi 5 handle buffer offsets
Related show

Commit Message

David Plowman June 29, 2026, 10:31 a.m. UTC
This allows camera images to be written to offset locations within
buffers (which must have be allocated with sufficient space
available).

Firstly, the RPi::Stream class tracks the associated "ispOutputIndex"
for output streams, that is, whether it corresponds to ISP output
branch 0 or branch 1.

Secondly, we pass buffer offsets on to libpisp for each request.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
---
 .../pipeline/rpi/common/rpi_stream.h          | 10 ++++++++--
 src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 19 +++++++++++++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rpi/common/rpi_stream.h b/src/libcamera/pipeline/rpi/common/rpi_stream.h
index 300a352a..51931867 100644
--- a/src/libcamera/pipeline/rpi/common/rpi_stream.h
+++ b/src/libcamera/pipeline/rpi/common/rpi_stream.h
@@ -97,14 +97,14 @@  public:
 	using StreamFlags = Flags<StreamFlag>;
 
 	Stream()
-		: flags_(StreamFlag::None), id_(0), swDownscale_(0)
+		: flags_(StreamFlag::None), id_(0), swDownscale_(0), ispOutputIndex_(-1)
 	{
 	}
 
 	Stream(const char *name, MediaEntity *dev, StreamFlags flags = StreamFlag::None)
 		: flags_(flags), name_(name),
 		  dev_(std::make_unique<V4L2VideoDevice>(dev)), id_(0),
-		  swDownscale_(0)
+		  swDownscale_(0), ispOutputIndex_(-1)
 	{
 	}
 
@@ -125,6 +125,9 @@  public:
 
 	void setExportedBuffer(FrameBuffer *buffer);
 
+	void setIspIndex(int ispIndex) { ispOutputIndex_ = ispIndex; }
+	int getIspIndex() const { return ispOutputIndex_; }
+
 	int allocateBuffers(unsigned int count);
 	int queueBuffer(FrameBuffer *buffer);
 	void returnBuffer(FrameBuffer *buffer);
@@ -181,6 +184,9 @@  private:
 	 * as the stream needs to maintain ownership of these buffers.
 	 */
 	std::vector<std::unique_ptr<FrameBuffer>> internalBuffers_;
+
+	/* For output streams, the ISP branch for this stream (otherwise -1). */
+	int ispOutputIndex_;
 };
 
 /*
diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp
index b744c901..1238d0e9 100644
--- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp
+++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp
@@ -1524,6 +1524,7 @@  int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConf
 			beEnables |= PISP_BE_RGB_ENABLE_OUTPUT0;
 			ispIndex = 0;
 		}
+		stream->setIspIndex(ispIndex);
 
 		format = outStreams[i].format;
 		bool needs32BitConversion = adjustDeviceFormat(format);
@@ -2317,6 +2318,24 @@  void PiSPCameraData::tryRunPipeline()
 	Request *request = requestQueue_.front();
 	ASSERT(request->metadata().empty());
 
+	/* Pass the plane offsets of any output buffers to the Back End ISP. */
+	for (auto const &[stream, buffer] : request->buffers()) {
+		int ispIndex = static_cast<const RPi::Stream *>(stream)->getIspIndex();
+		if (ispIndex >= 0) {
+			/*
+			 * PiSP takes only 2 offsets; offset 3 (where required) is assumed
+			 * to be the same as offset 2.
+			 */
+			unsigned int offset = buffer->planes()[0].offset;
+			unsigned int offset2 = 0;
+			if (buffer->planes().size() > 1)
+				offset2 = buffer->planes()[1].offset;
+
+			pisp_be_output_format_extra extra{ 0, 0, { offset, offset2 } };
+			be_->SetOutputFormatExtra(ispIndex, extra);
+		}
+	}
+
 	/* See if a new ScalerCrop value needs to be applied. */
 	applyScalerCrop(request->controls());