Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
5 #include "GStreamerAllocator.h"
7 #include <gst/video/video.h>
8 #include <gst/video/gstvideometa.h>
10 #include "GStreamerLoader.h"
12 using namespace mozilla::layers;
14 namespace mozilla {
16 typedef struct
17 {
18 GstAllocator parent;
19 GStreamerReader *reader;
20 } MozGfxMemoryAllocator;
22 typedef struct
23 {
24 GstAllocatorClass parent;
25 } MozGfxMemoryAllocatorClass;
27 typedef struct
28 {
29 GstMemory memory;
30 PlanarYCbCrImage* image;
31 guint8* data;
32 } MozGfxMemory;
34 typedef struct
35 {
36 GstMeta meta;
37 } MozGfxMeta;
39 typedef struct
40 {
41 GstVideoBufferPoolClass parent_class;
42 } MozGfxBufferPoolClass;
44 typedef struct
45 {
46 GstVideoBufferPool pool;
47 } MozGfxBufferPool;
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
56 void
57 moz_gfx_memory_reset(MozGfxMemory *mem)
58 {
59 if (mem->image)
60 mem->image->Release();
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 }
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);
80 return (GstMemory *) mem;
81 }
83 static void
84 moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem)
85 {
86 MozGfxMemory *mem = (MozGfxMemory *) gmem;
88 if (mem->memory.parent)
89 goto sub_mem;
91 if (mem->image)
92 mem->image->Release();
94 sub_mem:
95 g_slice_free (MozGfxMemory, mem);
96 }
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;
105 return mem->data + mem->memory.offset;
106 }
108 static gboolean
109 moz_gfx_memory_unmap (MozGfxMemory * mem)
110 {
111 return TRUE;
112 }
114 static MozGfxMemory *
115 moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size)
116 {
117 MozGfxMemory *sub;
118 GstMemory *parent;
120 /* find the real parent */
121 if ((parent = mem->memory.parent) == NULL)
122 parent = (GstMemory *) mem;
124 if (size == (gsize) -1)
125 size = mem->memory.size - offset;
127 /* the shared memory is always readonly */
128 sub = g_slice_new (MozGfxMemory);
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);
135 sub->image = mem->image;
136 sub->data = mem->data;
138 return sub;
139 }
141 static void
142 moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass)
143 {
144 GstAllocatorClass *allocator_class;
146 allocator_class = (GstAllocatorClass *) klass;
148 allocator_class->alloc = moz_gfx_memory_allocator_alloc;
149 allocator_class->free = moz_gfx_memory_allocator_free;
150 }
152 static void
153 moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator)
154 {
155 GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
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 }
164 void
165 moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader)
166 {
167 MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator;
168 allocator->reader = aReader;
169 }
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");
176 return ((MozGfxMemory *) aMemory)->image;
177 }
179 void
180 moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer)
181 {
182 GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0);
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 }
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 }
196 static void
197 moz_gfx_buffer_pool_init (MozGfxBufferPool * pool)
198 {
199 }
201 } // namespace mozilla