content/media/gstreamer/GStreamerAllocator.cpp

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

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

mercurial