caps: improve _do_simplify
[platform/upstream/gstreamer.git] / tests / check / gst / gstmemory.c
1 /* GStreamer
2  *
3  * unit test for GstMemory
4  *
5  * Copyright (C) <2012> Wim Taymans <wim.taymans at gmail.com>
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 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #ifdef HAVE_VALGRIND_H
28 # include <valgrind/valgrind.h>
29 #else
30 # define RUNNING_ON_VALGRIND FALSE
31 #endif
32
33 #include <gst/check/gstcheck.h>
34
35 GST_START_TEST (test_submemory)
36 {
37   GstMemory *memory, *sub;
38   GstMapInfo info, sinfo;
39
40   memory = gst_allocator_alloc (NULL, 4, 0);
41
42   /* check sizes, memory starts out empty */
43   fail_unless (gst_memory_map (memory, &info, GST_MAP_WRITE));
44   fail_unless (info.size == 4, "memory has wrong size");
45   fail_unless (info.maxsize >= 4, "memory has wrong size");
46   memset (info.data, 0, 4);
47   gst_memory_unmap (memory, &info);
48
49   fail_unless (gst_memory_map (memory, &info, GST_MAP_READ));
50
51   sub = gst_memory_share (memory, 1, 2);
52   fail_if (sub == NULL, "share of memory returned NULL");
53
54   fail_unless (gst_memory_map (sub, &sinfo, GST_MAP_READ));
55   fail_unless (sinfo.size == 2, "submemory has wrong size");
56   fail_unless (memcmp (info.data + 1, sinfo.data, 2) == 0,
57       "submemory contains the wrong data");
58   ASSERT_MEMORY_REFCOUNT (sub, "submemory", 1);
59   gst_memory_unmap (sub, &sinfo);
60   gst_memory_unref (sub);
61
62   /* create a submemory of size 0 */
63   sub = gst_memory_share (memory, 1, 0);
64   fail_if (sub == NULL, "share memory returned NULL");
65   fail_unless (gst_memory_map (sub, &sinfo, GST_MAP_READ));
66   fail_unless (sinfo.size == 0, "submemory has wrong size");
67   fail_unless (memcmp (info.data + 1, sinfo.data, 0) == 0,
68       "submemory contains the wrong data");
69   ASSERT_MEMORY_REFCOUNT (sub, "submemory", 1);
70   gst_memory_unmap (sub, &sinfo);
71   gst_memory_unref (sub);
72
73   /* test if metadata is coppied, not a complete memory copy so only the
74    * timestamp and offset fields are copied. */
75   sub = gst_memory_share (memory, 0, 1);
76   fail_if (sub == NULL, "share of memory returned NULL");
77   fail_unless (gst_memory_get_sizes (sub, NULL, NULL) == 1,
78       "submemory has wrong size");
79   gst_memory_unref (sub);
80
81   /* test if metadata is coppied, a complete memory is copied so all the timing
82    * fields should be copied. */
83   sub = gst_memory_share (memory, 0, 4);
84   fail_if (sub == NULL, "share of memory returned NULL");
85   fail_unless (gst_memory_get_sizes (sub, NULL, NULL) == 4,
86       "submemory has wrong size");
87
88   /* clean up */
89   gst_memory_unref (sub);
90
91   gst_memory_unmap (memory, &info);
92   gst_memory_unref (memory);
93 }
94
95 GST_END_TEST;
96
97 GST_START_TEST (test_is_span)
98 {
99   GstMemory *memory, *sub1, *sub2;
100
101   memory = gst_allocator_alloc (NULL, 4, 0);
102
103   sub1 = gst_memory_share (memory, 0, 2);
104   fail_if (sub1 == NULL, "share of memory returned NULL");
105
106   sub2 = gst_memory_share (memory, 2, 2);
107   fail_if (sub2 == NULL, "share of memory returned NULL");
108
109   fail_if (gst_memory_is_span (memory, sub2, NULL) == TRUE,
110       "a parent memory can't be span");
111
112   fail_if (gst_memory_is_span (sub1, memory, NULL) == TRUE,
113       "a parent memory can't be span");
114
115   fail_if (gst_memory_is_span (sub1, sub2, NULL) == FALSE,
116       "two submemorys next to each other should be span");
117
118   /* clean up */
119   gst_memory_unref (sub1);
120   gst_memory_unref (sub2);
121   gst_memory_unref (memory);
122 }
123
124 GST_END_TEST;
125
126 static const char ro_memory[] = "abcdefghijklmnopqrstuvwxyz";
127
128 static GstMemory *
129 create_read_only_memory (void)
130 {
131   GstMemory *mem;
132
133   /* assign some read-only data to the new memory */
134   mem = gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
135       (gpointer) ro_memory, sizeof (ro_memory), 0, sizeof (ro_memory), NULL,
136       NULL);
137   fail_unless (GST_MEMORY_IS_READONLY (mem));
138
139   return mem;
140 }
141
142 GST_START_TEST (test_writable)
143 {
144   GstMemory *mem, *mem2;
145   GstMapInfo info;
146
147   /* create read-only memory and try to write */
148   mem = create_read_only_memory ();
149
150   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
151
152   mem2 = gst_memory_copy (mem, 0, -1);
153   fail_unless (GST_MEMORY_IS_READONLY (mem));
154   fail_if (GST_MEMORY_IS_READONLY (mem2));
155
156   fail_unless (gst_memory_map (mem2, &info, GST_MAP_WRITE));
157   info.data[4] = 'a';
158   gst_memory_unmap (mem2, &info);
159
160   gst_memory_ref (mem2);
161   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
162   gst_memory_unref (mem2);
163
164   fail_unless (gst_memory_map (mem2, &info, GST_MAP_WRITE));
165   info.data[4] = 'a';
166   gst_memory_unmap (mem2, &info);
167   gst_memory_unref (mem2);
168
169   gst_memory_unref (mem);
170 }
171
172 GST_END_TEST;
173
174 GST_START_TEST (test_submemory_writable)
175 {
176   GstMemory *mem, *sub_mem;
177   GstMapInfo info;
178
179   /* create sub-memory of read-only memory and try to write */
180   mem = create_read_only_memory ();
181
182   sub_mem = gst_memory_share (mem, 0, 8);
183   fail_unless (GST_MEMORY_IS_READONLY (sub_mem));
184
185   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
186   fail_if (gst_memory_map (sub_mem, &info, GST_MAP_WRITE));
187
188   gst_memory_unref (sub_mem);
189   gst_memory_unref (mem);
190 }
191
192 GST_END_TEST;
193
194 GST_START_TEST (test_copy)
195 {
196   GstMemory *memory, *copy;
197   GstMapInfo info, sinfo;
198
199   memory = gst_allocator_alloc (NULL, 4, 0);
200   ASSERT_MEMORY_REFCOUNT (memory, "memory", 1);
201
202   copy = gst_memory_copy (memory, 0, -1);
203   ASSERT_MEMORY_REFCOUNT (memory, "memory", 1);
204   ASSERT_MEMORY_REFCOUNT (copy, "copy", 1);
205   /* memorys are copied and must point to different memory */
206   fail_if (memory == copy);
207
208   fail_unless (gst_memory_map (memory, &info, GST_MAP_READ));
209   fail_unless (gst_memory_map (copy, &sinfo, GST_MAP_READ));
210
211   /* NOTE that data is refcounted */
212   fail_unless (info.size == sinfo.size);
213
214   gst_memory_unmap (copy, &sinfo);
215   gst_memory_unmap (memory, &info);
216
217   gst_memory_unref (copy);
218   gst_memory_unref (memory);
219
220   memory = gst_allocator_alloc (NULL, 0, 0);
221   fail_unless (gst_memory_map (memory, &info, GST_MAP_READ));
222   fail_unless (info.size == 0);
223   gst_memory_unmap (memory, &info);
224
225   /* copying a 0-sized memory should not crash */
226   copy = gst_memory_copy (memory, 0, -1);
227   fail_unless (gst_memory_map (copy, &info, GST_MAP_READ));
228   fail_unless (info.size == 0);
229   gst_memory_unmap (copy, &info);
230
231   gst_memory_unref (copy);
232   gst_memory_unref (memory);
233 }
234
235 GST_END_TEST;
236
237 GST_START_TEST (test_try_new_and_alloc)
238 {
239   GstMemory *mem;
240   GstMapInfo info;
241
242   mem = gst_allocator_alloc (NULL, 0, 0);
243   fail_unless (mem != NULL);
244   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
245   fail_unless (info.size == 0);
246   gst_memory_unmap (mem, &info);
247   gst_memory_unref (mem);
248
249   /* normal alloc should still work */
250   mem = gst_allocator_alloc (NULL, 640 * 480 * 4, 0);
251   fail_unless (mem != NULL);
252   fail_unless (gst_memory_map (mem, &info, GST_MAP_WRITE));
253   fail_unless (info.data != NULL);
254   fail_unless (info.size == (640 * 480 * 4));
255   info.data[640 * 479 * 4 + 479] = 0xff;
256   gst_memory_unmap (mem, &info);
257
258   gst_memory_unref (mem);
259
260 #if 0
261   /* Disabled this part of the test, because it happily succeeds on 64-bit
262    * machines that have enough memory+swap, because the address space is large
263    * enough. There's not really any way to test the failure case except by
264    * allocating chunks of memory until it fails, which would suck. */
265
266   /* now this better fail (don't run in valgrind, it will abort
267    * or warn when passing silly arguments to malloc) */
268   if (!RUNNING_ON_VALGRIND) {
269     mem = gst_allocator_alloc (NULL, (guint) - 1, 0);
270     fail_unless (mem == NULL);
271   }
272 #endif
273 }
274
275 GST_END_TEST;
276
277 GST_START_TEST (test_resize)
278 {
279   GstMemory *mem;
280   gsize maxalloc;
281   gsize size, maxsize, offset;
282
283   /* one memory block */
284   mem = gst_allocator_alloc (NULL, 100, 0);
285
286   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
287   fail_unless (size == 100);
288   fail_unless (offset == 0);
289   fail_unless (maxalloc >= 100);
290
291   ASSERT_CRITICAL (gst_memory_resize (mem, 200, 50));
292   ASSERT_CRITICAL (gst_memory_resize (mem, 0, 150));
293   ASSERT_CRITICAL (gst_memory_resize (mem, 1, maxalloc));
294   ASSERT_CRITICAL (gst_memory_resize (mem, maxalloc, 1));
295
296   /* this does nothing */
297   gst_memory_resize (mem, 0, 100);
298
299   /* nothing should have changed */
300   size = gst_memory_get_sizes (mem, &offset, &maxsize);
301   fail_unless (size == 100);
302   fail_unless (offset == 0);
303   fail_unless (maxsize == maxalloc);
304
305   gst_memory_resize (mem, 0, 50);
306   size = gst_memory_get_sizes (mem, &offset, &maxsize);
307   fail_unless (size == 50);
308   fail_unless (offset == 0);
309   fail_unless (maxsize == maxalloc);
310
311   gst_memory_resize (mem, 0, 100);
312   size = gst_memory_get_sizes (mem, &offset, &maxsize);
313   fail_unless (size == 100);
314   fail_unless (offset == 0);
315   fail_unless (maxsize == maxalloc);
316
317   gst_memory_resize (mem, 1, 99);
318   size = gst_memory_get_sizes (mem, &offset, &maxsize);
319   fail_unless (size == 99);
320   fail_unless (offset == 1);
321   fail_unless (maxsize == maxalloc);
322
323   ASSERT_CRITICAL (gst_memory_resize (mem, 1, maxalloc - 1));
324
325   gst_memory_resize (mem, 0, 99);
326   size = gst_memory_get_sizes (mem, &offset, &maxsize);
327   fail_unless (size == 99);
328   fail_unless (offset == 1);
329   fail_unless (maxsize == maxalloc);
330
331   gst_memory_resize (mem, -1, 100);
332   size = gst_memory_get_sizes (mem, &offset, &maxsize);
333   fail_unless (size == 100);
334   fail_unless (offset == 0);
335   fail_unless (maxsize == maxalloc);
336
337   /* can't set offset below 0 */
338   ASSERT_CRITICAL (gst_memory_resize (mem, -1, 100));
339
340   gst_memory_resize (mem, 50, 40);
341   size = gst_memory_get_sizes (mem, &offset, &maxsize);
342   fail_unless (size == 40);
343   fail_unless (offset == 50);
344   fail_unless (maxsize == maxalloc);
345
346   gst_memory_resize (mem, -50, 100);
347   size = gst_memory_get_sizes (mem, &offset, &maxsize);
348   fail_unless (size == 100);
349   fail_unless (offset == 0);
350   fail_unless (maxsize == maxalloc);
351
352   gst_memory_resize (mem, 0, 0);
353   size = gst_memory_get_sizes (mem, &offset, &maxsize);
354   fail_unless (size == 0);
355   fail_unless (offset == 0);
356   fail_unless (maxsize == maxalloc);
357
358   gst_memory_resize (mem, 0, 100);
359   size = gst_memory_get_sizes (mem, &offset, &maxsize);
360   fail_unless (size == 100);
361   fail_unless (offset == 0);
362   fail_unless (maxsize == maxalloc);
363
364   gst_memory_resize (mem, 0, 100);
365   size = gst_memory_get_sizes (mem, &offset, &maxsize);
366   fail_unless (size == 100);
367   fail_unless (offset == 0);
368   fail_unless (maxsize == maxalloc);
369
370   gst_memory_unref (mem);
371 }
372
373 GST_END_TEST;
374
375 GST_START_TEST (test_map)
376 {
377   GstMemory *mem;
378   GstMapInfo info;
379   gsize maxalloc;
380   gsize size, offset;
381
382   /* one memory block */
383   mem = gst_allocator_alloc (NULL, 100, 0);
384
385   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
386   fail_unless (size == 100);
387   fail_unless (offset == 0);
388   fail_unless (maxalloc >= 100);
389
390   /* see if simply mapping works */
391   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
392   fail_unless (info.data != NULL);
393   fail_unless (info.size == 100);
394   fail_unless (info.maxsize == maxalloc);
395
396   gst_memory_unmap (mem, &info);
397   gst_memory_unref (mem);
398 }
399
400 GST_END_TEST;
401
402 GST_START_TEST (test_map_nested)
403 {
404   GstMemory *mem;
405   GstMapInfo info1, info2;
406
407   mem = gst_allocator_alloc (NULL, 100, 0);
408
409   /* nested mapping */
410   fail_unless (gst_memory_map (mem, &info1, GST_MAP_READ));
411   fail_unless (info1.data != NULL);
412   fail_unless (info1.size == 100);
413
414   fail_unless (gst_memory_map (mem, &info2, GST_MAP_READ));
415   fail_unless (info2.data == info1.data);
416   fail_unless (info2.size == 100);
417
418   /* unmap */
419   gst_memory_unmap (mem, &info2);
420   gst_memory_unmap (mem, &info1);
421
422   fail_unless (gst_memory_map (mem, &info1, GST_MAP_READ));
423   /* not allowed */
424   fail_if (gst_memory_map (mem, &info2, GST_MAP_WRITE));
425   fail_if (gst_memory_map (mem, &info2, GST_MAP_READWRITE));
426   fail_unless (gst_memory_map (mem, &info2, GST_MAP_READ));
427   gst_memory_unmap (mem, &info2);
428   gst_memory_unmap (mem, &info1);
429   fail_unless (mem->state == 0);
430
431   fail_unless (gst_memory_map (mem, &info1, GST_MAP_WRITE));
432   /* not allowed */
433   fail_if (gst_memory_map (mem, &info2, GST_MAP_READ));
434   fail_if (gst_memory_map (mem, &info2, GST_MAP_READWRITE));
435   fail_unless (gst_memory_map (mem, &info2, GST_MAP_WRITE));
436   gst_memory_unmap (mem, &info1);
437   gst_memory_unmap (mem, &info2);
438   /* nothing was mapped */
439   ASSERT_CRITICAL (gst_memory_unmap (mem, &info2));
440
441   fail_unless (gst_memory_map (mem, &info1, GST_MAP_READWRITE));
442   fail_unless (gst_memory_map (mem, &info2, GST_MAP_READ));
443   gst_memory_unmap (mem, &info2);
444   fail_unless (gst_memory_map (mem, &info2, GST_MAP_WRITE));
445   gst_memory_unmap (mem, &info2);
446   gst_memory_unmap (mem, &info1);
447   /* nothing was mapped */
448   ASSERT_CRITICAL (gst_memory_unmap (mem, &info1));
449
450   gst_memory_unref (mem);
451 }
452
453 GST_END_TEST;
454
455 GST_START_TEST (test_map_resize)
456 {
457   GstMemory *mem;
458   GstMapInfo info;
459   gsize size, maxalloc, offset;
460
461   mem = gst_allocator_alloc (NULL, 100, 0);
462
463   /* do mapping */
464   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
465   fail_unless (info.data != NULL);
466   fail_unless (info.size == 100);
467
468   /* resize the buffer */
469   gst_memory_resize (mem, 1, info.size - 1);
470   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
471   fail_unless (size == 99);
472   fail_unless (offset == 1);
473   fail_unless (maxalloc >= 100);
474   gst_memory_unmap (mem, &info);
475
476   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
477   fail_unless (size == 99);
478   fail_unless (offset == 1);
479   fail_unless (maxalloc >= 100);
480
481   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
482   fail_unless (info.data != NULL);
483   fail_unless (info.size == 99);
484   fail_unless (info.maxsize >= 100);
485   gst_memory_unmap (mem, &info);
486
487   /* and larger */
488   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
489   gst_memory_resize (mem, -1, 100);
490   gst_memory_unmap (mem, &info);
491
492   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
493   fail_unless (size == 100);
494   fail_unless (offset == 0);
495   fail_unless (maxalloc >= 100);
496
497   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
498   gst_memory_unmap (mem, &info);
499   gst_memory_unref (mem);
500 }
501
502 GST_END_TEST;
503
504
505 static Suite *
506 gst_memory_suite (void)
507 {
508   Suite *s = suite_create ("GstMemory");
509   TCase *tc_chain = tcase_create ("general");
510
511   suite_add_tcase (s, tc_chain);
512   tcase_add_test (tc_chain, test_submemory);
513   tcase_add_test (tc_chain, test_submemory_writable);
514   tcase_add_test (tc_chain, test_writable);
515   tcase_add_test (tc_chain, test_is_span);
516   tcase_add_test (tc_chain, test_copy);
517   tcase_add_test (tc_chain, test_try_new_and_alloc);
518   tcase_add_test (tc_chain, test_resize);
519   tcase_add_test (tc_chain, test_map);
520   tcase_add_test (tc_chain, test_map_nested);
521   tcase_add_test (tc_chain, test_map_resize);
522
523   return s;
524 }
525
526 GST_CHECK_MAIN (gst_memory);