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_subset)
331 {
332   GstCaps *c1, *c2;
333
334   c1 = gst_caps_from_string ("video/x-raw-yuv; video/x-raw-rgb");
335   c2 = gst_caps_from_string ("video/x-raw-yuv, format=(fourcc)YUY2");
336   fail_unless (gst_caps_is_subset (c2, c1));
337   fail_if (gst_caps_is_subset (c1, c2));
338   gst_caps_unref (c1);
339   gst_caps_unref (c2);
340
341   c1 = gst_caps_from_string
342       ("audio/x-raw-int, channels=(int)[ 1, 2 ], rate=(int)44100");
343   c2 = gst_caps_from_string
344       ("audio/x-raw-int, channels=(int)1, rate=(int)44100");
345   fail_unless (gst_caps_is_subset (c2, c1));
346   fail_if (gst_caps_is_subset (c1, c2));
347   gst_caps_unref (c1);
348   gst_caps_unref (c2);
349 }
350
351 GST_END_TEST;
352
353 GST_START_TEST (test_merge_fundamental)
354 {
355   GstCaps *c1, *c2;
356
357   /* ANY + specific = ANY */
358   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
359   c2 = gst_caps_new_any ();
360   gst_caps_merge (c2, c1);
361   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
362   fail_unless (gst_caps_get_size (c2) == 0, NULL);
363   fail_unless (gst_caps_is_any (c2), NULL);
364   gst_caps_unref (c2);
365
366   /* specific + ANY = ANY */
367   c2 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
368   c1 = gst_caps_new_any ();
369   gst_caps_merge (c2, c1);
370   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
371   fail_unless (gst_caps_get_size (c2) == 0, NULL);
372   fail_unless (gst_caps_is_any (c2), NULL);
373   gst_caps_unref (c2);
374
375   /* EMPTY + specific = specific */
376   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
377   c2 = gst_caps_new_empty ();
378   gst_caps_merge (c2, c1);
379   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
380   fail_unless (gst_caps_get_size (c2) == 1, NULL);
381   fail_if (gst_caps_is_empty (c2), NULL);
382   gst_caps_unref (c2);
383
384   /* specific + EMPTY = specific */
385   c2 = gst_caps_from_string ("audio/x-raw-int,rate=44100");
386   c1 = gst_caps_new_empty ();
387   gst_caps_merge (c2, c1);
388   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
389   fail_unless (gst_caps_get_size (c2) == 1, NULL);
390   fail_if (gst_caps_is_empty (c2), NULL);
391   gst_caps_unref (c2);
392 }
393
394 GST_END_TEST;
395
396 GST_START_TEST (test_merge_same)
397 {
398   GstCaps *c1, *c2, *test;
399
400   /* this is the same */
401   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
402   c2 = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
403   gst_caps_merge (c2, c1);
404   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
405   fail_unless (gst_caps_get_size (c2) == 1, NULL);
406   test = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
407   fail_unless (gst_caps_is_equal (c2, test));
408   gst_caps_unref (test);
409   gst_caps_unref (c2);
410
411   /* and so is this */
412   c1 = gst_caps_from_string ("audio/x-raw-int,rate=44100,channels=1");
413   c2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100");
414   gst_caps_merge (c2, c1);
415   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
416   fail_unless (gst_caps_get_size (c2) == 1, NULL);
417   gst_caps_unref (c2);
418
419   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
420   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
421   gst_caps_merge (c2, c1);
422   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
423   fail_unless (gst_caps_get_size (c2) == 2, NULL);
424   gst_caps_unref (c2);
425
426   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
427   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
428   gst_caps_merge (c2, c1);
429   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
430   fail_unless (gst_caps_get_size (c2) == 2, NULL);
431   gst_caps_unref (c2);
432
433   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
434   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
435   gst_caps_merge (c2, c1);
436   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
437   fail_unless (gst_caps_get_size (c2) == 1, NULL);
438   gst_caps_unref (c2);
439
440   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
441   c2 = gst_caps_from_string ("video/x-bar, data=(buffer)AA");
442   gst_caps_merge (c2, c1);
443   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
444   fail_unless (gst_caps_get_size (c2) == 2, NULL);
445   gst_caps_unref (c2);
446 }
447
448 GST_END_TEST;
449
450 GST_START_TEST (test_merge_subset)
451 {
452   GstCaps *c1, *c2, *test;
453
454   /* the 2nd is already covered */
455   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
456   c1 = gst_caps_from_string ("audio/x-raw-int,channels=1");
457   gst_caps_merge (c2, c1);
458   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
459   fail_unless (gst_caps_get_size (c2) == 1, NULL);
460   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
461   fail_unless (gst_caps_is_equal (c2, test));
462   gst_caps_unref (c2);
463   gst_caps_unref (test);
464
465   /* here it is not */
466   c2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100");
467   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2],rate=44100");
468   gst_caps_merge (c2, c1);
469   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
470   fail_unless (gst_caps_get_size (c2) == 2, NULL);
471   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,2],rate=44100");
472   fail_unless (gst_caps_is_equal (c2, test));
473   gst_caps_unref (c2);
474   gst_caps_unref (test);
475
476   /* second one was already contained in the first one */
477   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,3]");
478   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
479   gst_caps_merge (c2, c1);
480   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
481   fail_unless (gst_caps_get_size (c2) == 1, NULL);
482   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,3]");
483   fail_unless (gst_caps_is_equal (c2, test));
484   gst_caps_unref (c2);
485   gst_caps_unref (test);
486
487   /* second one was already contained in the first one */
488   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
489   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,2]");
490   gst_caps_merge (c2, c1);
491   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
492   fail_unless (gst_caps_get_size (c2) == 1, NULL);
493   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
494   fail_unless (gst_caps_is_equal (c2, test));
495   gst_caps_unref (c2);
496   gst_caps_unref (test);
497
498   /* second one was already contained in the first one */
499   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
500   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[2,4]");
501   gst_caps_merge (c2, c1);
502   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
503   fail_unless (gst_caps_get_size (c2) == 1, NULL);
504   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
505   fail_unless (gst_caps_is_equal (c2, test));
506   gst_caps_unref (c2);
507   gst_caps_unref (test);
508
509   /* second one was already contained in the first one */
510   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
511   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[2,3]");
512   gst_caps_merge (c2, c1);
513   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
514   fail_unless (gst_caps_get_size (c2) == 1, NULL);
515   test = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
516   fail_unless (gst_caps_is_equal (c2, test));
517   gst_caps_unref (c2);
518   gst_caps_unref (test);
519
520   /* these caps cannot be merged */
521   c2 = gst_caps_from_string ("audio/x-raw-int,channels=[2,3]");
522   c1 = gst_caps_from_string ("audio/x-raw-int,channels=[1,4]");
523   gst_caps_merge (c2, c1);
524   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
525   fail_unless (gst_caps_get_size (c2) == 2, NULL);
526   test =
527       gst_caps_from_string
528       ("audio/x-raw-int,channels=[2,3];audio/x-raw-int,channels=[1,4]");
529   fail_unless (gst_caps_is_equal (c2, test));
530   gst_caps_unref (c2);
531   gst_caps_unref (test);
532
533   /* these caps cannot be merged */
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 =
540       gst_caps_from_string
541       ("audio/x-raw-int,channels=[1,2];audio/x-raw-int,channels=[1,3]");
542   fail_unless (gst_caps_is_equal (c2, test));
543   gst_caps_unref (c2);
544   gst_caps_unref (test);
545
546   c2 = gst_caps_from_string ("audio/x-raw-int,channels={1,2}");
547   c1 = gst_caps_from_string ("audio/x-raw-int,channels={1,2,3,4}");
548   gst_caps_merge (c2, c1);
549   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
550   fail_unless (gst_caps_get_size (c2) == 2, NULL);
551   test = gst_caps_from_string ("audio/x-raw-int,channels={1,2};"
552       "audio/x-raw-int,channels={1,2,3,4}");
553   fail_unless (gst_caps_is_equal (c2, test));
554   gst_caps_unref (c2);
555   gst_caps_unref (test);
556
557   c2 = gst_caps_from_string ("audio/x-raw-int,channels={1,2}");
558   c1 = gst_caps_from_string ("audio/x-raw-int,channels={1,3}");
559   gst_caps_merge (c2, c1);
560   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
561   fail_unless (gst_caps_get_size (c2) == 2, NULL);
562   test = gst_caps_from_string ("audio/x-raw-int,channels={1,2};"
563       "audio/x-raw-int,channels={1,3}");
564   fail_unless (gst_caps_is_equal (c2, test));
565   gst_caps_unref (c2);
566   gst_caps_unref (test);
567
568   c2 = gst_caps_from_string
569       ("video/x-raw-yuv, framerate=(fraction){ 15/2, 5/1 }");
570   c1 = gst_caps_from_string
571       ("video/x-raw-yuv, framerate=(fraction){ 15/1, 5/1 }");
572   test = gst_caps_copy (c1);
573   gst_caps_merge (c2, c1);
574   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
575   fail_unless (gst_caps_is_subset (test, c2));
576   gst_caps_unref (test);
577   gst_caps_unref (c2);
578
579   c2 = gst_caps_from_string ("audio/x-raw-int");
580   c1 = gst_caps_from_string ("audio/x-raw-int,channels=1");
581   gst_caps_merge (c2, c1);
582   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
583   fail_unless (gst_caps_get_size (c2) == 1, NULL);
584   test = gst_caps_from_string ("audio/x-raw-int");
585   fail_unless (gst_caps_is_equal (c2, test));
586   gst_caps_unref (c2);
587   gst_caps_unref (test);
588
589   c2 = gst_caps_from_string ("audio/x-raw-int,channels=1");
590   c1 = gst_caps_from_string ("audio/x-raw-int");
591   gst_caps_merge (c2, c1);
592   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
593   fail_unless (gst_caps_get_size (c2) == 2, NULL);
594   test = gst_caps_from_string ("audio/x-raw-int,channels=1; audio/x-raw-int");
595   fail_unless (gst_caps_is_equal (c2, test));
596   gst_caps_unref (c2);
597   gst_caps_unref (test);
598 }
599
600 GST_END_TEST;
601
602 GST_START_TEST (test_intersect)
603 {
604   GstStructure *s;
605   GstCaps *c1, *c2, *ci1, *ci2;
606
607   /* field not specified = any value possible, so the intersection
608    * should keep fields which are only part of one set of caps */
609   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
610   c1 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420");
611
612   ci1 = gst_caps_intersect (c2, c1);
613   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
614   fail_unless (gst_caps_get_size (ci1) == 1, NULL);
615   s = gst_caps_get_structure (ci1, 0);
616   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
617   fail_unless (gst_structure_get_value (s, "format") != NULL);
618   fail_unless (gst_structure_get_value (s, "width") != NULL);
619
620   /* with changed order */
621   ci2 = gst_caps_intersect (c1, c2);
622   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
623   fail_unless (gst_caps_get_size (ci2) == 1, NULL);
624   s = gst_caps_get_structure (ci2, 0);
625   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
626   fail_unless (gst_structure_get_value (s, "format") != NULL);
627   fail_unless (gst_structure_get_value (s, "width") != NULL);
628
629   fail_unless (gst_caps_is_equal (ci1, ci2));
630
631   gst_caps_unref (ci1);
632   gst_caps_unref (ci2);
633
634   gst_caps_unref (c1);
635   gst_caps_unref (c2);
636
637   /* ========== */
638
639   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
640   c1 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=30");
641
642   ci1 = gst_caps_intersect (c2, c1);
643   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
644   fail_unless (gst_caps_is_empty (ci1), NULL);
645
646   /* with changed order */
647   ci2 = gst_caps_intersect (c1, c2);
648   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
649   fail_unless (gst_caps_is_empty (ci2), NULL);
650
651   fail_unless (gst_caps_is_equal (ci1, ci2));
652
653   gst_caps_unref (ci1);
654   gst_caps_unref (ci2);
655
656   gst_caps_unref (c1);
657   gst_caps_unref (c2);
658
659   /* ========== */
660
661   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
662   c1 = gst_caps_from_string ("video/x-raw-rgb,format=(fourcc)I420,width=20");
663
664   ci1 = gst_caps_intersect (c2, c1);
665   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
666   fail_unless (gst_caps_is_empty (ci1), NULL);
667
668   /* with changed order */
669   ci2 = gst_caps_intersect (c1, c2);
670   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
671   fail_unless (gst_caps_is_empty (ci2), NULL);
672
673   fail_unless (gst_caps_is_equal (ci1, ci2));
674
675   gst_caps_unref (ci1);
676   gst_caps_unref (ci2);
677
678   gst_caps_unref (c1);
679   gst_caps_unref (c2);
680
681   /* ========== */
682
683   c2 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,width=20");
684   c1 = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420,height=30");
685
686   ci1 = gst_caps_intersect (c2, c1);
687   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
688   fail_unless (gst_caps_get_size (ci1) == 1, NULL);
689   s = gst_caps_get_structure (ci1, 0);
690   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
691   fail_unless (gst_structure_get_value (s, "format") != NULL);
692   fail_unless (gst_structure_get_value (s, "width") != NULL);
693   fail_unless (gst_structure_get_value (s, "height") != NULL);
694
695   /* with changed order */
696   ci2 = gst_caps_intersect (c1, c2);
697   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
698   fail_unless (gst_caps_get_size (ci2) == 1, NULL);
699   s = gst_caps_get_structure (ci2, 0);
700   fail_unless (gst_structure_has_name (s, "video/x-raw-yuv"));
701   fail_unless (gst_structure_get_value (s, "format") != NULL);
702   fail_unless (gst_structure_get_value (s, "height") != NULL);
703   fail_unless (gst_structure_get_value (s, "width") != NULL);
704
705   fail_unless (gst_caps_is_equal (ci1, ci2));
706
707   gst_caps_unref (ci1);
708   gst_caps_unref (ci2);
709
710   gst_caps_unref (c1);
711   gst_caps_unref (c2);
712 }
713
714 GST_END_TEST;
715
716 GST_START_TEST (test_intersect2)
717 {
718   GstCaps *caps1, *caps2, *icaps;
719
720   /* tests array subtraction */
721   caps1 = gst_caps_from_string ("audio/x-raw-float, "
722       "channel-positions=(int)<                      "
723       "{ 1, 2, 3, 4, 5, 6 },                         "
724       "{ 1, 2, 3, 4, 5, 6 },                         "
725       "{ 1, 2, 3, 4, 5, 6 },                         "
726       "{ 1, 2, 3, 4, 5, 6 },                         "
727       "{ 1, 2, 3, 4, 5, 6 },                         " "{ 1, 2, 3, 4, 5, 6 }>");
728   caps2 = gst_caps_from_string ("audio/x-raw-float, "
729       "channel-positions=(int)< 1, 2, 3, 4, 5, 6 >");
730   icaps = gst_caps_intersect (caps1, caps2);
731   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
732   fail_if (gst_caps_is_empty (icaps));
733   fail_unless (gst_caps_is_equal (icaps, caps2));
734   gst_caps_unref (caps1);
735   gst_caps_unref (caps2);
736   gst_caps_unref (icaps);
737
738   /* ===== */
739
740   caps1 = gst_caps_from_string ("some/type, foo=(int)< { 1, 2 }, { 3, 4} >");
741   caps2 = gst_caps_from_string ("some/type, foo=(int)< 1, 3 >");
742   icaps = gst_caps_intersect (caps1, caps2);
743   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
744   fail_if (gst_caps_is_empty (icaps));
745   fail_unless (gst_caps_is_equal (icaps, caps2));
746   gst_caps_unref (caps1);
747   gst_caps_unref (caps2);
748   gst_caps_unref (icaps);
749 }
750
751 GST_END_TEST;
752
753
754 GST_START_TEST (test_intersect_zigzag)
755 {
756   GstCaps *caps1, *caps2, *icaps, *result;
757
758   /* tests if caps order is maintained */
759   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
760   caps2 = gst_caps_from_string ("format/D; format/A; format/B; format/C");
761
762   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
763   result = gst_caps_from_string ("format/B; format/A; format/D; format/C");
764   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
765   fail_if (gst_caps_is_empty (icaps));
766   fail_unless (gst_caps_is_equal (icaps, result));
767   gst_caps_unref (icaps);
768   gst_caps_unref (result);
769
770   icaps = gst_caps_intersect_full (caps2, caps1, GST_CAPS_INTERSECT_FIRST);
771   result = gst_caps_from_string ("format/A; format/B; format/D; format/C");
772   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
773   fail_if (gst_caps_is_empty (icaps));
774   fail_unless (gst_caps_is_equal (icaps, result));
775   gst_caps_unref (icaps);
776   gst_caps_unref (result);
777
778   gst_caps_unref (caps1);
779   gst_caps_unref (caps2);
780 }
781
782 GST_END_TEST;
783
784
785 GST_START_TEST (test_intersect_first)
786 {
787   GstCaps *caps1, *caps2, *icaps, *result;
788
789   /* tests if caps order is maintained */
790   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
791   caps2 = gst_caps_from_string ("format/C; format/D; format/A");
792   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_FIRST);
793   result = gst_caps_from_string ("format/A; format/C; format/D");
794   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
795   fail_if (gst_caps_is_empty (icaps));
796   fail_unless (gst_caps_is_equal (icaps, result));
797   gst_caps_unref (caps1);
798   gst_caps_unref (caps2);
799   gst_caps_unref (icaps);
800   gst_caps_unref (result);
801 }
802
803 GST_END_TEST;
804
805
806 GST_START_TEST (test_intersect_first2)
807 {
808   GstCaps *caps1, *caps2, *icaps, *result;
809
810   /* tests if caps order is maintained */
811   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
812   caps2 = gst_caps_from_string ("format/D; format/A; format/B; format/C");
813
814   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_FIRST);
815   result = gst_caps_from_string ("format/A; format/B; format/C; format/D");
816   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
817   fail_if (gst_caps_is_empty (icaps));
818   fail_unless (gst_caps_is_equal (icaps, result));
819   gst_caps_unref (icaps);
820   gst_caps_unref (result);
821
822   icaps = gst_caps_intersect_full (caps2, caps1, GST_CAPS_INTERSECT_FIRST);
823   result = gst_caps_from_string ("format/D; format/A; format/B; format/C");
824   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
825   fail_if (gst_caps_is_empty (icaps));
826   fail_unless (gst_caps_is_equal (icaps, result));
827   gst_caps_unref (icaps);
828   gst_caps_unref (result);
829
830   gst_caps_unref (caps1);
831   gst_caps_unref (caps2);
832 }
833
834 GST_END_TEST;
835
836 GST_START_TEST (test_intersect_duplication)
837 {
838   GstCaps *c1, *c2, *test;
839
840   c1 = gst_caps_from_string
841       ("audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ]");
842   c2 = gst_caps_from_string
843       ("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 }");
844
845   test = gst_caps_intersect_full (c1, c2, GST_CAPS_INTERSECT_FIRST);
846   fail_unless_equals_int (gst_caps_get_size (test), 1);
847   fail_unless (gst_caps_is_equal (c1, test));
848   gst_caps_unref (c1);
849   gst_caps_unref (c2);
850   gst_caps_unref (test);
851 }
852
853 GST_END_TEST;
854
855 static gboolean
856 _caps_is_fixed_foreach (GQuark field_id, const GValue * value, gpointer unused)
857 {
858   return gst_value_is_fixed (value);
859 }
860
861
862 GST_START_TEST (test_normalize)
863 {
864   GstCaps *in, *norm, *out;
865   guint i;
866
867   in = gst_caps_from_string ("some/type, foo=(int){ 1 , 2 }");
868   out = gst_caps_from_string ("some/type, foo=(int) 1; some/type, foo=(int) 2");
869   norm = gst_caps_normalize (in);
870   fail_if (gst_caps_is_empty (norm));
871   fail_unless (gst_caps_is_equal (norm, out));
872   for (i = 0; i < gst_caps_get_size (norm); i++) {
873     GstStructure *st = gst_caps_get_structure (norm, i);
874     /* Make sure all fields of all structures are fixed */
875     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
876   }
877
878   gst_caps_unref (in);
879   gst_caps_unref (out);
880   gst_caps_unref (norm);
881
882   in = gst_caps_from_string
883       ("some/type, foo=(int){ 1 , 2 }, bar=(int){ 3, 4 }");
884   out =
885       gst_caps_from_string
886       ("some/type, foo=(int) 1, bar=(int) 3; some/type, foo=(int) 2, bar=(int) 3;"
887       "some/type, foo=(int) 1, bar=(int) 4; some/type, foo=(int) 2, bar=(int) 4;");
888   norm = gst_caps_normalize (in);
889   fail_if (gst_caps_is_empty (norm));
890   fail_unless (gst_caps_is_equal (norm, out));
891   for (i = 0; i < gst_caps_get_size (norm); i++) {
892     GstStructure *st = gst_caps_get_structure (norm, i);
893     /* Make sure all fields of all structures are fixed */
894     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
895   }
896
897   gst_caps_unref (in);
898   gst_caps_unref (out);
899   gst_caps_unref (norm);
900
901   in = gst_caps_from_string
902       ("some/type, foo=(string){ 1 , 2 }, bar=(string) { 3 }");
903   out =
904       gst_caps_from_string
905       ("some/type, foo=(string) 1, bar=(string) 3; some/type, foo=(string) 2, bar=(string) 3");
906   norm = gst_caps_normalize (in);
907   fail_if (gst_caps_is_empty (norm));
908   fail_unless (gst_caps_is_equal (norm, out));
909   for (i = 0; i < gst_caps_get_size (norm); i++) {
910     GstStructure *st = gst_caps_get_structure (norm, i);
911     /* Make sure all fields of all structures are fixed */
912     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
913   }
914
915   gst_caps_unref (in);
916   gst_caps_unref (out);
917   gst_caps_unref (norm);
918 }
919
920 GST_END_TEST;
921
922 GST_START_TEST (test_broken)
923 {
924   GstCaps *c1;
925
926   /* NULL is not valid for media_type */
927   ASSERT_CRITICAL (c1 =
928       gst_caps_new_simple (NULL, "field", G_TYPE_INT, 1, NULL));
929   fail_if (c1);
930
931 #ifndef G_DISABLE_CHECKS
932   /* such a name is not valid, see gst_structure_validate_name() */
933   ASSERT_CRITICAL (c1 =
934       gst_caps_new_simple ("1#@abc", "field", G_TYPE_INT, 1, NULL));
935   fail_if (c1);
936 #endif
937 }
938
939 GST_END_TEST;
940
941
942 static Suite *
943 gst_caps_suite (void)
944 {
945   Suite *s = suite_create ("GstCaps");
946   TCase *tc_chain = tcase_create ("operations");
947
948   suite_add_tcase (s, tc_chain);
949   tcase_add_test (tc_chain, test_from_string);
950   tcase_add_test (tc_chain, test_double_append);
951   tcase_add_test (tc_chain, test_mutability);
952   tcase_add_test (tc_chain, test_static_caps);
953   tcase_add_test (tc_chain, test_simplify);
954   tcase_add_test (tc_chain, test_truncate);
955   tcase_add_test (tc_chain, test_subset);
956   tcase_add_test (tc_chain, test_merge_fundamental);
957   tcase_add_test (tc_chain, test_merge_same);
958   tcase_add_test (tc_chain, test_merge_subset);
959   tcase_add_test (tc_chain, test_intersect);
960   tcase_add_test (tc_chain, test_intersect2);
961   tcase_add_test (tc_chain, test_intersect_zigzag);
962   tcase_add_test (tc_chain, test_intersect_first);
963   tcase_add_test (tc_chain, test_intersect_first2);
964   tcase_add_test (tc_chain, test_intersect_duplication);
965   tcase_add_test (tc_chain, test_normalize);
966   tcase_add_test (tc_chain, test_broken);
967
968   return s;
969 }
970
971 GST_CHECK_MAIN (gst_caps);