mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
kmssink: add dmabuf support
This patch will enable the import of dmabufs into a KMS buffer using the PRIME kernel interface. If the driver does not support prime import, the method is skipped. It has been tested with a Freescale I.MX6 board. https://bugzilla.gnome.org/show_bug.cgi?id=761059
This commit is contained in:
parent
1aee6cdc25
commit
c419d17dbf
6 changed files with 268 additions and 31 deletions
|
@ -2326,6 +2326,7 @@ dnl *** kms ***
|
||||||
translit(dnm, m, l) AM_CONDITIONAL(USE_KMS, true)
|
translit(dnm, m, l) AM_CONDITIONAL(USE_KMS, true)
|
||||||
AG_GST_CHECK_FEATURE(KMS, [drm/kms libraries], kms, [
|
AG_GST_CHECK_FEATURE(KMS, [drm/kms libraries], kms, [
|
||||||
AG_GST_PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-1.0)
|
AG_GST_PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-1.0)
|
||||||
|
AG_GST_PKG_CHECK_MODULES(GST_ALLOCATORS, gstreamer-allocators-1.0)
|
||||||
PKG_CHECK_MODULES([DRM], [libdrm libkms], HAVE_KMS=yes, HAVE_KMS=no)
|
PKG_CHECK_MODULES([DRM], [libdrm libkms], HAVE_KMS=yes, HAVE_KMS=no)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ libgstkmssink_la_CFLAGS = \
|
||||||
$(GST_PLUGINS_BASE_CFLAGS) \
|
$(GST_PLUGINS_BASE_CFLAGS) \
|
||||||
$(GST_BASE_CFLAGS) \
|
$(GST_BASE_CFLAGS) \
|
||||||
$(GST_VIDEO_CFLAGS) \
|
$(GST_VIDEO_CFLAGS) \
|
||||||
|
$(GST_ALLOCATORS_CFLAGS) \
|
||||||
$(GST_CFLAGS) \
|
$(GST_CFLAGS) \
|
||||||
$(DRM_CFLAGS) \
|
$(DRM_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
@ -19,6 +20,7 @@ libgstkmssink_la_LIBADD = \
|
||||||
$(GST_PLUGINS_BASE_LIBS) \
|
$(GST_PLUGINS_BASE_LIBS) \
|
||||||
$(GST_BASE_LIBS) \
|
$(GST_BASE_LIBS) \
|
||||||
$(GST_VIDEO_LIBS) \
|
$(GST_VIDEO_LIBS) \
|
||||||
|
$(GST_ALLOCATORS_LIBS) \
|
||||||
$(GST_LIBS) \
|
$(GST_LIBS) \
|
||||||
$(DRM_LIBS) \
|
$(DRM_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -98,6 +98,51 @@ ensure_kms_driver (GstKMSAllocator * alloc)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_kms_allocator_memory_reset (GstKMSAllocator * allocator, GstKMSMemory * mem)
|
||||||
|
{
|
||||||
|
if (mem->fb_id) {
|
||||||
|
GST_DEBUG_OBJECT (allocator, "removing fb id %d", mem->fb_id);
|
||||||
|
drmModeRmFB (allocator->priv->fd, mem->fb_id);
|
||||||
|
mem->fb_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ensure_kms_driver (allocator))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mem->bo) {
|
||||||
|
kms_bo_destroy (&mem->bo);
|
||||||
|
mem->bo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_kms_allocator_memory_create (GstKMSAllocator * allocator,
|
||||||
|
GstKMSMemory * kmsmem, GstVideoInfo * vinfo)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
guint attrs[] = {
|
||||||
|
KMS_WIDTH, GST_VIDEO_INFO_WIDTH (vinfo),
|
||||||
|
KMS_HEIGHT, GST_VIDEO_INFO_HEIGHT (vinfo),
|
||||||
|
KMS_TERMINATE_PROP_LIST,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (kmsmem->bo)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!ensure_kms_driver (allocator))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = kms_bo_create (allocator->priv->driver, attrs, &kmsmem->bo);
|
||||||
|
if (ret) {
|
||||||
|
GST_ERROR_OBJECT (allocator, "Failed to create buffer object: %s (%d)",
|
||||||
|
strerror (-ret), ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_kms_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
gst_kms_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
||||||
{
|
{
|
||||||
|
@ -107,12 +152,7 @@ gst_kms_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
||||||
alloc = GST_KMS_ALLOCATOR (allocator);
|
alloc = GST_KMS_ALLOCATOR (allocator);
|
||||||
kmsmem = (GstKMSMemory *) mem;
|
kmsmem = (GstKMSMemory *) mem;
|
||||||
|
|
||||||
if (kmsmem->fb_id)
|
gst_kms_allocator_memory_reset (alloc, kmsmem);
|
||||||
drmModeRmFB (alloc->priv->fd, kmsmem->fb_id);
|
|
||||||
|
|
||||||
if (ensure_kms_driver (alloc) && kmsmem->bo)
|
|
||||||
kms_bo_destroy (&kmsmem->bo);
|
|
||||||
|
|
||||||
g_slice_free (GstKMSMemory, kmsmem);
|
g_slice_free (GstKMSMemory, kmsmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,13 +312,15 @@ gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem,
|
||||||
|
|
||||||
if (kmsmem->bo) {
|
if (kmsmem->bo) {
|
||||||
kms_bo_get_prop (kmsmem->bo, KMS_HANDLE, &bo_handles[0]);
|
kms_bo_get_prop (kmsmem->bo, KMS_HANDLE, &bo_handles[0]);
|
||||||
|
for (i = 1; i < 4; i++)
|
||||||
|
bo_handles[i] = bo_handles[0];
|
||||||
} else {
|
} else {
|
||||||
return FALSE;
|
for (i = 0; i < 4; i++)
|
||||||
|
bo_handles[i] = kmsmem->gem_handle[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @FIXME: fill the other handles */
|
GST_DEBUG_OBJECT (alloc, "bo handles: %d, %d, %d, %d", bo_handles[0],
|
||||||
bo_handles[1] = bo_handles[0];
|
bo_handles[1], bo_handles[2], bo_handles[3]);
|
||||||
bo_handles[2] = bo_handles[0];
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vinfo, i);
|
offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vinfo, i);
|
||||||
|
@ -295,38 +337,38 @@ gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstMemory *
|
||||||
|
gst_kms_allocator_alloc_empty (GstAllocator * allocator, GstVideoInfo * vinfo)
|
||||||
|
{
|
||||||
|
GstKMSMemory *kmsmem;
|
||||||
|
GstMemory *mem;
|
||||||
|
|
||||||
|
kmsmem = g_slice_new0 (GstKMSMemory);
|
||||||
|
if (!kmsmem)
|
||||||
|
return NULL;
|
||||||
|
mem = GST_MEMORY_CAST (kmsmem);
|
||||||
|
|
||||||
|
gst_memory_init (mem, GST_MEMORY_FLAG_NO_SHARE, allocator, NULL,
|
||||||
|
GST_VIDEO_INFO_SIZE (vinfo), 0, 0, GST_VIDEO_INFO_SIZE (vinfo));
|
||||||
|
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
GstMemory *
|
GstMemory *
|
||||||
gst_kms_allocator_bo_alloc (GstAllocator * allocator, GstVideoInfo * vinfo)
|
gst_kms_allocator_bo_alloc (GstAllocator * allocator, GstVideoInfo * vinfo)
|
||||||
{
|
{
|
||||||
GstKMSAllocator *alloc;
|
GstKMSAllocator *alloc;
|
||||||
GstKMSMemory *kmsmem;
|
GstKMSMemory *kmsmem;
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
int ret;
|
|
||||||
guint attrs[] = {
|
|
||||||
KMS_WIDTH, GST_VIDEO_INFO_WIDTH (vinfo),
|
|
||||||
KMS_HEIGHT, GST_VIDEO_INFO_HEIGHT (vinfo),
|
|
||||||
KMS_TERMINATE_PROP_LIST,
|
|
||||||
};
|
|
||||||
|
|
||||||
kmsmem = g_slice_new0 (GstKMSMemory);
|
mem = gst_kms_allocator_alloc_empty (allocator, vinfo);
|
||||||
if (!kmsmem)
|
if (!mem)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mem = GST_MEMORY_CAST (kmsmem);
|
|
||||||
gst_memory_init (mem, GST_MEMORY_FLAG_NO_SHARE, allocator, NULL,
|
|
||||||
GST_VIDEO_INFO_SIZE (vinfo), 0, 0, GST_VIDEO_INFO_SIZE (vinfo));
|
|
||||||
|
|
||||||
alloc = GST_KMS_ALLOCATOR (allocator);
|
alloc = GST_KMS_ALLOCATOR (allocator);
|
||||||
if (!ensure_kms_driver (alloc))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
kmsmem = (GstKMSMemory *) mem;
|
kmsmem = (GstKMSMemory *) mem;
|
||||||
ret = kms_bo_create (alloc->priv->driver, attrs, &kmsmem->bo);
|
if (!gst_kms_allocator_memory_create (alloc, kmsmem, vinfo))
|
||||||
if (ret) {
|
|
||||||
GST_ERROR_OBJECT (alloc, "Failed to create buffer object: %s (%d)",
|
|
||||||
strerror (-ret), ret);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
if (!gst_kms_allocator_add_fb (alloc, kmsmem, vinfo))
|
if (!gst_kms_allocator_add_fb (alloc, kmsmem, vinfo))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -337,3 +379,47 @@ fail:
|
||||||
gst_memory_unref (mem);
|
gst_memory_unref (mem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstKMSMemory *
|
||||||
|
gst_kms_allocator_dmabuf_import (GstAllocator * allocator, gint * prime_fds,
|
||||||
|
gint n_planes, GstVideoInfo * vinfo)
|
||||||
|
{
|
||||||
|
GstKMSAllocator *alloc;
|
||||||
|
GstMemory *mem;
|
||||||
|
GstKMSMemory *tmp;
|
||||||
|
gint i, ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (n_planes <= GST_VIDEO_MAX_PLANES, FALSE);
|
||||||
|
|
||||||
|
mem = gst_kms_allocator_alloc_empty (allocator, vinfo);
|
||||||
|
if (!mem)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
tmp = (GstKMSMemory *) mem;
|
||||||
|
alloc = GST_KMS_ALLOCATOR (allocator);
|
||||||
|
for (i = 0; i < n_planes; i++) {
|
||||||
|
ret = drmPrimeFDToHandle (alloc->priv->fd, prime_fds[i],
|
||||||
|
&tmp->gem_handle[i]);
|
||||||
|
if (ret)
|
||||||
|
goto import_fd_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_kms_allocator_add_fb (alloc, tmp, vinfo))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
import_fd_failed:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (alloc, "Failed to import prime fd %d: %s (%d)",
|
||||||
|
prime_fds[i], strerror (-ret), ret);
|
||||||
|
/* fallback */
|
||||||
|
}
|
||||||
|
|
||||||
|
failed:
|
||||||
|
{
|
||||||
|
gst_memory_unref (mem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct _GstKMSMemory
|
||||||
GstMemory parent;
|
GstMemory parent;
|
||||||
|
|
||||||
guint32 fb_id;
|
guint32 fb_id;
|
||||||
|
guint32 gem_handle[GST_VIDEO_MAX_PLANES];
|
||||||
struct kms_bo *bo;
|
struct kms_bo *bo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,6 +79,11 @@ GstAllocator* gst_kms_allocator_new (gint fd);
|
||||||
GstMemory* gst_kms_allocator_bo_alloc (GstAllocator *allocator,
|
GstMemory* gst_kms_allocator_bo_alloc (GstAllocator *allocator,
|
||||||
GstVideoInfo *vinfo);
|
GstVideoInfo *vinfo);
|
||||||
|
|
||||||
|
GstKMSMemory* gst_kms_allocator_dmabuf_import (GstAllocator *allocator,
|
||||||
|
gint *prime_fds,
|
||||||
|
gint n_planes,
|
||||||
|
GstVideoInfo *vinfo);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
#include <gst/allocators/gstdmabuf.h>
|
||||||
|
|
||||||
#include <drm.h>
|
#include <drm.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
@ -259,6 +260,7 @@ get_drm_caps (GstKMSSink * self)
|
||||||
{
|
{
|
||||||
gint ret;
|
gint ret;
|
||||||
guint64 has_dumb_buffer;
|
guint64 has_dumb_buffer;
|
||||||
|
guint64 has_prime;
|
||||||
|
|
||||||
has_dumb_buffer = 0;
|
has_dumb_buffer = 0;
|
||||||
ret = drmGetCap (self->fd, DRM_CAP_DUMB_BUFFER, &has_dumb_buffer);
|
ret = drmGetCap (self->fd, DRM_CAP_DUMB_BUFFER, &has_dumb_buffer);
|
||||||
|
@ -269,6 +271,16 @@ get_drm_caps (GstKMSSink * self)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has_prime = 0;
|
||||||
|
ret = drmGetCap (self->fd, DRM_CAP_PRIME, &has_prime);
|
||||||
|
if (ret)
|
||||||
|
GST_WARNING_OBJECT (self, "could not get prime capability");
|
||||||
|
else
|
||||||
|
self->has_prime_import = (gboolean) (has_prime & DRM_PRIME_CAP_IMPORT);
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (self, "prime import (%s)",
|
||||||
|
self->has_prime_import ? "✓" : "✗");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,6 +748,128 @@ gst_kms_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstMemory *
|
||||||
|
get_cached_kmsmem (GstMemory * mem)
|
||||||
|
{
|
||||||
|
return gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
|
||||||
|
g_quark_from_static_string ("kmsmem"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_cached_kmsmem (GstMemory * mem, GstMemory * kmsmem)
|
||||||
|
{
|
||||||
|
return gst_mini_object_set_qdata (GST_MINI_OBJECT (mem),
|
||||||
|
g_quark_from_static_string ("kmsmem"), kmsmem,
|
||||||
|
(GDestroyNotify) gst_memory_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gsize
|
||||||
|
get_plane_data_size (GstVideoInfo * info, guint plane)
|
||||||
|
{
|
||||||
|
gint padded_height;
|
||||||
|
gsize plane_size;
|
||||||
|
|
||||||
|
padded_height = info->height;
|
||||||
|
padded_height =
|
||||||
|
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, plane, padded_height);
|
||||||
|
|
||||||
|
plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height;
|
||||||
|
|
||||||
|
return plane_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_kms_sink_import_dmabuf (GstKMSSink * self, GstBuffer * inbuf,
|
||||||
|
GstBuffer ** outbuf)
|
||||||
|
{
|
||||||
|
gint prime_fds[GST_VIDEO_MAX_PLANES] = { 0, };
|
||||||
|
GstVideoMeta *meta;
|
||||||
|
guint i, n_mem, n_planes;
|
||||||
|
GstKMSMemory *kmsmem;
|
||||||
|
guint mems_idx[GST_VIDEO_MAX_PLANES];
|
||||||
|
gsize mems_skip[GST_VIDEO_MAX_PLANES];
|
||||||
|
GstMemory *mems[GST_VIDEO_MAX_PLANES];
|
||||||
|
|
||||||
|
if (!self->has_prime_import)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* This will eliminate most non-dmabuf out there */
|
||||||
|
if (!gst_is_dmabuf_memory (gst_buffer_peek_memory (inbuf, 0)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
n_planes = GST_VIDEO_INFO_N_PLANES (&self->vinfo);
|
||||||
|
n_mem = gst_buffer_n_memory (inbuf);
|
||||||
|
meta = gst_buffer_get_video_meta (inbuf);
|
||||||
|
|
||||||
|
/* We cannot have multiple dmabuf per plane */
|
||||||
|
if (n_mem > n_planes)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Update video info based on video meta */
|
||||||
|
if (meta) {
|
||||||
|
GST_VIDEO_INFO_WIDTH (&self->vinfo) = meta->width;
|
||||||
|
GST_VIDEO_INFO_HEIGHT (&self->vinfo) = meta->height;
|
||||||
|
|
||||||
|
for (i = 0; i < meta->n_planes; i++) {
|
||||||
|
GST_VIDEO_INFO_PLANE_OFFSET (&self->vinfo, i) = meta->offset[i];
|
||||||
|
GST_VIDEO_INFO_PLANE_STRIDE (&self->vinfo, i) = meta->stride[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find and validate all memories */
|
||||||
|
for (i = 0; i < n_planes; i++) {
|
||||||
|
guint plane_size;
|
||||||
|
guint length;
|
||||||
|
|
||||||
|
plane_size = get_plane_data_size (&self->vinfo, i);
|
||||||
|
if (!gst_buffer_find_memory (inbuf,
|
||||||
|
GST_VIDEO_INFO_PLANE_OFFSET (&self->vinfo, i), plane_size,
|
||||||
|
&mems_idx[i], &length, &mems_skip[i]))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* We can't have more then one dmabuf per plane */
|
||||||
|
if (length != 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
mems[i] = gst_buffer_peek_memory (inbuf, mems_idx[i]);
|
||||||
|
|
||||||
|
/* And all memory found must be dmabuf */
|
||||||
|
if (!gst_is_dmabuf_memory (mems[i]))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmsmem = (GstKMSMemory *) get_cached_kmsmem (mems[0]);
|
||||||
|
if (kmsmem) {
|
||||||
|
GST_LOG_OBJECT (self, "found KMS mem %p in DMABuf mem %p with fb id = %d",
|
||||||
|
kmsmem, mems[0], kmsmem->fb_id);
|
||||||
|
goto wrap_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n_planes; i++)
|
||||||
|
prime_fds[i] = gst_dmabuf_memory_get_fd (mems[i]);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (self, "found these prime ids: %d, %d, %d, %d", prime_fds[0],
|
||||||
|
prime_fds[1], prime_fds[2], prime_fds[3]);
|
||||||
|
|
||||||
|
kmsmem = gst_kms_allocator_dmabuf_import (self->allocator, prime_fds,
|
||||||
|
n_planes, &self->vinfo);
|
||||||
|
if (!kmsmem)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (self, "setting KMS mem %p to DMABuf mem %p with fb id = %d",
|
||||||
|
kmsmem, mems[0], kmsmem->fb_id);
|
||||||
|
set_cached_kmsmem (mems[0], GST_MEMORY_CAST (kmsmem));
|
||||||
|
|
||||||
|
wrap_mem:
|
||||||
|
*outbuf = gst_buffer_new ();
|
||||||
|
if (!*outbuf)
|
||||||
|
return FALSE;
|
||||||
|
gst_buffer_append_memory (*outbuf, gst_memory_ref (GST_MEMORY_CAST (kmsmem)));
|
||||||
|
gst_buffer_add_parent_buffer_meta (*outbuf, inbuf);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
gst_kms_sink_get_input_buffer (GstKMSSink * self, GstBuffer * inbuf)
|
gst_kms_sink_get_input_buffer (GstKMSSink * self, GstBuffer * inbuf)
|
||||||
{
|
{
|
||||||
|
@ -752,10 +886,15 @@ gst_kms_sink_get_input_buffer (GstKMSSink * self, GstBuffer * inbuf)
|
||||||
if (gst_is_kms_memory (mem))
|
if (gst_is_kms_memory (mem))
|
||||||
return gst_buffer_ref (inbuf);
|
return gst_buffer_ref (inbuf);
|
||||||
|
|
||||||
|
buf = NULL;
|
||||||
|
if (gst_kms_sink_import_dmabuf (self, inbuf, &buf))
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (self, "frame copy");
|
||||||
|
|
||||||
if (!gst_buffer_pool_set_active (self->pool, TRUE))
|
if (!gst_buffer_pool_set_active (self->pool, TRUE))
|
||||||
goto activate_pool_failed;
|
goto activate_pool_failed;
|
||||||
|
|
||||||
buf = NULL;
|
|
||||||
ret = gst_buffer_pool_acquire_buffer (self->pool, &buf, NULL);
|
ret = gst_buffer_pool_acquire_buffer (self->pool, &buf, NULL);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto create_buffer_failed;
|
goto create_buffer_failed;
|
||||||
|
|
|
@ -55,6 +55,9 @@ struct _GstKMSSink {
|
||||||
|
|
||||||
guint16 hdisplay, vdisplay;
|
guint16 hdisplay, vdisplay;
|
||||||
|
|
||||||
|
/* capabilities */
|
||||||
|
gboolean has_prime_import;
|
||||||
|
|
||||||
GstVideoInfo vinfo;
|
GstVideoInfo vinfo;
|
||||||
GstCaps *allowed_caps;
|
GstCaps *allowed_caps;
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool;
|
||||||
|
|
Loading…
Reference in a new issue