Skip to content

Unexpected memory increase when resizing pipeline with libcamerasrc and AppSink #306

@gasparramoa

Description

@gasparramoa

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.

  1. I start the pipeline with Selected sensor format: 3280x2464-SBGGR10_1X10/RAW - Selected unicam format: 3280x2464-pBAA/RAW
    Resolution: 3200x2400 (cuWidth and cuHeight)
    (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)

  1. 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);
  1. 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.

  2. 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:


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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions