• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26 
27 #include <gst/check/gstcheck.h>
28 
GST_START_TEST(test_submemory)29 GST_START_TEST (test_submemory)
30 {
31   GstMemory *memory, *sub;
32   GstMapInfo info, sinfo;
33 
34   memory = gst_allocator_alloc (NULL, 4, NULL);
35 
36   /* check sizes, memory starts out empty */
37   fail_unless (gst_memory_map (memory, &info, GST_MAP_WRITE));
38   fail_unless (info.size == 4, "memory has wrong size");
39   fail_unless (info.maxsize >= 4, "memory has wrong size");
40   memset (info.data, 0, 4);
41   gst_memory_unmap (memory, &info);
42 
43   fail_unless (gst_memory_map (memory, &info, GST_MAP_READ));
44 
45   sub = gst_memory_share (memory, 1, 2);
46   fail_if (sub == NULL, "share of memory returned NULL");
47 
48   fail_unless (gst_memory_map (sub, &sinfo, GST_MAP_READ));
49   fail_unless (sinfo.size == 2, "submemory has wrong size");
50   fail_unless (memcmp (info.data + 1, sinfo.data, 2) == 0,
51       "submemory contains the wrong data");
52   ASSERT_MINI_OBJECT_REFCOUNT (sub, "submemory", 1);
53   gst_memory_unmap (sub, &sinfo);
54   gst_memory_unref (sub);
55 
56   /* create a submemory of size 0 */
57   sub = gst_memory_share (memory, 1, 0);
58   fail_if (sub == NULL, "share memory returned NULL");
59   fail_unless (gst_memory_map (sub, &sinfo, GST_MAP_READ));
60   fail_unless (sinfo.size == 0, "submemory has wrong size");
61   fail_unless (memcmp (info.data + 1, sinfo.data, 0) == 0,
62       "submemory contains the wrong data");
63   ASSERT_MINI_OBJECT_REFCOUNT (sub, "submemory", 1);
64   gst_memory_unmap (sub, &sinfo);
65   gst_memory_unref (sub);
66 
67   /* test if metadata is copied, not a complete memory copy so only the
68    * timestamp and offset fields are copied. */
69   sub = gst_memory_share (memory, 0, 1);
70   fail_if (sub == NULL, "share of memory returned NULL");
71   fail_unless (gst_memory_get_sizes (sub, NULL, NULL) == 1,
72       "submemory has wrong size");
73   gst_memory_unref (sub);
74 
75   /* test if metadata is copied, a complete memory is copied so all the timing
76    * fields should be copied. */
77   sub = gst_memory_share (memory, 0, 4);
78   fail_if (sub == NULL, "share of memory returned NULL");
79   fail_unless (gst_memory_get_sizes (sub, NULL, NULL) == 4,
80       "submemory has wrong size");
81 
82   /* clean up */
83   gst_memory_unref (sub);
84 
85   gst_memory_unmap (memory, &info);
86 
87   /* test write map + share failure */
88   fail_unless (gst_memory_map (memory, &info, GST_MAP_WRITE));
89   sub = gst_memory_share (memory, 0, 4);
90   fail_unless (sub == NULL, "share with a write map succeeded");
91 
92   gst_memory_unmap (memory, &info);
93   gst_memory_unref (memory);
94 }
95 
96 GST_END_TEST;
97 
GST_START_TEST(test_is_span)98 GST_START_TEST (test_is_span)
99 {
100   GstMemory *memory, *sub1, *sub2;
101 
102   memory = gst_allocator_alloc (NULL, 4, NULL);
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 *
create_read_only_memory(void)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, sizeof (ro_memory), 0, sizeof (ro_memory), NULL,
137       NULL);
138   fail_unless (GST_MEMORY_IS_READONLY (mem));
139 
140   return mem;
141 }
142 
GST_START_TEST(test_writable)143 GST_START_TEST (test_writable)
144 {
145   GstMemory *mem, *mem2;
146   GstMapInfo info;
147 
148   /* create read-only memory and try to write */
149   mem = create_read_only_memory ();
150 
151   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
152 
153   /* Make sure mapping anxd unmapping it doesn't change it's locking state */
154   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
155   gst_memory_unmap (mem, &info);
156 
157   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
158 
159   mem2 = gst_memory_copy (mem, 0, -1);
160   fail_unless (GST_MEMORY_IS_READONLY (mem));
161   fail_if (GST_MEMORY_IS_READONLY (mem2));
162 
163   fail_unless (gst_memory_map (mem2, &info, GST_MAP_WRITE));
164   info.data[4] = 'a';
165   gst_memory_unmap (mem2, &info);
166 
167   gst_memory_ref (mem2);
168   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
169   gst_memory_unref (mem2);
170 
171   fail_unless (gst_memory_map (mem2, &info, GST_MAP_WRITE));
172   info.data[4] = 'a';
173   gst_memory_unmap (mem2, &info);
174   gst_memory_unref (mem2);
175 
176   gst_memory_unref (mem);
177 }
178 
179 GST_END_TEST;
180 
GST_START_TEST(test_submemory_writable)181 GST_START_TEST (test_submemory_writable)
182 {
183   GstMemory *mem, *sub_mem;
184   GstMapInfo info;
185 
186   /* create sub-memory of read-only memory and try to write */
187   mem = create_read_only_memory ();
188 
189   sub_mem = gst_memory_share (mem, 0, 8);
190   fail_unless (GST_MEMORY_IS_READONLY (sub_mem));
191 
192   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
193   fail_if (gst_memory_map (sub_mem, &info, GST_MAP_WRITE));
194 
195   gst_memory_unref (sub_mem);
196   gst_memory_unref (mem);
197 }
198 
199 GST_END_TEST;
200 
GST_START_TEST(test_copy)201 GST_START_TEST (test_copy)
202 {
203   GstMemory *memory, *copy;
204   GstMapInfo info, sinfo;
205 
206   memory = gst_allocator_alloc (NULL, 4, NULL);
207   ASSERT_MINI_OBJECT_REFCOUNT (memory, "memory", 1);
208 
209   copy = gst_memory_copy (memory, 0, -1);
210   ASSERT_MINI_OBJECT_REFCOUNT (memory, "memory", 1);
211   ASSERT_MINI_OBJECT_REFCOUNT (copy, "copy", 1);
212   /* memory is copied and must point to different memory */
213   fail_if (memory == copy);
214 
215   fail_unless (gst_memory_map (memory, &info, GST_MAP_READ));
216   fail_unless (gst_memory_map (copy, &sinfo, GST_MAP_READ));
217 
218   /* NOTE that data is refcounted */
219   fail_unless (info.size == sinfo.size);
220 
221   gst_memory_unmap (copy, &sinfo);
222   gst_memory_unmap (memory, &info);
223 
224   gst_memory_unref (copy);
225   gst_memory_unref (memory);
226 
227   memory = gst_allocator_alloc (NULL, 0, NULL);
228   fail_unless (gst_memory_map (memory, &info, GST_MAP_READ));
229   fail_unless (info.size == 0);
230   gst_memory_unmap (memory, &info);
231 
232   /* copying a 0-sized memory should not crash */
233   copy = gst_memory_copy (memory, 0, -1);
234   fail_unless (gst_memory_map (copy, &info, GST_MAP_READ));
235   fail_unless (info.size == 0);
236   gst_memory_unmap (copy, &info);
237 
238   gst_memory_unref (copy);
239   gst_memory_unref (memory);
240 }
241 
242 GST_END_TEST;
243 
GST_START_TEST(test_try_new_and_alloc)244 GST_START_TEST (test_try_new_and_alloc)
245 {
246   GstMemory *mem;
247   GstMapInfo info;
248   gsize size;
249 
250   mem = gst_allocator_alloc (NULL, 0, NULL);
251   fail_unless (mem != NULL);
252   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
253   fail_unless (info.size == 0);
254   gst_memory_unmap (mem, &info);
255   gst_memory_unref (mem);
256 
257   /* normal alloc should still work */
258   size = 640 * 480 * 4;
259   mem = gst_allocator_alloc (NULL, size, NULL);
260   fail_unless (mem != NULL);
261   fail_unless (gst_memory_map (mem, &info, GST_MAP_WRITE));
262   fail_unless (info.data != NULL);
263   fail_unless (info.size == (640 * 480 * 4));
264   info.data[640 * 479 * 4 + 479] = 0xff;
265   gst_memory_unmap (mem, &info);
266 
267   gst_memory_unref (mem);
268 }
269 
270 GST_END_TEST;
271 
GST_START_TEST(test_resize)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, NULL);
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 
GST_START_TEST(test_map)370 GST_START_TEST (test_map)
371 {
372   GstMemory *mem;
373   GstMapInfo info;
374   gsize maxalloc;
375   gsize size, offset;
376 
377   /* one memory block */
378   mem = gst_allocator_alloc (NULL, 100, NULL);
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   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
387   fail_unless (info.data != NULL);
388   fail_unless (info.size == 100);
389   fail_unless (info.maxsize == maxalloc);
390 
391   gst_memory_unmap (mem, &info);
392   gst_memory_unref (mem);
393 }
394 
395 GST_END_TEST;
396 
GST_START_TEST(test_map_nested)397 GST_START_TEST (test_map_nested)
398 {
399   GstMemory *mem;
400   GstMapInfo info1, info2;
401 
402   mem = gst_allocator_alloc (NULL, 100, NULL);
403 
404   /* nested mapping */
405   fail_unless (gst_memory_map (mem, &info1, GST_MAP_READ));
406   fail_unless (info1.data != NULL);
407   fail_unless (info1.size == 100);
408 
409   fail_unless (gst_memory_map (mem, &info2, GST_MAP_READ));
410   fail_unless (info2.data == info1.data);
411   fail_unless (info2.size == 100);
412 
413   /* unmap */
414   gst_memory_unmap (mem, &info2);
415   gst_memory_unmap (mem, &info1);
416 
417   fail_unless (gst_memory_map (mem, &info1, GST_MAP_READ));
418   /* not allowed */
419   fail_if (gst_memory_map (mem, &info2, GST_MAP_WRITE));
420   fail_if (gst_memory_map (mem, &info2, GST_MAP_READWRITE));
421   fail_unless (gst_memory_map (mem, &info2, GST_MAP_READ));
422   gst_memory_unmap (mem, &info2);
423   gst_memory_unmap (mem, &info1);
424 
425   fail_unless (gst_memory_map (mem, &info1, GST_MAP_WRITE));
426   /* not allowed */
427   fail_if (gst_memory_map (mem, &info2, GST_MAP_READ));
428   fail_if (gst_memory_map (mem, &info2, GST_MAP_READWRITE));
429   fail_unless (gst_memory_map (mem, &info2, GST_MAP_WRITE));
430   gst_memory_unmap (mem, &info1);
431   gst_memory_unmap (mem, &info2);
432   /* nothing was mapped */
433   ASSERT_CRITICAL (gst_memory_unmap (mem, &info2));
434 
435   fail_unless (gst_memory_map (mem, &info1, GST_MAP_READWRITE));
436   fail_unless (gst_memory_map (mem, &info2, GST_MAP_READ));
437   gst_memory_unmap (mem, &info2);
438   fail_unless (gst_memory_map (mem, &info2, GST_MAP_WRITE));
439   gst_memory_unmap (mem, &info2);
440   gst_memory_unmap (mem, &info1);
441   /* nothing was mapped */
442   ASSERT_CRITICAL (gst_memory_unmap (mem, &info1));
443 
444   gst_memory_unref (mem);
445 }
446 
447 GST_END_TEST;
448 
GST_START_TEST(test_map_resize)449 GST_START_TEST (test_map_resize)
450 {
451   GstMemory *mem;
452   GstMapInfo info;
453   gsize size, maxalloc, offset;
454 
455   mem = gst_allocator_alloc (NULL, 100, NULL);
456 
457   /* do mapping */
458   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
459   fail_unless (info.data != NULL);
460   fail_unless (info.size == 100);
461 
462   /* resize the buffer */
463   gst_memory_resize (mem, 1, info.size - 1);
464   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
465   fail_unless (size == 99);
466   fail_unless (offset == 1);
467   fail_unless (maxalloc >= 100);
468   gst_memory_unmap (mem, &info);
469 
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 
475   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
476   fail_unless (info.data != NULL);
477   fail_unless (info.size == 99);
478   fail_unless (info.maxsize >= 100);
479   gst_memory_unmap (mem, &info);
480 
481   /* and larger */
482   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
483   gst_memory_resize (mem, -1, 100);
484   gst_memory_unmap (mem, &info);
485 
486   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
487   fail_unless (size == 100);
488   fail_unless (offset == 0);
489   fail_unless (maxalloc >= 100);
490 
491   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
492   gst_memory_unmap (mem, &info);
493   gst_memory_unref (mem);
494 }
495 
496 GST_END_TEST;
497 
GST_START_TEST(test_alloc_params)498 GST_START_TEST (test_alloc_params)
499 {
500   GstMemory *mem;
501   GstMapInfo info;
502   gsize size, offset, maxalloc;
503   GstAllocationParams params;
504   guint8 arr[10];
505 
506   memset (arr, 0, 10);
507 
508   gst_allocation_params_init (&params);
509   params.padding = 10;
510   params.prefix = 10;
511   params.flags = GST_MEMORY_FLAG_ZERO_PREFIXED | GST_MEMORY_FLAG_ZERO_PADDED;
512   mem = gst_allocator_alloc (NULL, 100, &params);
513 
514   /*Checking size and offset */
515   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
516   fail_unless (size == 100);
517   fail_unless (offset == 10);
518   fail_unless (maxalloc >= 120);
519 
520   fail_unless (GST_MEMORY_FLAG_IS_SET (mem, GST_MEMORY_FLAG_ZERO_PREFIXED));
521   fail_unless (GST_MEMORY_FLAG_IS_SET (mem, GST_MEMORY_FLAG_ZERO_PADDED));
522 
523   fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
524   fail_unless (info.data != NULL);
525   fail_unless (info.size == 100);
526 
527   /*Checking prefix */
528   fail_unless (memcmp (info.data - 10, arr, 10) == 0);
529 
530   /*Checking padding */
531   fail_unless (memcmp (info.data + 100, arr, 10) == 0);
532 
533 
534   gst_memory_unmap (mem, &info);
535   gst_memory_unref (mem);
536 }
537 
538 GST_END_TEST;
539 
GST_START_TEST(test_lock)540 GST_START_TEST (test_lock)
541 {
542   GstMemory *mem;
543 
544   mem = gst_allocator_alloc (NULL, 10, NULL);
545   fail_unless (mem != NULL);
546 
547   /* test exclusivity */
548   fail_unless (gst_memory_lock (mem,
549           GST_LOCK_FLAG_WRITE | GST_LOCK_FLAG_EXCLUSIVE));
550   fail_if (gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE));
551   fail_unless (gst_memory_lock (mem, GST_LOCK_FLAG_WRITE));
552   gst_memory_unlock (mem, GST_LOCK_FLAG_WRITE | GST_LOCK_FLAG_EXCLUSIVE);
553   gst_memory_unlock (mem, GST_LOCK_FLAG_WRITE);
554 
555   /* no lock here */
556 
557   fail_unless (gst_memory_lock (mem,
558           GST_LOCK_FLAG_READ | GST_LOCK_FLAG_EXCLUSIVE));
559   fail_unless (gst_memory_lock (mem,
560           GST_LOCK_FLAG_READ | GST_LOCK_FLAG_EXCLUSIVE));
561   gst_memory_unlock (mem, GST_LOCK_FLAG_READ | GST_LOCK_FLAG_EXCLUSIVE);
562   gst_memory_unlock (mem, GST_LOCK_FLAG_READ | GST_LOCK_FLAG_EXCLUSIVE);
563 
564   /* no lock here */
565 
566   fail_unless (gst_memory_lock (mem,
567           GST_LOCK_FLAG_READWRITE | GST_LOCK_FLAG_EXCLUSIVE));
568   fail_unless (gst_memory_lock (mem, GST_LOCK_FLAG_READ));
569   fail_if (gst_memory_lock (mem, GST_LOCK_FLAG_READ | GST_LOCK_FLAG_EXCLUSIVE));
570   fail_if (gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE));
571   fail_unless (gst_memory_lock (mem, GST_LOCK_FLAG_WRITE));
572   gst_memory_unlock (mem, GST_LOCK_FLAG_WRITE);
573   gst_memory_unlock (mem, GST_LOCK_FLAG_READ);
574   gst_memory_unlock (mem, GST_LOCK_FLAG_READWRITE | GST_LOCK_FLAG_EXCLUSIVE);
575 
576   gst_memory_unref (mem);
577 }
578 
579 GST_END_TEST;
580 
581 typedef struct
582 {
583   GstMemory mem;
584   gpointer data;
585 } MyOpaqueMemory;
586 
587 static GstMemory *
_my_opaque_alloc(GstAllocator * allocator,gsize size,GstAllocationParams * params)588 _my_opaque_alloc (GstAllocator * allocator, gsize size,
589     GstAllocationParams * params)
590 {
591   MyOpaqueMemory *mem = g_slice_new (MyOpaqueMemory);
592   gsize maxsize = size + params->prefix + params->padding;
593 
594   gst_memory_init (GST_MEMORY_CAST (mem), params->flags, allocator, NULL,
595       maxsize, params->align, params->prefix, size);
596 
597   mem->data = g_malloc (maxsize);
598 
599   return (GstMemory *) mem;
600 }
601 
602 static void
_my_opaque_free(GstAllocator * allocator,GstMemory * mem)603 _my_opaque_free (GstAllocator * allocator, GstMemory * mem)
604 {
605   MyOpaqueMemory *mmem = (MyOpaqueMemory *) mem;
606 
607   g_free (mmem->data);
608   g_slice_free (MyOpaqueMemory, mmem);
609 }
610 
611 static gpointer
_my_opaque_mem_map(MyOpaqueMemory * mem,gsize maxsize,GstMapFlags flags)612 _my_opaque_mem_map (MyOpaqueMemory * mem, gsize maxsize, GstMapFlags flags)
613 {
614   /* the subclass is responsible for logging any error, by design choice and for
615    * testing purpose MyOpaqueMemory never logs any trace */
616   return NULL;
617 }
618 
619 static gboolean
_my_opaque_mem_unmap(MyOpaqueMemory * mem)620 _my_opaque_mem_unmap (MyOpaqueMemory * mem)
621 {
622   return FALSE;
623 }
624 
625 static MyOpaqueMemory *
_my_opaque_mem_share(MyOpaqueMemory * mem,gssize offset,gsize size)626 _my_opaque_mem_share (MyOpaqueMemory * mem, gssize offset, gsize size)
627 {
628   return NULL;
629 }
630 
631 typedef struct
632 {
633   GstAllocator parent;
634 } MyOpaqueMemoryAllocator;
635 
636 typedef struct
637 {
638   GstAllocatorClass parent_class;
639 } MyOpaqueMemoryAllocatorClass;
640 
641 GType my_opaque_memory_allocator_get_type (void);
642 G_DEFINE_TYPE (MyOpaqueMemoryAllocator, my_opaque_memory_allocator,
643     GST_TYPE_ALLOCATOR);
644 
645 static void
my_opaque_memory_allocator_class_init(MyOpaqueMemoryAllocatorClass * klass)646 my_opaque_memory_allocator_class_init (MyOpaqueMemoryAllocatorClass * klass)
647 {
648   GstAllocatorClass *allocator_class;
649 
650   allocator_class = (GstAllocatorClass *) klass;
651 
652   allocator_class->alloc = _my_opaque_alloc;
653   allocator_class->free = _my_opaque_free;
654 }
655 
656 static void
my_opaque_memory_allocator_init(MyOpaqueMemoryAllocator * allocator)657 my_opaque_memory_allocator_init (MyOpaqueMemoryAllocator * allocator)
658 {
659   GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
660 
661   alloc->mem_type = "MyOpaqueMemory";
662   alloc->mem_map = (GstMemoryMapFunction) _my_opaque_mem_map;
663   alloc->mem_unmap = (GstMemoryUnmapFunction) _my_opaque_mem_unmap;
664   alloc->mem_share = (GstMemoryShareFunction) _my_opaque_mem_share;
665 }
666 
667 static void
my_opaque_memory_init(void)668 my_opaque_memory_init (void)
669 {
670   GstAllocator *allocator;
671 
672   allocator = g_object_new (my_opaque_memory_allocator_get_type (), NULL);
673 
674   gst_allocator_register ("MyOpaqueMemory", allocator);
675 }
676 
677 static void
_custom_log_func(GstDebugCategory * category,GstDebugLevel level,const gchar * file,const gchar * function,gint line,GObject * object,GstDebugMessage * message,gpointer unused)678 _custom_log_func (GstDebugCategory * category,
679     GstDebugLevel level, const gchar * file, const gchar * function,
680     gint line, GObject * object, GstDebugMessage * message, gpointer unused)
681 {
682   const gchar *dbg_msg = gst_debug_message_get (message);
683   fail_unless (dbg_msg == NULL);
684 }
685 
686 #ifndef GST_DISABLE_GST_DEBUG
GST_START_TEST(test_no_error_and_no_warning_on_map_failure)687 GST_START_TEST (test_no_error_and_no_warning_on_map_failure)
688 {
689   GstAllocator *alloc;
690   GstMemory *mem;
691   GstMapInfo info;
692   gsize maxalloc;
693   gsize size, offset;
694   GstDebugLevel prev_debug_threshold;
695   gboolean prev_debug_is_active;
696 
697   my_opaque_memory_init ();
698   alloc = gst_allocator_find ("MyOpaqueMemory");
699   mem = gst_allocator_alloc (alloc, 100, NULL);
700 
701   size = gst_memory_get_sizes (mem, &offset, &maxalloc);
702   fail_unless (size == 100);
703   fail_unless (offset == 0);
704   fail_unless (maxalloc >= 100);
705 
706   /* Prepare custom logging to capture any GST_ERROR and GST_WARNING. */
707   prev_debug_threshold = gst_debug_get_default_threshold ();
708   prev_debug_is_active = gst_debug_is_active ();
709   gst_debug_set_active (TRUE);
710   fail_unless (gst_debug_is_active ());
711   gst_debug_set_default_threshold (GST_LEVEL_WARNING);
712   fail_unless (gst_debug_get_default_threshold () == GST_LEVEL_WARNING);
713   gst_debug_remove_log_function (gst_debug_log_default);
714   gst_debug_add_log_function (_custom_log_func, NULL, NULL);
715 
716   /* Ensure that the map does not log any error on failure. It has to fail
717    * because the custom opaque memory here is designed to not be mappable. */
718   fail_if (gst_memory_map (mem, &info, GST_MAP_READ));
719   fail_if (info.data != NULL);
720   fail_if (info.size != 0);
721   fail_if (info.maxsize != 0);
722 
723   fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
724   fail_if (info.data != NULL);
725   fail_if (info.size != 0);
726   fail_if (info.maxsize != 0);
727 
728   gst_memory_unref (mem);
729   gst_object_unref (alloc);
730 
731   /* Restore previous logging state. */
732   gst_debug_set_default_threshold (prev_debug_threshold);
733   gst_debug_add_log_function (gst_debug_log_default, NULL, NULL);
734   gst_debug_remove_log_function (_custom_log_func);
735   gst_debug_set_active (prev_debug_is_active);
736 }
737 
738 GST_END_TEST;
739 #endif /* !GST_DISABLE_GST_DEBUG */
740 
741 static Suite *
gst_memory_suite(void)742 gst_memory_suite (void)
743 {
744   Suite *s = suite_create ("GstMemory");
745   TCase *tc_chain = tcase_create ("general");
746 
747   suite_add_tcase (s, tc_chain);
748   tcase_add_test (tc_chain, test_submemory);
749   tcase_add_test (tc_chain, test_submemory_writable);
750   tcase_add_test (tc_chain, test_writable);
751   tcase_add_test (tc_chain, test_is_span);
752   tcase_add_test (tc_chain, test_copy);
753   tcase_add_test (tc_chain, test_try_new_and_alloc);
754   tcase_add_test (tc_chain, test_resize);
755   tcase_add_test (tc_chain, test_map);
756   tcase_add_test (tc_chain, test_map_nested);
757   tcase_add_test (tc_chain, test_map_resize);
758   tcase_add_test (tc_chain, test_alloc_params);
759   tcase_add_test (tc_chain, test_lock);
760 #ifndef GST_DISABLE_GST_DEBUG
761   tcase_add_test (tc_chain, test_no_error_and_no_warning_on_map_failure);
762 #endif
763 
764   return s;
765 }
766 
767 GST_CHECK_MAIN (gst_memory);
768