diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-06-19 15:29:14 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-06-19 15:31:53 +0200 |
commit | 6438f6f9b9edd3b4a014f5fd251b4b399ec6bce7 (patch) | |
tree | 6623ec3542b8412412f5d46f25e7f0652119bba5 /gst | |
parent | 17f794deebc36d284c82a9022cf2fd417a5d9df0 (diff) |
bufferlist: Various cleanups
Add new method to iterate a bufferlist without having to allocate an iterator.
Add convenience method for getting an item from the list based on the group and
index.
Remove redundant _do_data callback and method.
Update unit-tests and add some more for the new methods.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/gstbufferlist.c | 183 | ||||
-rw-r--r-- | gst/gstbufferlist.h | 69 |
2 files changed, 177 insertions, 75 deletions
diff --git a/gst/gstbufferlist.c b/gst/gstbufferlist.c index 02863ee54..20a2ef802 100644 --- a/gst/gstbufferlist.c +++ b/gst/gstbufferlist.c @@ -289,6 +289,127 @@ gst_buffer_list_n_groups (GstBufferList * list) return n; } +/** + * gst_buffer_list_foreach: + * @list: a #GstBufferList + * @func: a #GstBufferListFunc to call + * @user_data: user data passed to @func + * + * Call @func with @data for each buffer in @list. + * + * @func can modify the passed buffer pointer or its contents. The return value + * of @func define if this function returns or if the remaining buffers in a + * group should be skipped. + */ +void +gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func, + gpointer user_data) +{ + GList *tmp, *next; + guint group, idx; + GstBufferListItem res; + + g_return_if_fail (list != NULL); + g_return_if_fail (func != NULL); + + next = list->buffers; + group = idx = 0; + while (next) { + GstBuffer *buffer; + + tmp = next; + next = g_list_next (tmp); + + buffer = tmp->data; + + if (buffer == GROUP_START) { + group++; + idx = 0; + continue; + } else if (buffer == STOLEN) + continue; + else + idx++; + + /* need to decrement the indices */ + res = func (&buffer, group - 1, idx - 1, user_data); + + if (G_UNLIKELY (buffer != tmp->data)) { + /* the function changed the buffer */ + if (buffer == NULL) { + /* we were asked to remove the item */ + list->buffers = g_list_delete_link (list->buffers, tmp); + idx--; + } else { + /* change the buffer */ + tmp->data = buffer; + } + } + + switch (res) { + case GST_BUFFER_LIST_CONTINUE: + break; + case GST_BUFFER_LIST_SKIP_GROUP: + while (next && next->data != GROUP_START) + next = g_list_next (next); + break; + case GST_BUFFER_LIST_END: + return; + } + } +} + +/** + * gst_buffer_list_get: + * @list: a #GstBufferList + * @group: the group + * @idx: the index in @group + * + * Get the buffer at @idx in @group. + * + * Note that this function is not efficient for iterating over the entire list. + * Use and iterator or gst_buffer_list_foreach() instead. + * + * Returns: the buffer at @idx in @group or NULL when there is no buffer. The + * buffer remaing valid as long as @list is valid. + */ +GstBuffer * +gst_buffer_list_get (GstBufferList * list, guint group, guint idx) +{ + GList *tmp; + guint cgroup, cidx; + + g_return_val_if_fail (list != NULL, NULL); + + tmp = list->buffers; + cgroup = 0; + while (tmp) { + if (tmp->data == GROUP_START) { + if (cgroup == group) { + /* we found the group */ + tmp = g_list_next (tmp); + cidx = 0; + while (tmp && tmp->data != GROUP_START) { + if (tmp->data != STOLEN) { + if (cidx == idx) + return GST_BUFFER_CAST (tmp->data); + else + cidx++; + } + tmp = g_list_next (tmp); + } + break; + } else { + cgroup++; + if (cgroup > group) + break; + } + } + tmp = g_list_next (tmp); + } + return NULL; +} + GType gst_buffer_list_get_type (void) { @@ -474,9 +595,10 @@ gst_buffer_list_iterator_next (GstBufferListIterator * it) return buffer; no_buffer: - it->last_returned = NULL; - - return NULL; + { + it->last_returned = NULL; + return NULL; + } } /** @@ -590,11 +712,10 @@ gst_buffer_list_iterator_steal (GstBufferListIterator * it) } /** - * gst_buffer_list_iterator_do_data: + * gst_buffer_list_iterator_do: * @it: a #GstBufferListIterator * @do_func: the function to be called - * @data: the gpointer to optional user data. - * @data_notify: function to be called when @data is no longer used + * @user_data: the gpointer to optional user data. * * Calls the given function for the last buffer returned by * gst_buffer_list_iterator_next(). gst_buffer_list_iterator_next() must have @@ -604,15 +725,11 @@ gst_buffer_list_iterator_steal (GstBufferListIterator * it) * * See #GstBufferListDoFunction for more details. * - * The @data_notify function is called after @do_func has returned, before this - * function returns, usually used to free @data. - * * Returns: the return value from @do_func */ GstBuffer * -gst_buffer_list_iterator_do_data (GstBufferListIterator * it, - GstBufferListDoDataFunction do_func, gpointer data, - GDestroyNotify data_notify) +gst_buffer_list_iterator_do (GstBufferListIterator * it, + GstBufferListDoFunction do_func, gpointer user_data) { GstBuffer *buffer; @@ -624,56 +741,16 @@ gst_buffer_list_iterator_do_data (GstBufferListIterator * it, g_assert (it->last_returned->data != GROUP_START); buffer = gst_buffer_list_iterator_steal (it); - buffer = do_func (buffer, data); + buffer = do_func (buffer, user_data); if (buffer == NULL) { gst_buffer_list_iterator_remove (it); } else { gst_buffer_list_iterator_take (it, buffer); } - if (data_notify != NULL) { - data_notify (data); - } - return buffer; } -static GstBuffer * -do_func_no_data (GstBuffer * buffer, GstBufferListDoFunction do_func) -{ - return do_func (buffer); -} - -/** - * gst_buffer_list_iterator_do: - * @it: a #GstBufferListIterator - * @do_func: the function to be called - * - * Calls the given function for the last buffer returned by - * gst_buffer_list_iterator_next(). gst_buffer_list_iterator_next() must have - * been called on @it before this function is called. - * gst_buffer_list_iterator_remove() or gst_buffer_list_iterator_steal() must - * not have been called since the last call to gst_buffer_list_iterator_next(). - * - * See #GstBufferListDoFunction for more details. - * - * Returns: the return value from @do_func - */ -GstBuffer * -gst_buffer_list_iterator_do (GstBufferListIterator * it, - GstBufferListDoFunction do_func) -{ - g_return_val_if_fail (it != NULL, NULL); - g_return_val_if_fail (it->last_returned != NULL, NULL); - g_return_val_if_fail (it->last_returned->data != STOLEN, NULL); - g_return_val_if_fail (do_func != NULL, NULL); - g_return_val_if_fail (gst_buffer_list_is_writable (it->list), NULL); - g_assert (it->last_returned->data != GROUP_START); - - return gst_buffer_list_iterator_do_data (it, - (GstBufferListDoDataFunction) do_func_no_data, do_func, NULL); -} - /** * gst_buffer_list_iterator_merge_group: * @it: a #GstBufferListIterator diff --git a/gst/gstbufferlist.h b/gst/gstbufferlist.h index 5e3385ef5..392b338ad 100644 --- a/gst/gstbufferlist.h +++ b/gst/gstbufferlist.h @@ -42,6 +42,7 @@ typedef struct _GstBufferListIterator GstBufferListIterator; /** * GstBufferListDoFunction: * @buffer: the #GstBuffer + * @user_data: user data * * A function for accessing the last buffer returned by * gst_buffer_list_iterator_next(). The function can leave @buffer in the list, @@ -58,29 +59,49 @@ typedef struct _GstBufferListIterator GstBufferListIterator; * Returns: the buffer to replace @buffer in the list, or NULL to remove @buffer * from the list */ -typedef GstBuffer* (*GstBufferListDoFunction) (GstBuffer * buffer); +typedef GstBuffer* (*GstBufferListDoFunction) (GstBuffer * buffer, gpointer user_data); /** - * GstBufferListDoDataFunction: - * @buffer: the #GstBuffer - * @data: the gpointer to optional user data. - * - * A function for accessing the last buffer returned by - * gst_buffer_list_iterator_next(). The function can leave @buffer in the list, - * replace @buffer in the list or remove @buffer from the list, depending on - * the return value. If the function returns NULL, @buffer will be removed from - * the list, otherwise @buffer will be replaced with the returned buffer. - * - * The last buffer returned by gst_buffer_list_iterator_next() will be replaced - * with the buffer returned from the function. The function takes ownership of - * @buffer and if a different value than @buffer is returned, @buffer must be - * unreffed. If NULL is returned, the buffer will be removed from the list. The - * list must be writable. + * GstBufferListItem: + * @GST_BUFFER_LIST_CONTINUE: Retrieve next buffer + * @GST_BUFFER_LIST_SKIP_GROUP: Skip to next group + * @GST_BUFFER_LIST_REMOVE: Remove the current buffer + * @GST_BUFFER_LIST_END: End iteration * - * Returns: the buffer to replace @buffer in the list, or NULL to remove @buffer - * from the list + * The result of the #GstBufferListFunc. */ -typedef GstBuffer* (*GstBufferListDoDataFunction) (GstBuffer * buffer, gpointer data); +typedef enum { + GST_BUFFER_LIST_CONTINUE, + GST_BUFFER_LIST_SKIP_GROUP, + GST_BUFFER_LIST_END +} GstBufferListItem; + +/** + * GstBufferListFunc: + * @buffer: pointer the buffer + * @group: the group index of @buffer + * @idx: the index in @group of @buffer + * @user_data: user data passed to gst_buffer_list_foreach() + * + * A function that will be called from gst_buffer_list_foreach(). The @buffer + * field will point to a the reference of the buffer at @idx in @group. + * + * When this function returns #GST_BUFFER_LIST_CONTINUE, the next buffer will be + * returned. When #GST_BUFFER_LIST_SKIP_GROUP is returned, all remaining buffers + * in the current group will be skipped and the first buffer of the next group + * is returned (if any). When GST_BUFFER_LIST_END is returned, + * gst_buffer_list_foreach() will return. + * + * When @buffer is set to NULL, the item will be removed from the bufferlist. + * When @buffer has been made writable, the new buffer reference can be assigned + * to @buffer. This function is responsible for unreffing the old buffer when + * removing or modifying. + * + * Returns: a #GstBufferListItem + */ +typedef GstBufferListItem (*GstBufferListFunc) (GstBuffer **buffer, guint group, guint idx, + gpointer user_data); + GType gst_buffer_list_get_type (void); @@ -170,6 +191,11 @@ gst_buffer_list_copy (const GstBufferList * list) guint gst_buffer_list_n_groups (GstBufferList *list); +void gst_buffer_list_foreach (GstBufferList *list, + GstBufferListFunc func, + gpointer user_data); +GstBuffer * gst_buffer_list_get (GstBufferList *list, guint group, guint idx); + /* iterator */ GstBufferListIterator * gst_buffer_list_iterate (GstBufferList *list); void gst_buffer_list_iterator_free (GstBufferListIterator *it); @@ -184,9 +210,8 @@ void gst_buffer_list_iterator_remove (GstBufferListIte GstBuffer * gst_buffer_list_iterator_steal (GstBufferListIterator *it); void gst_buffer_list_iterator_take (GstBufferListIterator *it, GstBuffer *buffer); -GstBuffer * gst_buffer_list_iterator_do (GstBufferListIterator *it, GstBufferListDoFunction do_func); -GstBuffer * gst_buffer_list_iterator_do_data (GstBufferListIterator *it, GstBufferListDoDataFunction do_func, - gpointer data, GDestroyNotify data_notify); +GstBuffer * gst_buffer_list_iterator_do (GstBufferListIterator *it, GstBufferListDoFunction do_func, + gpointer user_data); /* conversion */ GstBuffer * gst_buffer_list_iterator_merge_group (const GstBufferListIterator *it); |