f677efa4c3599e110d49860d2d62737b88bef11c
[platform/upstream/gstreamer.git] / sys / applemedia / iosglmemory.c
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
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
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
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 *
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
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
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
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
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 *
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 *
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 }