splitmux: Fix memory leaks until the test valgrinds clean

This commit is contained in:
Jan Schmidt 2015-02-07 00:19:36 +11:00
parent ace6be8abb
commit aa4c29c5d6
3 changed files with 107 additions and 11 deletions

View File

@ -482,10 +482,12 @@ splitmux_part_pad_event (GstPad * pad, GstObject * parent, GstEvent * event)
} }
gst_object_unref (part_pad->queue); gst_object_unref (part_pad->queue);
gst_object_unref (target);
return ret; return ret;
wrong_segment: wrong_segment:
gst_event_unref (event); gst_event_unref (event);
gst_object_unref (target);
SPLITMUX_PART_UNLOCK (reader); SPLITMUX_PART_UNLOCK (reader);
GST_ELEMENT_ERROR (reader, STREAM, FAILED, (NULL), GST_ELEMENT_ERROR (reader, STREAM, FAILED, (NULL),
("Received non-time segment - reader %s pad %" GST_PTR_FORMAT, ("Received non-time segment - reader %s pad %" GST_PTR_FORMAT,
@ -495,6 +497,7 @@ drop_event:
GST_LOG_OBJECT (pad, "Dropping event %" GST_PTR_FORMAT GST_LOG_OBJECT (pad, "Dropping event %" GST_PTR_FORMAT
" from %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, event, pad, target); " from %" GST_PTR_FORMAT " on %" GST_PTR_FORMAT, event, pad, target);
gst_event_unref (event); gst_event_unref (event);
gst_object_unref (target);
SPLITMUX_PART_UNLOCK (reader); SPLITMUX_PART_UNLOCK (reader);
return TRUE; return TRUE;
} }
@ -536,6 +539,8 @@ splitmux_part_pad_constructed (GObject * pad)
GST_DEBUG_FUNCPTR (splitmux_part_pad_event)); GST_DEBUG_FUNCPTR (splitmux_part_pad_event));
gst_pad_set_query_function (GST_PAD (pad), gst_pad_set_query_function (GST_PAD (pad),
GST_DEBUG_FUNCPTR (splitmux_part_pad_query)); GST_DEBUG_FUNCPTR (splitmux_part_pad_query));
G_OBJECT_CLASS (gst_splitmux_part_pad_parent_class)->constructed (pad);
} }
static void static void
@ -560,7 +565,14 @@ static void
splitmux_part_pad_finalize (GObject * obj) splitmux_part_pad_finalize (GObject * obj)
{ {
GstSplitMuxPartPad *pad = (GstSplitMuxPartPad *) (obj); GstSplitMuxPartPad *pad = (GstSplitMuxPartPad *) (obj);
g_object_unref ((GObject *) (pad->queue));
GST_DEBUG_OBJECT (obj, "finalize");
gst_data_queue_set_flushing (pad->queue, TRUE);
gst_data_queue_flush (pad->queue);
gst_object_unref (GST_OBJECT_CAST (pad->queue));
pad->queue = NULL;
G_OBJECT_CLASS (gst_splitmux_part_pad_parent_class)->finalize (obj);
} }
static void static void
@ -575,6 +587,9 @@ static gboolean gst_splitmux_part_reader_send_event (GstElement * element,
static void gst_splitmux_part_reader_set_flushing_locked (GstSplitMuxPartReader static void gst_splitmux_part_reader_set_flushing_locked (GstSplitMuxPartReader
* part, gboolean flushing); * part, gboolean flushing);
static void bus_handler (GstBin * bin, GstMessage * msg); static void bus_handler (GstBin * bin, GstMessage * msg);
static void splitmux_part_reader_dispose (GObject * object);
static void splitmux_part_reader_finalize (GObject * object);
static void splitmux_part_reader_reset (GstSplitMuxPartReader * reader);
#define gst_splitmux_part_reader_parent_class parent_class #define gst_splitmux_part_reader_parent_class parent_class
G_DEFINE_TYPE (GstSplitMuxPartReader, gst_splitmux_part_reader, G_DEFINE_TYPE (GstSplitMuxPartReader, gst_splitmux_part_reader,
@ -583,12 +598,16 @@ G_DEFINE_TYPE (GstSplitMuxPartReader, gst_splitmux_part_reader,
static void static void
gst_splitmux_part_reader_class_init (GstSplitMuxPartReaderClass * klass) gst_splitmux_part_reader_class_init (GstSplitMuxPartReaderClass * klass)
{ {
GObjectClass *gobject_klass = (GObjectClass *) (klass);
GstElementClass *gstelement_class = (GstElementClass *) klass; GstElementClass *gstelement_class = (GstElementClass *) klass;
GstBinClass *gstbin_class = (GstBinClass *) klass; GstBinClass *gstbin_class = (GstBinClass *) klass;
GST_DEBUG_CATEGORY_INIT (splitmux_part_debug, "splitmuxpartreader", 0, GST_DEBUG_CATEGORY_INIT (splitmux_part_debug, "splitmuxpartreader", 0,
"Split File Demuxing Source helper"); "Split File Demuxing Source helper");
gobject_klass->dispose = splitmux_part_reader_dispose;
gobject_klass->finalize = splitmux_part_reader_finalize;
part_reader_signals[SIGNAL_PREPARED] = part_reader_signals[SIGNAL_PREPARED] =
g_signal_new ("prepared", G_TYPE_FROM_CLASS (klass), g_signal_new ("prepared", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstSplitMuxPartReaderClass, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstSplitMuxPartReaderClass,
@ -638,6 +657,43 @@ gst_splitmux_part_reader_init (GstSplitMuxPartReader * reader)
reader); reader);
} }
static void
splitmux_part_reader_dispose (GObject * object)
{
GstSplitMuxPartReader *reader = (GstSplitMuxPartReader *) object;
splitmux_part_reader_reset (reader);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
splitmux_part_reader_finalize (GObject * object)
{
GstSplitMuxPartReader *reader = (GstSplitMuxPartReader *) object;
g_free (reader->path);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
splitmux_part_reader_reset (GstSplitMuxPartReader * reader)
{
GList *cur;
SPLITMUX_PART_LOCK (reader);
for (cur = g_list_first (reader->pads); cur != NULL; cur = g_list_next (cur)) {
GstPad *pad = GST_PAD_CAST (cur->data);
gst_pad_set_active (GST_PAD_CAST (pad), FALSE);
gst_object_unref (GST_OBJECT_CAST (pad));
}
g_list_free (reader->pads);
reader->pads = NULL;
SPLITMUX_PART_UNLOCK (reader);
}
static GstSplitMuxPartPad * static GstSplitMuxPartPad *
gst_splitmux_part_reader_new_proxy_pad (GstSplitMuxPartReader * reader, gst_splitmux_part_reader_new_proxy_pad (GstSplitMuxPartReader * reader,
GstPad * target) GstPad * target)
@ -667,6 +723,9 @@ new_decoded_pad_added_cb (GstElement * element, GstPad * pad,
GST_DEBUG_OBJECT (reader, "file %s new decoded pad %" GST_PTR_FORMAT GST_DEBUG_OBJECT (reader, "file %s new decoded pad %" GST_PTR_FORMAT
" caps %" GST_PTR_FORMAT, reader->path, pad, caps); " caps %" GST_PTR_FORMAT, reader->path, pad, caps);
gst_caps_unref (caps);
/* Look up or create the output pad */ /* Look up or create the output pad */
if (reader->get_pad_cb) if (reader->get_pad_cb)
out_pad = reader->get_pad_cb (reader, pad, reader->cb_data); out_pad = reader->get_pad_cb (reader, pad, reader->cb_data);
@ -925,7 +984,7 @@ gst_splitmux_part_reader_src_query (GstSplitMuxPartReader * part,
gst_object_unref (GST_OBJECT_CAST (target)); gst_object_unref (GST_OBJECT_CAST (target));
if (ret == FALSE) if (ret == FALSE)
return ret; goto out;
/* Post-massaging of queries */ /* Post-massaging of queries */
switch (GST_QUERY_TYPE (query)) { switch (GST_QUERY_TYPE (query)) {
@ -949,6 +1008,8 @@ gst_splitmux_part_reader_src_query (GstSplitMuxPartReader * part,
break; break;
} }
out:
gst_object_unref (target);
return ret; return ret;
} }
@ -1023,6 +1084,7 @@ gst_splitmux_part_reader_change_state (GstElement * element,
break; break;
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
reader->prep_state = PART_STATE_NULL; reader->prep_state = PART_STATE_NULL;
splitmux_part_reader_reset (reader);
break; break;
default: default:
break; break;
@ -1209,6 +1271,7 @@ gst_splitmux_part_reader_pop (GstSplitMuxPartReader * reader, GstPad * pad,
{ {
GstSplitMuxPartPad *part_pad = (GstSplitMuxPartPad *) (pad); GstSplitMuxPartPad *part_pad = (GstSplitMuxPartPad *) (pad);
GstDataQueue *q; GstDataQueue *q;
GstFlowReturn ret;
/* Get one item from the appropriate dataqueue */ /* Get one item from the appropriate dataqueue */
SPLITMUX_PART_LOCK (reader); SPLITMUX_PART_LOCK (reader);
@ -1221,8 +1284,10 @@ gst_splitmux_part_reader_pop (GstSplitMuxPartReader * reader, GstPad * pad,
/* Have to drop the lock around pop, so we can be woken up for flush */ /* Have to drop the lock around pop, so we can be woken up for flush */
SPLITMUX_PART_UNLOCK (reader); SPLITMUX_PART_UNLOCK (reader);
if (!gst_data_queue_pop (q, item) || (*item == NULL)) if (!gst_data_queue_pop (q, item) || (*item == NULL)) {
return GST_FLOW_FLUSHING; ret = GST_FLOW_FLUSHING;
goto out;
}
SPLITMUX_PART_LOCK (reader); SPLITMUX_PART_LOCK (reader);
@ -1235,8 +1300,11 @@ gst_splitmux_part_reader_pop (GstSplitMuxPartReader * reader, GstPad * pad,
} }
SPLITMUX_PART_UNLOCK (reader); SPLITMUX_PART_UNLOCK (reader);
ret = GST_FLOW_OK;
out:
gst_object_unref (q); gst_object_unref (q);
return GST_FLOW_OK; return ret;
} }
static void static void

View File

@ -227,6 +227,21 @@ gst_splitmux_src_init (GstSplitMuxSrc * splitmux)
static void static void
gst_splitmux_src_dispose (GObject * object) gst_splitmux_src_dispose (GObject * object)
{ {
GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object);
GList *cur;
SPLITMUX_SRC_PADS_LOCK (splitmux);
for (cur = g_list_first (splitmux->pads);
cur != NULL; cur = g_list_next (cur)) {
GstPad *pad = GST_PAD (cur->data);
gst_element_remove_pad (GST_ELEMENT (splitmux), pad);
}
g_list_free (splitmux->pads);
splitmux->pads = NULL;
SPLITMUX_SRC_PADS_UNLOCK (splitmux);
G_OBJECT_CLASS (parent_class)->dispose (object);
} }
static void static void
@ -235,6 +250,9 @@ gst_splitmux_src_finalize (GObject * object)
GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object); GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object);
g_mutex_clear (&splitmux->lock); g_mutex_clear (&splitmux->lock);
g_mutex_clear (&splitmux->pads_lock); g_mutex_clear (&splitmux->pads_lock);
g_free (splitmux->location);
G_OBJECT_CLASS (parent_class)->finalize (object);
} }
static void static void
@ -292,8 +310,6 @@ gst_splitmux_src_change_state (GstElement * element, GstStateChange transition)
} }
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
if (!gst_splitmux_src_stop (splitmux))
return GST_STATE_CHANGE_FAILURE;
break; break;
default: default:
break; break;
@ -305,6 +321,8 @@ gst_splitmux_src_change_state (GstElement * element, GstStateChange transition)
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
if (!gst_splitmux_src_stop (splitmux))
return GST_STATE_CHANGE_FAILURE;
break; break;
default: default:
break; break;
@ -599,6 +617,8 @@ gst_splitmux_src_start (GstSplitMuxSrc * splitmux)
GstClockTime next_offset = 0; GstClockTime next_offset = 0;
guint i; guint i;
GST_DEBUG_OBJECT (splitmux, "Starting");
GST_OBJECT_LOCK (splitmux); GST_OBJECT_LOCK (splitmux);
if (splitmux->location != NULL && splitmux->location[0] != '\0') { if (splitmux->location != NULL && splitmux->location[0] != '\0') {
basename = g_path_get_basename (splitmux->location); basename = g_path_get_basename (splitmux->location);
@ -611,6 +631,10 @@ gst_splitmux_src_start (GstSplitMuxSrc * splitmux)
if (files == NULL || *files == NULL) if (files == NULL || *files == NULL)
goto no_files; goto no_files;
SPLITMUX_SRC_LOCK (splitmux);
splitmux->running = TRUE;
SPLITMUX_SRC_UNLOCK (splitmux);
splitmux->num_parts = g_strv_length (files); splitmux->num_parts = g_strv_length (files);
splitmux->parts = g_new0 (GstSplitMuxPartReader *, splitmux->num_parts); splitmux->parts = g_new0 (GstSplitMuxPartReader *, splitmux->num_parts);
@ -654,9 +678,6 @@ gst_splitmux_src_start (GstSplitMuxSrc * splitmux)
" Activating first part", GST_TIME_ARGS (splitmux->total_duration)); " Activating first part", GST_TIME_ARGS (splitmux->total_duration));
gst_splitmux_src_activate_part (splitmux, 0); gst_splitmux_src_activate_part (splitmux, 0);
SPLITMUX_SRC_LOCK (splitmux);
splitmux->running = TRUE;
SPLITMUX_SRC_UNLOCK (splitmux);
ret = TRUE; ret = TRUE;
done: done:
if (err != NULL) if (err != NULL)
@ -694,10 +715,15 @@ gst_splitmux_src_stop (GstSplitMuxSrc * splitmux)
if (!splitmux->running) if (!splitmux->running)
goto out; goto out;
GST_DEBUG_OBJECT (splitmux, "Stopping");
/* Stop and destroy all parts */ /* Stop and destroy all parts */
for (i = 0; i < splitmux->num_parts; i++) { for (i = 0; i < splitmux->num_parts; i++) {
if (splitmux->parts[i] == NULL)
continue;
gst_splitmux_part_reader_unprepare (splitmux->parts[i]); gst_splitmux_part_reader_unprepare (splitmux->parts[i]);
g_object_unref (splitmux->parts[i]); g_object_unref (splitmux->parts[i]);
splitmux->parts[i] = NULL;
} }
SPLITMUX_SRC_PADS_LOCK (splitmux); SPLITMUX_SRC_PADS_LOCK (splitmux);
@ -903,6 +929,8 @@ splitmux_src_pad_constructed (GObject * pad)
GST_DEBUG_FUNCPTR (splitmux_src_pad_event)); GST_DEBUG_FUNCPTR (splitmux_src_pad_event));
gst_pad_set_query_function (GST_PAD (pad), gst_pad_set_query_function (GST_PAD (pad),
GST_DEBUG_FUNCPTR (splitmux_src_pad_query)); GST_DEBUG_FUNCPTR (splitmux_src_pad_query));
G_OBJECT_CLASS (splitmux_src_pad_parent_class)->constructed (pad);
} }
static void static void

View File

@ -100,10 +100,10 @@ GST_START_TEST (test_splitmuxsrc)
g_free (uri); g_free (uri);
msg = run_pipeline (pipeline); msg = run_pipeline (pipeline);
gst_object_unref (pipeline);
fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR); fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
gst_message_unref (msg); gst_message_unref (msg);
gst_object_unref (pipeline);
} }
GST_END_TEST; GST_END_TEST;