Merge branch 'master' into 0.11
[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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, 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_take().
32  *
33  */
34 #include "gst_private.h"
35
36 #include "gstbuffer.h"
37 #include "gstbufferlist.h"
38
39 #define GST_CAT_DEFAULT GST_CAT_BUFFER_LIST
40
41 /**
42  * GstBufferList:
43  * @mini_object: the parent structure
44  *
45  * Opaque list of grouped buffers.
46  *
47  * Since: 0.10.24
48  */
49 struct _GstBufferList
50 {
51   GstMiniObject mini_object;
52
53   GArray *array;
54 };
55
56 GType _gst_buffer_list_type = 0;
57
58 void
59 _gst_buffer_list_initialize (void)
60 {
61   if (G_LIKELY (_gst_buffer_list_type == 0)) {
62     _gst_buffer_list_type = gst_mini_object_register ("GstBufferList");
63   }
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_sized_new (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 (GST_MINI_OBJECT_SIZE (list), list);
97 }
98
99 static void
100 gst_buffer_list_init (GstBufferList * list, gsize size, guint asize)
101 {
102   gst_mini_object_init (GST_MINI_OBJECT_CAST (list), _gst_buffer_list_type,
103       size);
104
105   list->mini_object.copy = (GstMiniObjectCopyFunction) _gst_buffer_list_copy;
106   list->mini_object.free = (GstMiniObjectFreeFunction) _gst_buffer_list_free;
107
108   list->array = g_array_sized_new (FALSE, FALSE, sizeof (GstBuffer *), asize);
109
110   GST_LOG ("init %p", list);
111 }
112
113 /**
114  * gst_buffer_list_sized_new:
115  * @size: an initial reserved size
116  *
117  * Creates a new, empty #GstBufferList. The caller is responsible for unreffing
118  * the returned #GstBufferList. The list will have @size space preallocated so
119  * that memory reallocations can be avoided.
120  *
121  * Free-function: gst_buffer_list_unref
122  *
123  * Returns: (transfer full): the new #GstBufferList. gst_buffer_list_unref()
124  *     after usage.
125  *
126  * Since: 0.10.24
127  */
128 GstBufferList *
129 gst_buffer_list_sized_new (guint size)
130 {
131   GstBufferList *list;
132
133   list = g_slice_new0 (GstBufferList);
134
135   GST_LOG ("new %p", list);
136
137   gst_buffer_list_init (list, sizeof (GstBufferList), size);
138
139   return list;
140 }
141
142 /**
143  * gst_buffer_list_new:
144  *
145  * Creates a new, empty #GstBufferList. The caller is responsible for unreffing
146  * the returned #GstBufferList.
147  *
148  * Free-function: gst_buffer_list_unref
149  *
150  * Returns: (transfer full): the new #GstBufferList. gst_buffer_list_unref()
151  *     after usage.
152  *
153  * Since: 0.10.24
154  */
155 GstBufferList *
156 gst_buffer_list_new (void)
157 {
158   return gst_buffer_list_sized_new (8);
159 }
160
161 /**
162  * gst_buffer_list_len:
163  * @list: a #GstBufferList
164  *
165  * Returns the number of buffers in @list.
166  *
167  * Returns: the number of buffers in the buffer list
168  *
169  * Since: 0.10.24
170  */
171 guint
172 gst_buffer_list_len (GstBufferList * list)
173 {
174   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 0);
175
176   return list->array->len;
177 }
178
179 /**
180  * gst_buffer_list_foreach:
181  * @list: a #GstBufferList
182  * @func: (scope call): a #GstBufferListFunc to call
183  * @user_data: user data passed to @func
184  *
185  * Call @func with @data for each buffer in @list.
186  *
187  * @func can modify the passed buffer pointer or its contents. The return value
188  * of @func define if this function returns or if the remaining buffers in a
189  * group should be skipped.
190  *
191  * Since: 0.10.24
192  */
193 void
194 gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
195     gpointer user_data)
196 {
197 }
198
199 /**
200  * gst_buffer_list_get:
201  * @list: a #GstBufferList
202  * @idx: the index
203  *
204  * Get the buffer at @idx.
205  *
206  * Returns: (transfer none): the buffer at @idx in @group or NULL when there
207  *     is no buffer. The buffer remains valid as long as @list is valid.
208  *
209  * Since: 0.10.24
210  */
211 GstBuffer *
212 gst_buffer_list_get (GstBufferList * list, guint idx)
213 {
214   GstBuffer *buf;
215
216   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
217   g_return_val_if_fail (idx < list->array->len, NULL);
218
219   buf = g_array_index (list->array, GstBuffer *, idx);
220
221   return buf;
222 }
223
224 /**
225  * gst_buffer_list_insert:
226  * @list: a #GstBufferList
227  * @idx: the index
228  * @buffer: a #GstBuffer
229  *
230  * Insert @buffer at @idx in @list. Other buffers are moved to make room for
231  * this new buffer.
232  *
233  * A -1 value for @idx will append the buffer at the end.
234  */
235 void
236 gst_buffer_list_insert (GstBufferList * list, guint idx, GstBuffer * buffer)
237 {
238   g_return_if_fail (GST_IS_BUFFER_LIST (list));
239   g_return_if_fail (buffer != NULL);
240
241   if (idx == -1)
242     g_array_append_val (list->array, buffer);
243   else {
244     g_return_if_fail (idx < list->array->len);
245     g_array_insert_val (list->array, idx, buffer);
246   }
247 }
248
249 void
250 gst_buffer_list_remove (GstBufferList * list, guint idx, guint length)
251 {
252   g_return_if_fail (GST_IS_BUFFER_LIST (list));
253   g_return_if_fail (idx < list->array->len);
254
255   g_array_remove_range (list->array, idx, length);
256 }