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