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 (¶ms);
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, ¶ms);
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