From c5d115bf88f0d2fb64f58b21b72a3195eae98d0a Mon Sep 17 00:00:00 2001 From: Pooja Prajod Date: Fri, 20 Jan 2017 14:41:45 +0530 Subject: [PATCH 1/5] gstdrmallocator: Add DRM allocator support Add DRM based allocator support. The following changes are included : 1. Use DRM dumb buffers and associated APIs for dmabuf allocation. 2. Have DRM device fd a member of allocator object 3. Allocate GstMemory objects with mem_type as 'dmabuf' Signed-off-by: Pooja Prajod --- configure.ac | 5 + gst-libs/gst/Makefile.am | 4 +- gst-libs/gst/drm/Makefile.am | 33 +++++ gst-libs/gst/drm/gstdrmallocator.c | 206 ++++++++++++++++++++++++++++++ gst-libs/gst/drm/gstdrmallocator.h | 77 +++++++++++ pkgconfig/Makefile.am | 3 + pkgconfig/gstreamer-drm-uninstalled.pc.in | 11 ++ pkgconfig/gstreamer-drm.pc.in | 12 ++ 8 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/drm/Makefile.am create mode 100644 gst-libs/gst/drm/gstdrmallocator.c create mode 100644 gst-libs/gst/drm/gstdrmallocator.h create mode 100644 pkgconfig/gstreamer-drm-uninstalled.pc.in create mode 100644 pkgconfig/gstreamer-drm.pc.in diff --git a/configure.ac b/configure.ac index 5e85e56..e254605 100644 --- a/configure.ac +++ b/configure.ac @@ -621,6 +621,8 @@ if test x$with_egl_module_name != x; then AC_DEFINE_UNQUOTED(GST_GL_LIBEGL_MODULE_NAME, "$with_egl_module_name", [EGL module name]) fi +PKG_CHECK_MODULES([DRM], [libdrm libdrm_omap], HAVE_KMS=yes, HAVE_KMS=no) + AC_ARG_ENABLE([wgl], [ --enable-wgl Enable WGL support @<:@default=auto@:>@], [case "${enableval}" in @@ -3590,6 +3592,7 @@ gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/adaptivedemux/Makefile gst-libs/gst/basecamerabinsrc/Makefile +gst-libs/gst/drm/Makefile gst-libs/gst/gl/Makefile gst-libs/gst/gl/android/Makefile gst-libs/gst/gl/cocoa/Makefile @@ -3749,6 +3752,8 @@ pkgconfig/gstreamer-plugins-bad.pc pkgconfig/gstreamer-plugins-bad-uninstalled.pc pkgconfig/gstreamer-codecparsers.pc pkgconfig/gstreamer-codecparsers-uninstalled.pc +pkgconfig/gstreamer-drm.pc +pkgconfig/gstreamer-drm-uninstalled.pc pkgconfig/gstreamer-insertbin.pc pkgconfig/gstreamer-insertbin-uninstalled.pc pkgconfig/gstreamer-gl.pc diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 7d0b309..5ec3967 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -11,7 +11,7 @@ WAYLAND_DIR=wayland endif SUBDIRS = uridownloader adaptivedemux interfaces basecamerabinsrc codecparsers \ - insertbin mpegts base video audio player $(GL_DIR) $(WAYLAND_DIR) + insertbin mpegts base video audio player drm $(GL_DIR) $(WAYLAND_DIR) noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h DIST_SUBDIRS = uridownloader adaptivedemux interfaces gl basecamerabinsrc \ @@ -24,7 +24,7 @@ adaptivedemux: uridownloader INDEPENDENT_SUBDIRS = \ interfaces basecamerabinsrc codecparsers insertbin uridownloader \ - mpegts base player $(GL_DIR) $(WAYLAND_DIR) + mpegts base player drm $(GL_DIR) $(WAYLAND_DIR) .PHONY: independent-subdirs $(INDEPENDENT_SUBDIRS) diff --git a/gst-libs/gst/drm/Makefile.am b/gst-libs/gst/drm/Makefile.am new file mode 100644 index 0000000..9a45dfb --- /dev/null +++ b/gst-libs/gst/drm/Makefile.am @@ -0,0 +1,33 @@ +lib_LTLIBRARIES = libgstdrm-@GST_API_VERSION@.la + +CLEANFILES = $(BUILT_SOURCES) + +libgstdrm_@GST_API_VERSION@_la_SOURCES = \ + gstdrmallocator.c + +libgstdrm_@GST_API_VERSION@includedir = \ + $(includedir)/gstreamer-@GST_API_VERSION@/gst/drm + +libgstdrm_@GST_API_VERSION@include_HEADERS = \ + gstdrmallocator.h + +libgstdrm_@GST_API_VERSION@_la_CFLAGS = \ + $(DRM_CFLAGS) \ + $(OMAPDRM_CFLAGS) \ + $(GST_PLUGINS_BAD_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) \ + -DGST_USE_UNSTABLE_API \ + $(GST_CFLAGS) + +libgstdrm_@GST_API_VERSION@_la_LIBADD = \ + $(DRM_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) \ + $(GST_BASE_LIBS) \ + -lgstallocators-$(GST_API_VERSION) \ + $(GST_LIBS) + +libgstdrm_@GST_API_VERSION@_la_LDFLAGS = \ + $(DRM_LDFLAGS) \ + $(GST_LIB_LDFLAGS) \ + $(GST_ALL_LDFLAGS) \ + $(GST_LT_LDFLAGS) diff --git a/gst-libs/gst/drm/gstdrmallocator.c b/gst-libs/gst/drm/gstdrmallocator.c new file mode 100644 index 0000000..b557ad2 --- /dev/null +++ b/gst-libs/gst/drm/gstdrmallocator.c @@ -0,0 +1,206 @@ +/* + * GStreamer + * + * Copyright (C) 2012 Texas Instruments + * + * Authors: + * Pooja Prajod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * SECTION:GstDRMAllocator + * @short_description: GStreamer DRM allocator support + * + * Since: 1.6.3 + */ + + +#include "gstdrmallocator.h" +#include +#include +#include +#include +#include +#include +#include + +#define INVALID_DRM_FD (-1) + +GST_DEBUG_CATEGORY (drmallocator_debug); +#define GST_CAT_DEFAULT drmallocator_debug + +#define gst_drm_allocator_parent_class parent_class +G_DEFINE_TYPE (GstDRMAllocator, gst_drm_allocator, GST_TYPE_FD_ALLOCATOR); + +static GstMemory * +gst_drm_allocator_alloc (GstAllocator * allocator, gsize size, + GstAllocationParams * params) +{ + GstDRMAllocator *self = GST_DRM_ALLOCATOR (allocator); + int fd = -1; + int DrmDeviceFD = self->DrmDeviceFD; + GstMemory *mem; + /* Variable for DRM Dumb Buffers */ + + struct drm_mode_create_dumb creq; + struct drm_mode_destroy_dumb dreq; + int ret ; + + GST_LOG_OBJECT (self, "DRM Memory alloc"); + + memset(&creq, 0, sizeof(struct drm_mode_create_dumb)); + /* + We have only total size as argument to _allocator_alloc. + Since the DDR storage is linear, it is as good as saying + the buffer is of width = size and height = 1 + */ + creq.width = size; + creq.height = 1; + creq.bpp = 8; + + /* Create a DRM dumb buffer */ + ret = drmIoctl (DrmDeviceFD, DRM_IOCTL_MODE_CREATE_DUMB, &creq); + if (ret < 0) { + GST_ERROR_OBJECT (self, "Create DRM dumb buffer failed"); + return NULL; + } + /* Get a dmabuf fd from the dumb buffer handle */ + drmPrimeHandleToFD (DrmDeviceFD, creq.handle, DRM_CLOEXEC | O_RDWR, &fd); + + if (fd < 0) { + GST_ERROR_OBJECT (self, "Invalid fd returned: %d", fd); + goto fail; + } + + /* Get a dmabuf gstmemory with the fd */ + mem = gst_fd_allocator_alloc (allocator, fd, size, 0); + + if (G_UNLIKELY (!mem)) { + GST_ERROR_OBJECT (self, "GstDmaBufMemory allocation failed"); + close (fd); + goto fail; + } + + return mem; + + fail: + memset(&dreq, 0, sizeof(struct drm_mode_destroy_dumb)); + dreq.handle = creq.handle; + drmIoctl (DrmDeviceFD, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); + return NULL; +} + +static void +gst_drm_allocator_free (GstAllocator * allocator, GstMemory * mem) +{ + GstDRMAllocator *self = GST_DRM_ALLOCATOR (allocator); + uint32_t handle = 0; + int DrmDeviceFD = self->DrmDeviceFD; + int fd = -1; + + GST_LOG_OBJECT (self, "DRM Memory free"); + + g_return_if_fail (GST_IS_ALLOCATOR (allocator)); + g_return_if_fail (mem != NULL); + g_return_if_fail (gst_is_drm_memory (mem)); + + fd = gst_fd_memory_get_fd (mem); + drmPrimeFDToHandle(DrmDeviceFD, fd, &handle); + + /* Incase there are some mapped memory, we unmap and ready it to be cleaned*/ + GST_ALLOCATOR_CLASS (parent_class)->free (allocator, mem); + + if (handle) { + struct drm_mode_destroy_dumb dreq; + memset(&dreq, 0, sizeof(struct drm_mode_destroy_dumb)); + dreq.handle = handle; + drmIoctl (DrmDeviceFD, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); + } + + close (fd); +} + +static void +gst_drm_allocator_finalize (GObject * obj) +{ + GstDRMAllocator *self = GST_DRM_ALLOCATOR (obj); + GST_LOG_OBJECT (obj, "DRM Allocator finalize"); + + close (self->DrmDeviceFD); + self->DrmDeviceFD = INVALID_DRM_FD; + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +static void +gst_drm_allocator_class_init (GstDRMAllocatorClass * klass) +{ + GstAllocatorClass *drm_alloc = (GstAllocatorClass *) klass; + + drm_alloc->alloc = GST_DEBUG_FUNCPTR (gst_drm_allocator_alloc); + drm_alloc->free = GST_DEBUG_FUNCPTR (gst_drm_allocator_free); + GST_DEBUG_CATEGORY_INIT (drmallocator_debug, "drmallocator", 0, + "GstDRMAllocator debug"); + +} + +static void +gst_drm_allocator_init (GstDRMAllocator * self) +{ + GstAllocator *alloc = GST_ALLOCATOR_CAST (self); + GObjectClass *object_class = G_OBJECT_CLASS (GST_DRM_ALLOCATOR_GET_CLASS(self)); + + if (self->DrmDeviceFD <= 0) { + self->DrmDeviceFD = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); + if (self->DrmDeviceFD < 0) { + GST_ERROR_OBJECT (self, "Failed to open DRM device"); + } else { + drmDropMaster (self->DrmDeviceFD); + } + } + + alloc->mem_type = GST_ALLOCATOR_DMABUF; + + object_class->finalize = gst_drm_allocator_finalize; + + GST_OBJECT_FLAG_UNSET (self, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); +} + +void +gst_drm_allocator_register (void) +{ + gst_allocator_register (GST_ALLOCATOR_DRM, + g_object_new (GST_TYPE_DRM_ALLOCATOR, NULL)); +} + +GstAllocator * +gst_drm_allocator_get (void) +{ + GstAllocator *alloc; + alloc = gst_allocator_find (GST_ALLOCATOR_DRM); + if (!alloc) { + gst_drm_allocator_register(); + alloc = gst_allocator_find (GST_ALLOCATOR_DRM); + } + return alloc; +} + +gboolean +gst_is_drm_memory (GstMemory * mem) +{ + return gst_memory_is_type (mem, GST_ALLOCATOR_DMABUF); +} diff --git a/gst-libs/gst/drm/gstdrmallocator.h b/gst-libs/gst/drm/gstdrmallocator.h new file mode 100644 index 0000000..1ca93ba --- /dev/null +++ b/gst-libs/gst/drm/gstdrmallocator.h @@ -0,0 +1,77 @@ +/* + * GStreamer + * + * Copyright (C) 2012 Texas Instruments + * + * Authors: + * Pooja Prajod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * SECTION:GstDRMAllocator + * @short_description: GStreamer DRM allocator support + * + * Since: 1.6.3 + */ + +#ifndef __GSTDRMALLOCATOR_H__ +#define __GSTDRMALLOCATOR_H__ + +#include +#include +#include +#include + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_DRM_ALLOCATOR (gst_drm_allocator_get_type ()) +#define GST_DRM_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DRM_ALLOCATOR, GstDRMAllocator)) +#define GST_IS_DRM_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DRM_ALLOCATOR)) +#define GST_DRM_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DRM_ALLOCATOR, GstDRMAllocatorClass)) +#define GST_IS_DRM_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DRM_ALLOCATOR)) +#define GST_DRM_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DRM_ALLOCATOR, GstDRMAllocatorClass)) + +#define GST_ALLOCATOR_DRM "DRM" + +typedef struct _GstDRMAllocator GstDRMAllocator; +typedef struct _GstDRMAllocatorClass GstDRMAllocatorClass; + +struct _GstDRMAllocator +{ + GstFdAllocator parent; + int DrmDeviceFD; +}; + +struct _GstDRMAllocatorClass +{ + GstFdAllocatorClass parent_class; +}; + +void gst_drm_allocator_register (void); +GstAllocator * gst_drm_allocator_get (void); + +gboolean gst_is_drm_memory (GstMemory * mem); + +GType gst_drm_allocator_get_type (void); + +G_END_DECLS + +#endif /* __GSTDRMALLOCATOR_H__ */ diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 88c7e52..5fdccbf 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -2,6 +2,7 @@ ### all of the standard pc files we need to generate pcverfiles = \ gstreamer-plugins-bad-@GST_API_VERSION@.pc \ + gstreamer-drm-@GST_API_VERSION@.pc \ gstreamer-codecparsers-@GST_API_VERSION@.pc \ gstreamer-insertbin-@GST_API_VERSION@.pc \ gstreamer-mpegts-@GST_API_VERSION@.pc \ @@ -12,6 +13,7 @@ pcverfiles = \ pcverfiles_uninstalled = \ gstreamer-plugins-bad-@GST_API_VERSION@-uninstalled.pc \ + gstreamer-drm-@GST_API_VERSION@-uninstalled.pc \ gstreamer-codecparsers-@GST_API_VERSION@-uninstalled.pc \ gstreamer-insertbin-@GST_API_VERSION@-uninstalled.pc \ gstreamer-mpegts-@GST_API_VERSION@-uninstalled.pc \ @@ -43,6 +45,7 @@ pkgconfig_DATA = $(pcverfiles) CLEANFILES = $(pcverfiles) $(pcverfiles_uninstalled) pcinfiles = \ gstreamer-plugins-bad.pc.in gstreamer-plugins-bad-uninstalled.pc.in \ + gstreamer-drm.pc.in gstreamer-drm-uninstalled.pc.in \ gstreamer-codecparsers.pc.in gstreamer-codecparsers-uninstalled.pc.in \ gstreamer-gl.pc.in gstreamer-gl-uninstalled.pc.in \ gstreamer-insertbin.pc.in gstreamer-insertbin-uninstalled.pc.in \ diff --git a/pkgconfig/gstreamer-drm-uninstalled.pc.in b/pkgconfig/gstreamer-drm-uninstalled.pc.in new file mode 100644 index 0000000..9dcf978 --- /dev/null +++ b/pkgconfig/gstreamer-drm-uninstalled.pc.in @@ -0,0 +1,11 @@ +prefix= +exec_prefix= +libdir=${pcfiledir}/../gst-libs/gst/drm +includedir=${pcfiledir}/../gst-libs + +Name: GStreamer DRM Allocator, Uninstalled +Description: DRM Allocator for GStreamer elements, uninstalled +Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ +Version: @VERSION@ +Libs: -L${libdir} ${libdir}/libgstdrm-@GST_MAJORMINOR@.la +Cflags: -I${includedir} diff --git a/pkgconfig/gstreamer-drm.pc.in b/pkgconfig/gstreamer-drm.pc.in new file mode 100644 index 0000000..d155e80 --- /dev/null +++ b/pkgconfig/gstreamer-drm.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ + +Name: GStreamer DRM Allocator +Description: DRM Allocator for GStreamer elements +Requires: gstreamer-@GST_MAJORMINOR@ gstreamer-base-@GST_MAJORMINOR@ +Version: @VERSION@ +Libs: -L${libdir} -lgstdrm-@GST_MAJORMINOR@ +Cflags: -I${includedir} + -- 1.9.1