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