diff --git a/subprojects/gst-plugins-base/gst-libs/gst/allocators/allocators.h b/subprojects/gst-plugins-base/gst-libs/gst/allocators/allocators.h index b616aa20e6..65e7e81f57 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/allocators/allocators.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/allocators/allocators.h @@ -27,6 +27,7 @@ #include #include #include +#include #endif /* __GST_ALLOCATORS_H__ */ diff --git a/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdrmdumb.c b/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdrmdumb.c new file mode 100644 index 0000000000..c5c4834248 --- /dev/null +++ b/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdrmdumb.c @@ -0,0 +1,755 @@ +/* GStreamer + * + * Copyright (C) 2023 Collabora + * Copyright (C) 2016 Igalia + * + * Authors: + * Víctor Manuel Jáquez Leal + * Javier Martin + * Colin Kinloch + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdrmdumb.h" +#include "gstdmabuf.h" + +/** + * SECTION:gstdrmdumb + * @title: GstDRMDumbAllocator + * @short_description: Memory wrapper for Linux DRM Dumb memory + * @see_also: #GstMemory + * + * Since: 1.24 + */ + +#ifdef HAVE_LIBDRM +#include +#include +#include +#include + +#include +#include +#include +#endif + +#define GST_CAT_DEFAULT drmdumballocator_debug +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); + +#define GST_DRM_DUMB_MEMORY_TYPE "DRMDumbMemory" + +typedef struct _GstDRMDumbMemory GstDRMDumbMemory; +struct _GstDRMDumbMemory +{ + GstMemory parent; + + gpointer ptr; + gsize size; + guint32 handle; + guint refs; +}; + +struct _GstDRMDumbAllocator +{ + GstAllocator parent; + + gint drm_fd; + gchar *drm_device_path; + + /* protected by GstDRMDumbAllocator object lock */ + GstAllocator *dmabuf_alloc; +}; + +#define parent_class gst_drm_dumb_allocator_parent_class +G_DEFINE_TYPE_WITH_CODE (GstDRMDumbAllocator, gst_drm_dumb_allocator, + GST_TYPE_ALLOCATOR, + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "drmdumballocator", 0, + "DRM dumb buffer allocator")); +enum +{ + PROP_DRM_FD = 1, + PROP_DRM_DEVICE_PATH, + PROP_N, +}; + +static GParamSpec *g_props[PROP_N] = { NULL, }; + +/** + * gst_is_drm_dumb_memory: + * @mem: the memory to be checked + * + * Returns: %TRUE if @mem is DRM Dumb memory, otherwise %FALSE + * + * Since: 1.24 + */ +gboolean +gst_is_drm_dumb_memory (GstMemory * mem) +{ + return gst_memory_is_type (mem, GST_DRM_DUMB_MEMORY_TYPE); +} + +/** + * gst_drm_dumb_memory_get_handle: + * @mem: the memory to get the handle from + * + * Return the DRM buffer object handle associated with @mem. + * + * Returns: the DRM buffer object handle associated with the memory, or 0. + * The handle is still owned by the GstMemory and cannot be used + * beyond the lifetime of this GstMemory unless it is being passed + * to DRM driver, which does handle a refcount internally. + * + * Since: 1.24 + */ +guint32 +gst_drm_dumb_memory_get_handle (GstMemory * mem) +{ + if (!gst_is_drm_dumb_memory (mem)) + return 0; + + return ((GstDRMDumbMemory *) mem)->handle; +} + +/** + * gst_drm_dumb_memory_export_dmabuf: + * @mem: the memory to export from + * + * Exports a DMABuf from the DRM Bumb buffer object. One can check if this + * feature is supported using gst_drm_dumb_allocator_has_prime_export(); + * + * Returns: a #GstMemory from #GstDmaBufAllocator wrapping the exported dma-buf + * file descriptor. + * + * Since: 1.24 + */ +GstMemory * +gst_drm_dumb_memory_export_dmabuf (GstMemory * mem) +{ +#ifdef HAVE_LIBDRM + GstDRMDumbMemory *drmmem = (GstDRMDumbMemory *) mem; + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (mem->allocator); + GstMemory *dmamem; + gint ret; + gint prime_fd; + + ret = drmPrimeHandleToFD (alloc->drm_fd, drmmem->handle, + DRM_CLOEXEC | DRM_RDWR, &prime_fd); + if (ret) + goto export_fd_failed; + + if (G_UNLIKELY (alloc->dmabuf_alloc == NULL)) + alloc->dmabuf_alloc = gst_dmabuf_allocator_new (); + + dmamem = gst_dmabuf_allocator_alloc (alloc->dmabuf_alloc, prime_fd, + gst_memory_get_sizes (mem, NULL, NULL)); + + GST_DEBUG_OBJECT (alloc, "Exported bo handle %d as %d", drmmem->handle, + prime_fd); + + return dmamem; + + /* ERRORS */ +export_fd_failed: + { + GST_ERROR_OBJECT (alloc, "Failed to export bo handle %d: %s (%d)", + drmmem->handle, g_strerror (errno), ret); + return NULL; + } + +#else + return NULL; +#endif +} + +#ifdef HAVE_LIBDRM +static guint32 +gst_drm_height_from_drm (guint32 drmfmt, guint32 height) +{ + guint32 ret; + + switch (drmfmt) { + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_P010: + case DRM_FORMAT_P016: + ret = height * 3 / 2; + break; + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + ret = height * 2; + break; + case DRM_FORMAT_NV24: + ret = height * 3; + break; + default: + ret = height; + break; + } + + return ret; +} + +static guint32 +gst_drm_bpp_from_drm (guint32 drm_fourcc) +{ + guint32 bpp; + + switch (drm_fourcc) { + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV24: + bpp = 8; + break; + case DRM_FORMAT_P010: + bpp = 10; + break; + case DRM_FORMAT_UYVY: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_P016: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + bpp = 16; + break; + case DRM_FORMAT_BGR888: + case DRM_FORMAT_RGB888: + bpp = 24; + break; + default: + bpp = 32; + break; + } + + return bpp; +} + +static gboolean +check_drm_fd (GstDRMDumbAllocator * alloc) +{ + return alloc->drm_fd > -1; +} +#endif + +static void +gst_drm_dumb_allocator_open_device (GstDRMDumbAllocator * alloc, + const gchar * path) +{ +#ifdef HAVE_LIBDRM + gint fd = -1; + + /* Ignore default constructor call */ + if (path == NULL) + return; + + /* construct only */ + g_assert (alloc->drm_fd == -1); + g_assert (alloc->drm_device_path == NULL); + + fd = open (path, O_RDWR | O_CLOEXEC); + + if (fd < 0) { + GST_WARNING_OBJECT (alloc, "Failed to open DRM device at %s", path); + return; + } + + alloc->drm_device_path = g_strdup (path); + alloc->drm_fd = fd; +#endif +} + +static void +gst_drm_dumb_allocator_set_fd (GstDRMDumbAllocator * alloc, gint fd) +{ +#ifdef HAVE_LIBDRM + /* Ignore default constructor call */ + if (fd == -1) + return; + + /* construct only */ + g_assert (alloc->drm_fd == -1); + g_assert (alloc->drm_device_path == NULL); + + if (fd >= 0) { + alloc->drm_device_path = drmGetDeviceNameFromFd2 (fd); + if (!alloc->drm_device_path) { + GST_WARNING_OBJECT (alloc, "Failed to verify DRM fd."); + return; + } + + GST_DEBUG_OBJECT (alloc, "Using external FD for %s", + alloc->drm_device_path); + + alloc->drm_fd = dup (fd); + } +#endif +} + +static void +gst_drm_dumb_allocator_memory_reset (GstDRMDumbAllocator * alloc, + GstDRMDumbMemory * mem) +{ +#ifdef HAVE_LIBDRM + gint err; + struct drm_mode_destroy_dumb arg = { 0, }; + + if (!mem->size) + return; + + if (!check_drm_fd (alloc)) + return; + + if (mem->ptr != NULL) { + GST_WARNING_OBJECT (alloc, "destroying mapped bo (refcount=%d)", mem->refs); + munmap (mem->ptr, mem->size); + mem->ptr = NULL; + } + + arg.handle = mem->handle; + + err = drmIoctl (alloc->drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); + if (err) + GST_WARNING_OBJECT (alloc, + "Failed to destroy dumb buffer object: %s %d", + g_strerror (errno), errno); + + mem->handle = -1; + mem->size = 0; +#endif +} + +static gboolean +gst_drm_dumb_allocator_memory_create (GstDRMDumbAllocator * alloc, + GstDRMDumbMemory * drmmem, + guint32 drm_fourcc, guint32 width, guint32 height, guint32 * out_pitch) +{ +#ifdef HAVE_LIBDRM + gint ret; + struct drm_mode_create_dumb arg = { 0, }; + + if (drmmem->size) + return TRUE; + + if (!check_drm_fd (alloc)) + return FALSE; + + arg.bpp = gst_drm_bpp_from_drm (drm_fourcc); + arg.width = width; + arg.height = gst_drm_height_from_drm (drm_fourcc, height); + + ret = drmIoctl (alloc->drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); + if (ret) + goto create_failed; + + if (!arg.pitch) { + GST_DEBUG_OBJECT (alloc, + "DRM dumb buffer pitch not set, no need to modify vinfo"); + goto done; + } + + GST_DEBUG_OBJECT (alloc, + "DRM dumb buffer pitch is set, vinfo modification required"); + *out_pitch = arg.pitch; + +done: + drmmem->handle = arg.handle; + /* will be used used as maxsize of GstMemory */ + drmmem->size = arg.size; + + return TRUE; + + /* ERRORS */ +create_failed: + { + GST_ERROR_OBJECT (alloc, "Failed to create buffer object: %s (%d)", + g_strerror (errno), errno); + return FALSE; + } + +#else + return FALSE; +#endif +} + +static void +gst_drm_dumb_allocator_free (GstAllocator * base_alloc, GstMemory * mem) +{ + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (base_alloc); + GstDRMDumbMemory *drmmem; + + drmmem = (GstDRMDumbMemory *) mem; + + gst_drm_dumb_allocator_memory_reset (alloc, drmmem); + g_free (drmmem); +} + +static void +gst_drm_dumb_allocator_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (object); + + switch (prop_id) { + case PROP_DRM_FD: + gst_drm_dumb_allocator_set_fd (alloc, g_value_get_int (value)); + break; + case PROP_DRM_DEVICE_PATH: + gst_drm_dumb_allocator_open_device (alloc, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_drm_dumb_allocator_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (object); + + switch (prop_id) { + case PROP_DRM_FD: + g_value_set_int (value, alloc->drm_fd); + break; + case PROP_DRM_DEVICE_PATH: + g_value_set_string (value, alloc->drm_device_path); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_drm_dumb_allocator_finalize (GObject * obj) +{ + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (obj); + + if (alloc->dmabuf_alloc) + gst_object_unref (alloc->dmabuf_alloc); + + g_free (alloc->drm_device_path); + alloc->drm_device_path = NULL; + +#ifdef HAVE_LIBDRM + if (alloc->drm_fd >= 0) { + close (alloc->drm_fd); + alloc->drm_fd = -1; + } +#endif + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +static void +gst_drm_dumb_allocator_class_init (GstDRMDumbAllocatorClass * klass) +{ + GObjectClass *gobject_class; + GstAllocatorClass *allocator_class; + + allocator_class = GST_ALLOCATOR_CLASS (klass); + gobject_class = G_OBJECT_CLASS (klass); + + allocator_class->free = gst_drm_dumb_allocator_free; + + gobject_class->set_property = gst_drm_dumb_allocator_set_property; + gobject_class->get_property = gst_drm_dumb_allocator_get_property; + gobject_class->finalize = gst_drm_dumb_allocator_finalize; + + /** + * GstDRMDumbAllocator:drm-fd: + * + * Since: 1.24 + */ + g_props[PROP_DRM_FD] = g_param_spec_int ("drm-fd", "DRM fd", + "DRM file descriptor", -1, G_MAXINT, -1, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + /** + * GstDRMDumbAllocator:drm-device-path: + * + * Since: 1.24 + */ + g_props[PROP_DRM_DEVICE_PATH] = g_param_spec_string ("drm-device-path", + "DRM device path", "DRM device path", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (gobject_class, PROP_N, g_props); +} + +static gpointer +gst_drm_dumb_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) +{ +#ifdef HAVE_LIBDRM + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (mem->allocator); + GstDRMDumbMemory *drmmem; + gint err; + gpointer out; + struct drm_mode_map_dumb arg = { 0, }; + + + if (!check_drm_fd (alloc)) + return NULL; + + drmmem = (GstDRMDumbMemory *) mem; + if (!drmmem->size) + return NULL; + + /* Reuse existing buffer object mapping if possible */ + if (drmmem->ptr != NULL) { + goto out; + } + + arg.handle = drmmem->handle; + + err = drmIoctl (alloc->drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); + if (err) { + GST_ERROR_OBJECT (alloc, "Failed to get offset of buffer object: %s %d", + g_strerror (errno), errno); + return NULL; + } + + out = mmap (0, drmmem->size, + PROT_READ | PROT_WRITE, MAP_SHARED, alloc->drm_fd, arg.offset); + if (out == MAP_FAILED) { + GST_ERROR_OBJECT (alloc, "Failed to map dumb buffer object: %s %d", + g_strerror (errno), errno); + return NULL; + } + drmmem->ptr = out; + +out: + g_atomic_int_inc (&drmmem->refs); + return drmmem->ptr; + +#else + return NULL; +#endif +} + +static void +gst_drm_dumb_memory_unmap (GstMemory * mem) +{ +#ifdef HAVE_LIBDRM + GstDRMDumbMemory *drmmem; + + if (!check_drm_fd ((GstDRMDumbAllocator *) mem->allocator)) + return; + + drmmem = (GstDRMDumbMemory *) mem; + if (!drmmem->size) + return; + + if (g_atomic_int_dec_and_test (&drmmem->refs)) { + munmap (drmmem->ptr, drmmem->size); + drmmem->ptr = NULL; + } +#endif +} + +static void +gst_drm_dumb_allocator_init (GstDRMDumbAllocator * alloc) +{ + GstAllocator *base_alloc = GST_ALLOCATOR_CAST (alloc); + + alloc->drm_fd = -1; + alloc->drm_device_path = NULL; + + base_alloc->mem_type = GST_DRM_DUMB_MEMORY_TYPE; + base_alloc->mem_map = gst_drm_dumb_memory_map; + base_alloc->mem_unmap = gst_drm_dumb_memory_unmap; + /* Use the default, fallback copy function */ + + GST_OBJECT_FLAG_SET (alloc, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); +} + +#ifdef HAVE_LIBDRM +static gboolean +check_cap (GstDRMDumbAllocator * alloc) +{ + gint ret; + guint64 has_dumb = 0; + + if (!alloc) + return FALSE; + + if (!check_drm_fd (alloc)) + return FALSE; + + ret = drmGetCap (alloc->drm_fd, DRM_CAP_DUMB_BUFFER, &has_dumb); + if (ret) + GST_WARNING_OBJECT (alloc, "could not get dumb buffer capability"); + + return ! !(has_dumb); +} +#endif + +/** + * gst_drm_dumb_allocator_new_with_fd: + * @drm_fd: file descriptor of the DRM device + * + * Creates a new #GstDRMDumbAllocator for the specific file desciptor. This + * function can fail if the file descriptor is not a DRM device or if + * the DRM device does not support DUMB allocation. + * + * Returns: (transfer full) (nullable): a new DRM Dumb allocator. Use gst_object_unref() + * to release the allocator after usage. + * + * Since: 1.24 + + */ +GstAllocator * +gst_drm_dumb_allocator_new_with_fd (gint drm_fd) +{ +#ifdef HAVE_LIBDRM + GstDRMDumbAllocator *alloc; + + alloc = g_object_new (GST_TYPE_DRM_DUMB_ALLOCATOR, "drm-fd", drm_fd, NULL); + gst_object_ref_sink (alloc); + + if (!check_drm_fd (alloc)) + g_clear_object (&alloc); + + if (!check_cap (alloc)) + g_clear_object (&alloc); + + return alloc ? GST_ALLOCATOR (alloc) : NULL; + +#else + return NULL; +#endif +} + +/** + * gst_drm_dumb_allocator_new_with_device_path: + * @drm_device_path: path to the DRM device to open + * + * Creates a new #GstDRMDumbAllocator for the specific device path. This + * function can fail if the path does not exist, is not a DRM device or if + * the DRM device doesnot support DUMB allocation. + * + * Returns: (transfer full) (nullable): a new DRM Dumb allocator. Use gst_object_unref() + * to release the allocator after usage. + * + * Since: 1.24 + */ +GstAllocator * +gst_drm_dumb_allocator_new_with_device_path (const gchar * drm_device_path) +{ +#ifdef HAVE_LIBDRM + GstDRMDumbAllocator *alloc; + + alloc = g_object_new (GST_TYPE_DRM_DUMB_ALLOCATOR, + "drm-device-path", drm_device_path, NULL); + gst_object_ref_sink (alloc); + + if (!check_drm_fd (alloc)) + g_clear_object (&alloc); + + if (!check_cap (alloc)) + g_clear_object (&alloc); + + return alloc ? GST_ALLOCATOR (alloc) : NULL; + +#else + return NULL; +#endif +} + +/** + * gst_drm_dumb_allocator_alloc: + * @allocator: the allocator instance + * @drm_fourcc: the DRM format to allocate for + * @width: padded width for this allocation + * @height: padded height for this allocation + * @out_pitch: (out): the pitch as returned by the driver + * + * Allocated a DRM buffer object for the specific @drm_fourcc, @width and + * @height. Note that the DRM Dumb allocation interface is agnostic to the + * pixel format. This @drm_fourcc is converted into a bpp (bit-per-pixel) + * number and the height is scaled according to the sub-sampling. + * + * Returns: (transfer full): a new DRM Dumb #GstMemory. Use gst_memory_unref() + * to release the memory after usage. + * + * Since: 1.24 + */ +GstMemory * +gst_drm_dumb_allocator_alloc (GstAllocator * base_alloc, + guint32 drm_fourcc, guint32 width, guint32 height, guint32 * out_pitch) +{ + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (base_alloc); + GstDRMDumbMemory *drmmem; + GstMemory *mem; + + drmmem = g_new0 (GstDRMDumbMemory, 1); + mem = GST_MEMORY_CAST (drmmem); + + if (!gst_drm_dumb_allocator_memory_create (alloc, drmmem, + drm_fourcc, width, height, out_pitch)) { + g_free (drmmem); + return NULL; + } + + gst_memory_init (mem, 0, base_alloc, NULL, drmmem->size, 0, 0, drmmem->size); + return mem; +} + +/** + * gst_drm_dumb_allocator_has_prime_export: + * @allocator: the #GstAllocator + * + * This function allow verifying if the driver support dma-buf exportation. + * + * Returns: %TRUE if the allocator support exporting dma-buf. + * + * Since: 1.24 + */ +gboolean +gst_drm_dumb_allocator_has_prime_export (GstAllocator * base_alloc) +{ +#ifdef HAVE_LIBDRM + GstDRMDumbAllocator *alloc = GST_DRM_DUMB_ALLOCATOR (base_alloc); + gint ret; + guint64 has_prime = 0; + + if (!check_drm_fd (alloc)) + return FALSE; + + ret = drmGetCap (alloc->drm_fd, DRM_CAP_PRIME, &has_prime); + if (ret) + GST_WARNING_OBJECT (alloc, "could not get prime capability"); + + return ! !(has_prime & DRM_PRIME_CAP_EXPORT); + +#else + return FALSE; +#endif +} diff --git a/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdrmdumb.h b/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdrmdumb.h new file mode 100644 index 0000000000..fa5f5eda5f --- /dev/null +++ b/subprojects/gst-plugins-base/gst-libs/gst/allocators/gstdrmdumb.h @@ -0,0 +1,88 @@ +/* GStreamer + * + * Copyright (C) 2016 Igalia + * Copyright (C) 2023 Collabora + * + * Authors: + * Víctor Manuel Jáquez Leal + * Javier Martin + * Colin Kinloch + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +/** + * GstDRMDumbAllocator: + * + * Private intance object for #GstDRMDumbAllocator. + * + * Since: 1.24 + */ + +/** + * GstDRMDumbAllocatorClass.parent_class: + * + * Parent Class. + * + * Since: 1.24 + */ + +/** + * GST_TYPE_DRM_DUMB_ALLOCATOR: + * + * Macro that returns the #GstDRMDumbAllocator type. + * + * Since: 1.24 + */ +#define GST_TYPE_DRM_DUMB_ALLOCATOR gst_drm_dumb_allocator_get_type () +GST_ALLOCATORS_API +G_DECLARE_FINAL_TYPE (GstDRMDumbAllocator, gst_drm_dumb_allocator, + GST, DRM_DUMB_ALLOCATOR, GstAllocator); + +GST_ALLOCATORS_API +gboolean gst_is_drm_dumb_memory (GstMemory * mem); + +GST_ALLOCATORS_API +guint32 gst_drm_dumb_memory_get_handle (GstMemory * mem); + +GST_ALLOCATORS_API +GstMemory* gst_drm_dumb_memory_export_dmabuf (GstMemory * mem); + +GST_ALLOCATORS_API +GstAllocator * gst_drm_dumb_allocator_new_with_fd (gint drm_fd); + +GST_ALLOCATORS_API +GstAllocator * gst_drm_dumb_allocator_new_with_device_path (const gchar *drm_device_path); + +GST_ALLOCATORS_API +GstMemory * gst_drm_dumb_allocator_alloc (GstAllocator * allocator, + guint32 drm_fourcc, + guint32 width, + guint32 height, + guint32 *out_pitch); + +GST_ALLOCATORS_API +gboolean gst_drm_dumb_allocator_has_prime_export (GstAllocator * allocator); + +G_END_DECLS diff --git a/subprojects/gst-plugins-base/gst-libs/gst/allocators/meson.build b/subprojects/gst-plugins-base/gst-libs/gst/allocators/meson.build index 6ee0bfd080..879c2fcb90 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/allocators/meson.build +++ b/subprojects/gst-plugins-base/gst-libs/gst/allocators/meson.build @@ -4,10 +4,11 @@ gst_allocators_headers = files([ 'gstfdmemory.h', 'gstphysmemory.h', 'gstdmabuf.h', + 'gstdrmdumb.h', ]) install_headers(gst_allocators_headers, subdir : 'gstreamer-1.0/gst/allocators/') -gst_allocators_sources = files([ 'gstdmabuf.c', 'gstfdmemory.c', 'gstphysmemory.c']) +gst_allocators_sources = files([ 'gstdrmdumb.c', 'gstdmabuf.c', 'gstfdmemory.c', 'gstphysmemory.c']) gstallocators = library('gstallocators-@0@'.format(api_version), gst_allocators_sources, c_args : gst_plugins_base_args + ['-DBUILDING_GST_ALLOCATORS', '-DG_LOG_DOMAIN="GStreamer-Allocators"'], @@ -16,12 +17,12 @@ gstallocators = library('gstallocators-@0@'.format(api_version), soversion : soversion, darwin_versions : osxversion, install : true, - dependencies : [gst_dep], + dependencies : [libdrm_dep, gst_dep], ) pkg_name = 'gstreamer-allocators-1.0' pkgconfig.generate(gstallocators, - libraries : [gst_dep], + libraries : [libdrm_dep, gst_dep], variables : pkgconfig_variables, subdirs : pkgconfig_subdirs, name : pkg_name, diff --git a/subprojects/gst-plugins-base/meson.build b/subprojects/gst-plugins-base/meson.build index a390dfd69b..91e0dc8d8c 100644 --- a/subprojects/gst-plugins-base/meson.build +++ b/subprojects/gst-plugins-base/meson.build @@ -305,6 +305,13 @@ if get_option('default_library') == 'static' gst_plugins_base_args += ['-DGST_STATIC_COMPILATION'] endif +libdrm_dep = dependency('libdrm', version : '>= 2.4.98', + required : get_option('drm'), + fallback: ['libdrm', 'ext_libdrm'] +) + +core_conf.set('HAVE_LIBDRM', libdrm_dep.found()) + # X11 checks are for sys/ and tests/ x11_dep = dependency('x11', required : get_option('x11')) # GIO is used by the GIO plugin, and by the TCP, SDP, and RTSP plugins diff --git a/subprojects/gst-plugins-base/meson_options.txt b/subprojects/gst-plugins-base/meson_options.txt index 50ec6aae1f..0db18408e7 100644 --- a/subprojects/gst-plugins-base/meson_options.txt +++ b/subprojects/gst-plugins-base/meson_options.txt @@ -36,6 +36,7 @@ option('audiorate', type : 'feature', value : 'auto') option('audioresample', type : 'feature', value : 'auto') option('audiotestsrc', type : 'feature', value : 'auto') option('compositor', type : 'feature', value : 'auto') +option('drm', type : 'feature', value : 'auto') option('encoding', type : 'feature', value : 'auto') option('gio', type : 'feature', value : 'auto') option('gio-typefinder', type : 'feature', value : 'auto')