GstBuffers from appsrc need-data callback are not getting freed
Nikos Chantziaras
realnc at gmail.com
Mon Feb 23 15:24:10 PST 2015
I have a severe memory leak when using gstreamer 1.4.5. (0.10.36 works
just fine.) The buffers I'm creating in the need-data callback of appsrc
are not getting freed. My application ends up using whole GBs of RAM as
videos are played.
I register the callbacks in the source-setup signal handler of playbin:
(All code was reduced to a minimum that still exhibits the memory leak.)
// ...
g_signal_connect(pipeline, "source-setup",
G_CALLBACK(cbOnSourceSetup), dataSource);
// ...
GstAppSrcCallbacks appSrcCbs;
static void
cbOnSourceSetup(GstPipeline* pipeline, GstAppSrc* source,
gpointer dataSource)
{
gst_app_src_set_stream_type(source,
GST_APP_STREAM_TYPE_RANDOM_ACCESS);
g_object_set(G_OBJECT(source), "format", GST_FORMAT_BYTES, NULL);
memset(&appSrcCbs, 0, sizeof(appSrcCbs));
appSrcCbs.need_data = cbAppsrcNeedData;
appSrcCbs.enough_data = NULL;
appSrcCbs.seek_data = cbAppSrcSeekData;
gst_app_src_set_callbacks(source, &appSrcCbs, dataSource,
NULL);
gst_app_src_set_size(source, dataSourceByteLen);
}
So far, everything is the same between gstreamer-0.10 and 1.0. The
need-data callback differs a bit between the two, so there's an #ifdef
in it:
static void
cbAppsrcNeedData(GstAppSrc* src, guint length, gpointer dataSource)
{
if (length == (guint)-1) {
// We're free to push any amount of bytes.
length = 32768;
}
GstBuffer* buffer;
void* data;
#if GST_CHECK_VERSION(1, 0, 0)
// *** This allocation leaks ***
buffer = gst_buffer_new_allocate(NULL, length, NULL);
GstMapInfo mapInf;
if (not gst_buffer_map(buffer, &mapInf, GST_MAP_WRITE)) {
showError("Can't map GstBuffer memory.");
gst_app_src_end_of_stream(src);
return;
}
data = mapInf.data;
#else
buffer = gst_buffer_new_and_alloc(length);
data = buffer->data;
#endif
long bytesCopied = copyBytesFromDataSource(data, dataSource,
length);
gst_app_src_push_buffer(src, buffer);
if (bytesCopied < length) {
gst_app_src_end_of_stream(src);
}
}
Everything is fine when building against gstreamer-0.10. However, the
buffer allocated in this line:
buffer = gst_buffer_new_allocate(NULL, length, NULL);
which only compiles with gstreamer-1.0, is the source of the memory leak
according to Valgrind.
Aren't the buffers supposed to be freed again by gstreamer automatically
at some point? Or am I supposed to free them manually? If the latter is
the case, I can't find any information about where this should be done.
In case it matters, I'm closing the pipeline with the following:
gst_bus_remove_signal_watch(bus);
// stop
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
// wait for stop
gst_element_get_state(GST_ELEMENT(pipeline), NULL, NULL,
GST_CLOCK_TIME_NONE);
// due to a gst_pipeline_get_bus() elsewhere
gst_object_unref(bus);
// free the pipeline
gst_object_unref(pipeline);
More information about the gstreamer-devel
mailing list