444 lines
13 KiB
Diff
444 lines
13 KiB
Diff
From 09c72d6fcdee9b1d529db187047085653d264da4 Mon Sep 17 00:00:00 2001
|
|
From: Haihua Hu <jared.hu@nxp.com>
|
|
Date: Thu, 18 May 2017 16:43:40 +0800
|
|
Subject: [PATCH 18/26] Add imx physical memory allocator
|
|
|
|
Upstream-Status: Inappropriate [i.MX specific]
|
|
|
|
Signed-off-by: Haihua Hu <jared.hu@nxp.com>
|
|
---
|
|
gst-libs/gst/allocators/Makefile.am | 6 +-
|
|
gst-libs/gst/allocators/badallocators.h | 1 +
|
|
gst-libs/gst/allocators/gstallocatorphymem.c | 314 +++++++++++++++++++++++++++
|
|
gst-libs/gst/allocators/gstallocatorphymem.h | 64 ++++++
|
|
4 files changed, 383 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 e50d077..46c75c0 100644
|
|
--- a/gst-libs/gst/allocators/Makefile.am
|
|
+++ b/gst-libs/gst/allocators/Makefile.am
|
|
@@ -4,12 +4,14 @@ libgstbadallocators_@GST_API_VERSION@_includedir = $(includedir)/gstreamer-@GST_
|
|
|
|
libgstbadallocators_@GST_API_VERSION@_include_HEADERS = \
|
|
badallocators.h \
|
|
- gstphysmemory.h
|
|
+ gstphysmemory.h \
|
|
+ gstallocatorphymem.h
|
|
|
|
noinst_HEADERS =
|
|
|
|
libgstbadallocators_@GST_API_VERSION@_la_SOURCES = \
|
|
- gstphysmemory.c
|
|
+ gstphysmemory.c \
|
|
+ gstallocatorphymem.c
|
|
|
|
libgstbadallocators_@GST_API_VERSION@_la_LIBADD = $(GST_LIBS) $(LIBM)
|
|
libgstbadallocators_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
|
diff --git a/gst-libs/gst/allocators/badallocators.h b/gst-libs/gst/allocators/badallocators.h
|
|
index 4e18215..2c143f4 100644
|
|
--- a/gst-libs/gst/allocators/badallocators.h
|
|
+++ b/gst-libs/gst/allocators/badallocators.h
|
|
@@ -23,6 +23,7 @@
|
|
#define __GST_ALLOCATORS_BAD_H__
|
|
|
|
#include <gst/allocators/gstphysmemory.h>
|
|
+#include <gst/allocators/gstallocatorphymem.h>
|
|
|
|
#endif /* __GST_ALLOCATORS_BAD_H__ */
|
|
|
|
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 <stdio.h>
|
|
+#include <string.h>
|
|
+#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 <gst/gst.h>
|
|
+#include <gst/gstallocator.h>
|
|
+
|
|
+#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
|
|
|