michael@0: #ifdef HAVE_CONFIG_H michael@0: #include "config.h" michael@0: #endif michael@0: michael@0: #include "GStreamerAllocator.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "GStreamerLoader.h" michael@0: michael@0: using namespace mozilla::layers; michael@0: michael@0: namespace mozilla { michael@0: michael@0: typedef struct michael@0: { michael@0: GstAllocator parent; michael@0: GStreamerReader *reader; michael@0: } MozGfxMemoryAllocator; michael@0: michael@0: typedef struct michael@0: { michael@0: GstAllocatorClass parent; michael@0: } MozGfxMemoryAllocatorClass; michael@0: michael@0: typedef struct michael@0: { michael@0: GstMemory memory; michael@0: PlanarYCbCrImage* image; michael@0: guint8* data; michael@0: } MozGfxMemory; michael@0: michael@0: typedef struct michael@0: { michael@0: GstMeta meta; michael@0: } MozGfxMeta; michael@0: michael@0: typedef struct michael@0: { michael@0: GstVideoBufferPoolClass parent_class; michael@0: } MozGfxBufferPoolClass; michael@0: michael@0: typedef struct michael@0: { michael@0: GstVideoBufferPool pool; michael@0: } MozGfxBufferPool; michael@0: michael@0: // working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899 michael@0: #pragma GCC diagnostic push michael@0: #pragma GCC diagnostic ignored "-Wunused-function" michael@0: G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR); michael@0: G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL); michael@0: #pragma GCC diagnostic pop michael@0: michael@0: void michael@0: moz_gfx_memory_reset(MozGfxMemory *mem) michael@0: { michael@0: if (mem->image) michael@0: mem->image->Release(); michael@0: michael@0: ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer(); michael@0: mem->image = reinterpret_cast(container->CreateImage(ImageFormat::PLANAR_YCBCR).take()); michael@0: mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size); michael@0: } michael@0: michael@0: static GstMemory* michael@0: moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize, michael@0: GstAllocationParams* aParams) michael@0: { michael@0: MozGfxMemory* mem = g_slice_new (MozGfxMemory); michael@0: gsize maxsize = aSize + aParams->prefix + aParams->padding; michael@0: gst_memory_init(GST_MEMORY_CAST (mem), michael@0: (GstMemoryFlags)aParams->flags, michael@0: aAllocator, NULL, maxsize, aParams->align, michael@0: aParams->prefix, aSize); michael@0: mem->image = NULL; michael@0: moz_gfx_memory_reset(mem); michael@0: michael@0: return (GstMemory *) mem; michael@0: } michael@0: michael@0: static void michael@0: moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem) michael@0: { michael@0: MozGfxMemory *mem = (MozGfxMemory *) gmem; michael@0: michael@0: if (mem->memory.parent) michael@0: goto sub_mem; michael@0: michael@0: if (mem->image) michael@0: mem->image->Release(); michael@0: michael@0: sub_mem: michael@0: g_slice_free (MozGfxMemory, mem); michael@0: } michael@0: michael@0: static gpointer michael@0: moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags) michael@0: { michael@0: // check that the allocation didn't fail michael@0: if (mem->data == nullptr) michael@0: return nullptr; michael@0: michael@0: return mem->data + mem->memory.offset; michael@0: } michael@0: michael@0: static gboolean michael@0: moz_gfx_memory_unmap (MozGfxMemory * mem) michael@0: { michael@0: return TRUE; michael@0: } michael@0: michael@0: static MozGfxMemory * michael@0: moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size) michael@0: { michael@0: MozGfxMemory *sub; michael@0: GstMemory *parent; michael@0: michael@0: /* find the real parent */ michael@0: if ((parent = mem->memory.parent) == NULL) michael@0: parent = (GstMemory *) mem; michael@0: michael@0: if (size == (gsize) -1) michael@0: size = mem->memory.size - offset; michael@0: michael@0: /* the shared memory is always readonly */ michael@0: sub = g_slice_new (MozGfxMemory); michael@0: michael@0: gst_memory_init (GST_MEMORY_CAST (sub), michael@0: (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), michael@0: mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align, michael@0: mem->memory.offset + offset, size); michael@0: michael@0: sub->image = mem->image; michael@0: sub->data = mem->data; michael@0: michael@0: return sub; michael@0: } michael@0: michael@0: static void michael@0: moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass) michael@0: { michael@0: GstAllocatorClass *allocator_class; michael@0: michael@0: allocator_class = (GstAllocatorClass *) klass; michael@0: michael@0: allocator_class->alloc = moz_gfx_memory_allocator_alloc; michael@0: allocator_class->free = moz_gfx_memory_allocator_free; michael@0: } michael@0: michael@0: static void michael@0: moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator) michael@0: { michael@0: GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); michael@0: michael@0: alloc->mem_type = "moz-gfx-image"; michael@0: alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map; michael@0: alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap; michael@0: alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share; michael@0: /* fallback copy and is_span */ michael@0: } michael@0: michael@0: void michael@0: moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader) michael@0: { michael@0: MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator; michael@0: allocator->reader = aReader; michael@0: } michael@0: michael@0: nsRefPtr michael@0: moz_gfx_memory_get_image(GstMemory *aMemory) michael@0: { michael@0: NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image"); michael@0: michael@0: return ((MozGfxMemory *) aMemory)->image; michael@0: } michael@0: michael@0: void michael@0: moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer) michael@0: { michael@0: GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); michael@0: michael@0: NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image"); michael@0: moz_gfx_memory_reset((MozGfxMemory *) mem); michael@0: GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer); michael@0: } michael@0: michael@0: static void michael@0: moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass) michael@0: { michael@0: GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass; michael@0: pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer; michael@0: } michael@0: michael@0: static void michael@0: moz_gfx_buffer_pool_init (MozGfxBufferPool * pool) michael@0: { michael@0: } michael@0: michael@0: } // namespace mozilla