libcamera: pipeline: rkisp1: Fix buffer queue memleaks

`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: c8f63760e5 ("pipeline: rkisp1: Support raw Bayer capture at runtime")
Fixes: 12b553d691 ("libcamera: rkisp1: Plumb the dw100 dewarper as V4L2M2M converter")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
This commit is contained in:
Barnabás Pőcze
2026-04-03 19:18:39 +02:00
parent ee6e0bf926
commit 63fd8476d8

View File

@@ -86,6 +86,8 @@ public:
RkISP1FrameInfo *find(Request *request);
private:
void recycleBuffers(const 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,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);