introspection: Assorted minor introspection and documentation fixes
[platform/upstream/gstreamer.git] / gst / gstbufferlist.c
1 /* GStreamer
2  * Copyright (C) 2009 Axis Communications <dev-gstreamer at axis dot com>
3  * @author Jonas Holmberg <jonas dot holmberg at axis dot com>
4  *
5  * gstbufferlist.c: Buffer list
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /**
24  * SECTION:gstbufferlist
25  * @short_description: Lists of buffers for data-passing
26  * @see_also: #GstPad, #GstMiniObject
27  *
28  * Buffer lists are an object containing a list of buffers.
29  *
30  * Buffer lists are created with gst_buffer_list_new() and filled with data
31  * using a gst_buffer_list_insert().
32  *
33  * Buffer lists can be pushed on a srcpad with gst_pad_push_list(). This is
34  * interesting when multiple buffers need to be pushed in one go because it
35  * can reduce the amount of overhead for pushing each buffer individually.
36  */
37 #include "gst_private.h"
38
39 #include "gstbuffer.h"
40 #include "gstbufferlist.h"
41
42 #define GST_CAT_DEFAULT GST_CAT_BUFFER_LIST
43
44 /**
45  * GstBufferList:
46  *
47  * Opaque list of grouped buffers.
48  */
49 struct _GstBufferList
50 {
51   GstMiniObject mini_object;
52
53   GArray *array;
54 };
55
56 GType _gst_buffer_list_type = 0;
57
58 GST_DEFINE_MINI_OBJECT_TYPE (GstBufferList, gst_buffer_list);
59
60 void
61 _priv_gst_buffer_list_initialize (void)
62 {
63   _gst_buffer_list_type = gst_buffer_list_get_type ();
64 }
65
66 static GstBufferList *
67 _gst_buffer_list_copy (GstBufferList * list)
68 {
69   GstBufferList *copy;
70   guint i, len;
71
72   len = list->array->len;
73   copy = gst_buffer_list_new_sized (len);
74
75   /* add and ref all buffers in the array */
76   for (i = 0; i < len; i++) {
77     GstBuffer *buf = g_array_index (list->array, GstBuffer *, i);
78     buf = gst_buffer_ref (buf);
79     g_array_append_val (copy->array, buf);
80   }
81   return copy;
82 }
83
84 static void
85 _gst_buffer_list_free (GstBufferList * list)
86 {
87   guint i, len;
88   GST_LOG ("free %p", list);
89
90   /* unrefs all buffers too */
91   len = list->array->len;
92   for (i = 0; i < len; i++)
93     gst_buffer_unref (g_array_index (list->array, GstBuffer *, i));
94   g_array_free (list->array, TRUE);
95
96   g_slice_free1 (sizeof (GstBufferList), list);
97 }
98
99 static void
100 gst_buffer_list_init (GstBufferList * list, guint asize)
101 {
102   gst_mini_object_init (GST_MINI_OBJECT_CAST (list), 0, _gst_buffer_list_type,
103       (GstMiniObjectCopyFunction) _gst_buffer_list_copy, NULL,
104       (GstMiniObjectFreeFunction) _gst_buffer_list_free);
105
106   list->array = g_array_sized_new (FALSE, FALSE, sizeof (GstBuffer *), asize);
107
108   GST_LOG ("init %p", list);
109 }
110
111 /**
112  * gst_buffer_list_new_sized:
113  * @size: an initial reserved size
114  *
115  * Creates a new, empty #GstBufferList. The caller is responsible for unreffing
116  * the returned #GstBufferList. The list will have @size space preallocated so
117  * that memory reallocations can be avoided.
118  *
119  * Free-function: gst_buffer_list_unref
120  *
121  * Returns: (transfer full): the new #GstBufferList. gst_buffer_list_unref()
122  *     after usage.
123  */
124 GstBufferList *
125 gst_buffer_list_new_sized (guint size)
126 {
127   GstBufferList *list;
128
129   list = g_slice_new0 (GstBufferList);
130
131   GST_LOG ("new %p", list);
132
133   gst_buffer_list_init (list, size);
134
135   return list;
136 }
137
138 /**
139  * gst_buffer_list_new:
140  *
141  * Creates a new, empty #GstBufferList. The caller is responsible for unreffing
142  * the returned #GstBufferList.
143  *
144  * Free-function: gst_buffer_list_unref
145  *
146  * Returns: (transfer full): the new #GstBufferList. gst_buffer_list_unref()
147  *     after usage.
148  */
149 GstBufferList *
150 gst_buffer_list_new (void)
151 {
152   return gst_buffer_list_new_sized (8);
153 }
154
155 /**
156  * gst_buffer_list_length:
157  * @list: a #GstBufferList
158  *
159  * Returns the number of buffers in @list.
160  *
161  * Returns: the number of buffers in the buffer list
162  */
163 guint
164 gst_buffer_list_length (GstBufferList * list)
165 {
166   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 0);
167
168   return list->array->len;
169 }
170
171 /**
172  * gst_buffer_list_foreach:
173  * @list: a #GstBufferList
174  * @func: (scope call): a #GstBufferListFunc to call
175  * @user_data: (closure): user data passed to @func
176  *
177  * Call @func with @data for each buffer in @list.
178  *
179  * @func can modify the passed buffer pointer or its contents. The return value
180  * of @func define if this function returns or if the remaining buffers in
181  * the list should be skipped.
182  *
183  * Returns: %TRUE when @func returned %TRUE for each buffer in @list or when
184  * @list is empty.
185  */
186 gboolean
187 gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
188     gpointer user_data)
189 {
190   guint i, len;
191   gboolean ret = TRUE;
192
193   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
194   g_return_val_if_fail (func != NULL, FALSE);
195
196   len = list->array->len;
197   for (i = 0; i < len;) {
198     GstBuffer *buf, *buf_ret;
199
200     buf = buf_ret = g_array_index (list->array, GstBuffer *, i);
201     ret = func (&buf_ret, i, user_data);
202
203     /* Check if the function changed the buffer */
204     if (buf != buf_ret) {
205       if (buf_ret == NULL) {
206         g_array_remove_index (list->array, i);
207         len--;
208       } else {
209         g_array_index (list->array, GstBuffer *, i) = buf_ret;
210       }
211     }
212
213     if (!ret)
214       break;
215
216     /* If the buffer was not removed by func go to the next buffer */
217     if (buf_ret != NULL)
218       i++;
219   }
220   return ret;
221 }
222
223 /**
224  * gst_buffer_list_get:
225  * @list: a #GstBufferList
226  * @idx: the index
227  *
228  * Get the buffer at @idx.
229  *
230  * Returns: (transfer none) (nullable): the buffer at @idx in @group
231  *     or %NULL when there is no buffer. The buffer remains valid as
232  *     long as @list is valid.
233  */
234 GstBuffer *
235 gst_buffer_list_get (GstBufferList * list, guint idx)
236 {
237   GstBuffer *buf;
238
239   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
240   g_return_val_if_fail (idx < list->array->len, NULL);
241
242   buf = g_array_index (list->array, GstBuffer *, idx);
243
244   return buf;
245 }
246
247 /**
248  * gst_buffer_list_add:
249  * @l: a #GstBufferList
250  * @b: a #GstBuffer
251  *
252  * Append @b at the end of @l.
253  */
254 /**
255  * gst_buffer_list_insert:
256  * @list: a #GstBufferList
257  * @idx: the index
258  * @buffer: (transfer full): a #GstBuffer
259  *
260  * Insert @buffer at @idx in @list. Other buffers are moved to make room for
261  * this new buffer.
262  *
263  * A -1 value for @idx will append the buffer at the end.
264  */
265 void
266 gst_buffer_list_insert (GstBufferList * list, gint idx, GstBuffer * buffer)
267 {
268   g_return_if_fail (GST_IS_BUFFER_LIST (list));
269   g_return_if_fail (buffer != NULL);
270
271   if (idx == -1)
272     g_array_append_val (list->array, buffer);
273   else {
274     g_return_if_fail (idx < list->array->len);
275     g_array_insert_val (list->array, idx, buffer);
276   }
277 }
278
279 /**
280  * gst_buffer_list_remove:
281  * @list: a #GstBufferList
282  * @idx: the index
283  * @length: the amount to remove
284  *
285  * Remove @length buffers starting from @idx in @list. The following buffers
286  * are moved to close the gap.
287  */
288 void
289 gst_buffer_list_remove (GstBufferList * list, guint idx, guint length)
290 {
291   GstBuffer *buf;
292   gint i;
293
294   g_return_if_fail (GST_IS_BUFFER_LIST (list));
295   g_return_if_fail (idx < list->array->len);
296
297   for (i = idx; i < idx + length; ++i) {
298     buf = g_array_index (list->array, GstBuffer *, i);
299     gst_buffer_unref (buf);
300   }
301   g_array_remove_range (list->array, idx, length);
302 }