diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index c922ad7cff..2f30b79ab6 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -373,6 +373,7 @@ gst_multi_queue_finalize (GObject * object) g_list_foreach (mqueue->queues, (GFunc) gst_single_queue_free, NULL); g_list_free (mqueue->queues); mqueue->queues = NULL; + mqueue->queues_cookie++; /* free/unref instance data */ g_mutex_free (mqueue->qlock); @@ -464,36 +465,89 @@ gst_multi_queue_get_property (GObject * object, guint prop_id, GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); } -static GList * -gst_multi_queue_get_internal_links (GstPad * pad) +typedef struct { - GList *res = NULL; + GstIterator parent; + GstMultiQueue *mqueue; - GstSingleQueue *sq = NULL; - GList *tmp; + GstPad *pad; + GList *current; +} GstMultiQueueIterator; + +static void +_iterate_free (GstIterator * it) +{ + GstMultiQueueIterator *mit = (GstMultiQueueIterator *) it; + + g_object_unref (mit->mqueue); + g_object_unref (mit->pad); + + g_free (it); +} + +static GstIteratorResult +_iterate_next (GstIterator * it, gpointer * result) +{ + GstMultiQueueIterator *mit = (GstMultiQueueIterator *) it; + GList *current; + GstPad *res = NULL; + + /* Find which single queue it belongs to */ + for (current = mit->current; !res && current; current = current->next) { + GstSingleQueue *sq = (GstSingleQueue *) current->data; + + if (sq->sinkpad == mit->pad) + res = sq->srcpad; + if (sq->srcpad == mit->pad) + res = sq->sinkpad; + } + + *result = res; + + mit->current = current; + + return res ? GST_ITERATOR_OK : GST_ITERATOR_DONE; +} + +static GstIteratorItem +_iterate_item (GstIterator * it, gpointer item) +{ + GstPad *pad = (GstPad *) item; + gst_object_ref (pad); + + return GST_ITERATOR_ITEM_PASS; +} + +static void +_iterate_resync (GstIterator * it) +{ + GstMultiQueueIterator *mit = (GstMultiQueueIterator *) it; + + mit->current = mit->mqueue->queues; +} + +static GstIterator * +gst_multi_queue_iterate_internal_links (GstPad * pad) +{ + GstMultiQueue *mqueue; + GstMultiQueueIterator *ret; g_return_val_if_fail (GST_IS_PAD (pad), NULL); - mqueue = GST_MULTI_QUEUE (GST_PAD_PARENT (pad)); if (!mqueue) goto no_parent; - GST_MULTI_QUEUE_MUTEX_LOCK (mqueue); - /* Find which single queue it belongs to */ - for (tmp = mqueue->queues; tmp && !res; tmp = g_list_next (tmp)) { - sq = (GstSingleQueue *) tmp->data; + ret = (GstMultiQueueIterator *) + gst_iterator_new (sizeof (GstMultiQueueIterator), + GST_TYPE_PAD, + mqueue->qlock, + &mqueue->queues_cookie, + _iterate_next, _iterate_item, _iterate_resync, _iterate_free); + ret->mqueue = g_object_ref (mqueue); + ret->current = mqueue->queues; + ret->pad = g_object_ref (pad); - if (sq->sinkpad == pad) - res = g_list_prepend (res, sq->srcpad); - if (sq->srcpad == pad) - res = g_list_prepend (res, sq->sinkpad); - } - - if (!res) - GST_WARNING_OBJECT (mqueue, "That pad doesn't belong to this element ???"); - GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue); - - return res; + return (GstIterator *) ret; no_parent: { @@ -521,6 +575,7 @@ gst_multi_queue_request_new_pad (GstElement * element, GstPadTemplate * temp, GST_MULTI_QUEUE_MUTEX_LOCK (mqueue); mqueue->queues = g_list_append (mqueue->queues, squeue); + mqueue->queues_cookie++; GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue); GST_DEBUG_OBJECT (mqueue, "Returning pad %s:%s", @@ -558,6 +613,7 @@ gst_multi_queue_release_pad (GstElement * element, GstPad * pad) /* remove it from the list */ mqueue->queues = g_list_delete_link (mqueue->queues, tmp); + mqueue->queues_cookie++; /* FIXME : recompute next-non-linked */ GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue); @@ -1461,8 +1517,8 @@ gst_single_queue_new (GstMultiQueue * mqueue) GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps)); gst_pad_set_bufferalloc_function (sq->sinkpad, GST_DEBUG_FUNCPTR (gst_multi_queue_bufferalloc)); - gst_pad_set_internal_link_function (sq->sinkpad, - GST_DEBUG_FUNCPTR (gst_multi_queue_get_internal_links)); + gst_pad_set_iterate_internal_links_function (sq->sinkpad, + GST_DEBUG_FUNCPTR (gst_multi_queue_iterate_internal_links)); tmp = g_strdup_printf ("src%d", sq->id); sq->srcpad = gst_pad_new_from_static_template (&srctemplate, tmp); @@ -1476,8 +1532,8 @@ gst_single_queue_new (GstMultiQueue * mqueue) GST_DEBUG_FUNCPTR (gst_multi_queue_src_event)); gst_pad_set_query_function (sq->srcpad, GST_DEBUG_FUNCPTR (gst_multi_queue_src_query)); - gst_pad_set_internal_link_function (sq->srcpad, - GST_DEBUG_FUNCPTR (gst_multi_queue_get_internal_links)); + gst_pad_set_iterate_internal_links_function (sq->sinkpad, + GST_DEBUG_FUNCPTR (gst_multi_queue_iterate_internal_links)); gst_pad_set_element_private (sq->sinkpad, (gpointer) sq); gst_pad_set_element_private (sq->srcpad, (gpointer) sq); diff --git a/plugins/elements/gstmultiqueue.h b/plugins/elements/gstmultiqueue.h index 4874563236..7a96d77ada 100644 --- a/plugins/elements/gstmultiqueue.h +++ b/plugins/elements/gstmultiqueue.h @@ -55,6 +55,7 @@ struct _GstMultiQueue { /* The list of individual queues */ GList *queues; + guint32 queues_cookie; GstDataQueueSize max_size, extra_size;