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