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
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 |