From 63fd8476d82ed66ab28451f09c72aba1c6e51744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= Date: Fri, 3 Apr 2026 19:18:39 +0200 Subject: [PATCH] libcamera: pipeline: rkisp1: Fix buffer queue memleaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `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 Reviewed-by: Jacopo Mondi Reviewed-by: Stefan Klug --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index faeeecd9..71516621 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(const RkISP1FrameInfo &info); + PipelineHandlerRkISP1 *pipe_; std::map 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,15 +326,24 @@ int RkISP1Frames::destroy(unsigned int frame) void RkISP1Frames::clear() { - for (const auto &[frame, info] : frameInfo_) { - pipe_->availableParamBuffers_.push(info.paramBuffer); - pipe_->availableStatBuffers_.push(info.statBuffer); - pipe_->availableMainPathBuffers_.push(info.mainPathBuffer); - } + for (const auto &[frame, info] : frameInfo_) + recycleBuffers(info); frameInfo_.clear(); } +void RkISP1Frames::recycleBuffers(const RkISP1FrameInfo &info) +{ + if (info.paramBuffer) + pipe_->availableParamBuffers_.push(info.paramBuffer); + + if (info.statBuffer) + pipe_->availableStatBuffers_.push(info.statBuffer); + + if (info.mainPathBuffer && pipe_->cameraData(pipe_->activeCamera_)->usesDewarper_) + pipe_->availableMainPathBuffers_.push(info.mainPathBuffer); +} + RkISP1FrameInfo *RkISP1Frames::find(unsigned int frame) { auto itInfo = frameInfo_.find(frame);