[v2,30/32] pipeline: rkisp1: rkisp1_path: Modify interface to be compatible with BufferQueue
diff mbox series

Message ID 20260325151416.2114564-31-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • rkisp1: pipeline rework for PFC
Related show

Commit Message

Stefan Klug March 25, 2026, 3:14 p.m. UTC
The BufferQueue delegate expects an interface equal to the one provided
by the V4L2VideoDevice. Modify the RkISP1Path class to support that
interface to prepare for the migration to BufferQueue.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>

---

Changes in v2:
- Added this patch
---
 src/libcamera/pipeline/rkisp1/rkisp1.cpp      | 44 ++++++++++++++-----
 src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 42 ++----------------
 src/libcamera/pipeline/rkisp1/rkisp1_path.h   | 23 ++++++++--
 3 files changed, 56 insertions(+), 53 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index c46515110ffc..998ee3c813bc 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -1099,14 +1099,15 @@  int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S
 int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
 {
 	RkISP1CameraData *data = cameraData(camera);
+	utils::ScopeExitActions actions;
 	unsigned int ipaBufferId = 1;
 	int ret;
 
-	auto errorCleanup = utils::scope_exit{ [&]() {
+	actions += [&]() {
 		paramBuffers_.clear();
 		statBuffers_.clear();
 		mainPathBuffers_.clear();
-	} };
+	};
 
 	if (!isRaw_) {
 		ret = param_->allocateBuffers(kRkISP1InternalBufferCount, &paramBuffers_);
@@ -1127,6 +1128,22 @@  int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
 
 		for (std::unique_ptr<FrameBuffer> &buffer : mainPathBuffers_)
 			availableMainPathBuffers_.push(buffer.get());
+	} else if (data->mainPath_->isEnabled()) {
+		ret = mainPath_.importBuffers(data->mainPathStream_.configuration().bufferCount);
+
+		if (ret < 0)
+			return ret;
+
+		actions += [&]() { mainPath_.releaseBuffers(); };
+	}
+
+	if (hasSelfPath_ && data->selfPath_->isEnabled()) {
+		ret = selfPath_.importBuffers(data->selfPathStream_.configuration().bufferCount);
+
+		if (ret < 0)
+			return ret;
+
+		actions += [&]() { selfPath_.releaseBuffers(); };
 	}
 
 	auto pushBuffers = [&](const std::vector<std::unique_ptr<FrameBuffer>> &buffers,
@@ -1147,7 +1164,7 @@  int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
 
 	data->ipa_->mapBuffers(data->ipaBuffers_);
 
-	errorCleanup.release();
+	actions.release();
 	return 0;
 }
 
@@ -1181,6 +1198,12 @@  int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
 	if (stat_->releaseBuffers())
 		LOG(RkISP1, Error) << "Failed to release stat buffers";
 
+	if (mainPath_.releaseBuffers())
+		LOG(RkISP1, Error) << "Failed to release main path buffers";
+
+	if (hasSelfPath_ && selfPath_.releaseBuffers())
+		LOG(RkISP1, Error) << "Failed to release self path buffers";
+
 	return 0;
 }
 
@@ -1263,16 +1286,17 @@  int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
 	}
 
 	if (data->mainPath_->isEnabled()) {
-		ret = mainPath_.start(data->mainPathStream_.configuration().bufferCount);
+		ret = mainPath_.streamOn();
 		if (ret)
 			return ret;
-		actions += [&]() { mainPath_.stop(); };
+		actions += [&]() { mainPath_.streamOff(); };
 	}
 
 	if (hasSelfPath_ && data->selfPath_->isEnabled()) {
-		ret = selfPath_.start(data->selfPathStream_.configuration().bufferCount);
+		ret = selfPath_.streamOn();
 		if (ret)
 			return ret;
+		actions += [&]() { selfPath_.streamOff(); };
 	}
 
 	isp_->setFrameStartEnabled(true);
@@ -1299,8 +1323,8 @@  void PipelineHandlerRkISP1::stopDevice(Camera *camera)
 	data->ipa_->stop();
 
 	if (hasSelfPath_)
-		selfPath_.stop();
-	mainPath_.stop();
+		selfPath_.streamOff();
+	mainPath_.streamOff();
 
 	if (!isRaw_) {
 		ret = stat_->streamOff();
@@ -1664,9 +1688,9 @@  bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
 		return false;
 
 	isp_->frameStart.connect(this, &PipelineHandlerRkISP1::frameStart);
-	mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::imageBufferReady);
+	mainPath_.bufferReady.connect(this, &PipelineHandlerRkISP1::imageBufferReady);
 	if (hasSelfPath_)
-		selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::imageBufferReady);
+		selfPath_.bufferReady.connect(this, &PipelineHandlerRkISP1::imageBufferReady);
 	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statBufferReady);
 	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramBufferReady);
 
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
index ef9cfbdc327a..80a01280e6f7 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
@@ -8,6 +8,7 @@ 
 #include "rkisp1_path.h"
 
 #include <array>
+#include <memory>
 
 #include <linux/media-bus-format.h>
 
@@ -58,7 +59,7 @@  const std::map<PixelFormat, uint32_t> formatToMediaBus = {
 
 RkISP1Path::RkISP1Path(const char *name, const Span<const PixelFormat> &formats,
 		       const Size &minResolution, const Size &maxResolution)
-	: name_(name), running_(false), formats_(formats),
+	: name_(name), formats_(formats),
 	  minResolution_(minResolution), maxResolution_(maxResolution),
 	  link_(nullptr)
 {
@@ -77,6 +78,7 @@  bool RkISP1Path::init(std::shared_ptr<MediaDevice> media)
 	if (video_->open() < 0)
 		return false;
 
+	video_->bufferReady.connect(this, [this](FrameBuffer *buffer) { this->bufferReady.emit(buffer); });
 	populateFormats();
 
 	link_ = media->link("rkisp1_isp", 2, resizer, 0);
@@ -480,44 +482,6 @@  int RkISP1Path::configure(const StreamConfiguration &config,
 	return 0;
 }
 
-int RkISP1Path::start(unsigned int bufferCount)
-{
-	int ret;
-
-	if (running_)
-		return -EBUSY;
-
-	ret = video_->importBuffers(bufferCount);
-	if (ret)
-		return ret;
-
-	ret = video_->streamOn();
-	if (ret) {
-		LOG(RkISP1, Error)
-			<< "Failed to start " << name_ << " path";
-
-		video_->releaseBuffers();
-		return ret;
-	}
-
-	running_ = true;
-
-	return 0;
-}
-
-void RkISP1Path::stop()
-{
-	if (!running_)
-		return;
-
-	if (video_->streamOff())
-		LOG(RkISP1, Warning) << "Failed to stop " << name_ << " path";
-
-	video_->releaseBuffers();
-
-	running_ = false;
-}
-
 /*
  * \todo Remove the hardcoded resolutions and formats once kernels older than
  * v6.4 will stop receiving LTS support (scheduled for December 2027 for v6.1).
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
index 0c68e9eb99af..d2bce01c9336 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h
+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
@@ -58,19 +58,34 @@  public:
 		return video_->exportBuffers(bufferCount, buffers);
 	}
 
-	int start(unsigned int bufferCount);
-	void stop();
+	int allocateBuffers(unsigned int bufferCount,
+			    std::vector<std::unique_ptr<FrameBuffer>> *buffers)
+	{
+		return video_->allocateBuffers(bufferCount, buffers);
+	}
+
+	int importBuffers(unsigned int count)
+	{
+		return video_->importBuffers(count);
+	}
+
+	int releaseBuffers()
+	{
+		return video_->releaseBuffers();
+	}
+
+	int streamOn() { return video_->streamOn(); };
+	int streamOff() { return video_->streamOff(); };
 
 	int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); }
-	Signal<FrameBuffer *> &bufferReady() { return video_->bufferReady; }
 	const Size &maxResolution() const { return maxResolution_; }
 
+	Signal<FrameBuffer *> bufferReady;
 private:
 	void populateFormats();
 	Size filterSensorResolution(const CameraSensor *sensor);
 
 	const char *name_;
-	bool running_;
 
 	const Span<const PixelFormat> formats_;
 	std::set<PixelFormat> streamFormats_;