summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-06-19 15:29:14 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2009-06-19 15:31:53 +0200
commit6438f6f9b9edd3b4a014f5fd251b4b399ec6bce7 (patch)
tree6623ec3542b8412412f5d46f25e7f0652119bba5 /gst
parent17f794deebc36d284c82a9022cf2fd417a5d9df0 (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.c183
-rw-r--r--gst/gstbufferlist.h69
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);