Commit c4c06a2b authored by Jonas Holmberg's avatar Jonas Holmberg Committed by Wim Taymans

bufferlist: Use a GQueue instead of a GList

Adding a buffer to the end of a GstBufferList is supposed to be a fast
operation, but it was not since the iterator does not advance its
nextpointer when adding buffers and GList does not have a tail pointer.
Using a GQueue to store the buffers makes it easier to add buffers to
the end of the list and this operation will now be much more efficient.

Adding an entire GList of buffers using
gst_buffer_list_iterator_add_list() will however have to iterate over
the list being added to be able to update the tail pointer in the
GQueue.
parent 90b4dc48
...@@ -142,7 +142,7 @@ struct _GstBufferList ...@@ -142,7 +142,7 @@ struct _GstBufferList
{ {
GstMiniObject mini_object; GstMiniObject mini_object;
GList *buffers; GQueue *buffers;
}; };
struct _GstBufferListClass struct _GstBufferListClass
...@@ -180,7 +180,7 @@ _gst_buffer_list_initialize (void) ...@@ -180,7 +180,7 @@ _gst_buffer_list_initialize (void)
static void static void
gst_buffer_list_init (GstBufferList * list) gst_buffer_list_init (GstBufferList * list)
{ {
list->buffers = NULL; list->buffers = g_queue_new ();
GST_LOG ("init %p", list); GST_LOG ("init %p", list);
} }
...@@ -194,14 +194,14 @@ gst_buffer_list_finalize (GstBufferList * list) ...@@ -194,14 +194,14 @@ gst_buffer_list_finalize (GstBufferList * list)
GST_LOG ("finalize %p", list); GST_LOG ("finalize %p", list);
tmp = list->buffers; tmp = list->buffers->head;
while (tmp) { while (tmp) {
if (tmp->data != GROUP_START && tmp->data != STOLEN) { if (tmp->data != GROUP_START && tmp->data != STOLEN) {
gst_buffer_unref (GST_BUFFER_CAST (tmp->data)); gst_buffer_unref (GST_BUFFER_CAST (tmp->data));
} }
tmp = tmp->next; tmp = tmp->next;
} }
g_list_free (list->buffers); g_queue_free (list->buffers);
/* Not chaining up because GstMiniObject::finalize() does nothing /* Not chaining up because GstMiniObject::finalize() does nothing
GST_MINI_OBJECT_CLASS (gst_buffer_list_parent_class)->finalize GST_MINI_OBJECT_CLASS (gst_buffer_list_parent_class)->finalize
...@@ -212,17 +212,16 @@ static GstBufferList * ...@@ -212,17 +212,16 @@ static GstBufferList *
_gst_buffer_list_copy (GstBufferList * list) _gst_buffer_list_copy (GstBufferList * list)
{ {
GstBufferList *list_copy; GstBufferList *list_copy;
GQueue *buffers_copy;
GList *tmp; GList *tmp;
g_return_val_if_fail (list != NULL, NULL); g_return_val_if_fail (list != NULL, NULL);
list_copy = gst_buffer_list_new ();
/* shallow copy of list and pointers */ /* shallow copy of list and pointers */
list_copy->buffers = g_list_copy (list->buffers); buffers_copy = g_queue_copy (list->buffers);
/* ref all buffers in the list */ /* ref all buffers in the list */
tmp = list_copy->buffers; tmp = list->buffers->head;
while (tmp) { while (tmp) {
if (tmp->data != GROUP_START && tmp->data != STOLEN) { if (tmp->data != GROUP_START && tmp->data != STOLEN) {
tmp->data = gst_buffer_ref (GST_BUFFER_CAST (tmp->data)); tmp->data = gst_buffer_ref (GST_BUFFER_CAST (tmp->data));
...@@ -230,6 +229,10 @@ _gst_buffer_list_copy (GstBufferList * list) ...@@ -230,6 +229,10 @@ _gst_buffer_list_copy (GstBufferList * list)
tmp = g_list_next (tmp); tmp = g_list_next (tmp);
} }
list_copy = gst_buffer_list_new ();
g_queue_free (list_copy->buffers);
list_copy->buffers = buffers_copy;
return list_copy; return list_copy;
} }
...@@ -285,7 +288,7 @@ gst_buffer_list_n_groups (GstBufferList * list) ...@@ -285,7 +288,7 @@ gst_buffer_list_n_groups (GstBufferList * list)
g_return_val_if_fail (list != NULL, 0); g_return_val_if_fail (list != NULL, 0);
tmp = list->buffers; tmp = list->buffers->head;
n = 0; n = 0;
while (tmp) { while (tmp) {
if (tmp->data == GROUP_START) { if (tmp->data == GROUP_START) {
...@@ -322,7 +325,7 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func, ...@@ -322,7 +325,7 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
g_return_if_fail (list != NULL); g_return_if_fail (list != NULL);
g_return_if_fail (func != NULL); g_return_if_fail (func != NULL);
next = list->buffers; next = list->buffers->head;
group = idx = 0; group = idx = 0;
while (next) { while (next) {
GstBuffer *buffer; GstBuffer *buffer;
...@@ -348,7 +351,7 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func, ...@@ -348,7 +351,7 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
/* the function changed the buffer */ /* the function changed the buffer */
if (buffer == NULL) { if (buffer == NULL) {
/* we were asked to remove the item */ /* we were asked to remove the item */
list->buffers = g_list_delete_link (list->buffers, tmp); g_queue_delete_link (list->buffers, tmp);
idx--; idx--;
} else { } else {
/* change the buffer */ /* change the buffer */
...@@ -393,7 +396,7 @@ gst_buffer_list_get (GstBufferList * list, guint group, guint idx) ...@@ -393,7 +396,7 @@ gst_buffer_list_get (GstBufferList * list, guint group, guint idx)
g_return_val_if_fail (list != NULL, NULL); g_return_val_if_fail (list != NULL, NULL);
tmp = list->buffers; tmp = list->buffers->head;
cgroup = 0; cgroup = 0;
while (tmp) { while (tmp) {
if (tmp->data == GROUP_START) { if (tmp->data == GROUP_START) {
...@@ -445,7 +448,7 @@ gst_buffer_list_iterate (GstBufferList * list) ...@@ -445,7 +448,7 @@ gst_buffer_list_iterate (GstBufferList * list)
it = g_slice_new (GstBufferListIterator); it = g_slice_new (GstBufferListIterator);
it->list = list; it->list = list;
it->next = list->buffers; it->next = list->buffers->head;
it->last_returned = NULL; it->last_returned = NULL;
return it; return it;
...@@ -524,11 +527,14 @@ gst_buffer_list_iterator_add (GstBufferListIterator * it, GstBuffer * buffer) ...@@ -524,11 +527,14 @@ gst_buffer_list_iterator_add (GstBufferListIterator * it, GstBuffer * buffer)
g_return_if_fail (buffer != NULL); g_return_if_fail (buffer != NULL);
/* adding before the first group start is not allowed */ /* adding before the first group start is not allowed */
g_return_if_fail (it->next != it->list->buffers); g_return_if_fail (it->next != it->list->buffers->head);
/* cheap insert into the GList */ /* cheap insert into the GQueue */
it->list->buffers = g_list_insert_before (it->list->buffers, it->next, if (it->next != NULL) {
buffer); g_queue_insert_before (it->list->buffers, it->next, buffer);
} else {
g_queue_push_tail (it->list->buffers, buffer);
}
} }
/** /**
...@@ -550,31 +556,33 @@ void ...@@ -550,31 +556,33 @@ void
gst_buffer_list_iterator_add_list (GstBufferListIterator * it, GList * list) gst_buffer_list_iterator_add_list (GstBufferListIterator * it, GList * list)
{ {
GList *last; GList *last;
guint len;
g_return_if_fail (it != NULL); g_return_if_fail (it != NULL);
g_return_if_fail (it->next != it->list->buffers); g_return_if_fail (it->next != it->list->buffers->head);
if (list == NULL) if (list == NULL)
return; return;
if (it->next) { last = list;
last = list; len = 1;
while (last->next) while (last->next) {
last = last->next; last = last->next;
len++;
}
if (it->next) {
last->next = it->next; last->next = it->next;
list->prev = it->next->prev; list->prev = it->next->prev;
it->next->prev = last; it->next->prev = last;
if (list->prev) if (list->prev)
list->prev->next = list; list->prev->next = list;
} else { } else {
last = it->list->buffers; it->list->buffers->tail->next = list;
while (last->next) list->prev = it->list->buffers->tail;
last = last->next; it->list->buffers->tail = last;
last->next = list;
list->prev = last;
} }
it->list->buffers->length += len;
} }
/** /**
...@@ -599,9 +607,12 @@ gst_buffer_list_iterator_add_group (GstBufferListIterator * it) ...@@ -599,9 +607,12 @@ gst_buffer_list_iterator_add_group (GstBufferListIterator * it)
it->next = g_list_next (it->next); it->next = g_list_next (it->next);
} }
/* cheap insert of a group start into the GList */ /* cheap insert of a group start into the GQueue */
it->list->buffers = g_list_insert_before (it->list->buffers, it->next, if (it->next != NULL) {
GROUP_START); g_queue_insert_before (it->list->buffers, it->next, GROUP_START);
} else {
g_queue_push_tail (it->list->buffers, GROUP_START);
}
} }
/** /**
...@@ -706,7 +717,7 @@ gst_buffer_list_iterator_remove (GstBufferListIterator * it) ...@@ -706,7 +717,7 @@ gst_buffer_list_iterator_remove (GstBufferListIterator * it)
if (it->last_returned->data != STOLEN) { if (it->last_returned->data != STOLEN) {
gst_buffer_unref (it->last_returned->data); gst_buffer_unref (it->last_returned->data);
} }
it->list->buffers = g_list_delete_link (it->list->buffers, it->last_returned); g_queue_delete_link (it->list->buffers, it->last_returned);
it->last_returned = NULL; it->last_returned = NULL;
} }
......
...@@ -783,7 +783,14 @@ GST_START_TEST (test_list) ...@@ -783,7 +783,14 @@ GST_START_TEST (test_list)
gst_buffer_list_iterator_add_group (it); gst_buffer_list_iterator_add_group (it);
gst_buffer_list_iterator_add_list (it, l); gst_buffer_list_iterator_add_list (it, l);
for (i = 0; i < 10; i++) { /* add a buffer */
gst_buffer_list_iterator_add (it, buffer_from_string ("10"));
/* add another list */
l = g_list_append (NULL, buffer_from_string ("11"));
gst_buffer_list_iterator_add_list (it, l);
for (i = 0; i < 12; i++) {
GstBuffer *buf; GstBuffer *buf;
gchar name[10]; gchar name[10];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment