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);
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;
- g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+static void
+_iterate_free (GstIterator * it)
+{
+ GstMultiQueueIterator *mit = (GstMultiQueueIterator *) it;
- mqueue = GST_MULTI_QUEUE (GST_PAD_PARENT (pad));
- if (!mqueue)
- goto no_parent;
+ 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;
- 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;
+ for (current = mit->current; !res && current; current = current->next) {
+ GstSingleQueue *sq = (GstSingleQueue *) current->data;
- if (sq->sinkpad == pad)
- res = g_list_prepend (res, sq->srcpad);
- if (sq->srcpad == pad)
- res = g_list_prepend (res, sq->sinkpad);
+ if (sq->sinkpad == mit->pad)
+ res = sq->srcpad;
+ if (sq->srcpad == mit->pad)
+ res = sq->sinkpad;
}
- if (!res)
- GST_WARNING_OBJECT (mqueue, "That pad doesn't belong to this element ???");
- GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
+ *result = res;
- return 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;
+
+ 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);
+
+ return (GstIterator *) ret;
no_parent:
{
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",
/* 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);
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);
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);