[v1] libcamera: pipeline: rkisp1: Fix buffer queue memleaks
diff mbox series

Message ID 20260403173106.473431-1-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • [v1] libcamera: pipeline: rkisp1: Fix buffer queue memleaks
Related show

Commit Message

Barnabás Pőcze April 3, 2026, 5:31 p.m. UTC
`RkISP1Frames::{clear,destroy}()` always push all buffers from the
`RkISP1FrameInfo` object to the corresponding `available*Buffers_`
queues. This is not entirely correct.

If no dewarper is used, then `availableMainPathBuffers_` is never
consumed, so it will grow with each request. Fix it by only queueing
the buffer if `RkISP1CameraData::usesDewarper_`.

Additionally, in raw capture mode, no parameter or statistics buffers are
used, so those queues will be filled up with `nullptr`s without limit.
Fix that by only queueing them if they are not null.

Fixes: c8f63760e55a ("pipeline: rkisp1: Support raw Bayer capture at runtime")
Fixes: 12b553d691d4 ("libcamera: rkisp1: Plumb the dw100 dewarper as V4L2M2M converter")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 26 +++++++++++++++---------
 1 file changed, 16 insertions(+), 10 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index faeeecd96..a8756cefa 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -86,6 +86,8 @@  public:
 	RkISP1FrameInfo *find(Request *request);
 
 private:
+	void recycleBuffers(RkISP1FrameInfo &info);
+
 	PipelineHandlerRkISP1 *pipe_;
 	std::map<unsigned int, RkISP1FrameInfo> frameInfo_;
 };
@@ -316,12 +318,7 @@  int RkISP1Frames::destroy(unsigned int frame)
 	if (it == frameInfo_.end())
 		return -ENOENT;
 
-	auto &info = it->second;
-
-	pipe_->availableParamBuffers_.push(info.paramBuffer);
-	pipe_->availableStatBuffers_.push(info.statBuffer);
-	pipe_->availableMainPathBuffers_.push(info.mainPathBuffer);
-
+	recycleBuffers(it->second);
 	frameInfo_.erase(it);
 
 	return 0;
@@ -329,13 +326,22 @@  int RkISP1Frames::destroy(unsigned int frame)
 
 void RkISP1Frames::clear()
 {
-	for (const auto &[frame, info] : frameInfo_) {
+	for (auto &[frame, info] : frameInfo_)
+		recycleBuffers(info);
+
+	frameInfo_.clear();
+}
+
+void RkISP1Frames::recycleBuffers(RkISP1FrameInfo &info)
+{
+	if (info.paramBuffer)
 		pipe_->availableParamBuffers_.push(info.paramBuffer);
+
+	if (info.statBuffer)
 		pipe_->availableStatBuffers_.push(info.statBuffer);
-		pipe_->availableMainPathBuffers_.push(info.mainPathBuffer);
-	}
 
-	frameInfo_.clear();
+	if (pipe_->cameraData(pipe_->activeCamera_)->usesDewarper_)
+		pipe_->availableMainPathBuffers_.push(info.mainPathBuffer);
 }
 
 RkISP1FrameInfo *RkISP1Frames::find(unsigned int frame)