tests: add test for gst_buffer_list_remove()
[platform/upstream/gstreamer.git] / tests / check / gst / gstbufferlist.c
1 /* GStreamer
2  *
3  * unit test for GstBufferList
4  *
5  * Copyright (C) 2009 Axis Communications <dev-gstreamer at axis dot com>
6  * @author Jonas Holmberg <jonas dot holmberg at axis dot com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include <gst/check/gstcheck.h>
25 #include <gst/gstbufferlist.h>
26 #include <string.h>
27
28 #define TIMESTAMP 42
29
30 static GstBufferList *list;
31 static GstCaps *caps;
32
33 static void
34 setup (void)
35 {
36   list = gst_buffer_list_new ();
37   caps = gst_caps_new_empty_simple ("text/plain");
38 }
39
40 static void
41 cleanup (void)
42 {
43   gst_caps_unref (caps);
44   gst_buffer_list_unref (list);
45 }
46
47 #if 0
48 static GstBuffer *
49 buffer_from_string (const gchar * str)
50 {
51   gsize size;
52   GstBuffer *buf;
53   gpointer data;
54
55   size = strlen (str);
56   buf = gst_buffer_new_and_alloc (size);
57   gst_buffer_set_caps (buf, caps);
58   GST_BUFFER_TIMESTAMP (buf) = TIMESTAMP;
59
60   data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
61   memcpy (data, str, size);
62   gst_buffer_unmap (buf, data, size);
63
64   return buf;
65 }
66
67 static void
68 check_buffer (GstBuffer * buf, gsize size, const gchar * data)
69 {
70   gchar *bdata;
71   gsize bsize, csize, msize;
72
73   bdata = gst_buffer_map (buf, &bsize, &msize, GST_MAP_READ);
74   csize = size ? size : bsize;
75   GST_DEBUG ("%lu %lu %lu", bsize, csize, msize);
76   fail_unless (bsize == csize);
77   fail_unless (memcmp (bdata, data, csize) == 0);
78   gst_buffer_unmap (buf, bdata, bsize);
79 }
80 #endif
81
82 GST_START_TEST (test_add_and_iterate)
83 {
84   GstBuffer *buf1;
85   GstBuffer *buf2;
86
87   /* buffer list is initially empty */
88   fail_unless (gst_buffer_list_length (list) == 0);
89
90   ASSERT_CRITICAL (gst_buffer_list_insert (list, 0, NULL));
91   ASSERT_CRITICAL (gst_buffer_list_insert (NULL, 0, NULL));
92
93   buf1 = gst_buffer_new ();
94
95   /* add a group of 2 buffers */
96   fail_unless (gst_buffer_list_length (list) == 0);
97   ASSERT_CRITICAL (gst_buffer_list_insert (list, -1, NULL));
98   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);
99   gst_buffer_list_add (list, buf1);
100   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);     /* list takes ownership */
101   fail_unless (gst_buffer_list_length (list) == 1);
102   buf2 = gst_buffer_new ();
103   gst_buffer_list_add (list, buf2);
104   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1);
105   fail_unless (gst_buffer_list_length (list) == 2);
106 }
107
108 GST_END_TEST;
109
110 GST_START_TEST (test_remove)
111 {
112   GstBuffer *buf;
113
114   /* buffer list is initially empty */
115   fail_unless (gst_buffer_list_length (list) == 0);
116
117   buf = gst_buffer_new ();
118
119   /* add our own ref so it stays alive after removal from the list */
120   buf = gst_buffer_ref (buf);
121
122   /* add a buffer */
123   fail_unless (gst_buffer_list_length (list) == 0);
124   ASSERT_CRITICAL (gst_buffer_list_insert (list, -1, NULL));
125   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
126   gst_buffer_list_add (list, buf);
127   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);       /* list takes ownership */
128   fail_unless (gst_buffer_list_length (list) == 1);
129   gst_buffer_list_remove (list, 0, 1);
130   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
131   gst_buffer_unref (buf);
132   fail_unless (gst_buffer_list_length (list) == 0);
133 }
134
135 GST_END_TEST;
136
137 #if 0
138 GST_START_TEST (test_make_writable)
139 {
140   GstBufferListIterator *it;
141   GstBufferList *wlist;
142   GstBuffer *buf1;
143   GstBuffer *buf2;
144   GstBuffer *buf3;
145   GstBuffer *buf;
146
147   /* add buffers to list */
148   it = gst_buffer_list_iterate (list);
149   gst_buffer_list_iterator_add_group (it);
150   buf1 = gst_buffer_new_and_alloc (1);
151   gst_buffer_list_iterator_add (it, buf1);
152   gst_buffer_list_iterator_add_group (it);
153   buf2 = gst_buffer_new_and_alloc (2);
154   gst_buffer_list_iterator_add (it, buf2);
155   buf3 = gst_buffer_new_and_alloc (3);
156   gst_buffer_list_iterator_add (it, buf3);
157   gst_buffer_list_iterator_free (it);
158
159   /* making it writable with refcount 1 returns the same list */
160   wlist = gst_buffer_list_make_writable (list);
161   fail_unless (wlist == list);
162   it = gst_buffer_list_iterate (list);
163   fail_unless (gst_buffer_list_iterator_next_group (it));
164   buf = gst_buffer_list_iterator_next (it);
165   fail_unless (buf == buf1);
166   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);
167   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
168   fail_unless (gst_buffer_list_iterator_next_group (it));
169   buf = gst_buffer_list_iterator_next (it);
170   fail_unless (buf == buf2);
171   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1);
172   buf = gst_buffer_list_iterator_next (it);
173   fail_unless (buf == buf3);
174   ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 1);
175   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
176   fail_if (gst_buffer_list_iterator_next_group (it));
177   gst_buffer_list_iterator_free (it);
178
179   /* making it writable with refcount 2 returns a copy of the list with
180    * increased refcount on the buffers in the list */
181   gst_buffer_list_ref (list);
182   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list) == 2);
183   wlist = gst_buffer_list_make_writable (list);
184   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list) == 1);
185   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (wlist) == 1);
186   fail_unless (wlist != list);
187   it = gst_buffer_list_iterate (wlist);
188   fail_unless (gst_buffer_list_iterator_next_group (it));
189   buf = gst_buffer_list_iterator_next (it);
190   fail_unless (buf == buf1);
191   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2);
192   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
193   fail_unless (gst_buffer_list_iterator_next_group (it));
194   buf = gst_buffer_list_iterator_next (it);
195   fail_unless (buf == buf2);
196   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2);
197   buf = gst_buffer_list_iterator_next (it);
198   fail_unless (buf == buf3);
199   ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 2);
200   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
201   fail_if (gst_buffer_list_iterator_next_group (it));
202   gst_buffer_list_iterator_free (it);
203   gst_buffer_list_unref (wlist);
204 }
205
206 GST_END_TEST;
207
208 GST_START_TEST (test_copy)
209 {
210   GstBufferListIterator *it;
211   GstBufferList *list_copy;
212   GstBuffer *buf1;
213   GstBuffer *buf2;
214   GstBuffer *buf3;
215   GstBuffer *buf;
216
217   /* add buffers to the list */
218   it = gst_buffer_list_iterate (list);
219   gst_buffer_list_iterator_add_group (it);
220   buf1 = gst_buffer_new ();
221   gst_buffer_list_iterator_add (it, buf1);
222   gst_buffer_list_iterator_add_group (it);
223   buf2 = gst_buffer_new ();
224   gst_buffer_list_iterator_add (it, buf2);
225   buf3 = gst_buffer_new ();
226   gst_buffer_list_iterator_add (it, buf3);
227   gst_buffer_list_iterator_free (it);
228
229   /* make a copy */
230   list_copy = gst_buffer_list_copy (list);
231   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list) == 1);
232   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list_copy) == 1);
233   fail_unless (list_copy != list);
234   it = gst_buffer_list_iterate (list_copy);
235   fail_unless (gst_buffer_list_iterator_next_group (it));
236   buf = gst_buffer_list_iterator_next (it);
237   fail_unless (buf == buf1);
238   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2);
239   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
240   fail_unless (gst_buffer_list_iterator_next_group (it));
241   buf = gst_buffer_list_iterator_next (it);
242   fail_unless (buf == buf2);
243   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2);
244   buf = gst_buffer_list_iterator_next (it);
245   fail_unless (buf == buf3);
246   ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 2);
247   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
248   fail_if (gst_buffer_list_iterator_next_group (it));
249   gst_buffer_list_iterator_free (it);
250   gst_buffer_list_unref (list_copy);
251 }
252
253 GST_END_TEST;
254
255 GST_START_TEST (test_steal)
256 {
257   GstBufferListIterator *it;
258   GstBuffer *buf1;
259   GstBuffer *buf2;
260   GstBuffer *buf3;
261   GstBuffer *buf;
262
263   /* add buffers to the list */
264   it = gst_buffer_list_iterate (list);
265   gst_buffer_list_iterator_add_group (it);
266   buf1 = gst_buffer_new ();
267   gst_buffer_list_iterator_add (it, buf1);
268   gst_buffer_list_iterator_add_group (it);
269   buf2 = gst_buffer_new ();
270   gst_buffer_list_iterator_add (it, buf2);
271   buf3 = gst_buffer_new ();
272   gst_buffer_list_iterator_add (it, buf3);
273   gst_buffer_list_iterator_free (it);
274
275   /* check some error handling */
276   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (NULL)));
277   fail_unless (buf == NULL);
278   it = gst_buffer_list_iterate (list);
279   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
280   fail_unless (buf == NULL);
281
282   /* steal the first buffer */
283   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
284   fail_unless (gst_buffer_list_iterator_next_group (it));
285   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
286   fail_unless (gst_buffer_list_iterator_next (it) == buf1);
287   buf = gst_buffer_list_iterator_steal (it);
288   fail_unless (buf == buf1);
289   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
290   gst_buffer_unref (buf);
291   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
292   fail_unless (buf == NULL);
293
294   /* steal the second buffer */
295   fail_unless (gst_buffer_list_iterator_next_group (it));
296   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
297   fail_unless (gst_buffer_list_iterator_next (it) == buf2);
298   buf = gst_buffer_list_iterator_steal (it);
299   fail_unless (buf == buf2);
300   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
301   gst_buffer_unref (buf);
302   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
303
304   /* steal the third buffer */
305   fail_unless (gst_buffer_list_iterator_next (it) == buf3);
306   buf = gst_buffer_list_iterator_steal (it);
307   fail_unless (buf == buf3);
308   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
309   gst_buffer_unref (buf);
310   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it)));
311
312   gst_buffer_list_iterator_free (it);
313
314   /* iterate again when all buffers have been stolen */
315   it = gst_buffer_list_iterate (list);
316   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
317   fail_unless (gst_buffer_list_iterator_next_group (it));
318   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
319   fail_unless (gst_buffer_list_iterator_next_group (it));
320   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
321   fail_if (gst_buffer_list_iterator_next_group (it));
322   gst_buffer_list_iterator_free (it);
323 }
324
325 GST_END_TEST;
326
327 GST_START_TEST (test_take)
328 {
329   GstBufferListIterator *it;
330   GstBuffer *buf1;
331   GstBuffer *buf2;
332   GstBuffer *buf3;
333   GstBuffer *buf;
334
335   /* add buffers to the list */
336   it = gst_buffer_list_iterate (list);
337   gst_buffer_list_iterator_add_group (it);
338   buf1 = gst_buffer_new ();
339   gst_buffer_ref (buf1);
340   gst_buffer_list_iterator_add (it, buf1);
341   gst_buffer_list_iterator_add_group (it);
342   buf2 = gst_buffer_new ();
343   gst_buffer_ref (buf2);
344   gst_buffer_list_iterator_add (it, buf2);
345   buf3 = gst_buffer_new ();
346   gst_buffer_ref (buf3);
347   gst_buffer_list_iterator_add (it, buf3);
348   gst_buffer_list_iterator_free (it);
349
350   /* check some error handling */
351   ASSERT_CRITICAL (gst_buffer_list_iterator_take (NULL, NULL));
352   it = gst_buffer_list_iterate (list);
353   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, NULL));
354   buf = gst_buffer_new ();
355   gst_buffer_ref (buf);
356   ASSERT_CRITICAL (gst_buffer_list_iterator_take (NULL, buf));
357   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
358
359   /* replace the first buffer */
360   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf));
361   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
362   fail_unless (gst_buffer_list_iterator_next_group (it));
363   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf));
364   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
365   fail_unless (gst_buffer_list_iterator_next (it) == buf1);
366   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, NULL));
367   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2);
368   gst_buffer_list_iterator_take (it, buf);
369   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
370   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);
371   gst_buffer_unref (buf1);
372
373   /* replace the first buffer again, with itself */
374   gst_buffer_ref (buf);
375   gst_buffer_list_iterator_take (it, buf);
376   ASSERT_BUFFER_REFCOUNT (buf, "buf", 2);
377
378   /* replace the second buffer */
379   gst_buffer_ref (buf);
380   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
381   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf));
382   ASSERT_BUFFER_REFCOUNT (buf, "buf", 3);
383   fail_unless (gst_buffer_list_iterator_next_group (it));
384   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2);
385   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf));
386   ASSERT_BUFFER_REFCOUNT (buf, "buf", 3);
387   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2);
388   fail_unless (gst_buffer_list_iterator_next (it) == buf2);
389   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, NULL));
390   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2);
391   gst_buffer_list_iterator_take (it, buf);
392   ASSERT_BUFFER_REFCOUNT (buf, "buf", 3);
393   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1);
394   gst_buffer_unref (buf2);
395
396   /* replace the third buffer */
397   gst_buffer_ref (buf);
398   fail_unless (gst_buffer_list_iterator_next (it) == buf3);
399   ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 2);
400   gst_buffer_list_iterator_take (it, buf);
401   ASSERT_BUFFER_REFCOUNT (buf, "buf", 4);
402   ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 1);
403   gst_buffer_unref (buf3);
404   fail_if (gst_buffer_list_iterator_next_group (it));
405   ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf));
406   ASSERT_BUFFER_REFCOUNT (buf, "buf", 4);
407   gst_buffer_unref (buf);
408
409   gst_buffer_list_iterator_free (it);
410 }
411
412 GST_END_TEST;
413
414 static gpointer do_data_func_data;
415 static gboolean notified;
416
417 static GstBuffer *
418 do_data_func (GstBuffer * buffer, gpointer data)
419 {
420   do_data_func_data = data;
421   fail_if (notified);
422
423   return buffer;
424 }
425
426 static GstBuffer *
427 do_func_null (GstBuffer * buffer)
428 {
429   gst_buffer_unref (buffer);
430
431   return NULL;
432 }
433
434 GST_START_TEST (test_do)
435 {
436   GstBufferListIterator *it;
437   GstBuffer *buf1;
438   GstBuffer *buf;
439   gchar *data;
440
441   /* error handling */
442   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (NULL, NULL, NULL)));
443   fail_unless (buf == NULL);
444   fail_unless (buf == NULL);
445   it = gst_buffer_list_iterate (list);
446   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (it, NULL, NULL)));
447   fail_unless (buf == NULL);
448   fail_unless (buf == NULL);
449
450   /* add buffers to the list */
451   gst_buffer_list_iterator_add_group (it);
452   buf1 = gst_buffer_new ();
453   gst_buffer_ref (buf1);
454   gst_buffer_list_iterator_add (it, buf1);
455   gst_buffer_list_iterator_add_group (it);
456   gst_buffer_list_iterator_free (it);
457
458   /* call do-function */
459   it = gst_buffer_list_iterate (list);
460   fail_unless (gst_buffer_list_iterator_next_group (it));
461   ASSERT_CRITICAL ((buf =
462           gst_buffer_list_iterator_do (it,
463               (GstBufferListDoFunction) gst_buffer_ref, NULL)));
464   fail_unless (buf == NULL);
465   data = (char *) "data";
466   ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (it, do_data_func,
467               data)));
468   fail_unless (buf == NULL);
469   fail_unless (do_data_func_data != data);
470   buf = gst_buffer_list_iterator_next (it);
471   fail_unless (buf == buf1);
472   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2);
473   buf =
474       gst_buffer_list_iterator_do (it, (GstBufferListDoFunction) gst_buffer_ref,
475       NULL);
476   fail_unless (buf == buf1);
477   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 3);
478   gst_buffer_unref (buf);
479   buf = gst_buffer_list_iterator_do (it, do_data_func, data);
480   fail_unless (buf == buf1);
481   fail_unless (do_data_func_data == data);
482
483   /* do-function that return a new buffer replaces the buffer in the list */
484   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2);
485   buf = gst_buffer_list_iterator_do (it,
486       (GstBufferListDoFunction) gst_mini_object_make_writable, NULL);
487   fail_unless (buf != buf1);
488   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
489   ASSERT_BUFFER_REFCOUNT (buf, "buf1", 1);
490   gst_buffer_replace (&buf1, buf);
491
492   /* do-function that return NULL removes the buffer from the list */
493   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2);
494   fail_unless (gst_buffer_list_iterator_do (it,
495           (GstBufferListDoFunction) do_func_null, NULL) == NULL);
496   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);
497   ASSERT_CRITICAL ((buf =
498           gst_buffer_list_iterator_do (it,
499               (GstBufferListDoFunction) gst_buffer_ref, NULL)));
500   fail_unless (buf == NULL);
501   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
502   gst_buffer_list_iterator_free (it);
503   it = gst_buffer_list_iterate (list);
504   fail_unless (gst_buffer_list_iterator_next_group (it));
505   fail_unless (gst_buffer_list_iterator_next (it) == NULL);
506   fail_if (gst_buffer_list_iterator_next_group (it));
507   gst_buffer_list_iterator_free (it);
508   gst_buffer_unref (buf1);
509 }
510
511 GST_END_TEST;
512
513 GST_START_TEST (test_merge)
514 {
515   GstBufferListIterator *it;
516   GstBufferListIterator *merge_it;
517   GstBuffer *merged_buf;
518   GstBuffer *buf;
519
520   it = gst_buffer_list_iterate (list);
521   fail_unless (gst_buffer_list_iterator_merge_group (it) == NULL);
522
523   /* create a new group and add a buffer */
524   gst_buffer_list_iterator_add_group (it);
525   fail_unless (gst_buffer_list_iterator_merge_group (it) == NULL);
526   buf = buffer_from_string ("One");
527   gst_buffer_ref (buf);
528   gst_buffer_list_iterator_add (it, buf);
529
530   /* merging a group with one buffer returns a copy of the buffer */
531   merge_it = gst_buffer_list_iterate (list);
532   fail_unless (gst_buffer_list_iterator_next_group (merge_it));
533   merged_buf = gst_buffer_list_iterator_merge_group (merge_it);
534   fail_unless (merged_buf != buf);
535   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
536   gst_buffer_unref (buf);
537   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
538   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
539   check_buffer (merged_buf, 3, "One");
540   gst_buffer_unref (merged_buf);
541
542   /* add another buffer to the same group */
543   gst_buffer_list_iterator_add (it, buffer_from_string ("Group"));
544
545   /* merging a group returns a new buffer with merged data */
546   merged_buf = gst_buffer_list_iterator_merge_group (merge_it);
547   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
548   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
549   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
550   check_buffer (merged_buf, 8, "OneGroup");
551
552   /* merging the same group again should return a new buffer with merged data */
553   buf = gst_buffer_list_iterator_merge_group (merge_it);
554   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
555   fail_unless (buf != merged_buf);
556   check_buffer (buf, 8, "OneGroup");
557   gst_buffer_unref (buf);
558   gst_buffer_unref (merged_buf);
559
560   /* add a new group */
561   gst_buffer_list_iterator_add_group (it);
562   gst_buffer_list_iterator_add (it, buffer_from_string ("AnotherGroup"));
563   gst_buffer_list_iterator_free (it);
564
565   /* merge the first group again */
566   merged_buf = gst_buffer_list_iterator_merge_group (merge_it);
567   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
568   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
569   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
570   check_buffer (merged_buf, 8, "OneGroup");
571   gst_buffer_unref (merged_buf);
572
573   /* merge the second group */
574   fail_unless (gst_buffer_list_iterator_next_group (merge_it));
575   merged_buf = gst_buffer_list_iterator_merge_group (merge_it);
576   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
577   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
578   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
579   check_buffer (merged_buf, 12, "AnotherGroup");
580   gst_buffer_unref (merged_buf);
581
582   gst_buffer_list_iterator_free (merge_it);
583
584   /* steal the second buffer and merge the first group again */
585   it = gst_buffer_list_iterate (list);
586   fail_unless (gst_buffer_list_iterator_next_group (it));
587   fail_unless (gst_buffer_list_iterator_next (it) != NULL);
588   fail_unless (gst_buffer_list_iterator_next (it) != NULL);
589   buf = gst_buffer_list_iterator_steal (it);
590   gst_buffer_list_iterator_free (it);
591   fail_unless (buf != NULL);
592   check_buffer (buf, 0, "Group");
593   gst_buffer_unref (buf);
594   merge_it = gst_buffer_list_iterate (list);
595   fail_unless (gst_buffer_list_iterator_next_group (merge_it));
596   merged_buf = gst_buffer_list_iterator_merge_group (merge_it);
597   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
598   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
599   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
600   check_buffer (merged_buf, 3, "One");
601   gst_buffer_unref (merged_buf);
602
603   /* steal the first buffer too and merge the first group again */
604   it = gst_buffer_list_iterate (list);
605   fail_unless (gst_buffer_list_iterator_next_group (it));
606   fail_unless (gst_buffer_list_iterator_next (it) != NULL);
607   buf = gst_buffer_list_iterator_steal (it);
608   fail_unless (buf != NULL);
609   check_buffer (buf, 3, "One");
610   gst_buffer_unref (buf);
611   gst_buffer_list_iterator_free (it);
612   fail_unless (gst_buffer_list_iterator_merge_group (merge_it) == NULL);
613   gst_buffer_list_iterator_free (merge_it);
614 }
615
616 GST_END_TEST;
617
618 typedef struct
619 {
620   GstBuffer *buf[3][3];
621   guint iter;
622 } ForeachData;
623
624 static GstBufferListItem
625 foreach_func1 (GstBuffer ** buffer, guint group, guint idx, ForeachData * data)
626 {
627   fail_unless (buffer != NULL);
628   fail_unless (*buffer == data->buf[group][idx]);
629
630   data->iter++;
631
632   return GST_BUFFER_LIST_CONTINUE;
633 }
634
635 static GstBufferListItem
636 foreach_func2 (GstBuffer ** buffer, guint group, guint idx, ForeachData * data)
637 {
638   fail_unless (idx == 0);
639   fail_unless (buffer != NULL);
640   fail_unless (*buffer == data->buf[group][idx]);
641
642   data->iter++;
643
644   return GST_BUFFER_LIST_SKIP_GROUP;
645 }
646
647 static GstBufferListItem
648 foreach_func3 (GstBuffer ** buffer, guint group, guint idx, ForeachData * data)
649 {
650   fail_unless (group == 0);
651   fail_unless (idx == 0);
652   fail_unless (buffer != NULL);
653   fail_unless (*buffer == data->buf[group][idx]);
654
655   data->iter++;
656
657   return GST_BUFFER_LIST_END;
658 }
659
660 static GstBufferListItem
661 foreach_func4 (GstBuffer ** buffer, guint group, guint idx, ForeachData * data)
662 {
663   fail_unless (idx == 0);
664   fail_unless (buffer != NULL);
665   fail_unless (*buffer == data->buf[group][idx]);
666
667   gst_buffer_unref (*buffer);
668   *buffer = NULL;
669   data->iter++;
670
671   return GST_BUFFER_LIST_SKIP_GROUP;
672 }
673
674 static GstBufferListItem
675 foreach_func5 (GstBuffer ** buffer, guint group, guint idx, ForeachData * data)
676 {
677   fail_unless (buffer != NULL);
678
679   data->iter++;
680
681   return GST_BUFFER_LIST_CONTINUE;
682 }
683
684 GST_START_TEST (test_foreach)
685 {
686   GstBufferListIterator *it;
687   ForeachData data;
688
689   /* add buffers to the list */
690   it = gst_buffer_list_iterate (list);
691   gst_buffer_list_iterator_add_group (it);
692   data.buf[0][0] = gst_buffer_new ();
693   gst_buffer_list_iterator_add (it, data.buf[0][0]);
694   gst_buffer_list_iterator_add_group (it);
695   data.buf[1][0] = gst_buffer_new ();
696   gst_buffer_list_iterator_add (it, data.buf[1][0]);
697   data.buf[1][1] = gst_buffer_new ();
698   gst_buffer_list_iterator_add (it, data.buf[1][1]);
699   gst_buffer_list_iterator_free (it);
700
701   fail_unless (gst_buffer_list_get (list, 0, 0) == data.buf[0][0]);
702   fail_unless (gst_buffer_list_get (list, 0, 1) == NULL);
703   fail_unless (gst_buffer_list_get (list, 1, 0) == data.buf[1][0]);
704   fail_unless (gst_buffer_list_get (list, 1, 1) == data.buf[1][1]);
705   fail_unless (gst_buffer_list_get (list, 1, 2) == NULL);
706   fail_unless (gst_buffer_list_get (list, 2, 0) == NULL);
707   fail_unless (gst_buffer_list_get (list, 2, 1) == NULL);
708   fail_unless (gst_buffer_list_get (list, 3, 3) == NULL);
709
710   /* iterate everything */
711   data.iter = 0;
712   gst_buffer_list_foreach (list, (GstBufferListFunc) foreach_func1, &data);
713   fail_unless (data.iter == 3);
714
715   /* iterate only the first buffer of groups */
716   data.iter = 0;
717   gst_buffer_list_foreach (list, (GstBufferListFunc) foreach_func2, &data);
718   fail_unless (data.iter == 2);
719
720   /* iterate only the first buffer */
721   data.iter = 0;
722   gst_buffer_list_foreach (list, (GstBufferListFunc) foreach_func3, &data);
723   fail_unless (data.iter == 1);
724
725   /* remove the first buffer of each group */
726   data.iter = 0;
727   gst_buffer_list_foreach (list, (GstBufferListFunc) foreach_func4, &data);
728   fail_unless (data.iter == 2);
729
730   fail_unless (gst_buffer_list_get (list, 0, 0) == NULL);
731   fail_unless (gst_buffer_list_get (list, 0, 1) == NULL);
732   fail_unless (gst_buffer_list_get (list, 1, 0) == data.buf[1][1]);
733   fail_unless (gst_buffer_list_get (list, 1, 1) == NULL);
734   fail_unless (gst_buffer_list_get (list, 1, 2) == NULL);
735   fail_unless (gst_buffer_list_get (list, 2, 0) == NULL);
736
737   /* iterate everything, just one more buffer now */
738   data.iter = 0;
739   gst_buffer_list_foreach (list, (GstBufferListFunc) foreach_func5, &data);
740   fail_unless (data.iter == 1);
741 }
742
743 GST_END_TEST;
744
745 GST_START_TEST (test_list)
746 {
747   GstBufferListIterator *it;
748   GList *l = NULL;
749   gint i;
750
751   for (i = 0; i < 10; i++) {
752     gchar name[10];
753     g_snprintf (name, 10, "%d", i);
754     l = g_list_append (l, buffer_from_string (name));
755   }
756
757   /* add buffers to the list */
758   it = gst_buffer_list_iterate (list);
759   gst_buffer_list_iterator_add_group (it);
760   gst_buffer_list_iterator_add_list (it, l);
761
762   /* add a buffer */
763   gst_buffer_list_iterator_add (it, buffer_from_string ("10"));
764
765   /* add another list */
766   l = g_list_append (NULL, buffer_from_string ("11"));
767   gst_buffer_list_iterator_add_list (it, l);
768
769   for (i = 0; i < 12; i++) {
770     GstBuffer *buf;
771     gchar name[10];
772
773     buf = gst_buffer_list_get (list, 0, i);
774     g_snprintf (name, 10, "%d", i);
775     check_buffer (buf, 0, name);
776   }
777   gst_buffer_list_iterator_free (it);
778 }
779
780 GST_END_TEST;
781 #endif
782
783 static Suite *
784 gst_buffer_list_suite (void)
785 {
786   Suite *s = suite_create ("GstBufferList");
787   TCase *tc_chain = tcase_create ("general");
788
789   suite_add_tcase (s, tc_chain);
790   tcase_add_checked_fixture (tc_chain, setup, cleanup);
791   tcase_add_test (tc_chain, test_add_and_iterate);
792   tcase_add_test (tc_chain, test_remove);
793 #if 0
794   tcase_add_test (tc_chain, test_make_writable);
795   tcase_add_test (tc_chain, test_copy);
796   tcase_add_test (tc_chain, test_steal);
797   tcase_add_test (tc_chain, test_take);
798   tcase_add_test (tc_chain, test_do);
799   tcase_add_test (tc_chain, test_merge);
800   tcase_add_test (tc_chain, test_foreach);
801   tcase_add_test (tc_chain, test_list);
802 #endif
803
804   return s;
805 }
806
807 GST_CHECK_MAIN (gst_buffer_list);