From d58bab2ab3df3b40d6f65d88d0c827a303e0a651 Mon Sep 17 00:00:00 2001 From: Haihua Hu Date: Fri, 5 Aug 2016 17:08:40 +0800 Subject: [PATCH 11/16] [MMFMWK-7259] Remove dependence on imx plugin git. Add physical memory allocator Upstream-Status: Inappropriate [i.MX specific] Signed-off-by: Haihua Hu --- gst-libs/gst/allocators/Makefile.am | 6 +- gst-libs/gst/allocators/gstallocatorphymem.c | 314 +++++++++++++++++++++++++++ gst-libs/gst/allocators/gstallocatorphymem.h | 64 ++++++ 3 files changed, 382 insertions(+), 2 deletions(-) create mode 100755 gst-libs/gst/allocators/gstallocatorphymem.c create mode 100755 gst-libs/gst/allocators/gstallocatorphymem.h diff --git a/gst-libs/gst/allocators/Makefile.am b/gst-libs/gst/allocators/Makefile.am index bccfdb3..a19c249 100644 --- a/gst-libs/gst/allocators/Makefile.am +++ b/gst-libs/gst/allocators/Makefile.am @@ -5,13 +5,15 @@ libgstallocators_@GST_API_VERSION@_includedir = $(includedir)/gstreamer-@GST_API libgstallocators_@GST_API_VERSION@_include_HEADERS = \ allocators.h \ gstfdmemory.h \ - gstdmabuf.h + gstdmabuf.h \ + gstallocatorphymem.h noinst_HEADERS = libgstallocators_@GST_API_VERSION@_la_SOURCES = \ gstfdmemory.c \ - gstdmabuf.c + gstdmabuf.c \ + gstallocatorphymem.c libgstallocators_@GST_API_VERSION@_la_LIBADD = $(GST_LIBS) $(LIBM) libgstallocators_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) diff --git a/gst-libs/gst/allocators/gstallocatorphymem.c b/gst-libs/gst/allocators/gstallocatorphymem.c new file mode 100755 index 0000000..cf5995e --- /dev/null +++ b/gst-libs/gst/allocators/gstallocatorphymem.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2013-2015, Freescale Semiconductor, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include "gstallocatorphymem.h" + +typedef struct { + GstMemory mem; + guint8 *vaddr; + guint8 *paddr; + PhyMemBlock block; +} GstMemoryPhy; + +static int +default_copy (GstAllocatorPhyMem *allocator, PhyMemBlock *dst_mem, + PhyMemBlock *src_mem, guint offset, guint size) +{ + GST_WARNING ("No default copy implementation for physical memory allocator.\n"); + return -1; +} + +static gpointer +gst_phymem_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) +{ + GstMemoryPhy *phymem = (GstMemoryPhy*) mem; + + if (GST_MEMORY_IS_READONLY(mem) && (flags & GST_MAP_WRITE)) { + GST_ERROR("memory is read only"); + return NULL; + } + + return phymem->vaddr; +} + +static void +gst_phymem_unmap (GstMemory * mem) +{ + return; +} + +static GstMemory * +gst_phymem_copy (GstMemory * mem, gssize offset, gssize size) +{ + GstAllocatorPhyMemClass *klass; + GstMemoryPhy *src_mem = (GstMemoryPhy *)mem; + + GstMemoryPhy *dst_mem = g_slice_alloc(sizeof(GstMemoryPhy)); + if(dst_mem == NULL) { + GST_ERROR("Can't allocate for GstMemoryPhy structure.\n"); + return NULL; + } + + klass = GST_ALLOCATOR_PHYMEM_CLASS(G_OBJECT_GET_CLASS(mem->allocator)); + if(klass == NULL) { + GST_ERROR("Can't get class from allocator object.\n"); + return NULL; + } + + if(klass->copy_phymem((GstAllocatorPhyMem*)mem->allocator, + &dst_mem->block, &src_mem->block, offset, size) < 0) { + GST_WARNING ("Copy phymem %d failed.\n", size); + return NULL; + } + + GST_DEBUG ("copied phymem, vaddr(%p), paddr(%p), size(%d).\n", + dst_mem->block.vaddr, dst_mem->block.paddr, dst_mem->block.size); + + dst_mem->vaddr = dst_mem->block.vaddr; + dst_mem->paddr = dst_mem->block.paddr; + + gst_memory_init (GST_MEMORY_CAST (dst_mem), + mem->mini_object.flags&(~GST_MEMORY_FLAG_READONLY), + mem->allocator, NULL, mem->maxsize, mem->align, + mem->offset, mem->size); + + return (GstMemory*)dst_mem; +} + +static GstMemory * +gst_phymem_share (GstMemory * mem, gssize offset, gssize size) +{ + GST_ERROR("Not implemented mem_share in gstallocatorphymem.\n"); + return NULL; +} + +static gboolean +gst_phymem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) +{ + return FALSE; +} + +static gpointer +gst_phymem_get_phy (GstMemory * mem) +{ + GstMemoryPhy *phymem = (GstMemoryPhy*) mem; + + return phymem->paddr; +} + +static GstMemory * +base_alloc (GstAllocator * allocator, gsize size, + GstAllocationParams * params) +{ + GstAllocatorPhyMemClass *klass; + GstMemoryPhy *mem; + gsize maxsize, aoffset, offset, align, padding; + guint8 *data; + + mem = g_slice_alloc(sizeof(GstMemoryPhy)); + if(mem == NULL) { + GST_ERROR("Can allocate for GstMemoryPhy structure.\n"); + return NULL; + } + + klass = GST_ALLOCATOR_PHYMEM_CLASS(G_OBJECT_GET_CLASS(allocator)); + if(klass == NULL) { + GST_ERROR("Can't get class from allocator object.\n"); + return NULL; + } + + GST_DEBUG ("allocate params, prefix (%d), padding (%d), align (%d), flags (%x).\n", + params->prefix, params->padding, params->align, params->flags); + + maxsize = size + params->prefix + params->padding; + mem->block.size = maxsize; + if(klass->alloc_phymem((GstAllocatorPhyMem*)allocator, &mem->block) < 0) { + GST_ERROR("Allocate phymem %d failed.\n", maxsize); + return NULL; + } + + GST_DEBUG ("allocated phymem, vaddr(%p), paddr(%p), size(%d).\n", + mem->block.vaddr, mem->block.paddr, mem->block.size); + + data = mem->block.vaddr; + offset = params->prefix; + align = params->align; + /* do alignment */ + if ((aoffset = ((guintptr)data & align))) { + aoffset = (align + 1) - aoffset; + data += aoffset; + maxsize -= aoffset; + } + mem->vaddr = mem->block.vaddr + aoffset; + mem->paddr = mem->block.paddr + aoffset; + + GST_DEBUG ("aligned vaddr(%p), paddr(%p), size(%d).\n", + mem->block.vaddr, mem->block.paddr, mem->block.size); + + if (offset && (params->flags & GST_MEMORY_FLAG_ZERO_PREFIXED)) + memset (data, 0, offset); + + padding = maxsize - (offset + size); + if (padding && (params->flags & GST_MEMORY_FLAG_ZERO_PADDED)) + memset (data + offset + size, 0, padding); + + gst_memory_init (GST_MEMORY_CAST (mem), params->flags, allocator, NULL, maxsize, align, offset, size); + + return (GstMemory*)mem; +} + +static void +base_free (GstAllocator * allocator, GstMemory * mem) +{ + GstAllocatorPhyMemClass *klass; + GstMemoryPhy *phymem; + + klass = GST_ALLOCATOR_PHYMEM_CLASS(G_OBJECT_GET_CLASS(allocator)); + if(klass == NULL) { + GST_ERROR("Can't get class from allocator object, can't free %p\n", mem); + return; + } + + phymem = (GstMemoryPhy*)mem; + + GST_DEBUG ("free phymem, vaddr(%p), paddr(%p), size(%d).\n", + phymem->block.vaddr, phymem->block.paddr, phymem->block.size); + + klass->free_phymem((GstAllocatorPhyMem*)allocator, &phymem->block); + g_slice_free1(sizeof(GstMemoryPhy), mem); + + return; +} + +static int +default_alloc (GstAllocatorPhyMem *allocator, PhyMemBlock *phy_mem) +{ + GST_ERROR ("No default allocating implementation for physical memory allocation.\n"); + return -1; +} + +static int +default_free (GstAllocatorPhyMem *allocator, PhyMemBlock *phy_mem) +{ + GST_ERROR ("No default free implementation for physical memory allocation.\n"); + return -1; +} + +G_DEFINE_TYPE (GstAllocatorPhyMem, gst_allocator_phymem, GST_TYPE_ALLOCATOR); + +static void +gst_allocator_phymem_class_init (GstAllocatorPhyMemClass * klass) +{ + GstAllocatorClass *allocator_class; + + allocator_class = (GstAllocatorClass *) klass; + + allocator_class->alloc = base_alloc; + allocator_class->free = base_free; + klass->alloc_phymem = default_alloc; + klass->free_phymem = default_free; + klass->copy_phymem = default_copy; +} + +static void +gst_allocator_phymem_init (GstAllocatorPhyMem * allocator) +{ + GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); + + alloc->mem_map = gst_phymem_map; + alloc->mem_unmap = gst_phymem_unmap; + alloc->mem_copy = gst_phymem_copy; + alloc->mem_share = gst_phymem_share; + alloc->mem_is_span = gst_phymem_is_span; +} + + +//global functions + +gboolean +gst_buffer_is_phymem (GstBuffer *buffer) +{ + gboolean ret = FALSE; + PhyMemBlock * memblk; + GstMemory *mem = gst_buffer_get_memory (buffer, 0); + if(mem == NULL) { + GST_ERROR ("Not get memory from buffer.\n"); + return FALSE; + } + + if(GST_IS_ALLOCATOR_PHYMEM(mem->allocator)) { + if (NULL == ((GstMemoryPhy*)mem)->block.paddr) { + GST_WARNING("physical address in memory block is invalid"); + ret = FALSE; + } else { + ret = TRUE; + } + } + + gst_memory_unref (mem); + + return ret; +} + +PhyMemBlock * +gst_buffer_query_phymem_block (GstBuffer *buffer) +{ + GstMemory *mem; + GstMemoryPhy *memphy; + PhyMemBlock *memblk; + + mem = gst_buffer_get_memory (buffer, 0); + if(mem == NULL) { + GST_ERROR ("Not get memory from buffer.\n"); + return NULL; + } + + if(!GST_IS_ALLOCATOR_PHYMEM(mem->allocator)) { + gst_memory_unref (mem); + return NULL; + } + + memphy = (GstMemoryPhy*) mem; + memblk = &memphy->block; + + gst_memory_unref (mem); + + return memblk; +} + +PhyMemBlock * +gst_memory_query_phymem_block (GstMemory *mem) +{ + GstMemoryPhy *memphy; + PhyMemBlock *memblk; + + if (!mem) + return NULL; + + if (!GST_IS_ALLOCATOR_PHYMEM(mem->allocator)) + return NULL; + + memphy = (GstMemoryPhy*) mem; + memblk = &memphy->block; + + return memblk; +} + diff --git a/gst-libs/gst/allocators/gstallocatorphymem.h b/gst-libs/gst/allocators/gstallocatorphymem.h new file mode 100755 index 0000000..f0833ae --- /dev/null +++ b/gst-libs/gst/allocators/gstallocatorphymem.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2015, Freescale Semiconductor, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __ALLOCATOR_PHYMEM_H__ +#define __ALLOCATOR_PHYMEM_H__ + +#include +#include + +#define PAGE_ALIGN(x) (((x) + 4095) & ~4095) + +#define GST_TYPE_ALLOCATOR_PHYMEM (gst_allocator_phymem_get_type()) +#define GST_ALLOCATOR_PHYMEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_ALLOCATOR_PHYMEM, GstAllocatorPhyMem)) +#define GST_ALLOCATOR_PHYMEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_ALLOCATOR_PHYMEM, GstAllocatorPhyMemClass)) +#define GST_IS_ALLOCATOR_PHYMEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_ALLOCATOR_PHYMEM)) +#define GST_IS_ALLOCATOR_PHYMEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_ALLOCATOR_PHYMEM)) + +typedef struct _GstAllocatorPhyMem GstAllocatorPhyMem; +typedef struct _GstAllocatorPhyMemClass GstAllocatorPhyMemClass; + +/* also change gst-libs/gst/gl/gstglvivdirecttexture.c in gst-plugins-bad git + * if changed below structure */ +typedef struct { + guint8 *vaddr; + guint8 *paddr; + guint8 *caddr; + gsize size; + gpointer *user_data; +} PhyMemBlock; + +struct _GstAllocatorPhyMem { + GstAllocator parent; +}; + +struct _GstAllocatorPhyMemClass { + GstAllocatorClass parent_class; + int (*alloc_phymem) (GstAllocatorPhyMem *allocator, PhyMemBlock *phy_mem); + int (*free_phymem) (GstAllocatorPhyMem *allocator, PhyMemBlock *phy_mem); + int (*copy_phymem) (GstAllocatorPhyMem *allocator, PhyMemBlock *det_mem, + PhyMemBlock *src_mem, guint offset, guint size); +}; + +GType gst_allocator_phymem_get_type (void); +gboolean gst_buffer_is_phymem (GstBuffer *buffer); +PhyMemBlock *gst_buffer_query_phymem_block (GstBuffer *buffer); +PhyMemBlock *gst_memory_query_phymem_block (GstMemory *mem); + +#endif -- 1.9.1