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