/* * Copyright (C) 2014-2019 Amlogic, Inc. All rights reserved. * * All information contained herein is Amlogic confidential. * * This software is provided to you pursuant to Software License Agreement * (SLA) with Amlogic Inc ("Amlogic"). This software may be used * only in accordance with the terms of this agreement. * * Redistribution and use in source and binary forms, with or without * modification is strictly prohibited without prior written permission from * Amlogic. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include "gstamldmaallocator.h" #include "dma_allocator.h" GST_DEBUG_CATEGORY_STATIC(amldma_allocator_debug); #define GST_CAT_DEFAULT amldma_allocator_debug #define gst_amldma_allocator_parent_class parent_class G_DEFINE_TYPE(GstAmlDMAAllocator, gst_amldma_allocator, GST_TYPE_ALLOCATOR) static void gst_amldma_mem_init(char *name) { GstAllocator *allocator = g_object_new(gst_amldma_allocator_get_type(), NULL); GstAmlDMAAllocator *self = GST_AMLDMA_ALLOCATOR (allocator); gint heap_fd = aml_dmabuf_heap_open (name); if (heap_fd < 0) { GST_ERROR ("Could not open DMA buffer device:%s", name); g_object_unref (self); return; } GST_INFO("heap name:%s heap_fd=%d", name, heap_fd); self->heap_fd = heap_fd; self->dma_allocator = gst_dmabuf_allocator_new(); gst_allocator_register(g_type_name(GST_TYPE_AMLDMA_ALLOCATOR), allocator); } GstAllocator* gst_amldma_allocator_obtain(char *name) { // static GOnce allocator_once = G_ONCE_INIT; GstAllocator *allocator; // g_once(&allocator_once, (GThreadFunc)gst_amldma_mem_init, (void *)name); gst_amldma_mem_init(name); allocator = gst_allocator_find(g_type_name(GST_TYPE_AMLDMA_ALLOCATOR)); if (allocator == NULL) GST_WARNING("No allocator named %s found", g_type_name(GST_TYPE_AMLDMA_ALLOCATOR)); return allocator; } GQuark gst_amldma_memory_quark (void) { static GQuark quark = 0; if (quark == 0) quark = g_quark_from_string ("GstAmlDMAPrivate"); return quark; } static GstMemory * gst_amldma_alloc_alloc (GstAllocator * allocator, gsize size, GstAllocationParams * params) { int ret = 0; GstAmlDMAAllocator *self = GST_AMLDMA_ALLOCATOR (allocator); gint dmaSize = (size + params->prefix + params->padding); int dmabuf_fd = -1; ret = aml_dmabuf_heap_alloc(self->heap_fd, dmaSize, &dmabuf_fd); GST_INFO("ret=%d heap_fd=%d, phyalloc dmaSize:%d dmabuf_fd: %d", ret, self->heap_fd, dmaSize, dmabuf_fd); GstAmlDMAMemory *dma_mem = g_slice_new0 (GstAmlDMAMemory); gst_memory_init (GST_MEMORY_CAST(dma_mem), GST_MEMORY_FLAG_NO_SHARE, allocator, 0, size, 0, 0, size); dma_mem->size = dmaSize; dma_mem->dmabuf_fd = (gint)dmabuf_fd; GstMemory *mem = gst_dmabuf_allocator_alloc (self->dma_allocator, dmabuf_fd, size); // GstMemory *mem = &dma_mem->mem; gst_mini_object_set_qdata (GST_MINI_OBJECT(mem), GST_AMLDMA_MEMORY_QUARK, dma_mem, (GDestroyNotify) gst_memory_unref); // GstMemory *mem = // gst_dmabuf_allocator_alloc (self->dma_allocator, data_fd, dmaSize); // gst_mini_object_set_qdata (GST_MINI_OBJECT(mem), GST_AMLDMA_MEMORY_QUARK, // dma_mem, (GDestroyNotify) gst_memory_unref); GST_INFO ("allocated mem %p by allocator %p with dma_mem %p\n", mem, allocator, dma_mem); // return (GstMemory *)dma_mem; return mem; } static void gst_amldma_alloc_free (GstAllocator * allocator, GstMemory * memory) { GstAmlDMAAllocator *self = GST_AMLDMA_ALLOCATOR (allocator); GstAmlDMAMemory *dma_mem = (GstAmlDMAMemory *) memory; if (!dma_mem || self->heap_fd < 0) return; //GST_DEBUG ("phyfree dmaSize:%lu dmabuf_fd: %d", dma_mem->size, dma_mem->dmabuf_fd); //not need close dmabuf_fd,gstfdmemory.c gst_fd_mem_free will do close fd // aml_dmabuf_heap_free(dma_mem->dmabuf_fd); g_slice_free (GstAmlDMAMemory, dma_mem); } static void gst_amldma_allocator_dispose (GObject * object) { GstAmlDMAAllocator *self = GST_AMLDMA_ALLOCATOR (object); if (self->heap_fd) { close (self->heap_fd); self->heap_fd = -1; } if (self->dma_allocator) gst_object_unref(self->dma_allocator); self->dma_allocator = NULL; G_OBJECT_CLASS (parent_class)->dispose (object); } static void gst_amldma_allocator_class_init (GstAmlDMAAllocatorClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstAllocatorClass *allocator_class = GST_ALLOCATOR_CLASS (klass); allocator_class->alloc = GST_DEBUG_FUNCPTR (gst_amldma_alloc_alloc); allocator_class->free = GST_DEBUG_FUNCPTR (gst_amldma_alloc_free); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_amldma_allocator_dispose); GST_DEBUG_CATEGORY_INIT(amldma_allocator_debug, "amldmaallocator", 0, "DMA FD memory allocator"); } static void gst_amldma_allocator_init (GstAmlDMAAllocator * self) { GstAllocator *allocator = GST_ALLOCATOR (self); allocator->mem_type = GST_ALLOCATOR_AMLDMA; allocator->mem_map = NULL; allocator->mem_unmap = NULL; } // gboolean // gst_is_amldmabuf_memory (GstMemory * mem) // { // g_return_val_if_fail (mem != NULL, FALSE); // gpointer qdata = gst_mini_object_get_qdata (GST_MINI_OBJECT(mem), GST_AMLDMA_MEMORY_QUARK); // return qdata != NULL; // } // gint gst_amldmabuf_memory_get_fd (GstMemory * mem) // { // g_return_val_if_fail (mem != NULL, FALSE); // GstAmlDMAMemory *dma_mem = (GstAmlDMAMemory *) mem; // GST_INFO("gst_amldmabuf_memory_get_fd: memory:%p dmabuf_fd:%d", mem, dma_mem->dmabuf_fd); // return dma_mem->dmabuf_fd; // } // unsigned char *gst_amldmabuf_mmap (GstMemory * mem) // { // g_return_val_if_fail (mem != NULL, FALSE); // GstAmlDMAMemory *dma_mem = (GstAmlDMAMemory *) mem; // GST_INFO("gst_amldmabuf_memory_get_fd: memory:%p dmabuf_fd:%d", mem, dma_mem->dmabuf_fd); // return mmap(NULL, // dma_mem->size, // PROT_READ | PROT_WRITE, // MAP_SHARED, // dma_mem->dmabuf_fd, // 0); // } // void gst_amldmabuf_munmap (unsigned char *p, GstMemory * mem) // { // g_return_val_if_fail (mem != NULL, FALSE); // GstAmlDMAMemory *dma_mem = (GstAmlDMAMemory *) mem; // GST_INFO("gst_amldmabuf_memory_get_fd: memory:%p dmabuf_fd:%d", mem, dma_mem->dmabuf_fd); // munmap(p, dma_mem->size); // }