• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  *
3  * unit test for GstMeta
4  *
5  * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com>
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 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26 
27 #include <gst/check/gstcheck.h>
28 
29 /* test metadata for PTS/DTS and duration */
30 typedef struct
31 {
32   GstMeta meta;
33 
34   GstClockTime pts;
35   GstClockTime dts;
36   GstClockTime duration;
37   GstClockTime clock_rate;
38 } GstMetaTest;
39 
40 static GType gst_meta_test_api_get_type (void);
41 #define GST_META_TEST_API_TYPE (gst_meta_test_api_get_type())
42 
43 static const GstMetaInfo *gst_meta_test_get_info (void);
44 #define GST_META_TEST_INFO (gst_meta_test_get_info())
45 
46 #define GST_META_TEST_GET(buf) ((GstMetaTest *)gst_buffer_get_meta(buf,GST_META_TEST_API_TYPE))
47 #define GST_META_TEST_ADD(buf) ((GstMetaTest *)gst_buffer_add_meta(buf,GST_META_TEST_INFO,NULL))
48 
49 typedef struct
50 {
51   GstMeta meta;
52 } GstMetaFoo;
53 
54 static GType gst_meta_foo_api_get_type (void);
55 #define GST_META_FOO_API_TYPE (gst_meta_foo_api_get_type())
56 
57 static const GstMetaInfo *gst_meta_foo_get_info (void);
58 #define GST_META_FOO_INFO (gst_meta_foo_get_info())
59 
60 #define GST_META_FOO_GET(buf) ((GstMetaFoo *)gst_buffer_get_meta(buf,GST_META_FOO_API_TYPE))
61 #define GST_META_FOO_ADD(buf) ((GstMetaFoo *)gst_buffer_add_meta(buf,GST_META_FOO_INFO,NULL))
62 
63 #if 0
64 /* unused currently. This is a user function to fill the metadata with default
65  * values. We don't call this from the init function because the user is mostly
66  * likely going to override the values immediately after */
67 static void
68 gst_meta_test_init (GstMetaTest * meta)
69 {
70   meta->pts = GST_CLOCK_TIME_NONE;
71   meta->dts = GST_CLOCK_TIME_NONE;
72   meta->duration = GST_CLOCK_TIME_NONE;
73   meta->clock_rate = GST_SECOND;
74 }
75 #endif
76 
77 static gboolean
test_init_func(GstMeta * meta,gpointer params,GstBuffer * buffer)78 test_init_func (GstMeta * meta, gpointer params, GstBuffer * buffer)
79 {
80   GST_DEBUG ("init called on buffer %p, meta %p", buffer, meta);
81   /* nothing to init really, the init function is mostly for allocating
82    * additional memory or doing special setup as part of adding the metadata to
83    * the buffer*/
84   return TRUE;
85 }
86 
87 static void
test_free_func(GstMeta * meta,GstBuffer * buffer)88 test_free_func (GstMeta * meta, GstBuffer * buffer)
89 {
90   GST_DEBUG ("free called on buffer %p, meta %p", buffer, meta);
91   /* nothing to free really */
92 }
93 
94 static gboolean
test_transform_func(GstBuffer * transbuf,GstMeta * meta,GstBuffer * buffer,GQuark type,gpointer data)95 test_transform_func (GstBuffer * transbuf, GstMeta * meta,
96     GstBuffer * buffer, GQuark type, gpointer data)
97 {
98   GstMetaTest *test, *tmeta = (GstMetaTest *) meta;
99 
100   GST_DEBUG ("transform %s called from buffer %p to %p, meta %p",
101       g_quark_to_string (type), buffer, transbuf, meta);
102 
103   if (GST_META_TRANSFORM_IS_COPY (type)) {
104     GstMetaTransformCopy *copy_data = data;
105 
106     test = GST_META_TEST_ADD (transbuf);
107 
108     if (copy_data->offset == 0) {
109       /* same offset, copy timestamps */
110       test->pts = tmeta->pts;
111       test->dts = tmeta->dts;
112       if (!copy_data->region) {
113         fail_unless (gst_buffer_get_size (buffer) == copy_data->size);
114         /* same size, copy duration */
115         test->duration = tmeta->duration;
116       } else {
117         fail_unless (gst_buffer_get_size (buffer) > copy_data->size);
118         /* else clear */
119         test->duration = GST_CLOCK_TIME_NONE;
120       }
121     } else {
122       fail_unless (copy_data->region == TRUE);
123       test->pts = -1;
124       test->dts = -1;
125       test->duration = -1;
126     }
127     test->clock_rate = tmeta->clock_rate;
128   } else {
129     /* return FALSE, if transform type is not supported */
130     return FALSE;
131   }
132   return TRUE;
133 }
134 
135 static GType
gst_meta_test_api_get_type(void)136 gst_meta_test_api_get_type (void)
137 {
138   static GType type;
139   static const gchar *tags[] = { "timing", NULL };
140 
141   if (g_once_init_enter (&type)) {
142     GType _type = gst_meta_api_type_register ("GstMetaTestAPI", tags);
143     g_once_init_leave (&type, _type);
144   }
145   return type;
146 }
147 
148 static gboolean
foo_init_func(GstMeta * meta,gpointer params,GstBuffer * buffer)149 foo_init_func (GstMeta * meta, gpointer params, GstBuffer * buffer)
150 {
151   GST_DEBUG ("init called on buffer %p, foo meta %p", buffer, meta);
152   return TRUE;
153 }
154 
155 static void
foo_free_func(GstMeta * meta,GstBuffer * buffer)156 foo_free_func (GstMeta * meta, GstBuffer * buffer)
157 {
158   GST_DEBUG ("free called on buffer %p, foo meta %p", buffer, meta);
159 }
160 
161 
162 static const GstMetaInfo *
gst_meta_test_get_info(void)163 gst_meta_test_get_info (void)
164 {
165   static const GstMetaInfo *meta_test_info = NULL;
166 
167   if (g_once_init_enter ((GstMetaInfo **) & meta_test_info)) {
168     const GstMetaInfo *mi = gst_meta_register (GST_META_TEST_API_TYPE,
169         "GstMetaTest",
170         sizeof (GstMetaTest),
171         test_init_func, test_free_func, test_transform_func);
172     g_once_init_leave ((GstMetaInfo **) & meta_test_info, (GstMetaInfo *) mi);
173   }
174   return meta_test_info;
175 }
176 
177 static gboolean
foo_transform_func(GstBuffer * transbuf,GstMeta * meta,GstBuffer * buffer,GQuark type,gpointer data)178 foo_transform_func (GstBuffer * transbuf, GstMeta * meta,
179     GstBuffer * buffer, GQuark type, gpointer data)
180 {
181   GST_DEBUG ("transform %s called from buffer %p to %p, meta %p",
182       g_quark_to_string (type), buffer, transbuf, meta);
183 
184   if (GST_META_TRANSFORM_IS_COPY (type)) {
185     G_GNUC_UNUSED GstMetaFoo *unused = GST_META_FOO_ADD (transbuf);
186   } else {
187     /* return FALSE, if transform type is not supported */
188     return FALSE;
189   }
190   return TRUE;
191 }
192 
193 static GType
gst_meta_foo_api_get_type(void)194 gst_meta_foo_api_get_type (void)
195 {
196   static GType type;
197   static const gchar *tags[] = { NULL };
198 
199   if (g_once_init_enter (&type)) {
200     GType _type = gst_meta_api_type_register ("GstMetaFooAPI", tags);
201     g_once_init_leave (&type, _type);
202   }
203   return type;
204 }
205 
206 static const GstMetaInfo *
gst_meta_foo_get_info(void)207 gst_meta_foo_get_info (void)
208 {
209   static const GstMetaInfo *meta_foo_info = NULL;
210 
211   if (g_once_init_enter ((GstMetaInfo **) & meta_foo_info)) {
212     const GstMetaInfo *mi = gst_meta_register (GST_META_FOO_API_TYPE,
213         "GstMetaFoo",
214         sizeof (GstMetaFoo),
215         foo_init_func, foo_free_func, foo_transform_func);
216     g_once_init_leave ((GstMetaInfo **) & meta_foo_info, (GstMetaInfo *) mi);
217   }
218   return meta_foo_info;
219 }
220 
GST_START_TEST(test_meta_test)221 GST_START_TEST (test_meta_test)
222 {
223   GstBuffer *buffer, *copy, *subbuf;
224   GstMetaTest *meta;
225   GstMapInfo info;
226 
227   buffer = gst_buffer_new_and_alloc (4);
228   fail_if (buffer == NULL);
229 
230   fail_unless (gst_buffer_map (buffer, &info, GST_MAP_WRITE));
231   fail_if (info.data == NULL);
232   memset (info.data, 0, 4);
233   gst_buffer_unmap (buffer, &info);
234 
235   /* add some metadata */
236   meta = GST_META_TEST_ADD (buffer);
237   fail_if (meta == NULL);
238   /* fill some values */
239   meta->pts = 1000;
240   meta->dts = 2000;
241   meta->duration = 1000;
242   meta->clock_rate = 1000;
243 
244   /* copy of the buffer */
245   copy = gst_buffer_copy (buffer);
246   /* get metadata of the buffer */
247   meta = GST_META_TEST_GET (copy);
248   fail_if (meta == NULL);
249   fail_if (meta->pts != 1000);
250   fail_if (meta->dts != 2000);
251   fail_if (meta->duration != 1000);
252   fail_if (meta->clock_rate != 1000);
253   gst_buffer_unref (copy);
254 
255   /* make subbuffer */
256   subbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 1);
257   /* get metadata of the buffer */
258   meta = GST_META_TEST_GET (subbuf);
259   fail_if (meta == NULL);
260   fail_if (meta->pts != 1000);
261   fail_if (meta->dts != 2000);
262   fail_if (meta->duration != -1);
263   fail_if (meta->clock_rate != 1000);
264   gst_buffer_unref (subbuf);
265 
266   /* make another subbuffer */
267   subbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 1, 3);
268   /* get metadata of the buffer */
269   meta = GST_META_TEST_GET (subbuf);
270   fail_if (meta == NULL);
271   fail_if (meta->pts != -1);
272   fail_if (meta->dts != -1);
273   fail_if (meta->duration != -1);
274   fail_if (meta->clock_rate != 1000);
275   gst_buffer_unref (subbuf);
276 
277   /* clean up */
278   gst_buffer_unref (buffer);
279 }
280 
281 GST_END_TEST;
282 
283 static gboolean
foreach_meta(GstBuffer * buffer,GstMeta ** meta,gpointer user_data)284 foreach_meta (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
285 {
286   /* try to remove */
287   *meta = NULL;
288   return TRUE;
289 }
290 
GST_START_TEST(test_meta_locked)291 GST_START_TEST (test_meta_locked)
292 {
293   GstBuffer *buffer;
294   GstMetaTest *meta;
295 
296   buffer = gst_buffer_new_and_alloc (4);
297   fail_if (buffer == NULL);
298 
299   /* add some metadata */
300   meta = GST_META_TEST_ADD (buffer);
301   fail_if (meta == NULL);
302   GST_META_FLAG_SET (meta, GST_META_FLAG_LOCKED);
303 
304   ASSERT_CRITICAL (gst_buffer_remove_meta (buffer, (GstMeta *) meta));
305   ASSERT_CRITICAL (gst_buffer_foreach_meta (buffer, foreach_meta, NULL));
306 
307   GST_META_FLAG_UNSET (meta, GST_META_FLAG_LOCKED);
308 
309   gst_buffer_remove_meta (buffer, (GstMeta *) meta);
310 
311   /* clean up */
312   gst_buffer_unref (buffer);
313 }
314 
315 GST_END_TEST;
316 
317 static gboolean
foreach_meta_remove_one(GstBuffer * buffer,GstMeta ** meta,gpointer to_remove)318 foreach_meta_remove_one (GstBuffer * buffer, GstMeta ** meta,
319     gpointer to_remove)
320 {
321   if (*meta == to_remove) {
322     *meta = NULL;
323   }
324 
325   return TRUE;
326 }
327 
328 static gint
count_buffer_meta(GstBuffer * buffer)329 count_buffer_meta (GstBuffer * buffer)
330 {
331   gint ret = 0;
332   gpointer state = NULL;
333 
334   while (gst_buffer_iterate_meta (buffer, &state))
335     ret++;
336 
337   return ret;
338 }
339 
GST_START_TEST(test_meta_foreach_remove_one_of_one)340 GST_START_TEST (test_meta_foreach_remove_one_of_one)
341 {
342   GstBuffer *buffer;
343   GstMetaTest *meta1;
344   gpointer state = NULL;
345 
346   buffer = gst_buffer_new_and_alloc (4);
347   fail_if (buffer == NULL);
348 
349   /* add some metadata */
350   meta1 = GST_META_TEST_ADD (buffer);
351   fail_if (meta1 == NULL);
352 
353   fail_unless_equals_int (count_buffer_meta (buffer), 1);
354 
355   gst_buffer_foreach_meta (buffer, foreach_meta_remove_one, meta1);
356 
357   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
358 
359   /* clean up */
360   gst_buffer_unref (buffer);
361 }
362 
363 GST_END_TEST;
364 
GST_START_TEST(test_meta_foreach_remove_head_of_three)365 GST_START_TEST (test_meta_foreach_remove_head_of_three)
366 {
367   GstBuffer *buffer;
368   GstMetaTest *meta1, *meta2, *meta3;
369   gpointer state = NULL;
370 
371   buffer = gst_buffer_new_and_alloc (4);
372   fail_if (buffer == NULL);
373 
374   /* add some metadata */
375   meta1 = GST_META_TEST_ADD (buffer);
376   fail_if (meta1 == NULL);
377   meta2 = GST_META_TEST_ADD (buffer);
378   fail_if (meta2 == NULL);
379   meta3 = GST_META_TEST_ADD (buffer);
380   fail_if (meta3 == NULL);
381 
382   fail_unless_equals_int (count_buffer_meta (buffer), 3);
383 
384   gst_buffer_foreach_meta (buffer, foreach_meta_remove_one, meta3);
385 
386   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta1);
387   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta2);
388   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
389 
390   /* clean up */
391   gst_buffer_unref (buffer);
392 }
393 
394 GST_END_TEST;
395 
GST_START_TEST(test_meta_foreach_remove_middle_of_three)396 GST_START_TEST (test_meta_foreach_remove_middle_of_three)
397 {
398   GstBuffer *buffer;
399   GstMetaTest *meta1, *meta2, *meta3;
400   gpointer state = NULL;
401 
402   buffer = gst_buffer_new_and_alloc (4);
403   fail_if (buffer == NULL);
404 
405   /* add some metadata */
406   meta1 = GST_META_TEST_ADD (buffer);
407   fail_if (meta1 == NULL);
408   meta2 = GST_META_TEST_ADD (buffer);
409   fail_if (meta2 == NULL);
410   meta3 = GST_META_TEST_ADD (buffer);
411   fail_if (meta3 == NULL);
412 
413   fail_unless_equals_int (count_buffer_meta (buffer), 3);
414 
415   gst_buffer_foreach_meta (buffer, foreach_meta_remove_one, meta2);
416 
417   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta1);
418   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta3);
419   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
420 
421   /* clean up */
422   gst_buffer_unref (buffer);
423 }
424 
425 GST_END_TEST;
426 
GST_START_TEST(test_meta_foreach_remove_tail_of_three)427 GST_START_TEST (test_meta_foreach_remove_tail_of_three)
428 {
429   GstBuffer *buffer;
430   GstMetaTest *meta1, *meta2, *meta3;
431   gpointer state = NULL;
432 
433   buffer = gst_buffer_new_and_alloc (4);
434   fail_if (buffer == NULL);
435 
436   /* add some metadata */
437   meta1 = GST_META_TEST_ADD (buffer);
438   fail_if (meta1 == NULL);
439   meta2 = GST_META_TEST_ADD (buffer);
440   fail_if (meta2 == NULL);
441   meta3 = GST_META_TEST_ADD (buffer);
442   fail_if (meta3 == NULL);
443 
444   fail_unless_equals_int (count_buffer_meta (buffer), 3);
445 
446   gst_buffer_foreach_meta (buffer, foreach_meta_remove_one, meta1);
447 
448   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta2);
449   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta3);
450   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
451 
452   /* clean up */
453   gst_buffer_unref (buffer);
454 }
455 
456 GST_END_TEST;
457 
458 static gboolean
foreach_meta_remove_unpooled(GstBuffer * buffer,GstMeta ** meta,gpointer unused)459 foreach_meta_remove_unpooled (GstBuffer * buffer, GstMeta ** meta,
460     gpointer unused)
461 {
462   if (!GST_META_FLAG_IS_SET (*meta, GST_META_FLAG_POOLED)) {
463     *meta = NULL;
464   }
465 
466   return TRUE;
467 }
468 
GST_START_TEST(test_meta_foreach_remove_head_and_tail_of_three)469 GST_START_TEST (test_meta_foreach_remove_head_and_tail_of_three)
470 {
471   GstBuffer *buffer;
472   GstMetaTest *meta1, *meta2, *meta3;
473   gpointer state = NULL;
474 
475   buffer = gst_buffer_new_and_alloc (4);
476   fail_if (buffer == NULL);
477 
478   /* add some metadata */
479   meta1 = GST_META_TEST_ADD (buffer);
480   fail_if (meta1 == NULL);
481   meta2 = GST_META_TEST_ADD (buffer);
482   fail_if (meta2 == NULL);
483   GST_META_FLAG_SET (meta2, GST_META_FLAG_POOLED);
484   meta3 = GST_META_TEST_ADD (buffer);
485   fail_if (meta3 == NULL);
486 
487   fail_unless_equals_int (count_buffer_meta (buffer), 3);
488 
489   gst_buffer_foreach_meta (buffer, foreach_meta_remove_unpooled, NULL);
490 
491   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta2);
492   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
493 
494   /* clean up */
495   gst_buffer_unref (buffer);
496 }
497 
498 GST_END_TEST;
499 
500 
GST_START_TEST(test_meta_foreach_remove_several)501 GST_START_TEST (test_meta_foreach_remove_several)
502 {
503   GstBuffer *buffer;
504   GstMetaTest *meta1, *meta2, *meta3, *meta4, *meta5;
505   gpointer state = NULL;
506 
507   buffer = gst_buffer_new_and_alloc (4);
508   fail_if (buffer == NULL);
509 
510   /* add some metadata */
511   meta1 = GST_META_TEST_ADD (buffer);
512   fail_if (meta1 == NULL);
513   meta2 = GST_META_TEST_ADD (buffer);
514   fail_if (meta2 == NULL);
515   GST_META_FLAG_SET (meta2, GST_META_FLAG_POOLED);
516   meta3 = GST_META_TEST_ADD (buffer);
517   fail_if (meta3 == NULL);
518   meta4 = GST_META_TEST_ADD (buffer);
519   fail_if (meta4 == NULL);
520   meta5 = GST_META_TEST_ADD (buffer);
521   fail_if (meta5 == NULL);
522   GST_META_FLAG_SET (meta5, GST_META_FLAG_POOLED);
523 
524   fail_unless_equals_int (count_buffer_meta (buffer), 5);
525 
526   gst_buffer_foreach_meta (buffer, foreach_meta_remove_unpooled, NULL);
527 
528   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta2);
529   fail_unless (gst_buffer_iterate_meta (buffer, &state) == (GstMeta *) meta5);
530   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
531 
532   /* clean up */
533   gst_buffer_unref (buffer);
534 }
535 
536 GST_END_TEST;
537 
GST_START_TEST(test_meta_iterate)538 GST_START_TEST (test_meta_iterate)
539 {
540   GstBuffer *buffer;
541   GstMeta *m1, *m2, *m3, *m_found;
542   GList *metas;
543   gpointer state;
544 
545   /* buffer with single meta */
546   buffer = gst_buffer_new_and_alloc (4);
547   m1 = (GstMeta *) GST_META_TEST_ADD (buffer);
548   fail_unless (m1 != NULL);
549 
550   state = NULL;
551   fail_unless (gst_buffer_iterate_meta (buffer, &state) != NULL);
552   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
553 
554   state = NULL;
555   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
556           GST_META_TEST_API_TYPE) != NULL);
557   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
558           GST_META_TEST_API_TYPE) == NULL);
559 
560   state = NULL;
561   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
562           GST_META_FOO_API_TYPE) == NULL);
563 
564   state = NULL;
565   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
566           GST_META_TEST_API_TYPE) != NULL);
567   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
568           GST_META_TEST_API_TYPE) == NULL);
569 
570   /* buffer with multiple metas */
571   m2 = (GstMeta *) GST_META_FOO_ADD (buffer);
572   fail_unless (m2 != NULL);
573   m3 = (GstMeta *) GST_META_TEST_ADD (buffer);
574   fail_unless (m3 != NULL);
575 
576   /* create a list with metas, we don't know what order buffer_iterate has */
577   metas = g_list_prepend (g_list_prepend (g_list_prepend (NULL, m1), m2), m3);
578 
579   state = NULL;
580   m_found = gst_buffer_iterate_meta (buffer, &state);
581   fail_unless (m_found != NULL);
582   metas = g_list_remove (metas, m_found);
583   m_found = gst_buffer_iterate_meta (buffer, &state);
584   fail_unless (m_found != NULL);
585   metas = g_list_remove (metas, m_found);
586   m_found = gst_buffer_iterate_meta (buffer, &state);
587   fail_unless (m_found != NULL);
588   metas = g_list_remove (metas, m_found);
589 
590   /* should only have 3 metas, so the 4th time we should get NULL back */
591   fail_unless (gst_buffer_iterate_meta (buffer, &state) == NULL);
592 
593   /* list should be empty now, we should have seen each meta once */
594   fail_unless (metas == NULL);
595 
596   /* same test as above with iterate_filtered */
597 
598   /* create a list with metas, we don't know what order buffer_iterate has */
599   metas = g_list_prepend (g_list_prepend (g_list_prepend (NULL, m1), m2), m3);
600 
601   state = NULL;
602   m_found =
603       gst_buffer_iterate_meta_filtered (buffer, &state, GST_META_TEST_API_TYPE);
604   fail_unless (m_found != NULL);
605   metas = g_list_remove (metas, m_found);
606   m_found =
607       gst_buffer_iterate_meta_filtered (buffer, &state, GST_META_TEST_API_TYPE);
608   fail_unless (m_found != NULL);
609   metas = g_list_remove (metas, m_found);
610 
611   /* should only have 2 Test metas, so now we should get NULL back */
612   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
613           GST_META_TEST_API_TYPE) == NULL);
614 
615   /* but there should also still be a Foo meta */
616   fail_unless_equals_int (g_list_length (metas), 1);
617   fail_unless (metas->data == m2);
618   metas = g_list_remove (metas, m2);
619 
620   state = NULL;
621   m_found =
622       gst_buffer_iterate_meta_filtered (buffer, &state, GST_META_FOO_API_TYPE);
623   fail_unless (m_found == m2);
624 
625   /* only have 1 Foo meta, so now we should get NULL back */
626   fail_unless (gst_buffer_iterate_meta_filtered (buffer, &state,
627           GST_META_FOO_API_TYPE) == NULL);
628 
629   gst_buffer_unref (buffer);
630 
631 
632 }
633 
634 GST_END_TEST;
635 
636 #define test_meta_compare_seqnum(a,b) \
637     gst_meta_compare_seqnum((GstMeta*)(a),(GstMeta*)(b))
638 
GST_START_TEST(test_meta_seqnum)639 GST_START_TEST (test_meta_seqnum)
640 {
641   GstMetaTest *meta1, *meta2, *meta3;
642   GstBuffer *buffer;
643 
644   buffer = gst_buffer_new_and_alloc (4);
645   fail_unless (buffer != NULL);
646 
647   /* add some metadata */
648   meta1 = GST_META_TEST_ADD (buffer);
649   fail_unless (meta1 != NULL);
650   meta2 = GST_META_TEST_ADD (buffer);
651   fail_unless (meta2 != NULL);
652   meta3 = GST_META_TEST_ADD (buffer);
653   fail_unless (meta3 != NULL);
654 
655   fail_unless (test_meta_compare_seqnum (meta1, meta2) < 0);
656   fail_unless (test_meta_compare_seqnum (meta2, meta3) < 0);
657   fail_unless (test_meta_compare_seqnum (meta1, meta3) < 0);
658 
659   fail_unless_equals_int (test_meta_compare_seqnum (meta1, meta1), 0);
660   fail_unless_equals_int (test_meta_compare_seqnum (meta2, meta2), 0);
661   fail_unless_equals_int (test_meta_compare_seqnum (meta3, meta3), 0);
662 
663   fail_unless (test_meta_compare_seqnum (meta2, meta1) > 0);
664   fail_unless (test_meta_compare_seqnum (meta3, meta2) > 0);
665   fail_unless (test_meta_compare_seqnum (meta3, meta1) > 0);
666 
667   /* Check that gst_meta_compare_seqnum() works correctly as a GCompareFunc */
668   {
669     GList *list;
670 
671     /* Make list: 3, 1, 2 */
672     list = g_list_prepend (NULL, meta2);
673     list = g_list_prepend (list, meta1);
674     list = g_list_prepend (list, meta3);
675 
676     list = g_list_sort (list, (GCompareFunc) gst_meta_compare_seqnum);
677 
678     fail_unless (g_list_nth_data (list, 0) == meta1);
679     fail_unless (g_list_nth_data (list, 1) == meta2);
680     fail_unless (g_list_nth_data (list, 2) == meta3);
681 
682     g_list_free (list);
683   }
684 
685   /* clean up */
686   gst_buffer_unref (buffer);
687 }
688 
689 GST_END_TEST;
690 
GST_START_TEST(test_meta_custom)691 GST_START_TEST (test_meta_custom)
692 {
693   GstBuffer *buffer;
694   const GstMetaInfo *info;
695   GstCustomMeta *meta;
696   GstMeta *it;
697   GstStructure *s, *expected;
698   gpointer state = NULL;
699   const gchar *tags[] = { "test-tag", NULL };
700 
701   info = gst_meta_register_custom ("test-custom", tags, NULL, NULL, NULL);
702 
703   fail_unless (info != NULL);
704 
705   buffer = gst_buffer_new_and_alloc (4);
706   fail_if (buffer == NULL);
707 
708   /* add some metadata */
709   meta = gst_buffer_add_custom_meta (buffer, "test-custom");
710   fail_if (meta == NULL);
711 
712   fail_unless (gst_custom_meta_has_name ((GstCustomMeta *) meta,
713           "test-custom"));
714 
715   expected = gst_structure_new_empty ("test-custom");
716   s = gst_custom_meta_get_structure (meta);
717   fail_unless (gst_structure_is_equal (s, expected));
718   gst_structure_free (expected);
719 
720   gst_structure_set (s, "test-field", G_TYPE_INT, 42, NULL);
721   gst_buffer_ref (buffer);
722   ASSERT_CRITICAL (gst_structure_set (s, "test-field", G_TYPE_INT, 43, NULL));
723   gst_buffer_unref (buffer);
724   expected = gst_structure_new ("test-custom",
725       "test-field", G_TYPE_INT, 42, NULL);
726   fail_unless (gst_structure_is_equal (s, expected));
727   gst_structure_free (expected);
728 
729   it = gst_buffer_iterate_meta (buffer, &state);
730 
731   fail_unless ((GstCustomMeta *) it == meta);
732 
733   fail_unless (it->info == info);
734 
735   /* clean up */
736   gst_buffer_unref (buffer);
737 }
738 
739 GST_END_TEST;
740 
741 static gboolean
transform_custom(GstBuffer * transbuf,GstMeta * meta,GstBuffer * buffer,GQuark type,gpointer data,gint * user_data)742 transform_custom (GstBuffer * transbuf, GstMeta * meta, GstBuffer * buffer,
743     GQuark type, gpointer data, gint * user_data)
744 {
745   if (GST_META_TRANSFORM_IS_COPY (type)) {
746     GstStructure *s;
747     GstCustomMeta *custom;
748 
749     custom = (GstCustomMeta *) gst_buffer_add_meta (transbuf, meta->info, NULL);
750     s = gst_custom_meta_get_structure (custom);
751     gst_structure_set (s, "test-field", G_TYPE_INT, *user_data, NULL);
752   } else {
753     return FALSE;
754   }
755 
756   return TRUE;
757 }
758 
GST_START_TEST(test_meta_custom_transform)759 GST_START_TEST (test_meta_custom_transform)
760 {
761   GstBuffer *buffer, *buffer_copy;
762   const GstMetaInfo *info;
763   GstCustomMeta *meta;
764   GstStructure *s, *expected;
765   const gchar *tags[] = { "test-tag", NULL };
766   gint *user_data;
767 
768   /* That memory should be deallocated at gst_deinit time */
769   user_data = g_malloc (sizeof (gint));
770   *user_data = 42;
771   info =
772       gst_meta_register_custom ("test-custom-transform", tags,
773       (GstCustomMetaTransformFunction) transform_custom, user_data, g_free);
774 
775   fail_unless (info != NULL);
776 
777   buffer = gst_buffer_new_and_alloc (4);
778   fail_if (buffer == NULL);
779 
780   /* add some metadata */
781   meta = gst_buffer_add_custom_meta (buffer, "test-custom-transform");
782   fail_if (meta == NULL);
783 
784   buffer_copy = gst_buffer_copy (buffer);
785   meta = gst_buffer_get_custom_meta (buffer_copy, "test-custom-transform");
786   fail_unless (meta != NULL);
787   expected = gst_structure_new ("test-custom-transform",
788       "test-field", G_TYPE_INT, 42, NULL);
789   s = gst_custom_meta_get_structure (meta);
790   fail_unless (gst_structure_is_equal (s, expected));
791   gst_structure_free (expected);
792 
793   /* clean up */
794   gst_buffer_unref (buffer_copy);
795   gst_buffer_unref (buffer);
796 }
797 
798 GST_END_TEST;
799 
800 static Suite *
gst_buffermeta_suite(void)801 gst_buffermeta_suite (void)
802 {
803   Suite *s = suite_create ("GstMeta");
804   TCase *tc_chain = tcase_create ("general");
805 
806   suite_add_tcase (s, tc_chain);
807   tcase_add_test (tc_chain, test_meta_test);
808   tcase_add_test (tc_chain, test_meta_locked);
809   tcase_add_test (tc_chain, test_meta_foreach_remove_one_of_one);
810   tcase_add_test (tc_chain, test_meta_foreach_remove_head_of_three);
811   tcase_add_test (tc_chain, test_meta_foreach_remove_middle_of_three);
812   tcase_add_test (tc_chain, test_meta_foreach_remove_tail_of_three);
813   tcase_add_test (tc_chain, test_meta_foreach_remove_head_and_tail_of_three);
814   tcase_add_test (tc_chain, test_meta_foreach_remove_several);
815   tcase_add_test (tc_chain, test_meta_iterate);
816   tcase_add_test (tc_chain, test_meta_seqnum);
817   tcase_add_test (tc_chain, test_meta_custom);
818   tcase_add_test (tc_chain, test_meta_custom_transform);
819 
820   return s;
821 }
822 
823 GST_CHECK_MAIN (gst_buffermeta);
824