Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / tests / check / gst / gstcaps.c
1 /* GStreamer
2  * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
3  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
4  *
5  * gstcaps.c: Unit test for GstCaps
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 #include <gst/check/gstcheck.h>
25 #include <gst/gstcaps.h>
26 #include "capslist.h"
27
28 GST_START_TEST (test_from_string)
29 {
30   GstCaps *caps;
31   GstCaps *caps2;
32   gchar *to_str;
33   int i;
34
35   for (i = 0; i < G_N_ELEMENTS (caps_list); i++) {
36     caps = gst_caps_from_string (caps_list[i]);
37     fail_if (caps == NULL,
38         "Could not create caps from string %s\n", caps_list[i]);
39     to_str = gst_caps_to_string (caps);
40     fail_if (to_str == NULL,
41         "Could not convert caps back to string %s\n", caps_list[i]);
42     caps2 = gst_caps_from_string (caps_list[i]);
43     fail_if (caps2 == NULL, "Could not create caps from string %s\n", to_str);
44
45     fail_unless (gst_caps_is_equal (caps, caps));
46     fail_unless (gst_caps_is_equal (caps, caps2));
47
48     gst_caps_unref (caps);
49     gst_caps_unref (caps2);
50     g_free (to_str);
51   }
52 }
53
54 GST_END_TEST;
55
56 GST_START_TEST (test_double_append)
57 {
58   GstStructure *s1;
59   GstCaps *c1;
60
61   c1 = gst_caps_new_any ();
62   s1 = gst_structure_from_string ("audio/x-raw-int,rate=44100", NULL);
63   gst_caps_append_structure (c1, s1);
64   ASSERT_CRITICAL (gst_caps_append_structure (c1, s1));
65
66   gst_caps_unref (c1);
67 }
68
69 GST_END_TEST;
70
71 GST_START_TEST (test_mutability)
72 {
73   GstStructure *s1;
74   GstCaps *c1;
75   gint ret;
76
77   c1 = gst_caps_new_any ();
78   s1 = gst_structure_from_string ("audio/x-raw-int,rate=44100", NULL);
79   gst_structure_set (s1, "rate", G_TYPE_INT, 48000, NULL);
80   gst_caps_append_structure (c1, s1);
81   gst_structure_set (s1, "rate", G_TYPE_INT, 22500, NULL);
82   gst_caps_ref (c1);
83   ASSERT_CRITICAL (gst_structure_set (s1, "rate", G_TYPE_INT, 11250, NULL));
84   fail_unless (gst_structure_get_int (s1, "rate", &ret));
85   fail_unless (ret == 22500);
86   ASSERT_CRITICAL (gst_caps_set_simple (c1, "rate", G_TYPE_INT, 11250, NULL));
87   fail_unless (gst_structure_get_int (s1, "rate", &ret));
88   fail_unless (ret == 22500);
89   gst_caps_unref (c1);
90   gst_structure_set (s1, "rate", G_TYPE_INT, 11250, NULL);
91   fail_unless (gst_structure_get_int (s1, "rate", &ret));
92   fail_unless (ret == 11250);
93   gst_caps_set_simple (c1, "rate", G_TYPE_INT, 1, NULL);
94   fail_unless (gst_structure_get_int (s1, "rate", &ret));
95   fail_unless (ret == 1);
96   gst_caps_unref (c1);
97 }
98
99 GST_END_TEST;
100
101 GST_START_TEST (test_static_caps)
102 {
103   static GstStaticCaps scaps = GST_STATIC_CAPS ("audio/x-raw-int,rate=44100");
104   GstCaps *caps1;
105   GstCaps *caps2;
106
107   /* caps creation */
108   caps1 = gst_static_caps_get (&scaps);
109   fail_unless (caps1 != NULL);
110   /* 1 refcount core, one from us */
111   fail_unless (GST_CAPS_REFCOUNT (caps1) == 2);
112
113   /* caps should be the same */
114   caps2 = gst_static_caps_get (&scaps);
115   fail_unless (caps2 != NULL);
116   /* 1 refcount core, two from us */
117   fail_unless (GST_CAPS_REFCOUNT (caps1) == 3);
118   /* caps must be equal */
119   fail_unless (caps1 == caps2);
120
121   gst_caps_unref (caps1);
122   gst_caps_unref (caps2);
123 }
124
125 GST_END_TEST;
126
127 static const gchar non_simple_caps_string[] =
128     "video/x-raw-yuv, format=(fourcc)I420, framerate=(fraction)[ 1/100, 100 ], "
129     "width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
130     "format=(fourcc)YUY2, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
131     "height=(int)[ 16, 4096 ]; video/x-raw-rgb, bpp=(int)8, depth=(int)8, "
132     "endianness=(int)1234, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
133     "height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
134     "format=(fourcc){ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], "
135     "height=(int)[ 16, 4096 ], framerate=(fraction)[ 1/100, 100 ]";
136
137 static gboolean
138 check_fourcc_list (const GValue * format_value)
139 {
140   const GValue *fourcc_value;
141   gboolean got_yv12 = FALSE;
142   gboolean got_i420 = FALSE;
143   gboolean got_yuy2 = FALSE;
144   guint32 fourcc;
145
146   fourcc_value = gst_value_list_get_value (format_value, 0);
147   fail_unless (fourcc_value != NULL);
148   fail_unless (GST_VALUE_HOLDS_FOURCC (fourcc_value));
149   fourcc = gst_value_get_fourcc (fourcc_value);
150   fail_unless (fourcc != 0);
151   got_i420 = got_i420 || (fourcc == GST_STR_FOURCC ("I420"));
152   got_yuy2 = got_yuy2 || (fourcc == GST_STR_FOURCC ("YUY2"));
153   got_yv12 = got_yv12 || (fourcc == GST_STR_FOURCC ("YV12"));
154
155   fourcc_value = gst_value_list_get_value (format_value, 1);
156   fail_unless (fourcc_value != NULL);
157   fail_unless (GST_VALUE_HOLDS_FOURCC (fourcc_value));
158   fourcc = gst_value_get_fourcc (fourcc_value);
159   fail_unless (fourcc != 0);
160   got_i420 = got_i420 || (fourcc == GST_STR_FOURCC ("I420"));
161   got_yuy2 = got_yuy2 || (fourcc == GST_STR_FOURCC ("YUY2"));
162   got_yv12 = got_yv12 || (fourcc == GST_STR_FOURCC ("YV12"));
163
164   fourcc_value = gst_value_list_get_value (format_value, 2);
165   fail_unless (fourcc_value != NULL);
166   fail_unless (GST_VALUE_HOLDS_FOURCC (fourcc_value));
167   fourcc = gst_value_get_fourcc (fourcc_value);
168   fail_unless (fourcc != 0);
169   got_i420 = got_i420 || (fourcc == GST_STR_FOURCC ("I420"));
170   got_yuy2 = got_yuy2 || (fourcc == GST_STR_FOURCC ("YUY2"));
171   got_yv12 = got_yv12 || (fourcc == GST_STR_FOURCC ("YV12"));
172
173   return (got_i420 && got_yuy2 && got_yv12);
174 }
175
176 GST_START_TEST (test_simplify)
177 {
178   GstStructure *s1, *s2;
179   gboolean did_simplify;
180   GstCaps *caps;
181
182   caps = gst_caps_from_string (non_simple_caps_string);
183   fail_unless (caps != NULL,
184       "gst_caps_from_string (non_simple_caps_string) failed");
185
186   did_simplify = gst_caps_do_simplify (caps);
187   fail_unless (did_simplify == TRUE,
188       "gst_caps_do_simplify() should have worked");
189
190   /* check simplified caps, should be:
191    *
192    * video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234,
193    *     framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ],
194    *     height=(int)[ 16, 4096 ];
195    * video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
196    *     width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
197    *     framerate=(fraction)[ 1/100, 100 ]
198    */
199   fail_unless (gst_caps_get_size (caps) == 2);
200   s1 = gst_caps_get_structure (caps, 0);
201   s2 = gst_caps_get_structure (caps, 1);
202   fail_unless (s1 != NULL);
203   fail_unless (s2 != NULL);
204
205   if (!gst_structure_has_name (s1, "video/x-raw-rgb")) {
206     GstStructure *tmp;
207
208     tmp = s1;
209     s1 = s2;
210     s2 = tmp;
211   }
212
213   fail_unless (gst_structure_has_name (s1, "video/x-raw-rgb"));
214   {
215     const GValue *framerate_value;
216     const GValue *width_value;
217     const GValue *height_value;
218     const GValue *val_fps;
219     GValue test_fps = { 0, };
220     gint bpp, depth, endianness;
221     gint min_width, max_width;
222     gint min_height, max_height;
223
224     fail_unless (gst_structure_get_int (s1, "bpp", &bpp));
225     fail_unless (bpp == 8);
226
227     fail_unless (gst_structure_get_int (s1, "depth", &depth));
228     fail_unless (depth == 8);
229
230     fail_unless (gst_structure_get_int (s1, "endianness", &endianness));
231     fail_unless (endianness == G_LITTLE_ENDIAN);
232
233     g_value_init (&test_fps, GST_TYPE_FRACTION);
234     framerate_value = gst_structure_get_value (s1, "framerate");
235     fail_unless (framerate_value != NULL);
236     fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
237
238     val_fps = gst_value_get_fraction_range_min (framerate_value);
239     gst_value_set_fraction (&test_fps, 1, 100);
240     fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
241
242     val_fps = gst_value_get_fraction_range_max (framerate_value);
243     gst_value_set_fraction (&test_fps, 100, 1);
244     fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
245
246     g_value_unset (&test_fps);
247
248     width_value = gst_structure_get_value (s1, "width");
249     fail_unless (width_value != NULL);
250     fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value));
251     min_width = gst_value_get_int_range_min (width_value);
252     max_width = gst_value_get_int_range_max (width_value);
253     fail_unless (min_width == 16 && max_width == 4096);
254
255     height_value = gst_structure_get_value (s1, "height");
256     fail_unless (height_value != NULL);
257     fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value));
258     min_height = gst_value_get_int_range_min (height_value);
259     max_height = gst_value_get_int_range_max (height_value);
260     fail_unless (min_height == 16 && max_height == 4096);
261   }
262
263   fail_unless (gst_structure_has_name (s2, "video/x-raw-yuv"));
264   {
265     const GValue *framerate_value;
266     const GValue *format_value;
267     const GValue *width_value;
268     const GValue *height_value;
269     const GValue *val_fps;
270     GValue test_fps = { 0, };
271     gint min_width, max_width;
272     gint min_height, max_height;
273
274     format_value = gst_structure_get_value (s2, "format");
275     fail_unless (format_value != NULL);
276     fail_unless (GST_VALUE_HOLDS_LIST (format_value));
277     fail_unless (gst_value_list_get_size (format_value) == 3);
278     fail_unless (check_fourcc_list (format_value) == TRUE);
279
280     g_value_init (&test_fps, GST_TYPE_FRACTION);
281     framerate_value = gst_structure_get_value (s2, "framerate");
282     fail_unless (framerate_value != NULL);
283     fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
284
285     val_fps = gst_value_get_fraction_range_min (framerate_value);
286     gst_value_set_fraction (&test_fps, 1, 100);
287     fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
288
289     val_fps = gst_value_get_fraction_range_max (framerate_value);
290     gst_value_set_fraction (&test_fps, 100, 1);
291     fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
292
293     g_value_unset (&test_fps);
294
295     width_value = gst_structure_get_value (s2, "width");
296     fail_unless (width_value != NULL);
297     fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value));
298     min_width = gst_value_get_int_range_min (width_value);
299     max_width = gst_value_get_int_range_max (width_value);
300     fail_unless (min_width == 16 && max_width == 4096);
301
302     height_value = gst_structure_get_value (s2, "height");
303     fail_unless (height_value != NULL);
304     fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value));
305     min_height = gst_value_get_int_range_min (height_value);
306     max_height = gst_value_get_int_range_max (height_value);
307     fail_unless (min_height == 16 && max_height == 4096);
308   }
309
310   gst_caps_unref (caps);
311 }
312
313 GST_END_TEST;
314
315 GST_START_TEST (test_truncate)
316 {
317   GstCaps *caps;
318
319   caps = gst_caps_from_string (non_simple_caps_string);
320   fail_unless (caps != NULL,
321       "gst_caps_from_string (non_simple_caps_string) failed");
322   fail_unless_equals_int (gst_caps_get_size (caps), 4);
323   gst_caps_truncate (caps);
324   fail_unless_equals_int (gst_caps_get_size (caps), 1);
325   gst_caps_unref (caps);
326 }
327
328 GST_END_TEST;
329
330 GST_START_TEST (test_merge_fundamental)
331 {
332   GstCaps *c1, *c2;
333
334   /* ANY + specific = ANY */
335   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
336   c2 = gst_caps_new_any ();
337   gst_caps_merge (c2, c1);
338   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
339   fail_unless (gst_caps_get_size (c2) == 0, NULL);
340   fail_unless (gst_caps_is_any (c2), NULL);
341   gst_caps_unref (c2);
342
343   /* specific + ANY = ANY */
344   c2 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
345   c1 = gst_caps_new_any ();
346   gst_caps_merge (c2, c1);
347   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
348   fail_unless (gst_caps_get_size (c2) == 0, NULL);
349   fail_unless (gst_caps_is_any (c2), NULL);
350   gst_caps_unref (c2);
351
352   /* EMPTY + specific = specific */
353   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
354   c2 = gst_caps_new_empty ();
355   gst_caps_merge (c2, c1);
356   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
357   fail_unless (gst_caps_get_size (c2) == 1, NULL);
358   fail_if (gst_caps_is_empty (c2), NULL);
359   gst_caps_unref (c2);
360
361   /* specific + EMPTY = specific */
362   c2 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
363   c1 = gst_caps_new_empty ();
364   gst_caps_merge (c2, c1);
365   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
366   fail_unless (gst_caps_get_size (c2) == 1, NULL);
367   fail_if (gst_caps_is_empty (c2), NULL);
368   gst_caps_unref (c2);
369 }
370
371 GST_END_TEST;
372
373 GST_START_TEST (test_merge_same)
374 {
375   GstCaps *c1, *c2, *test;
376
377   /* this is the same */
378   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
379   c2 = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
380   gst_caps_merge (c2, c1);
381   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
382   fail_unless (gst_caps_get_size (c2) == 1, NULL);
383   test = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
384   fail_unless (gst_caps_is_equal (c2, test));
385   gst_caps_unref (test);
386   gst_caps_unref (c2);
387
388   /* and so is this */
389   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
390   c2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100");
391   gst_caps_merge (c2, c1);
392   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
393   fail_unless (gst_caps_get_size (c2) == 1, NULL);
394   gst_caps_unref (c2);
395
396   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
397   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
398   gst_caps_merge (c2, c1);
399   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
400   fail_unless (gst_caps_get_size (c2) == 2, NULL);
401   gst_caps_unref (c2);
402
403   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
404   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
405   gst_caps_merge (c2, c1);
406   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
407   fail_unless (gst_caps_get_size (c2) == 2, NULL);
408   gst_caps_unref (c2);
409
410   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
411   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
412   gst_caps_merge (c2, c1);
413   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
414   fail_unless (gst_caps_get_size (c2) == 1, NULL);
415   gst_caps_unref (c2);
416
417   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
418   c2 = gst_caps_from_string ("video/x-bar, data=(buffer)AA");
419   gst_caps_merge (c2, c1);
420   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
421   fail_unless (gst_caps_get_size (c2) == 2, NULL);
422   gst_caps_unref (c2);
423 }
424
425 GST_END_TEST;
426
427 GST_START_TEST (test_merge_subset)
428 {
429   GstCaps *c1, *c2, *test;
430
431   /* the 2nd is already covered */
432   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
433   c1 = gst_caps_from_string ("audio/x-raw-int,channels=1");
434   gst_caps_merge (c2, c1);
435   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
436   fail_unless (gst_caps_get_size (c2) == 1, NULL);
437   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
438   fail_unless (gst_caps_is_equal (c2, test));
439   gst_caps_unref (c2);
440   gst_caps_unref (test);
441
442   /* here it is not */
443   c2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100");
444   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2],rate=44100");
445   gst_caps_merge (c2, c1);
446   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
447   fail_unless (gst_caps_get_size (c2) == 2, NULL);
448   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,2],rate=44100");
449   fail_unless (gst_caps_is_equal (c2, test));
450   gst_caps_unref (c2);
451   gst_caps_unref (test);
452
453   /* second one was already contained in the first one */
454   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,3]");
455   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
456   gst_caps_merge (c2, c1);
457   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
458   fail_unless (gst_caps_get_size (c2) == 1, NULL);
459   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,3]");
460   fail_unless (gst_caps_is_equal (c2, test));
461   gst_caps_unref (c2);
462   gst_caps_unref (test);
463
464   /* second one was already contained in the first one */
465   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
466   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
467   gst_caps_merge (c2, c1);
468   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
469   fail_unless (gst_caps_get_size (c2) == 1, NULL);
470   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
471   fail_unless (gst_caps_is_equal (c2, test));
472   gst_caps_unref (c2);
473   gst_caps_unref (test);
474
475   /* second one was already contained in the first one */
476   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
477   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[2,4]");
478   gst_caps_merge (c2, c1);
479   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
480   fail_unless (gst_caps_get_size (c2) == 1, NULL);
481   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
482   fail_unless (gst_caps_is_equal (c2, test));
483   gst_caps_unref (c2);
484   gst_caps_unref (test);
485
486   /* second one was already contained in the first one */
487   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
488   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[2,3]");
489   gst_caps_merge (c2, c1);
490   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
491   fail_unless (gst_caps_get_size (c2) == 1, NULL);
492   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
493   fail_unless (gst_caps_is_equal (c2, test));
494   gst_caps_unref (c2);
495   gst_caps_unref (test);
496
497   /* these caps cannot be merged */
498   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[2,3]");
499   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
500   gst_caps_merge (c2, c1);
501   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
502   fail_unless (gst_caps_get_size (c2) == 2, NULL);
503   test =
504       gst_caps_from_string
505       ("audio/x-raw-int,channels=[2,3];audio/x-raw-int,channels=[1,4]");
506   fail_unless (gst_caps_is_equal (c2, test));
507   gst_caps_unref (c2);
508   gst_caps_unref (test);
509
510   /* these caps cannot be merged */
511   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
512   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,3]");
513   gst_caps_merge (c2, c1);
514   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
515   fail_unless (gst_caps_get_size (c2) == 2, NULL);
516   test =
517       gst_caps_from_string
518       ("audio/x-raw-int,channels=[1,2];audio/x-raw-int,channels=[1,3]");
519   fail_unless (gst_caps_is_equal (c2, test));
520   gst_caps_unref (c2);
521   gst_caps_unref (test);
522
523   c2 = gst_caps_from_string ("audio/x-raw-int,channels={1,2}");
524   c1 = gst_caps_from_string ("audio/x-raw-int,channels={1,2,3,4}");
525   gst_caps_merge (c2, c1);
526   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
527   fail_unless (gst_caps_get_size (c2) == 2, NULL);
528   test = gst_caps_from_string ("audio/x-raw-int,channels={1,2};"
529       "audio/x-raw-int,channels={1,2,3,4}");
530   fail_unless (gst_caps_is_equal (c2, test));
531   gst_caps_unref (c2);
532   gst_caps_unref (test);
533
534   c2 = gst_caps_from_string ("audio/x-raw-int,channels={1,2}");
535   c1 = gst_caps_from_string ("audio/x-raw-int,channels={1,3}");
536   gst_caps_merge (c2, c1);
537   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
538   fail_unless (gst_caps_get_size (c2) == 2, NULL);
539   test = gst_caps_from_string ("audio/x-raw-int,channels={1,2};"
540       "audio/x-raw-int,channels={1,3}");
541   fail_unless (gst_caps_is_equal (c2, test));
542   gst_caps_unref (c2);
543   gst_caps_unref (test);
544
545   c2 = gst_caps_from_string
546       ("video/x-raw-yuv, framerate=(fraction){ 15/2, 5/1 }");
547   c1 = gst_caps_from_string
548       ("video/x-raw-yuv, framerate=(fraction){ 15/1, 5/1 }");
549   test = gst_caps_copy (c1);
550   gst_caps_merge (c2, c1);
551   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
552   fail_unless (gst_caps_is_subset (test, c2));
553   gst_caps_unref (test);
554   gst_caps_unref (c2);
555 }
556
557 GST_END_TEST;
558
559 GST_START_TEST (test_intersect)
560 {
561   GstStructure *s;
562   GstCaps *c1, *c2, *ci1, *ci2;
563
564   /* field not specified = any value possible, so the intersection
565    * should keep fields which are only part of one set of caps */
566   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
567   c1 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420");
568
569   ci1 = gst_caps_intersect (c2, c1);
570   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
571   fail_unless (gst_caps_get_size (ci1) == 1, NULL);
572   s = gst_caps_get_structure (ci1, 0);
573   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
574   fail_unless (gst_structure_get_value (s, "format") != NULL);
575   fail_unless (gst_structure_get_value (s, "width") != NULL);
576
577   /* with changed order */
578   ci2 = gst_caps_intersect (c1, c2);
579   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
580   fail_unless (gst_caps_get_size (ci2) == 1, NULL);
581   s = gst_caps_get_structure (ci2, 0);
582   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
583   fail_unless (gst_structure_get_value (s, "format") != NULL);
584   fail_unless (gst_structure_get_value (s, "width") != NULL);
585
586   fail_unless (gst_caps_is_equal (ci1, ci2));
587
588   gst_caps_unref (ci1);
589   gst_caps_unref (ci2);
590
591   gst_caps_unref (c1);
592   gst_caps_unref (c2);
593
594   /* ========== */
595
596   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
597   c1 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=30");
598
599   ci1 = gst_caps_intersect (c2, c1);
600   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
601   fail_unless (gst_caps_is_empty (ci1), NULL);
602
603   /* with changed order */
604   ci2 = gst_caps_intersect (c1, c2);
605   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
606   fail_unless (gst_caps_is_empty (ci2), NULL);
607
608   fail_unless (gst_caps_is_equal (ci1, ci2));
609
610   gst_caps_unref (ci1);
611   gst_caps_unref (ci2);
612
613   gst_caps_unref (c1);
614   gst_caps_unref (c2);
615
616   /* ========== */
617
618   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
619   c1 = gst_caps_from_string ("video/x-raw-rgb,format=(fourcc)I420,width=20");
620
621   ci1 = gst_caps_intersect (c2, c1);
622   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
623   fail_unless (gst_caps_is_empty (ci1), NULL);
624
625   /* with changed order */
626   ci2 = gst_caps_intersect (c1, c2);
627   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
628   fail_unless (gst_caps_is_empty (ci2), NULL);
629
630   fail_unless (gst_caps_is_equal (ci1, ci2));
631
632   gst_caps_unref (ci1);
633   gst_caps_unref (ci2);
634
635   gst_caps_unref (c1);
636   gst_caps_unref (c2);
637
638   /* ========== */
639
640   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
641   c1 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,height=30");
642
643   ci1 = gst_caps_intersect (c2, c1);
644   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
645   fail_unless (gst_caps_get_size (ci1) == 1, NULL);
646   s = gst_caps_get_structure (ci1, 0);
647   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
648   fail_unless (gst_structure_get_value (s, "format") != NULL);
649   fail_unless (gst_structure_get_value (s, "width") != NULL);
650   fail_unless (gst_structure_get_value (s, "height") != NULL);
651
652   /* with changed order */
653   ci2 = gst_caps_intersect (c1, c2);
654   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
655   fail_unless (gst_caps_get_size (ci2) == 1, NULL);
656   s = gst_caps_get_structure (ci2, 0);
657   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
658   fail_unless (gst_structure_get_value (s, "format") != NULL);
659   fail_unless (gst_structure_get_value (s, "height") != NULL);
660   fail_unless (gst_structure_get_value (s, "width") != NULL);
661
662   fail_unless (gst_caps_is_equal (ci1, ci2));
663
664   gst_caps_unref (ci1);
665   gst_caps_unref (ci2);
666
667   gst_caps_unref (c1);
668   gst_caps_unref (c2);
669 }
670
671 GST_END_TEST;
672
673 GST_START_TEST (test_intersect2)
674 {
675   GstCaps *caps1, *caps2, *icaps;
676
677   /* tests array subtraction */
678   caps1 = gst_caps_from_string ("audio/x-raw-float, "
679       "channel-positions=(int)<                      "
680       "{ 1, 2, 3, 4, 5, 6 },                         "
681       "{ 1, 2, 3, 4, 5, 6 },                         "
682       "{ 1, 2, 3, 4, 5, 6 },                         "
683       "{ 1, 2, 3, 4, 5, 6 },                         "
684       "{ 1, 2, 3, 4, 5, 6 },                         " "{ 1, 2, 3, 4, 5, 6 }>");
685   caps2 = gst_caps_from_string ("audio/x-raw-float, "
686       "channel-positions=(int)< 1, 2, 3, 4, 5, 6 >");
687   icaps = gst_caps_intersect (caps1, caps2);
688   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
689   fail_if (gst_caps_is_empty (icaps));
690   fail_unless (gst_caps_is_equal (icaps, caps2));
691   gst_caps_unref (caps1);
692   gst_caps_unref (caps2);
693   gst_caps_unref (icaps);
694
695   /* ===== */
696
697   caps1 = gst_caps_from_string ("some/type, foo=(int)< { 1, 2 }, { 3, 4} >");
698   caps2 = gst_caps_from_string ("some/type, foo=(int)< 1, 3 >");
699   icaps = gst_caps_intersect (caps1, caps2);
700   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
701   fail_if (gst_caps_is_empty (icaps));
702   fail_unless (gst_caps_is_equal (icaps, caps2));
703   gst_caps_unref (caps1);
704   gst_caps_unref (caps2);
705   gst_caps_unref (icaps);
706 }
707
708 GST_END_TEST;
709
710
711 GST_START_TEST (test_intersect_zigzag)
712 {
713   GstCaps *caps1, *caps2, *icaps, *result;
714
715   /* tests if caps order is maintained */
716   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
717   caps2 = gst_caps_from_string ("format/D; format/A; format/B; format/C");
718
719   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
720   result = gst_caps_from_string ("format/B; format/A; format/D; format/C");
721   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
722   fail_if (gst_caps_is_empty (icaps));
723   fail_unless (gst_caps_is_equal (icaps, result));
724   gst_caps_unref (icaps);
725   gst_caps_unref (result);
726
727   icaps = gst_caps_intersect_full (caps2, caps1, GST_CAPS_INTERSECT_FIRST);
728   result = gst_caps_from_string ("format/A; format/B; format/D; format/C");
729   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
730   fail_if (gst_caps_is_empty (icaps));
731   fail_unless (gst_caps_is_equal (icaps, result));
732   gst_caps_unref (icaps);
733   gst_caps_unref (result);
734
735   gst_caps_unref (caps1);
736   gst_caps_unref (caps2);
737 }
738
739 GST_END_TEST;
740
741
742 GST_START_TEST (test_intersect_first)
743 {
744   GstCaps *caps1, *caps2, *icaps, *result;
745
746   /* tests if caps order is maintained */
747   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
748   caps2 = gst_caps_from_string ("format/C; format/D; format/A");
749   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_FIRST);
750   result = gst_caps_from_string ("format/A; format/C; format/D");
751   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
752   fail_if (gst_caps_is_empty (icaps));
753   fail_unless (gst_caps_is_equal (icaps, result));
754   gst_caps_unref (caps1);
755   gst_caps_unref (caps2);
756   gst_caps_unref (icaps);
757   gst_caps_unref (result);
758 }
759
760 GST_END_TEST;
761
762
763 GST_START_TEST (test_intersect_first2)
764 {
765   GstCaps *caps1, *caps2, *icaps, *result;
766
767   /* tests if caps order is maintained */
768   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
769   caps2 = gst_caps_from_string ("format/D; format/A; format/B; format/C");
770
771   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_FIRST);
772   result = gst_caps_from_string ("format/A; format/B; format/C; format/D");
773   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
774   fail_if (gst_caps_is_empty (icaps));
775   fail_unless (gst_caps_is_equal (icaps, result));
776   gst_caps_unref (icaps);
777   gst_caps_unref (result);
778
779   icaps = gst_caps_intersect_full (caps2, caps1, GST_CAPS_INTERSECT_FIRST);
780   result = gst_caps_from_string ("format/D; format/A; format/B; format/C");
781   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
782   fail_if (gst_caps_is_empty (icaps));
783   fail_unless (gst_caps_is_equal (icaps, result));
784   gst_caps_unref (icaps);
785   gst_caps_unref (result);
786
787   gst_caps_unref (caps1);
788   gst_caps_unref (caps2);
789 }
790
791 GST_END_TEST;
792
793 GST_START_TEST (test_intersect_duplication)
794 {
795   GstCaps *c1, *c2, *test;
796
797   c1 = gst_caps_from_string
798       ("audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ]");
799   c2 = gst_caps_from_string
800       ("audio/x-raw-int, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ], endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }; audio/x-raw-int, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 11 ], endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }; audio/x-raw-int, width=(int)16, depth=(int)[ 1, 16 ], rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 11 ], endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }");
801
802   test = gst_caps_intersect_full (c1, c2, GST_CAPS_INTERSECT_FIRST);
803   fail_unless_equals_int (gst_caps_get_size (test), 1);
804   fail_unless (gst_caps_is_equal (c1, test));
805   gst_caps_unref (c1);
806   gst_caps_unref (c2);
807   gst_caps_unref (test);
808 }
809
810 GST_END_TEST;
811
812 static gboolean
813 _caps_is_fixed_foreach (GQuark field_id, const GValue * value, gpointer unused)
814 {
815   return gst_value_is_fixed (value);
816 }
817
818
819 GST_START_TEST (test_normalize)
820 {
821   GstCaps *in, *norm, *out;
822   guint i;
823
824   in = gst_caps_from_string ("some/type, foo=(int){ 1 , 2 }");
825   out = gst_caps_from_string ("some/type, foo=(int) 1; some/type, foo=(int) 2");
826   norm = gst_caps_normalize (in);
827   fail_if (gst_caps_is_empty (norm));
828   fail_unless (gst_caps_is_equal (norm, out));
829   for (i = 0; i < gst_caps_get_size (norm); i++) {
830     GstStructure *st = gst_caps_get_structure (norm, i);
831     /* Make sure all fields of all structures are fixed */
832     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
833   }
834
835   gst_caps_unref (in);
836   gst_caps_unref (out);
837   gst_caps_unref (norm);
838
839   in = gst_caps_from_string
840       ("some/type, foo=(int){ 1 , 2 }, bar=(int){ 3, 4 }");
841   out =
842       gst_caps_from_string
843       ("some/type, foo=(int) 1, bar=(int) 3; some/type, foo=(int) 2, bar=(int) 3;"
844       "some/type, foo=(int) 1, bar=(int) 4; some/type, foo=(int) 2, bar=(int) 4;");
845   norm = gst_caps_normalize (in);
846   fail_if (gst_caps_is_empty (norm));
847   fail_unless (gst_caps_is_equal (norm, out));
848   for (i = 0; i < gst_caps_get_size (norm); i++) {
849     GstStructure *st = gst_caps_get_structure (norm, i);
850     /* Make sure all fields of all structures are fixed */
851     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
852   }
853
854   gst_caps_unref (in);
855   gst_caps_unref (out);
856   gst_caps_unref (norm);
857
858   in = gst_caps_from_string
859       ("some/type, foo=(string){ 1 , 2 }, bar=(string) { 3 }");
860   out =
861       gst_caps_from_string
862       ("some/type, foo=(string) 1, bar=(string) 3; some/type, foo=(string) 2, bar=(string) 3");
863   norm = gst_caps_normalize (in);
864   fail_if (gst_caps_is_empty (norm));
865   fail_unless (gst_caps_is_equal (norm, out));
866   for (i = 0; i < gst_caps_get_size (norm); i++) {
867     GstStructure *st = gst_caps_get_structure (norm, i);
868     /* Make sure all fields of all structures are fixed */
869     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
870   }
871
872   gst_caps_unref (in);
873   gst_caps_unref (out);
874   gst_caps_unref (norm);
875 }
876
877 GST_END_TEST;
878
879 GST_START_TEST (test_broken)
880 {
881   GstCaps *c1;
882
883   /* NULL is not valid for media_type */
884   ASSERT_CRITICAL (c1 =
885       gst_caps_new_simple (NULL, "field", G_TYPE_INT, 1, NULL));
886   fail_if (c1);
887
888 #ifndef G_DISABLE_CHECKS
889   /* such a name is not valid, see gst_structure_validate_name() */
890   ASSERT_CRITICAL (c1 =
891       gst_caps_new_simple ("1#@abc", "field", G_TYPE_INT, 1, NULL));
892   fail_if (c1);
893 #endif
894 }
895
896 GST_END_TEST;
897
898
899 static Suite *
900 gst_caps_suite (void)
901 {
902   Suite *s = suite_create ("GstCaps");
903   TCase *tc_chain = tcase_create ("operations");
904
905   suite_add_tcase (s, tc_chain);
906   tcase_add_test (tc_chain, test_from_string);
907   tcase_add_test (tc_chain, test_double_append);
908   tcase_add_test (tc_chain, test_mutability);
909   tcase_add_test (tc_chain, test_static_caps);
910   tcase_add_test (tc_chain, test_simplify);
911   tcase_add_test (tc_chain, test_truncate);
912   tcase_add_test (tc_chain, test_merge_fundamental);
913   tcase_add_test (tc_chain, test_merge_same);
914   tcase_add_test (tc_chain, test_merge_subset);
915   tcase_add_test (tc_chain, test_intersect);
916   tcase_add_test (tc_chain, test_intersect2);
917   tcase_add_test (tc_chain, test_intersect_zigzag);
918   tcase_add_test (tc_chain, test_intersect_first);
919   tcase_add_test (tc_chain, test_intersect_first2);
920   tcase_add_test (tc_chain, test_intersect_duplication);
921   tcase_add_test (tc_chain, test_normalize);
922   tcase_add_test (tc_chain, test_broken);
923
924   return s;
925 }
926
927 GST_CHECK_MAIN (gst_caps);