|
1 #ifdef HAVE_CONFIG_H |
|
2 #include "config.h" |
|
3 #endif |
|
4 |
|
5 #include "GStreamerAllocator.h" |
|
6 |
|
7 #include <gst/video/video.h> |
|
8 #include <gst/video/gstvideometa.h> |
|
9 |
|
10 #include "GStreamerLoader.h" |
|
11 |
|
12 using namespace mozilla::layers; |
|
13 |
|
14 namespace mozilla { |
|
15 |
|
16 typedef struct |
|
17 { |
|
18 GstAllocator parent; |
|
19 GStreamerReader *reader; |
|
20 } MozGfxMemoryAllocator; |
|
21 |
|
22 typedef struct |
|
23 { |
|
24 GstAllocatorClass parent; |
|
25 } MozGfxMemoryAllocatorClass; |
|
26 |
|
27 typedef struct |
|
28 { |
|
29 GstMemory memory; |
|
30 PlanarYCbCrImage* image; |
|
31 guint8* data; |
|
32 } MozGfxMemory; |
|
33 |
|
34 typedef struct |
|
35 { |
|
36 GstMeta meta; |
|
37 } MozGfxMeta; |
|
38 |
|
39 typedef struct |
|
40 { |
|
41 GstVideoBufferPoolClass parent_class; |
|
42 } MozGfxBufferPoolClass; |
|
43 |
|
44 typedef struct |
|
45 { |
|
46 GstVideoBufferPool pool; |
|
47 } MozGfxBufferPool; |
|
48 |
|
49 // working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899 |
|
50 #pragma GCC diagnostic push |
|
51 #pragma GCC diagnostic ignored "-Wunused-function" |
|
52 G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR); |
|
53 G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL); |
|
54 #pragma GCC diagnostic pop |
|
55 |
|
56 void |
|
57 moz_gfx_memory_reset(MozGfxMemory *mem) |
|
58 { |
|
59 if (mem->image) |
|
60 mem->image->Release(); |
|
61 |
|
62 ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer(); |
|
63 mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(ImageFormat::PLANAR_YCBCR).take()); |
|
64 mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size); |
|
65 } |
|
66 |
|
67 static GstMemory* |
|
68 moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize, |
|
69 GstAllocationParams* aParams) |
|
70 { |
|
71 MozGfxMemory* mem = g_slice_new (MozGfxMemory); |
|
72 gsize maxsize = aSize + aParams->prefix + aParams->padding; |
|
73 gst_memory_init(GST_MEMORY_CAST (mem), |
|
74 (GstMemoryFlags)aParams->flags, |
|
75 aAllocator, NULL, maxsize, aParams->align, |
|
76 aParams->prefix, aSize); |
|
77 mem->image = NULL; |
|
78 moz_gfx_memory_reset(mem); |
|
79 |
|
80 return (GstMemory *) mem; |
|
81 } |
|
82 |
|
83 static void |
|
84 moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem) |
|
85 { |
|
86 MozGfxMemory *mem = (MozGfxMemory *) gmem; |
|
87 |
|
88 if (mem->memory.parent) |
|
89 goto sub_mem; |
|
90 |
|
91 if (mem->image) |
|
92 mem->image->Release(); |
|
93 |
|
94 sub_mem: |
|
95 g_slice_free (MozGfxMemory, mem); |
|
96 } |
|
97 |
|
98 static gpointer |
|
99 moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags) |
|
100 { |
|
101 // check that the allocation didn't fail |
|
102 if (mem->data == nullptr) |
|
103 return nullptr; |
|
104 |
|
105 return mem->data + mem->memory.offset; |
|
106 } |
|
107 |
|
108 static gboolean |
|
109 moz_gfx_memory_unmap (MozGfxMemory * mem) |
|
110 { |
|
111 return TRUE; |
|
112 } |
|
113 |
|
114 static MozGfxMemory * |
|
115 moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size) |
|
116 { |
|
117 MozGfxMemory *sub; |
|
118 GstMemory *parent; |
|
119 |
|
120 /* find the real parent */ |
|
121 if ((parent = mem->memory.parent) == NULL) |
|
122 parent = (GstMemory *) mem; |
|
123 |
|
124 if (size == (gsize) -1) |
|
125 size = mem->memory.size - offset; |
|
126 |
|
127 /* the shared memory is always readonly */ |
|
128 sub = g_slice_new (MozGfxMemory); |
|
129 |
|
130 gst_memory_init (GST_MEMORY_CAST (sub), |
|
131 (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), |
|
132 mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align, |
|
133 mem->memory.offset + offset, size); |
|
134 |
|
135 sub->image = mem->image; |
|
136 sub->data = mem->data; |
|
137 |
|
138 return sub; |
|
139 } |
|
140 |
|
141 static void |
|
142 moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass) |
|
143 { |
|
144 GstAllocatorClass *allocator_class; |
|
145 |
|
146 allocator_class = (GstAllocatorClass *) klass; |
|
147 |
|
148 allocator_class->alloc = moz_gfx_memory_allocator_alloc; |
|
149 allocator_class->free = moz_gfx_memory_allocator_free; |
|
150 } |
|
151 |
|
152 static void |
|
153 moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator) |
|
154 { |
|
155 GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); |
|
156 |
|
157 alloc->mem_type = "moz-gfx-image"; |
|
158 alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map; |
|
159 alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap; |
|
160 alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share; |
|
161 /* fallback copy and is_span */ |
|
162 } |
|
163 |
|
164 void |
|
165 moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader) |
|
166 { |
|
167 MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator; |
|
168 allocator->reader = aReader; |
|
169 } |
|
170 |
|
171 nsRefPtr<PlanarYCbCrImage> |
|
172 moz_gfx_memory_get_image(GstMemory *aMemory) |
|
173 { |
|
174 NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image"); |
|
175 |
|
176 return ((MozGfxMemory *) aMemory)->image; |
|
177 } |
|
178 |
|
179 void |
|
180 moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer) |
|
181 { |
|
182 GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); |
|
183 |
|
184 NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image"); |
|
185 moz_gfx_memory_reset((MozGfxMemory *) mem); |
|
186 GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer); |
|
187 } |
|
188 |
|
189 static void |
|
190 moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass) |
|
191 { |
|
192 GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass; |
|
193 pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer; |
|
194 } |
|
195 |
|
196 static void |
|
197 moz_gfx_buffer_pool_init (MozGfxBufferPool * pool) |
|
198 { |
|
199 } |
|
200 |
|
201 } // namespace mozilla |