-
Notifications
You must be signed in to change notification settings - Fork 155
Description
Description:
When using Gstreamer with libcamerasrc → capsfilter → videoconvert → appsink
with drop=true
and max-buffers=1
, memory (RAM) still rises during resolution changes. Even if I change to the same resolution or decrease the framerate.
- I start the pipeline with
Selected sensor format: 3280x2464-SBGGR10_1X10/RAW - Selected unicam format: 3280x2464-pBAA/RAW
Resolution: 3200x2400 (cuWidth
andcuHeight
)
(RAM increases: 160 MB → ~323 MB)
libCamSrc = ElementFactory.make("libcamerasrc", "source");
libCamSrc.set("camera-name", "/base/soc/i2c0mux/i2c@1/imx219@10");
libCamSrc.set("analogue-gain-mode", 1);
libCamSrc.set("analogue-gain", 6);
libCamSrc.set("exposure-time-mode", 1);
//libCamSrc.set("awb-enable", false); // to ignore warnings.
Caps caps = Caps.fromString("video/x-raw,width=" + cuWidth + ",height=" + cuHeight + ", format=BGR, framerate=1/1");
Element capsfilter = ElementFactory.make("capsfilter", FILTER);
capsfilter.set("caps", caps);
//Element rate = ElementFactory.make("videorate", "rate"); // Does not add anything
Element conv = ElementFactory.make("videoconvert", "conv");
AppSink appSink = (AppSink) ElementFactory.make("appsink", "sink");
appSink.set("emit-signals", true); // emit new samples signals.
appSink.set("drop", true); // Drop old buffers if a new one arrives
appSink.set("max-buffers", 1); // 1: only the latest frame stays in buffer
//appSink.set("sync", false); // false: sink ignores timestamps and processes data as it arrives.
appSink.set("wait-on-eos", false);
pipeline = new Pipeline();
pipeline.addMany(libCamSrc, capsfilter, conv, appSink);
Element.linkMany(libCamSrc, capsfilter, conv, appSink);
// sleep("Pipeline config", 1000); // RAM: ~170 MB
appSinkPreRoll(appSink);
pipeline.play();
// sleep("Pipeline-play", 1); // RAM: ~320 MB
setSampleCallback(appSink);
Let it run for a couple of seconds (20s)
- Then I change the resolution with capsfilter (to 3200x2400):
(RAM increases: 323 MB → ~343 MB) ... instead of maintaining. Even if I wait 20sec...
Caps newCaps = Caps.fromString("video/x-raw,width=" + cuWidth + ",height=" + cuHeight + ",format=BGR,framerate="+fps+"/1");
capsfilter.set("caps", newCaps);
-
If I even change the resolution to 1600x1200 and back to 3200x2400 (with capsfilter again)
On 1600x1200, RAM: 300 MB.
On 3200x2400, RAM: 380 MB
(It reaches its maximum here... I changed sizes back and forth 100 times and got these values. -
If I let it run normally without changing resolution:
With size 1600x1200, I always have RAM: 210 MB
With size 3200x2400, I always have RAM: 323 MB
(no oscillations or spikes)
System and Versions:
- Using RPi4 with JAVA Gstreamer (libcamerasrc)
- rpicam-apps build: v1.9.0 eca9928b76c1 09-09-2025 (12:41:27)
- libcamera build: v0.5.2+99-bfd68f78
- camera /base/soc/i2c0mux/i2c@1/imx219@10
Notes:
- I am disposing of each sample in appSink.
- I tried with different framerates, but the results are exactly the same.
- This might be related to issue GStreamer libcamerasrc zero-copy pipeline #305
What I think is happening:
When I changed from 3200 resolution to 1600, I got the following logs:
0x7f90b0a800 DEBUG libcamerasrc gstlibcamerasrc.cpp:556:gst_libcamera_create_video_pool:<source> Didn't get downstream ALLOCATION hints
0x7f90b0a800 WARN libcamerasrc gstlibcamerasrc.cpp:560:gst_libcamera_create_video_pool:<source> Downstream doesn't support video meta, need to copy frame.
0x7f90b0a800 DEBUG libcamerasrc gstlibcamerasrc.cpp:578:gst_libcamera_create_video_pool:<source> Own pool config is GstBufferPoolConfig, caps=(GstCaps)"video/x-raw\,\ format\=\(string\)BGR\,\ width\=\(int\)1600\,\ height\=\(int\)1200\,\ colorimetry\=\(string\)1:1:5:1", size=(uint)5760000, min-buffers=(uint)3, max-buffers=(uint)0, allocator=(GstAllocator)"NULL", params=(GstAllocationParams)NULL;
It seems possible that memory rises during resolution changes because libcamerasrc allocates a small internal pool of DMA-BUFs (min-buffers=3)
whenever caps are set. Even though your app disposes of every sample and does not copy buffers (zero copy mode), the source might still allocate new buffers for the pool, which could explain the RAM increase.