1 /*
2 * GStreamer
3 * Copyright (C) 2015 Alessandro Decina <twi@centricular.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "iosglmemory.h"
26
27 GST_DEBUG_CATEGORY_STATIC (GST_CAT_IOS_GL_MEMORY);
28 #define GST_CAT_DEFAULT GST_CAT_IOS_GL_MEMORY
29
30 G_DEFINE_TYPE (GstIOSGLMemoryAllocator, gst_ios_gl_memory_allocator,
31 GST_TYPE_GL_MEMORY_ALLOCATOR);
32
33 typedef struct
34 {
35 GstIOSGLMemory *memory;
36 } ContextThreadData;
37
38 static GstAllocator *_ios_gl_memory_allocator;
39
40 static void
_ios_gl_memory_destroy(GstGLBaseMemory * gl_mem)41 _ios_gl_memory_destroy (GstGLBaseMemory * gl_mem)
42 {
43 GstIOSGLMemory *mem = (GstIOSGLMemory *) gl_mem;
44
45 mem->gl_notify (mem->gl_data);
46 gst_memory_unref (GST_MEMORY_CAST (mem->cv_mem));
47 GST_GL_BASE_MEMORY_ALLOCATOR_CLASS
48 (gst_ios_gl_memory_allocator_parent_class)->destroy (gl_mem);
49 }
50
51 static gpointer
_ios_gl_memory_allocator_map(GstGLBaseMemory * bmem,GstMapInfo * info,gsize size)52 _ios_gl_memory_allocator_map (GstGLBaseMemory * bmem,
53 GstMapInfo * info, gsize size)
54 {
55 GstGLMemory *gl_mem = (GstGLMemory *) bmem;
56 GstIOSGLMemory *mem = (GstIOSGLMemory *) gl_mem;
57
58 if (info->flags & GST_MAP_GL)
59 return &gl_mem->tex_id;
60 return GST_MEMORY_CAST (mem->cv_mem)->allocator->
61 mem_map (GST_MEMORY_CAST (mem->cv_mem), size, info->flags);
62 }
63
64 static void
_ios_gl_memory_allocator_unmap(GstGLBaseMemory * bmem,GstMapInfo * info)65 _ios_gl_memory_allocator_unmap (GstGLBaseMemory * bmem, GstMapInfo * info)
66 {
67 GstIOSGLMemory *mem = (GstIOSGLMemory *) bmem;
68
69 if (!(info->flags & GST_MAP_GL))
70 GST_MEMORY_CAST (mem->cv_mem)->allocator->
71 mem_unmap (GST_MEMORY_CAST (mem->cv_mem));
72 }
73
74 static GstMemory *
_mem_alloc(GstAllocator * allocator,gsize size,GstAllocationParams * params)75 _mem_alloc (GstAllocator * allocator, gsize size, GstAllocationParams * params)
76 {
77 g_warning ("use gst_ios_gl_memory_new_wrapped () to allocate from this "
78 "IOSGL allocator");
79
80 return NULL;
81 }
82
83 static void
gst_ios_gl_memory_allocator_class_init(GstIOSGLMemoryAllocatorClass * klass)84 gst_ios_gl_memory_allocator_class_init (GstIOSGLMemoryAllocatorClass * klass)
85 {
86 GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
87 GstGLBaseMemoryAllocatorClass *gl_base_allocator_class =
88 (GstGLBaseMemoryAllocatorClass *) klass;
89
90 allocator_class->alloc = _mem_alloc;
91 gl_base_allocator_class->destroy = _ios_gl_memory_destroy;
92 gl_base_allocator_class->map = _ios_gl_memory_allocator_map;
93 gl_base_allocator_class->unmap = _ios_gl_memory_allocator_unmap;
94 }
95
96 static void
gst_ios_gl_memory_allocator_init(GstIOSGLMemoryAllocator * allocator)97 gst_ios_gl_memory_allocator_init (GstIOSGLMemoryAllocator * allocator)
98 {
99 GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
100
101 alloc->mem_type = GST_IOS_GL_MEMORY_ALLOCATOR_NAME;
102 GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
103 }
104
105 void
gst_ios_gl_memory_init(void)106 gst_ios_gl_memory_init (void)
107 {
108 static volatile gsize _init = 0;
109
110 if (g_once_init_enter (&_init)) {
111 GST_DEBUG_CATEGORY_INIT (GST_CAT_IOS_GL_MEMORY, "iosurface", 0,
112 "IOSGL Buffer");
113
114 _ios_gl_memory_allocator =
115 g_object_new (GST_TYPE_IOS_GL_MEMORY_ALLOCATOR, NULL);
116 gst_object_ref_sink (_ios_gl_memory_allocator);
117
118 gst_allocator_register (GST_IOS_GL_MEMORY_ALLOCATOR_NAME,
119 gst_object_ref (_ios_gl_memory_allocator));
120 g_once_init_leave (&_init, 1);
121 }
122 }
123
124 gboolean
gst_is_ios_gl_memory(GstMemory * mem)125 gst_is_ios_gl_memory (GstMemory * mem)
126 {
127 return mem != NULL && mem->allocator != NULL &&
128 g_type_is_a (G_OBJECT_TYPE (mem->allocator),
129 GST_TYPE_IOS_GL_MEMORY_ALLOCATOR);
130 }
131
132 static GstIOSGLMemory *
_ios_gl_memory_new(GstGLContext * context,GstAppleCoreVideoMemory * cv_mem,GstGLTextureTarget target,GstGLFormat tex_format,guint tex_id,GstVideoInfo * info,guint plane,GstVideoAlignment * valign,gpointer gl_data,GDestroyNotify gl_notify)133 _ios_gl_memory_new (GstGLContext * context,
134 GstAppleCoreVideoMemory * cv_mem,
135 GstGLTextureTarget target,
136 GstGLFormat tex_format,
137 guint tex_id,
138 GstVideoInfo * info,
139 guint plane,
140 GstVideoAlignment * valign, gpointer gl_data, GDestroyNotify gl_notify)
141 {
142 GstIOSGLMemory *mem;
143
144 mem = g_new0 (GstIOSGLMemory, 1);
145 mem->gl_mem.tex_id = tex_id;
146 mem->gl_mem.texture_wrapped = TRUE;
147 gst_gl_memory_init (&mem->gl_mem, _ios_gl_memory_allocator, NULL, context,
148 target, tex_format, NULL, info, plane, valign, NULL, NULL);
149 mem->cv_mem = cv_mem;
150 mem->gl_data = gl_data;
151 mem->gl_notify = gl_notify;
152
153 GST_MINI_OBJECT_FLAG_SET (mem, GST_MEMORY_FLAG_READONLY);
154
155 return mem;
156 }
157
158 GstIOSGLMemory *
gst_ios_gl_memory_new_wrapped(GstGLContext * context,GstAppleCoreVideoMemory * cv_mem,GstGLTextureTarget target,GstGLFormat tex_format,guint tex_id,GstVideoInfo * info,guint plane,GstVideoAlignment * valign,gpointer gl_data,GDestroyNotify gl_notify)159 gst_ios_gl_memory_new_wrapped (GstGLContext * context,
160 GstAppleCoreVideoMemory * cv_mem,
161 GstGLTextureTarget target,
162 GstGLFormat tex_format,
163 guint tex_id,
164 GstVideoInfo * info,
165 guint plane,
166 GstVideoAlignment * valign, gpointer gl_data, GDestroyNotify gl_notify)
167 {
168 return _ios_gl_memory_new (context, cv_mem, target, tex_format, tex_id, info,
169 plane, valign, gl_data, gl_notify);
170 }
171