GstBase/PushSrc GstBuffer ownership

Tim Müller tim at centricular.com
Thu Mar 26 11:51:16 PDT 2015


On Thu, 2015-03-26 at 17:49 +0000, Samuel Hurst wrote:

Hi Sam,

> I have a query regarding how to handle buffers in a source element. I'm
> using GstPushSrc at present to implement an element for GStreamer, and
> I'm currently debugging a few memory leak problems that seem to be
> arising from the usage of buffers, so I would like some clarification as
> to their usage.
> 
> What leads me to believe the leak is thanks to my GstBuffer handling is
> the output from valgrind below:
> 
> ==4572== 232,616,688 bytes in 223 blocks are still reachable in loss
> record 2,846 of 2,846
> ==4572==    at 0x4C2845D: malloc (in
> /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==4572==    by 0x58E770E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
> ==4572==    by 0x58FD7DD: g_slice_alloc (in
> /usr/lib64/libglib-2.0.so.0.3600.3)
> ==4572==    by 0x4E600FC: _sysmem_new_block (gstallocator.c:414)
> ==4572==    by 0x4E6A061: gst_buffer_new_allocate (gstbuffer.c:673)
> ...
> 
> I'm thinking that the "still reachable" means that there's still
> references being held internally because I'm not currently unreferencing
> it (but feel free to correct me if this thinking is wrong!).
> 
> At present, I'm overriding the gst_base_src_create() function, which
> provides a GstBuffer** object to pass data upstream. Once my element has
> processed its request, it uses gst_buffer_new_allocate() to allocate a
> new buffer of the appropriate size, and then I'm using gst_buffer_map to
> write the data in, then _unmap()ing before returning GST_FLOW_OK.
> 
> In the documentation, it mentions that after using
> gst_buffer_new_allocate() you should use gst_buffer_unref() when you're
> ready to say goodbye to that buffer, but where should this be done? I'm
> going to assume it's at some point after the _create() function has
> returned, as otherwise the buffer will never go to the upstream
> element's sink pad.

What you do in your create function sounds right.

What happens is basically that you give ownership of that buffer ref to
the base class (who will then either unref the buffer, or push it
downstream with gst_pad_push(), which passes ownership to the next
element).

What you're seeing here is mostly likely a downstream element not
freeing a buffer it has received correctly. What's the full pipeline?

It's a bit curious that it says 'still reachable' and not 'definitely
lost', so perhaps the buffers are held in a cache somewhere that's not
cleaned up properly?

Cheers
 -Tim


-- 
Tim Müller, Centricular Ltd - http://www.centricular.com



More information about the gstreamer-devel mailing list