Files
BPI-CM9-Linux/aml-comp/multimedia/gst-aml-utils/gst-aml-dma-allocator/gstamldmaallocator.c
T

246 lines
7.1 KiB
C
Raw Normal View History

2026-08-13 11:28:40 +08:00
/*
* 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <gst/gst.h>
#include <gst/base/base.h>
#include <gst/allocators/gstdmabuf.h>
#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);
// }