02115c7516aa7807b6a55adf7bcde0d4520b2c92
[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
162   gst_memory_ref (mem2);
163   ASSERT_CRITICAL (gst_memory_map (mem, &size, NULL, GST_MAP_WRITE));
164   gst_memory_unref (mem2);
165
166   data = gst_memory_map (mem2, &size, NULL, GST_MAP_WRITE);
167   data[4] = 'a';
168   gst_memory_unmap (mem2, data, size);
169
170   gst_memory_unref (mem2);
171
172   gst_memory_unref (mem);
173 }
174
175 GST_END_TEST;
176
177 GST_START_TEST (test_submemory_writable)
178 {
179   GstMemory *mem, *sub_mem;
180   gsize size;
181
182   /* create sub-memory of read-only memory and try to write */
183   mem = create_read_only_memory ();
184
185   sub_mem = gst_memory_share (mem, 0, 8);
186   fail_if (gst_memory_is_writable (sub_mem));
187
188   ASSERT_CRITICAL (gst_memory_map (mem, &size, NULL, GST_MAP_WRITE));
189   ASSERT_CRITICAL (gst_memory_map (sub_mem, &size, NULL, GST_MAP_WRITE));
190
191   gst_memory_unref (sub_mem);
192   gst_memory_unref (mem);
193 }
194
195 GST_END_TEST;
196
197 GST_START_TEST (test_copy)
198 {
199   GstMemory *memory, *copy;
200   gsize size, ssize;
201   guint8 *data, *sdata;
202
203   memory = gst_allocator_alloc (NULL, 4, 0);
204   ASSERT_MEMORY_REFCOUNT (memory, "memory", 1);
205
206   copy = gst_memory_copy (memory, 0, -1);
207   ASSERT_MEMORY_REFCOUNT (memory, "memory", 1);
208   ASSERT_MEMORY_REFCOUNT (copy, "copy", 1);
209   /* memorys are copied and must point to different memory */
210   fail_if (memory == copy);
211
212   data = gst_memory_map (memory, &size, NULL, GST_MAP_READ);
213   sdata = gst_memory_map (copy, &ssize, NULL, GST_MAP_READ);
214
215   /* NOTE that data is refcounted */
216   fail_unless (size == ssize);
217
218   gst_memory_unmap (copy, sdata, ssize);
219   gst_memory_unmap (memory, data, size);
220
221   gst_memory_unref (copy);
222   gst_memory_unref (memory);
223
224   memory = gst_allocator_alloc (NULL, 0, 0);
225   data = gst_memory_map (memory, &size, NULL, GST_MAP_READ);
226   fail_unless (size == 0);
227   gst_memory_unmap (memory, data, size);
228
229   /* copying a 0-sized memory should not crash */
230   copy = gst_memory_copy (memory, 0, -1);
231   data = gst_memory_map (copy, &size, NULL, GST_MAP_READ);
232   fail_unless (size == 0);
233   gst_memory_unmap (copy, data, size);
234
235   gst_memory_unref (copy);
236   gst_memory_unref (memory);
237 }
238
239 GST_END_TEST;
240
241 GST_START_TEST (test_try_new_and_alloc)
242 {
243   GstMemory *mem;
244   gsize size;
245   guint8 *data;
246
247   mem = gst_allocator_alloc (NULL, 0, 0);
248   fail_unless (mem != NULL);
249   data = gst_memory_map (mem, &size, NULL, GST_MAP_READ);
250   fail_unless (size == 0);
251   gst_memory_unmap (mem, data, size);
252   gst_memory_unref (mem);
253
254   /* normal alloc should still work */
255   mem = gst_allocator_alloc (NULL, 640 * 480 * 4, 0);
256   fail_unless (mem != NULL);
257   data = gst_memory_map (mem, &size, NULL, GST_MAP_WRITE);
258   fail_unless (data != NULL);
259   fail_unless (size == (640 * 480 * 4));
260   data[640 * 479 * 4 + 479] = 0xff;
261   gst_memory_unmap (mem, data, size);
262
263   gst_memory_unref (mem);
264
265 #if 0
266   /* Disabled this part of the test, because it happily succeeds on 64-bit
267    * machines that have enough memory+swap, because the address space is large
268    * enough. There's not really any way to test the failure case except by
269    * allocating chunks of memory until it fails, which would suck. */
270
271   /* now this better fail (don't run in valgrind, it will abort
272    * or warn when passing silly arguments to malloc) */
273   if (!RUNNING_ON_VALGRIND) {
274     mem = gst_allocator_alloc (NULL, (guint) - 1, 0);
275     fail_unless (mem == NULL);
276   }
277 #endif
278 }
279
280 GST_END_TEST;
281
282 GST_START_TEST (test_resize)
283 {
284   GstMemory *mem;
285   gsize maxalloc;
286   gsize size, maxsize, offset;
287
288   /* one memory block */
289   mem = gst_allocator_alloc (NULL, 100, 0);
290
291   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
292   fail_unless (size == 100);
293   fail_unless (offset == 0);
294   fail_unless (maxalloc >= 100);
295
296   ASSERT_CRITICAL (gst_memory_resize (mem, 200, 50));
297   ASSERT_CRITICAL (gst_memory_resize (mem, 0, 150));
298   ASSERT_CRITICAL (gst_memory_resize (mem, 1, maxalloc));
299   ASSERT_CRITICAL (gst_memory_resize (mem, maxalloc, 1));
300
301   /* this does nothing */
302   gst_memory_resize (mem, 0, 100);
303
304   /* nothing should have changed */
305   size = gst_memory_get_sizes (mem, &offset, &maxsize);
306   fail_unless (size == 100);
307   fail_unless (offset == 0);
308   fail_unless (maxsize == maxalloc);
309
310   gst_memory_resize (mem, 0, 50);
311   size = gst_memory_get_sizes (mem, &offset, &maxsize);
312   fail_unless (size == 50);
313   fail_unless (offset == 0);
314   fail_unless (maxsize == maxalloc);
315
316   gst_memory_resize (mem, 0, 100);
317   size = gst_memory_get_sizes (mem, &offset, &maxsize);
318   fail_unless (size == 100);
319   fail_unless (offset == 0);
320   fail_unless (maxsize == maxalloc);
321
322   gst_memory_resize (mem, 1, 99);
323   size = gst_memory_get_sizes (mem, &offset, &maxsize);
324   fail_unless (size == 99);
325   fail_unless (offset == 1);
326   fail_unless (maxsize == maxalloc);
327
328   ASSERT_CRITICAL (gst_memory_resize (mem, 1, maxalloc - 1));
329
330   gst_memory_resize (mem, 0, 99);
331   size = gst_memory_get_sizes (mem, &offset, &maxsize);
332   fail_unless (size == 99);
333   fail_unless (offset == 1);
334   fail_unless (maxsize == maxalloc);
335
336   gst_memory_resize (mem, -1, 100);
337   size = gst_memory_get_sizes (mem, &offset, &maxsize);
338   fail_unless (size == 100);
339   fail_unless (offset == 0);
340   fail_unless (maxsize == maxalloc);
341
342   /* can't set offset below 0 */
343   ASSERT_CRITICAL (gst_memory_resize (mem, -1, 100));
344
345   gst_memory_resize (mem, 50, 40);
346   size = gst_memory_get_sizes (mem, &offset, &maxsize);
347   fail_unless (size == 40);
348   fail_unless (offset == 50);
349   fail_unless (maxsize == maxalloc);
350
351   gst_memory_resize (mem, -50, 100);
352   size = gst_memory_get_sizes (mem, &offset, &maxsize);
353   fail_unless (size == 100);
354   fail_unless (offset == 0);
355   fail_unless (maxsize == maxalloc);
356
357   gst_memory_resize (mem, 0, 0);
358   size = gst_memory_get_sizes (mem, &offset, &maxsize);
359   fail_unless (size == 0);
360   fail_unless (offset == 0);
361   fail_unless (maxsize == maxalloc);
362
363   gst_memory_resize (mem, 0, 100);
364   size = gst_memory_get_sizes (mem, &offset, &maxsize);
365   fail_unless (size == 100);
366   fail_unless (offset == 0);
367   fail_unless (maxsize == maxalloc);
368
369   gst_memory_resize (mem, 0, 100);
370   size = gst_memory_get_sizes (mem, &offset, &maxsize);
371   fail_unless (size == 100);
372   fail_unless (offset == 0);
373   fail_unless (maxsize == maxalloc);
374
375   gst_memory_unref (mem);
376 }
377
378 GST_END_TEST;
379
380 GST_START_TEST (test_map)
381 {
382   GstMemory *mem;
383   gsize maxalloc;
384   gsize size, maxsize, offset;
385   gpointer data;
386
387   /* one memory block */
388   mem = gst_allocator_alloc (NULL, 100, 0);
389
390   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
391   fail_unless (size == 100);
392   fail_unless (offset == 0);
393   fail_unless (maxalloc >= 100);
394
395   /* see if simply mapping works */
396   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
397   fail_unless (data != NULL);
398   fail_unless (size == 100);
399   fail_unless (maxsize == maxalloc);
400   ASSERT_CRITICAL (gst_memory_unmap (mem, (guint8 *) data - 1, maxsize + 1));
401   gst_memory_unmap (mem, data, size);
402
403   /* make smaller by unmapping less */
404   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
405   fail_unless (data != NULL);
406   fail_unless (size == 100);
407   fail_unless (maxsize == maxalloc);
408   gst_memory_unmap (mem, data, size - 1);
409
410   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
411   fail_unless (size == 99);
412   fail_unless (offset == 0);
413   fail_unless (maxalloc >= 100);
414
415   /* make bigger by unmapping more */
416   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
417   fail_unless (data != NULL);
418   fail_unless (size == 99);
419   fail_unless (maxsize == maxalloc);
420   gst_memory_unmap (mem, data, size + 1);
421
422   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
423   fail_unless (size == 100);
424   fail_unless (offset == 0);
425   fail_unless (maxalloc >= 100);
426
427   /* resize beyond the maxsize */
428   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
429   fail_unless (data != NULL);
430   fail_unless (size == 100);
431   fail_unless (maxsize == maxalloc);
432   ASSERT_CRITICAL (gst_memory_unmap (mem, data, maxsize + 1));
433   gst_memory_unmap (mem, data, maxsize);
434
435   /* add offset, maxsize should be smaller now */
436   gst_memory_resize (mem, 1, 99);
437
438   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
439   fail_unless (data != NULL);
440   fail_unless (size == 99);
441   fail_unless (maxsize == maxalloc - 1);
442   ASSERT_CRITICAL (gst_memory_unmap (mem, data, maxsize + 1));
443   gst_memory_unmap (mem, data, maxsize);
444
445   gst_memory_unref (mem);
446 }
447
448 GST_END_TEST;
449
450 GST_START_TEST (test_map_nested)
451 {
452   GstMemory *mem;
453   gsize size1, maxsize1, size2, maxsize2;
454   gpointer data1, data2;
455
456   mem = gst_allocator_alloc (NULL, 100, 0);
457
458   /* nested mapping */
459   data1 = gst_memory_map (mem, &size1, &maxsize1, GST_MAP_READ);
460   fail_unless (data1 != NULL);
461   fail_unless (size1 == 100);
462
463   data2 = gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READ);
464   fail_unless (data2 == data1);
465   fail_unless (size2 == 100);
466
467   /* unmap in reverse order */
468   gst_memory_unmap (mem, data2, size2);
469   gst_memory_unmap (mem, data1, size1);
470
471   /* nested mapping */
472   data1 = gst_memory_map (mem, &size1, &maxsize1, GST_MAP_READ);
473   fail_unless (data1 != NULL);
474   fail_unless (size1 == 100);
475
476   data2 = gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READ);
477   fail_unless (data2 == data1);
478   fail_unless (size2 == 100);
479
480   /* unmap in different order */
481   gst_memory_unmap (mem, data1, size1);
482   gst_memory_unmap (mem, data2, size2);
483
484   data1 = gst_memory_map (mem, &size1, &maxsize1, GST_MAP_READ);
485   /* not allowed */
486   ASSERT_CRITICAL (gst_memory_map (mem, &size2, &maxsize2, GST_MAP_WRITE));
487   ASSERT_CRITICAL (gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READWRITE));
488   data2 = gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READ);
489   gst_memory_unmap (mem, data1, size1);
490   gst_memory_unmap (mem, data2, size2);
491   fail_unless (mem->state == 0);
492
493   data1 = gst_memory_map (mem, &size1, &maxsize1, GST_MAP_WRITE);
494   /* not allowed */
495   ASSERT_CRITICAL (gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READ));
496   ASSERT_CRITICAL (gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READWRITE));
497   data2 = gst_memory_map (mem, &size2, &maxsize2, GST_MAP_WRITE);
498   gst_memory_unmap (mem, data1, size1);
499   gst_memory_unmap (mem, data2, size2);
500   /* nothing was mapped */
501   ASSERT_CRITICAL (gst_memory_unmap (mem, data2, size2));
502
503   data1 = gst_memory_map (mem, &size1, &maxsize1, GST_MAP_READWRITE);
504   data2 = gst_memory_map (mem, &size2, &maxsize2, GST_MAP_READ);
505   gst_memory_unmap (mem, data2, size2);
506   data2 = gst_memory_map (mem, &size2, &maxsize2, GST_MAP_WRITE);
507   gst_memory_unmap (mem, data2, size2);
508   /* ut of range */
509   ASSERT_CRITICAL (gst_memory_unmap (mem, (guint8 *) data1 - 1, size1));
510   gst_memory_unmap (mem, data1, size1);
511   /* nothing was mapped */
512   ASSERT_CRITICAL (gst_memory_unmap (mem, data1, size1));
513
514   gst_memory_unref (mem);
515 }
516
517 GST_END_TEST;
518
519 GST_START_TEST (test_map_resize)
520 {
521   GstMemory *mem;
522   gsize size, maxsize, maxalloc, offset;
523   gpointer data;
524
525   mem = gst_allocator_alloc (NULL, 100, 0);
526
527   /* do mapping */
528   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
529   fail_unless (data != NULL);
530   fail_unless (size == 100);
531
532   /* resize the buffer */
533   gst_memory_resize (mem, 1, size - 1);
534   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
535   fail_unless (size == 99);
536   fail_unless (offset == 1);
537   fail_unless (maxalloc >= 100);
538
539   /* unmap the buffer with original pointer and size, should restore the offset
540    * and size */
541   gst_memory_unmap (mem, data, 100);
542
543   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
544   fail_unless (size == 100);
545   fail_unless (offset == 0);
546   fail_unless (maxalloc >= 100);
547
548   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
549   fail_unless (data != NULL);
550   fail_unless (size == 100);
551   fail_unless (maxsize >= 100);
552
553   /* resize the buffer with unmap */
554   gst_memory_unmap (mem, (guint8 *) data + 1, 99);
555
556   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
557   fail_unless (size == 99);
558   fail_unless (offset == 1);
559   fail_unless (maxalloc >= 100);
560
561   /* and larger */
562   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
563   gst_memory_unmap (mem, (guint8 *) data - 1, 100);
564
565   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
566   fail_unless (size == 100);
567   fail_unless (offset == 0);
568   fail_unless (maxalloc >= 100);
569
570   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
571   gst_memory_unmap (mem, (guint8 *) data + 1, -1);
572
573   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
574   fail_unless (size == 99);
575   fail_unless (offset == 1);
576   fail_unless (maxalloc >= 100);
577
578   data = gst_memory_map (mem, &size, &maxsize, GST_MAP_READ);
579   gst_memory_unmap (mem, (guint8 *) data - 1, -1);
580
581   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
582   fail_unless (size == 100);
583   fail_unless (offset == 0);
584   fail_unless (maxalloc >= 100);
585
586   gst_memory_unref (mem);
587 }
588
589 GST_END_TEST;
590
591
592 static Suite *
593 gst_memory_suite (void)
594 {
595   Suite *s = suite_create ("GstMemory");
596   TCase *tc_chain = tcase_create ("general");
597
598   suite_add_tcase (s, tc_chain);
599   tcase_add_test (tc_chain, test_submemory);
600   tcase_add_test (tc_chain, test_submemory_writable);
601   tcase_add_test (tc_chain, test_writable);
602   tcase_add_test (tc_chain, test_is_span);
603   tcase_add_test (tc_chain, test_copy);
604   tcase_add_test (tc_chain, test_try_new_and_alloc);
605   tcase_add_test (tc_chain, test_resize);
606   tcase_add_test (tc_chain, test_map);
607   tcase_add_test (tc_chain, test_map_nested);
608   tcase_add_test (tc_chain, test_map_resize);
609
610   return s;
611 }
612
613 GST_CHECK_MAIN (gst_memory);