caps: improve _do_simplify
[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,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,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,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, format=(string)I420, framerate=(fraction)[ 1/100, 100 ], "
129     "width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw, "
130     "format=(string)YUY2, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
131     "height=(int)[ 16, 4096 ]; video/x-raw, format=(string)RGB8_PALETTED, "
132     "framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
133     "height=(int)[ 16, 4096 ]; video/x-raw, "
134     "format=(string){ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], "
135     "height=(int)[ 16, 4096 ], framerate=(fraction)[ 1/100, 100 ]";
136
137 static gboolean
138 check_string_list (const GValue * format_value)
139 {
140   const GValue *string_value;
141   gboolean got_rgb8 = FALSE;
142   gboolean got_yv12 = FALSE;
143   gboolean got_i420 = FALSE;
144   gboolean got_yuy2 = FALSE;
145   const gchar *string;
146
147   string_value = gst_value_list_get_value (format_value, 0);
148   fail_unless (string_value != NULL);
149   fail_unless (G_VALUE_HOLDS_STRING (string_value));
150   string = g_value_get_string (string_value);
151   fail_unless (string != NULL);
152   got_rgb8 = got_rgb8 || (g_str_equal (string, "RGB8_PALETTED"));
153   got_i420 = got_i420 || (g_str_equal (string, "I420"));
154   got_yuy2 = got_yuy2 || (g_str_equal (string, "YUY2"));
155   got_yv12 = got_yv12 || (g_str_equal (string, "YV12"));
156
157   string_value = gst_value_list_get_value (format_value, 1);
158   fail_unless (string_value != NULL);
159   fail_unless (G_VALUE_HOLDS_STRING (string_value));
160   string = g_value_get_string (string_value);
161   fail_unless (string != NULL);
162   got_rgb8 = got_rgb8 || (g_str_equal (string, "RGB8_PALETTED"));
163   got_i420 = got_i420 || (g_str_equal (string, "I420"));
164   got_yuy2 = got_yuy2 || (g_str_equal (string, "YUY2"));
165   got_yv12 = got_yv12 || (g_str_equal (string, "YV12"));
166
167   string_value = gst_value_list_get_value (format_value, 2);
168   fail_unless (string_value != NULL);
169   fail_unless (G_VALUE_HOLDS_STRING (string_value));
170   string = g_value_get_string (string_value);
171   fail_unless (string != NULL);
172   got_rgb8 = got_rgb8 || (g_str_equal (string, "RGB8_PALETTED"));
173   got_i420 = got_i420 || (g_str_equal (string, "I420"));
174   got_yuy2 = got_yuy2 || (g_str_equal (string, "YUY2"));
175   got_yv12 = got_yv12 || (g_str_equal (string, "YV12"));
176
177   string_value = gst_value_list_get_value (format_value, 3);
178   fail_unless (string_value != NULL);
179   fail_unless (G_VALUE_HOLDS_STRING (string_value));
180   string = g_value_get_string (string_value);
181   fail_unless (string != NULL);
182   got_rgb8 = got_rgb8 || (g_str_equal (string, "RGB8_PALETTED"));
183   got_i420 = got_i420 || (g_str_equal (string, "I420"));
184   got_yuy2 = got_yuy2 || (g_str_equal (string, "YUY2"));
185   got_yv12 = got_yv12 || (g_str_equal (string, "YV12"));
186
187   return (got_rgb8 && got_i420 && got_yuy2 && got_yv12);
188 }
189
190 GST_START_TEST (test_simplify)
191 {
192   GstStructure *s1;
193   GstCaps *caps;
194
195   caps = gst_caps_from_string (non_simple_caps_string);
196   fail_unless (caps != NULL,
197       "gst_caps_from_string (non_simple_caps_string) failed");
198
199   caps = gst_caps_do_simplify (caps);
200   fail_unless (caps != NULL, "gst_caps_do_simplify() should have worked");
201
202   /* check simplified caps, should be:
203    *
204    * video/x-raw, format=(string){ RGB8_PALETTED, YV12, YUY2, I420 },
205    *     width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
206    *     framerate=(fraction)[ 1/100, 100 ]
207    */
208   GST_DEBUG ("simplyfied %" GST_PTR_FORMAT, caps);
209   fail_unless (gst_caps_get_size (caps) == 1);
210   s1 = gst_caps_get_structure (caps, 0);
211   fail_unless (s1 != NULL);
212
213   fail_unless (gst_structure_has_name (s1, "video/x-raw"));
214   {
215     const GValue *framerate_value;
216     const GValue *format_value;
217     const GValue *width_value;
218     const GValue *height_value;
219     const GValue *val_fps;
220     GValue test_fps = { 0, };
221     gint min_width, max_width;
222     gint min_height, max_height;
223
224     format_value = gst_structure_get_value (s1, "format");
225     fail_unless (format_value != NULL);
226     fail_unless (GST_VALUE_HOLDS_LIST (format_value));
227     fail_unless (gst_value_list_get_size (format_value) == 4);
228     fail_unless (check_string_list (format_value) == TRUE);
229
230     g_value_init (&test_fps, GST_TYPE_FRACTION);
231     framerate_value = gst_structure_get_value (s1, "framerate");
232     fail_unless (framerate_value != NULL);
233     fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
234
235     val_fps = gst_value_get_fraction_range_min (framerate_value);
236     gst_value_set_fraction (&test_fps, 1, 100);
237     fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
238
239     val_fps = gst_value_get_fraction_range_max (framerate_value);
240     gst_value_set_fraction (&test_fps, 100, 1);
241     fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
242
243     g_value_unset (&test_fps);
244
245     width_value = gst_structure_get_value (s1, "width");
246     fail_unless (width_value != NULL);
247     fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value));
248     min_width = gst_value_get_int_range_min (width_value);
249     max_width = gst_value_get_int_range_max (width_value);
250     fail_unless (min_width == 16 && max_width == 4096);
251
252     height_value = gst_structure_get_value (s1, "height");
253     fail_unless (height_value != NULL);
254     fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value));
255     min_height = gst_value_get_int_range_min (height_value);
256     max_height = gst_value_get_int_range_max (height_value);
257     fail_unless (min_height == 16 && max_height == 4096);
258   }
259
260   gst_caps_unref (caps);
261 }
262
263 GST_END_TEST;
264
265 GST_START_TEST (test_truncate)
266 {
267   GstCaps *caps;
268
269   caps = gst_caps_from_string (non_simple_caps_string);
270   fail_unless (caps != NULL,
271       "gst_caps_from_string (non_simple_caps_string) failed");
272   fail_unless_equals_int (gst_caps_get_size (caps), 4);
273   caps = gst_caps_truncate (caps);
274   fail_unless_equals_int (gst_caps_get_size (caps), 1);
275   gst_caps_unref (caps);
276 }
277
278 GST_END_TEST;
279
280 GST_START_TEST (test_subset)
281 {
282   GstCaps *c1, *c2;
283
284   c1 = gst_caps_from_string ("video/x-raw; video/x-raw");
285   c2 = gst_caps_from_string ("video/x-raw, format=(string)YUY2");
286   fail_unless (gst_caps_is_subset (c2, c1));
287   fail_if (gst_caps_is_subset (c1, c2));
288   gst_caps_unref (c1);
289   gst_caps_unref (c2);
290
291   c1 = gst_caps_from_string
292       ("audio/x-raw, channels=(int)[ 1, 2 ], rate=(int)44100");
293   c2 = gst_caps_from_string ("audio/x-raw, channels=(int)1, rate=(int)44100");
294   fail_unless (gst_caps_is_subset (c2, c1));
295   fail_if (gst_caps_is_subset (c1, c2));
296   gst_caps_unref (c1);
297   gst_caps_unref (c2);
298
299   c1 = gst_caps_from_string ("audio/x-raw, channels=(int) {1}");
300   c2 = gst_caps_from_string ("audio/x-raw, channels=(int)1");
301   fail_unless (gst_caps_is_subset (c2, c1));
302   fail_unless (gst_caps_is_subset (c1, c2));
303   fail_unless (gst_caps_is_equal (c1, c2));
304   gst_caps_unref (c1);
305   gst_caps_unref (c2);
306
307   c1 = gst_caps_from_string
308       ("audio/x-raw, rate=(int)44100, channels=(int)3, format=(string)U16_LE");
309   c2 = gst_caps_from_string
310       ("audio/x-raw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], format=(string){ S16_LE, U16_LE }");
311   fail_unless (gst_caps_is_subset (c1, c2));
312   fail_if (gst_caps_is_subset (c2, c1));
313   gst_caps_unref (c1);
314   gst_caps_unref (c2);
315 }
316
317 GST_END_TEST;
318
319 GST_START_TEST (test_merge_fundamental)
320 {
321   GstCaps *c1, *c2;
322
323   /* ANY + specific = ANY */
324   c1 = gst_caps_from_string ("audio/x-raw,rate=44100");
325   c2 = gst_caps_new_any ();
326   c2 = gst_caps_merge (c2, c1);
327   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
328   fail_unless (gst_caps_get_size (c2) == 0, NULL);
329   fail_unless (gst_caps_is_any (c2), NULL);
330   gst_caps_unref (c2);
331
332   /* specific + ANY = ANY */
333   c2 = gst_caps_from_string ("audio/x-raw,rate=44100");
334   c1 = gst_caps_new_any ();
335   c2 = gst_caps_merge (c2, c1);
336   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
337   fail_unless (gst_caps_get_size (c2) == 0, NULL);
338   fail_unless (gst_caps_is_any (c2), NULL);
339   gst_caps_unref (c2);
340
341   /* EMPTY + specific = specific */
342   c1 = gst_caps_from_string ("audio/x-raw,rate=44100");
343   c2 = gst_caps_new_empty ();
344   c2 = gst_caps_merge (c2, c1);
345   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
346   fail_unless (gst_caps_get_size (c2) == 1, NULL);
347   fail_if (gst_caps_is_empty (c2), NULL);
348   gst_caps_unref (c2);
349
350   /* specific + EMPTY = specific */
351   c2 = gst_caps_from_string ("audio/x-raw,rate=44100");
352   c1 = gst_caps_new_empty ();
353   c2 = gst_caps_merge (c2, c1);
354   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
355   fail_unless (gst_caps_get_size (c2) == 1, NULL);
356   fail_if (gst_caps_is_empty (c2), NULL);
357   gst_caps_unref (c2);
358 }
359
360 GST_END_TEST;
361
362 GST_START_TEST (test_merge_same)
363 {
364   GstCaps *c1, *c2, *test;
365
366   /* this is the same */
367   c1 = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
368   c2 = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
369   c2 = 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) == 1, NULL);
372   test = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
373   fail_unless (gst_caps_is_equal (c2, test));
374   gst_caps_unref (test);
375   gst_caps_unref (c2);
376
377   /* and so is this */
378   c1 = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
379   c2 = gst_caps_from_string ("audio/x-raw,channels=1,rate=44100");
380   c2 = 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   gst_caps_unref (c2);
384
385   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
386   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
387   c2 = 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) == 2, NULL);
390   gst_caps_unref (c2);
391
392   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
393   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
394   c2 = gst_caps_merge (c2, c1);
395   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
396   fail_unless (gst_caps_get_size (c2) == 2, NULL);
397   gst_caps_unref (c2);
398
399   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
400   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
401   c2 = gst_caps_merge (c2, c1);
402   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
403   fail_unless (gst_caps_get_size (c2) == 1, NULL);
404   gst_caps_unref (c2);
405
406   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
407   c2 = gst_caps_from_string ("video/x-bar, data=(buffer)AA");
408   c2 = gst_caps_merge (c2, c1);
409   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
410   fail_unless (gst_caps_get_size (c2) == 2, NULL);
411   gst_caps_unref (c2);
412 }
413
414 GST_END_TEST;
415
416 GST_START_TEST (test_merge_subset)
417 {
418   GstCaps *c1, *c2, *test;
419
420   /* the 2nd is already covered */
421   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
422   c1 = gst_caps_from_string ("audio/x-raw,channels=1");
423   c2 = gst_caps_merge (c2, c1);
424   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
425   fail_unless (gst_caps_get_size (c2) == 1, NULL);
426   test = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
427   fail_unless (gst_caps_is_equal (c2, test));
428   gst_caps_unref (c2);
429   gst_caps_unref (test);
430
431   /* here it is not */
432   c2 = gst_caps_from_string ("audio/x-raw,channels=1,rate=44100");
433   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,2],rate=44100");
434   c2 = 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) == 2, NULL);
437   test = gst_caps_from_string ("audio/x-raw,channels=[1,2],rate=44100");
438   fail_unless (gst_caps_is_equal (c2, test));
439   gst_caps_unref (c2);
440   gst_caps_unref (test);
441
442   /* second one was already contained in the first one */
443   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,3]");
444   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
445   c2 = 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) == 1, NULL);
448   test = gst_caps_from_string ("audio/x-raw,channels=[1,3]");
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,channels=[1,4]");
455   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
456   c2 = 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,channels=[1,4]");
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,channels=[1,4]");
466   c1 = gst_caps_from_string ("audio/x-raw,channels=[2,4]");
467   c2 = 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,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,channels=[1,4]");
477   c1 = gst_caps_from_string ("audio/x-raw,channels=[2,3]");
478   c2 = 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,channels=[1,4]");
482   fail_unless (gst_caps_is_equal (c2, test));
483   gst_caps_unref (c2);
484   gst_caps_unref (test);
485
486   /* these caps cannot be merged */
487   c2 = gst_caps_from_string ("audio/x-raw,channels=[2,3]");
488   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
489   c2 = 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) == 2, NULL);
492   test =
493       gst_caps_from_string
494       ("audio/x-raw,channels=[2,3];audio/x-raw,channels=[1,4]");
495   fail_unless (gst_caps_is_equal (c2, test));
496   gst_caps_unref (c2);
497   gst_caps_unref (test);
498
499   /* these caps cannot be merged */
500   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
501   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,3]");
502   c2 = gst_caps_merge (c2, c1);
503   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
504   fail_unless (gst_caps_get_size (c2) == 2, NULL);
505   test =
506       gst_caps_from_string
507       ("audio/x-raw,channels=[1,2];audio/x-raw,channels=[1,3]");
508   fail_unless (gst_caps_is_equal (c2, test));
509   gst_caps_unref (c2);
510   gst_caps_unref (test);
511
512   c2 = gst_caps_from_string ("audio/x-raw,channels={1,2}");
513   c1 = gst_caps_from_string ("audio/x-raw,channels={1,2,3,4}");
514   c2 = gst_caps_merge (c2, c1);
515   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
516   fail_unless (gst_caps_get_size (c2) == 2, NULL);
517   test = gst_caps_from_string ("audio/x-raw,channels={1,2};"
518       "audio/x-raw,channels={1,2,3,4}");
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,channels={1,2}");
524   c1 = gst_caps_from_string ("audio/x-raw,channels={1,3}");
525   c2 = 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,channels={1,2};"
529       "audio/x-raw,channels={1,3}");
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 ("video/x-raw, framerate=(fraction){ 15/2, 5/1 }");
535   c1 = gst_caps_from_string ("video/x-raw, framerate=(fraction){ 15/1, 5/1 }");
536   test = gst_caps_copy (c1);
537   c2 = gst_caps_merge (c2, c1);
538   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
539   fail_unless (gst_caps_is_subset (test, c2));
540   gst_caps_unref (test);
541   gst_caps_unref (c2);
542
543   c2 = gst_caps_from_string ("audio/x-raw");
544   c1 = gst_caps_from_string ("audio/x-raw,channels=1");
545   c2 = gst_caps_merge (c2, c1);
546   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
547   fail_unless (gst_caps_get_size (c2) == 1, NULL);
548   test = gst_caps_from_string ("audio/x-raw");
549   fail_unless (gst_caps_is_equal (c2, test));
550   gst_caps_unref (c2);
551   gst_caps_unref (test);
552
553   c2 = gst_caps_from_string ("audio/x-raw,channels=1");
554   c1 = gst_caps_from_string ("audio/x-raw");
555   c2 = gst_caps_merge (c2, c1);
556   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
557   fail_unless (gst_caps_get_size (c2) == 2, NULL);
558   test = gst_caps_from_string ("audio/x-raw,channels=1; audio/x-raw");
559   fail_unless (gst_caps_is_equal (c2, test));
560   gst_caps_unref (c2);
561   gst_caps_unref (test);
562 }
563
564 GST_END_TEST;
565
566 GST_START_TEST (test_intersect)
567 {
568   GstStructure *s;
569   GstCaps *c1, *c2, *ci1, *ci2;
570
571   /* field not specified = any value possible, so the intersection
572    * should keep fields which are only part of one set of caps */
573   c2 = gst_caps_from_string ("video/x-raw,format=(string)I420,width=20");
574   c1 = gst_caps_from_string ("video/x-raw,format=(string)I420");
575
576   ci1 = gst_caps_intersect (c2, c1);
577   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
578   fail_unless (gst_caps_get_size (ci1) == 1, NULL);
579   s = gst_caps_get_structure (ci1, 0);
580   fail_unless (gst_structure_has_name (s, "video/x-raw"));
581   fail_unless (gst_structure_get_value (s, "format") != NULL);
582   fail_unless (gst_structure_get_value (s, "width") != NULL);
583
584   /* with changed order */
585   ci2 = gst_caps_intersect (c1, c2);
586   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
587   fail_unless (gst_caps_get_size (ci2) == 1, NULL);
588   s = gst_caps_get_structure (ci2, 0);
589   fail_unless (gst_structure_has_name (s, "video/x-raw"));
590   fail_unless (gst_structure_get_value (s, "format") != NULL);
591   fail_unless (gst_structure_get_value (s, "width") != NULL);
592
593   fail_unless (gst_caps_is_equal (ci1, ci2));
594
595   gst_caps_unref (ci1);
596   gst_caps_unref (ci2);
597
598   gst_caps_unref (c1);
599   gst_caps_unref (c2);
600
601   /* ========== */
602
603   c2 = gst_caps_from_string ("video/x-raw,format=(string)I420,width=20");
604   c1 = gst_caps_from_string ("video/x-raw,format=(string)I420,width=30");
605
606   ci1 = gst_caps_intersect (c2, c1);
607   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
608   fail_unless (gst_caps_is_empty (ci1), NULL);
609
610   /* with changed order */
611   ci2 = gst_caps_intersect (c1, c2);
612   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
613   fail_unless (gst_caps_is_empty (ci2), NULL);
614
615   fail_unless (gst_caps_is_equal (ci1, ci2));
616
617   gst_caps_unref (ci1);
618   gst_caps_unref (ci2);
619
620   gst_caps_unref (c1);
621   gst_caps_unref (c2);
622
623   /* ========== */
624
625   c2 = gst_caps_from_string ("video/x-raw,format=(string)I420,width=20");
626   c1 = gst_caps_from_string ("video/x-raw2,format=(string)I420,width=20");
627
628   ci1 = gst_caps_intersect (c2, c1);
629   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
630   fail_unless (gst_caps_is_empty (ci1), NULL);
631
632   /* with changed order */
633   ci2 = gst_caps_intersect (c1, c2);
634   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
635   fail_unless (gst_caps_is_empty (ci2), NULL);
636
637   fail_unless (gst_caps_is_equal (ci1, ci2));
638
639   gst_caps_unref (ci1);
640   gst_caps_unref (ci2);
641
642   gst_caps_unref (c1);
643   gst_caps_unref (c2);
644
645   /* ========== */
646
647   c2 = gst_caps_from_string ("video/x-raw,format=(string)I420,width=20");
648   c1 = gst_caps_from_string ("video/x-raw,format=(string)I420,height=30");
649
650   ci1 = gst_caps_intersect (c2, c1);
651   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci1);
652   fail_unless (gst_caps_get_size (ci1) == 1, NULL);
653   s = gst_caps_get_structure (ci1, 0);
654   fail_unless (gst_structure_has_name (s, "video/x-raw"));
655   fail_unless (gst_structure_get_value (s, "format") != NULL);
656   fail_unless (gst_structure_get_value (s, "width") != NULL);
657   fail_unless (gst_structure_get_value (s, "height") != NULL);
658
659   /* with changed order */
660   ci2 = gst_caps_intersect (c1, c2);
661   GST_DEBUG ("intersected: %" GST_PTR_FORMAT, ci2);
662   fail_unless (gst_caps_get_size (ci2) == 1, NULL);
663   s = gst_caps_get_structure (ci2, 0);
664   fail_unless (gst_structure_has_name (s, "video/x-raw"));
665   fail_unless (gst_structure_get_value (s, "format") != NULL);
666   fail_unless (gst_structure_get_value (s, "height") != NULL);
667   fail_unless (gst_structure_get_value (s, "width") != NULL);
668
669   fail_unless (gst_caps_is_equal (ci1, ci2));
670
671   gst_caps_unref (ci1);
672   gst_caps_unref (ci2);
673
674   gst_caps_unref (c1);
675   gst_caps_unref (c2);
676 }
677
678 GST_END_TEST;
679
680 GST_START_TEST (test_intersect2)
681 {
682   GstCaps *caps1, *caps2, *icaps;
683
684   /* tests array subtraction */
685   caps1 = gst_caps_from_string ("audio/x-raw, "
686       "channel-positions=(int)<                      "
687       "{ 1, 2, 3, 4, 5, 6 },                         "
688       "{ 1, 2, 3, 4, 5, 6 },                         "
689       "{ 1, 2, 3, 4, 5, 6 },                         "
690       "{ 1, 2, 3, 4, 5, 6 },                         "
691       "{ 1, 2, 3, 4, 5, 6 },                         " "{ 1, 2, 3, 4, 5, 6 }>");
692   caps2 = gst_caps_from_string ("audio/x-raw, "
693       "channel-positions=(int)< 1, 2, 3, 4, 5, 6 >");
694   icaps = gst_caps_intersect (caps1, caps2);
695   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
696   fail_if (gst_caps_is_empty (icaps));
697   fail_unless (gst_caps_is_equal (icaps, caps2));
698   gst_caps_unref (caps1);
699   gst_caps_unref (caps2);
700   gst_caps_unref (icaps);
701
702   /* ===== */
703
704   caps1 = gst_caps_from_string ("some/type, foo=(int)< { 1, 2 }, { 3, 4} >");
705   caps2 = gst_caps_from_string ("some/type, foo=(int)< 1, 3 >");
706   icaps = gst_caps_intersect (caps1, caps2);
707   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
708   fail_if (gst_caps_is_empty (icaps));
709   fail_unless (gst_caps_is_equal (icaps, caps2));
710   gst_caps_unref (caps1);
711   gst_caps_unref (caps2);
712   gst_caps_unref (icaps);
713 }
714
715 GST_END_TEST;
716
717
718 GST_START_TEST (test_intersect_zigzag)
719 {
720   GstCaps *caps1, *caps2, *icaps, *result;
721
722   /* tests if caps order is maintained */
723   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
724   caps2 = gst_caps_from_string ("format/D; format/A; format/B; format/C");
725
726   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
727   result = gst_caps_from_string ("format/B; format/A; format/D; format/C");
728   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
729   fail_if (gst_caps_is_empty (icaps));
730   fail_unless (gst_caps_is_equal (icaps, result));
731   gst_caps_unref (icaps);
732   gst_caps_unref (result);
733
734   icaps = gst_caps_intersect_full (caps2, caps1, GST_CAPS_INTERSECT_FIRST);
735   result = gst_caps_from_string ("format/A; format/B; format/D; format/C");
736   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
737   fail_if (gst_caps_is_empty (icaps));
738   fail_unless (gst_caps_is_equal (icaps, result));
739   gst_caps_unref (icaps);
740   gst_caps_unref (result);
741
742   gst_caps_unref (caps1);
743   gst_caps_unref (caps2);
744 }
745
746 GST_END_TEST;
747
748
749 GST_START_TEST (test_intersect_first)
750 {
751   GstCaps *caps1, *caps2, *icaps, *result;
752
753   /* tests if caps order is maintained */
754   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
755   caps2 = gst_caps_from_string ("format/C; format/D; format/A");
756   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_FIRST);
757   result = gst_caps_from_string ("format/A; format/C; format/D");
758   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
759   fail_if (gst_caps_is_empty (icaps));
760   fail_unless (gst_caps_is_equal (icaps, result));
761   gst_caps_unref (caps1);
762   gst_caps_unref (caps2);
763   gst_caps_unref (icaps);
764   gst_caps_unref (result);
765 }
766
767 GST_END_TEST;
768
769
770 GST_START_TEST (test_intersect_first2)
771 {
772   GstCaps *caps1, *caps2, *icaps, *result;
773
774   /* tests if caps order is maintained */
775   caps1 = gst_caps_from_string ("format/A; format/B; format/C; format/D");
776   caps2 = gst_caps_from_string ("format/D; format/A; format/B; format/C");
777
778   icaps = gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_FIRST);
779   result = gst_caps_from_string ("format/A; format/B; format/C; format/D");
780   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
781   fail_if (gst_caps_is_empty (icaps));
782   fail_unless (gst_caps_is_equal (icaps, result));
783   gst_caps_unref (icaps);
784   gst_caps_unref (result);
785
786   icaps = gst_caps_intersect_full (caps2, caps1, GST_CAPS_INTERSECT_FIRST);
787   result = gst_caps_from_string ("format/D; format/A; format/B; format/C");
788   GST_LOG ("intersected caps: %" GST_PTR_FORMAT, icaps);
789   fail_if (gst_caps_is_empty (icaps));
790   fail_unless (gst_caps_is_equal (icaps, result));
791   gst_caps_unref (icaps);
792   gst_caps_unref (result);
793
794   gst_caps_unref (caps1);
795   gst_caps_unref (caps2);
796 }
797
798 GST_END_TEST;
799
800 GST_START_TEST (test_intersect_duplication)
801 {
802   GstCaps *c1, *c2, *test;
803
804   c1 = gst_caps_from_string
805       ("audio/x-raw, format=(string)S16_LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ]");
806   c2 = gst_caps_from_string
807       ("audio/x-raw, format=(string) { S16_LE, S16_BE, U16_LE, U16_BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ]; audio/x-raw, format=(string) { S16_LE, S16_BE, U16_LE, U16_BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 11 ]; audio/x-raw, format=(string) { S16_LE, S16_BE, U16_LE, U16_BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 11 ]");
808
809   test = gst_caps_intersect_full (c1, c2, GST_CAPS_INTERSECT_FIRST);
810   fail_unless_equals_int (gst_caps_get_size (test), 1);
811   fail_unless (gst_caps_is_equal (c1, test));
812   gst_caps_unref (c1);
813   gst_caps_unref (c2);
814   gst_caps_unref (test);
815 }
816
817 GST_END_TEST;
818
819 static gboolean
820 _caps_is_fixed_foreach (GQuark field_id, const GValue * value, gpointer unused)
821 {
822   return gst_value_is_fixed (value);
823 }
824
825
826 GST_START_TEST (test_normalize)
827 {
828   GstCaps *in, *norm, *out;
829   guint i;
830
831   in = gst_caps_from_string ("some/type, foo=(int){ 1 , 2 }");
832   out = gst_caps_from_string ("some/type, foo=(int) 1; some/type, foo=(int) 2");
833   norm = gst_caps_normalize (in);
834   fail_if (gst_caps_is_empty (norm));
835   fail_unless (gst_caps_is_equal (norm, out));
836   for (i = 0; i < gst_caps_get_size (norm); i++) {
837     GstStructure *st = gst_caps_get_structure (norm, i);
838     /* Make sure all fields of all structures are fixed */
839     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
840   }
841
842   gst_caps_unref (in);
843   gst_caps_unref (out);
844   gst_caps_unref (norm);
845
846   in = gst_caps_from_string
847       ("some/type, foo=(int){ 1 , 2 }, bar=(int){ 3, 4 }");
848   out =
849       gst_caps_from_string
850       ("some/type, foo=(int) 1, bar=(int) 3; some/type, foo=(int) 2, bar=(int) 3;"
851       "some/type, foo=(int) 1, bar=(int) 4; some/type, foo=(int) 2, bar=(int) 4;");
852   norm = gst_caps_normalize (in);
853   fail_if (gst_caps_is_empty (norm));
854   fail_unless (gst_caps_is_equal (norm, out));
855   for (i = 0; i < gst_caps_get_size (norm); i++) {
856     GstStructure *st = gst_caps_get_structure (norm, i);
857     /* Make sure all fields of all structures are fixed */
858     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
859   }
860
861   gst_caps_unref (in);
862   gst_caps_unref (out);
863   gst_caps_unref (norm);
864
865   in = gst_caps_from_string
866       ("some/type, foo=(string){ 1 , 2 }, bar=(string) { 3 }");
867   out =
868       gst_caps_from_string
869       ("some/type, foo=(string) 1, bar=(string) 3; some/type, foo=(string) 2, bar=(string) 3");
870   norm = gst_caps_normalize (in);
871   fail_if (gst_caps_is_empty (norm));
872   fail_unless (gst_caps_is_equal (norm, out));
873   for (i = 0; i < gst_caps_get_size (norm); i++) {
874     GstStructure *st = gst_caps_get_structure (norm, i);
875     /* Make sure all fields of all structures are fixed */
876     fail_unless (gst_structure_foreach (st, _caps_is_fixed_foreach, NULL));
877   }
878
879   gst_caps_unref (in);
880   gst_caps_unref (out);
881   gst_caps_unref (norm);
882 }
883
884 GST_END_TEST;
885
886 GST_START_TEST (test_broken)
887 {
888   GstCaps *c1;
889
890   /* NULL is not valid for media_type */
891   ASSERT_CRITICAL (c1 =
892       gst_caps_new_simple (NULL, "field", G_TYPE_INT, 1, NULL));
893   fail_if (c1);
894
895 #ifndef G_DISABLE_CHECKS
896   /* such a name is not valid, see gst_structure_validate_name() */
897   ASSERT_CRITICAL (c1 =
898       gst_caps_new_simple ("1#@abc", "field", G_TYPE_INT, 1, NULL));
899   fail_if (c1);
900 #endif
901 }
902
903 GST_END_TEST;
904
905
906 static Suite *
907 gst_caps_suite (void)
908 {
909   Suite *s = suite_create ("GstCaps");
910   TCase *tc_chain = tcase_create ("operations");
911
912   suite_add_tcase (s, tc_chain);
913   tcase_add_test (tc_chain, test_from_string);
914   tcase_add_test (tc_chain, test_double_append);
915   tcase_add_test (tc_chain, test_mutability);
916   tcase_add_test (tc_chain, test_static_caps);
917   tcase_add_test (tc_chain, test_simplify);
918   tcase_add_test (tc_chain, test_truncate);
919   tcase_add_test (tc_chain, test_subset);
920   tcase_add_test (tc_chain, test_merge_fundamental);
921   tcase_add_test (tc_chain, test_merge_same);
922   tcase_add_test (tc_chain, test_merge_subset);
923   tcase_add_test (tc_chain, test_intersect);
924   tcase_add_test (tc_chain, test_intersect2);
925   tcase_add_test (tc_chain, test_intersect_zigzag);
926   tcase_add_test (tc_chain, test_intersect_first);
927   tcase_add_test (tc_chain, test_intersect_first2);
928   tcase_add_test (tc_chain, test_intersect_duplication);
929   tcase_add_test (tc_chain, test_normalize);
930   tcase_add_test (tc_chain, test_broken);
931
932   return s;
933 }
934
935 GST_CHECK_MAIN (gst_caps);