mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-09 07:52:36 +00:00
plugins: add support for dma_buf exports (v4l2src).
Allow v4l2src element to connected to vaapipostproc or vaapisink when "io-mode" is set to "dmabuf-import". In practice, this is a more likely operational mode with uvcvideo. Supporting v4lsrc with "io-mode" set to "dmabuf" could work, but with more demanding driver or kernel reqs. Note: with GStreamer 1.4, v4l2src (gst-plugins-good) needs to be built with --without-libv4l2. https://bugzilla.gnome.org/show_bug.cgi?id=743635
This commit is contained in:
parent
667749c67e
commit
82fc406dfd
5 changed files with 405 additions and 10 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "gst/vaapi/sysdeps.h"
|
#include "gst/vaapi/sysdeps.h"
|
||||||
#include <gst/vaapi/gstvaapisurface_drm.h>
|
#include <gst/vaapi/gstvaapisurface_drm.h>
|
||||||
|
#include <gst/base/gstpushsrc.h>
|
||||||
#include "gstvaapipluginbase.h"
|
#include "gstvaapipluginbase.h"
|
||||||
#include "gstvaapipluginutil.h"
|
#include "gstvaapipluginutil.h"
|
||||||
#include "gstvaapivideocontext.h"
|
#include "gstvaapivideocontext.h"
|
||||||
|
@ -392,6 +393,42 @@ gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Checks whether the supplied pad peer element supports DMABUF sharing */
|
||||||
|
/* XXX: this is a workaround to the absence of any proposer way to
|
||||||
|
specify DMABUF memory capsfeatures or bufferpool option to downstream */
|
||||||
|
static gboolean
|
||||||
|
has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad)
|
||||||
|
{
|
||||||
|
GstPad *other_pad = NULL;
|
||||||
|
GstElement *element = NULL;
|
||||||
|
gchar *element_name = NULL;
|
||||||
|
gboolean is_dmabuf_capable = FALSE;
|
||||||
|
gint v;
|
||||||
|
|
||||||
|
do {
|
||||||
|
other_pad = gst_pad_get_peer (pad);
|
||||||
|
if (!other_pad)
|
||||||
|
break;
|
||||||
|
|
||||||
|
element = gst_pad_get_parent_element (other_pad);
|
||||||
|
if (!element || !GST_IS_PUSH_SRC (element))
|
||||||
|
break;
|
||||||
|
|
||||||
|
element_name = gst_element_get_name (element);
|
||||||
|
if (!element_name || sscanf (element_name, "v4l2src%d", &v) != 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
v = 0;
|
||||||
|
g_object_get (element, "io-mode", &v, NULL);
|
||||||
|
is_dmabuf_capable = v == 5; /* "dmabuf-import" enum value */
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
g_free (element_name);
|
||||||
|
g_clear_object (&element);
|
||||||
|
g_clear_object (&other_pad);
|
||||||
|
return is_dmabuf_capable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ensure_sinkpad_buffer_pool:
|
* ensure_sinkpad_buffer_pool:
|
||||||
* @plugin: a #GstVaapiPluginBase
|
* @plugin: a #GstVaapiPluginBase
|
||||||
|
@ -536,6 +573,16 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool,
|
gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool,
|
||||||
plugin->sinkpad_buffer_size, 0, 0);
|
plugin->sinkpad_buffer_size, 0, 0);
|
||||||
|
|
||||||
|
if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) {
|
||||||
|
GstStructure *const config =
|
||||||
|
gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool);
|
||||||
|
|
||||||
|
gst_buffer_pool_config_add_option (config,
|
||||||
|
GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
|
||||||
|
if (!gst_buffer_pool_set_config (plugin->sinkpad_buffer_pool, config))
|
||||||
|
goto error_pool_config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL);
|
gst_query_add_allocation_meta (query, GST_VAAPI_VIDEO_META_API_TYPE, NULL);
|
||||||
|
@ -548,6 +595,11 @@ error_no_caps:
|
||||||
GST_ERROR ("no caps specified");
|
GST_ERROR ("no caps specified");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
error_pool_config:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to reset buffer pool config");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,12 @@ struct _GstVaapiVideoBufferPoolPrivate
|
||||||
GstVideoInfo video_info[2];
|
GstVideoInfo video_info[2];
|
||||||
guint video_info_index;
|
guint video_info_index;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
|
GstVideoInfo alloc_info;
|
||||||
GstVaapiDisplay *display;
|
GstVaapiDisplay *display;
|
||||||
guint has_video_meta:1;
|
guint has_video_meta:1;
|
||||||
guint has_video_alignment:1;
|
guint has_video_alignment:1;
|
||||||
guint has_texture_upload_meta:1;
|
guint has_texture_upload_meta:1;
|
||||||
|
guint use_dmabuf_memory:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \
|
#define GST_VAAPI_VIDEO_BUFFER_POOL_GET_PRIVATE(obj) \
|
||||||
|
@ -105,8 +107,7 @@ gst_vaapi_video_buffer_pool_get_property (GObject * object, guint prop_id,
|
||||||
static void
|
static void
|
||||||
fill_video_alignment (GstVaapiVideoBufferPool * pool, GstVideoAlignment * align)
|
fill_video_alignment (GstVaapiVideoBufferPool * pool, GstVideoAlignment * align)
|
||||||
{
|
{
|
||||||
GstVideoInfo *const vip =
|
GstVideoInfo *const vip = &pool->priv->alloc_info;
|
||||||
&GST_VAAPI_VIDEO_ALLOCATOR_CAST (pool->priv->allocator)->image_info;
|
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
gst_video_alignment_reset (align);
|
gst_video_alignment_reset (align);
|
||||||
|
@ -140,26 +141,48 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
|
||||||
GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index];
|
GstVideoInfo *const new_vip = &priv->video_info[!priv->video_info_index];
|
||||||
GstVideoAlignment align;
|
GstVideoAlignment align;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
gboolean changed_caps;
|
gboolean changed_caps, use_dmabuf_memory;
|
||||||
|
|
||||||
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
|
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
|
||||||
goto error_invalid_config;
|
goto error_invalid_config;
|
||||||
if (!caps || !gst_video_info_from_caps (new_vip, caps))
|
if (!caps || !gst_video_info_from_caps (new_vip, caps))
|
||||||
goto error_no_caps;
|
goto error_no_caps;
|
||||||
|
|
||||||
|
use_dmabuf_memory = gst_buffer_pool_config_has_option (config,
|
||||||
|
GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
|
||||||
|
if (priv->use_dmabuf_memory != use_dmabuf_memory) {
|
||||||
|
priv->use_dmabuf_memory = use_dmabuf_memory;
|
||||||
|
g_clear_object (&priv->allocator);
|
||||||
|
}
|
||||||
|
|
||||||
changed_caps = !priv->allocator ||
|
changed_caps = !priv->allocator ||
|
||||||
GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) ||
|
GST_VIDEO_INFO_FORMAT (cur_vip) != GST_VIDEO_INFO_FORMAT (new_vip) ||
|
||||||
GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) ||
|
GST_VIDEO_INFO_WIDTH (cur_vip) != GST_VIDEO_INFO_WIDTH (new_vip) ||
|
||||||
GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip);
|
GST_VIDEO_INFO_HEIGHT (cur_vip) != GST_VIDEO_INFO_HEIGHT (new_vip);
|
||||||
|
|
||||||
if (changed_caps) {
|
if (changed_caps) {
|
||||||
allocator = gst_vaapi_video_allocator_new (priv->display, new_vip, 0);
|
const GstVideoInfo *alloc_vip;
|
||||||
|
guint flags = 0;
|
||||||
|
|
||||||
|
if (use_dmabuf_memory) {
|
||||||
|
/* XXX: also needs fixed strides/offsets */
|
||||||
|
flags |= GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE;
|
||||||
|
allocator =
|
||||||
|
gst_vaapi_dmabuf_allocator_new (priv->display, new_vip, flags);
|
||||||
|
} else {
|
||||||
|
allocator = gst_vaapi_video_allocator_new (priv->display, new_vip, 0);
|
||||||
|
}
|
||||||
if (!allocator)
|
if (!allocator)
|
||||||
goto error_create_allocator;
|
goto error_create_allocator;
|
||||||
gst_object_replace ((GstObject **) & priv->allocator,
|
gst_object_replace ((GstObject **) & priv->allocator,
|
||||||
GST_OBJECT_CAST (allocator));
|
GST_OBJECT_CAST (allocator));
|
||||||
gst_object_unref (allocator);
|
gst_object_unref (allocator);
|
||||||
priv->video_info_index ^= 1;
|
priv->video_info_index ^= 1;
|
||||||
|
|
||||||
|
alloc_vip = gst_allocator_get_vaapi_video_info (allocator, NULL);
|
||||||
|
if (!alloc_vip)
|
||||||
|
goto error_create_allocator_info;
|
||||||
|
priv->alloc_info = *alloc_vip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_buffer_pool_config_has_option (config,
|
if (!gst_buffer_pool_config_has_option (config,
|
||||||
|
@ -199,6 +222,11 @@ error_create_allocator:
|
||||||
GST_ERROR ("failed to create GstVaapiVideoAllocator object");
|
GST_ERROR ("failed to create GstVaapiVideoAllocator object");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
error_create_allocator_info:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to create GstVaapiVideoAllocator `video-info'");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
error_no_vaapi_video_meta_option:
|
error_no_vaapi_video_meta_option:
|
||||||
{
|
{
|
||||||
GST_ERROR ("no GstVaapiVideoMeta option");
|
GST_ERROR ("no GstVaapiVideoMeta option");
|
||||||
|
@ -235,15 +263,17 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
goto error_create_buffer;
|
goto error_create_buffer;
|
||||||
|
|
||||||
mem = gst_vaapi_video_memory_new (priv->allocator, meta);
|
if (priv->use_dmabuf_memory)
|
||||||
|
mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta);
|
||||||
|
else
|
||||||
|
mem = gst_vaapi_video_memory_new (priv->allocator, meta);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto error_create_memory;
|
goto error_create_memory;
|
||||||
gst_vaapi_video_meta_replace (&meta, NULL);
|
gst_vaapi_video_meta_replace (&meta, NULL);
|
||||||
gst_buffer_append_memory (buffer, mem);
|
gst_buffer_append_memory (buffer, mem);
|
||||||
|
|
||||||
if (priv->has_video_meta) {
|
if (priv->has_video_meta) {
|
||||||
GstVideoInfo *const vip =
|
GstVideoInfo *const vip = &priv->alloc_info;
|
||||||
&GST_VAAPI_VIDEO_ALLOCATOR_CAST (priv->allocator)->image_info;
|
|
||||||
GstVideoMeta *vmeta;
|
GstVideoMeta *vmeta;
|
||||||
|
|
||||||
vmeta = gst_buffer_add_video_meta_full (buffer, 0,
|
vmeta = gst_buffer_add_video_meta_full (buffer, 0,
|
||||||
|
@ -251,9 +281,13 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
|
||||||
GST_VIDEO_INFO_HEIGHT (vip), GST_VIDEO_INFO_N_PLANES (vip),
|
GST_VIDEO_INFO_HEIGHT (vip), GST_VIDEO_INFO_N_PLANES (vip),
|
||||||
&GST_VIDEO_INFO_PLANE_OFFSET (vip, 0),
|
&GST_VIDEO_INFO_PLANE_OFFSET (vip, 0),
|
||||||
&GST_VIDEO_INFO_PLANE_STRIDE (vip, 0));
|
&GST_VIDEO_INFO_PLANE_STRIDE (vip, 0));
|
||||||
vmeta->map = gst_video_meta_map_vaapi_memory;
|
|
||||||
vmeta->unmap = gst_video_meta_unmap_vaapi_memory;
|
if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) {
|
||||||
|
vmeta->map = gst_video_meta_map_vaapi_memory;
|
||||||
|
vmeta->unmap = gst_video_meta_unmap_vaapi_memory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
|
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
|
||||||
if (priv->has_texture_upload_meta)
|
if (priv->has_texture_upload_meta)
|
||||||
gst_buffer_add_texture_upload_meta (buffer);
|
gst_buffer_add_texture_upload_meta (buffer);
|
||||||
|
@ -295,7 +329,8 @@ gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool,
|
||||||
GstMemory *const mem = gst_buffer_peek_memory (buffer, 0);
|
GstMemory *const mem = gst_buffer_peek_memory (buffer, 0);
|
||||||
|
|
||||||
/* Release the underlying surface proxy */
|
/* Release the underlying surface proxy */
|
||||||
gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem));
|
if (GST_VAAPI_IS_VIDEO_MEMORY (mem))
|
||||||
|
gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem));
|
||||||
|
|
||||||
GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer
|
GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer
|
||||||
(pool, buffer);
|
(pool, buffer);
|
||||||
|
@ -344,6 +379,7 @@ gst_vaapi_video_buffer_pool_init (GstVaapiVideoBufferPool * pool)
|
||||||
|
|
||||||
gst_video_info_init (&priv->video_info[0]);
|
gst_video_info_init (&priv->video_info[0]);
|
||||||
gst_video_info_init (&priv->video_info[1]);
|
gst_video_info_init (&priv->video_info[1]);
|
||||||
|
gst_video_info_init (&priv->alloc_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstBufferPool *
|
GstBufferPool *
|
||||||
|
|
|
@ -69,6 +69,17 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate;
|
||||||
"GstBufferPoolOptionVideoGLTextureUploadMeta"
|
"GstBufferPoolOptionVideoGLTextureUploadMeta"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_BUFFER_POOL_OPTION_DMABUF_MEMORY:
|
||||||
|
*
|
||||||
|
* An option that can be activated on bufferpool to request dmabuf
|
||||||
|
* handles on buffers from the pool.
|
||||||
|
*/
|
||||||
|
#ifndef GST_BUFFER_POOL_OPTION_DMABUF_MEMORY
|
||||||
|
#define GST_BUFFER_POOL_OPTION_DMABUF_MEMORY \
|
||||||
|
"GstBufferPoolOptionDMABUFMemory"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiVideoBufferPoolAcquireFlags:
|
* GstVaapiVideoBufferPoolAcquireFlags:
|
||||||
* @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to
|
* @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gst/vaapi/sysdeps.h"
|
#include "gst/vaapi/sysdeps.h"
|
||||||
|
#include <gst/vaapi/gstvaapisurface_drm.h>
|
||||||
#include <gst/vaapi/gstvaapisurfacepool.h>
|
#include <gst/vaapi/gstvaapisurfacepool.h>
|
||||||
#include <gst/vaapi/gstvaapiimagepool.h>
|
#include <gst/vaapi/gstvaapiimagepool.h>
|
||||||
#include "gstvaapivideomemory.h"
|
#include "gstvaapivideomemory.h"
|
||||||
|
@ -298,6 +299,8 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator,
|
||||||
const GstVideoInfo *vip;
|
const GstVideoInfo *vip;
|
||||||
GstVaapiVideoMemory *mem;
|
GstVaapiVideoMemory *mem;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), NULL);
|
||||||
|
|
||||||
mem = g_slice_new (GstVaapiVideoMemory);
|
mem = g_slice_new (GstVaapiVideoMemory);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -725,6 +728,9 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display,
|
||||||
&allocator->image_info);
|
&allocator->image_info);
|
||||||
if (!allocator->image_pool)
|
if (!allocator->image_pool)
|
||||||
goto error_create_image_pool;
|
goto error_create_image_pool;
|
||||||
|
|
||||||
|
gst_allocator_set_vaapi_video_info (GST_ALLOCATOR_CAST (allocator),
|
||||||
|
&allocator->image_info, 0);
|
||||||
return GST_ALLOCATOR_CAST (allocator);
|
return GST_ALLOCATOR_CAST (allocator);
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -741,3 +747,260 @@ error_create_image_pool:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* --- GstVaapiDmaBufMemory --- */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
#define GST_VAAPI_BUFFER_PROXY_QUARK gst_vaapi_buffer_proxy_quark_get ()
|
||||||
|
static GQuark
|
||||||
|
gst_vaapi_buffer_proxy_quark_get (void)
|
||||||
|
{
|
||||||
|
static gsize g_quark;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&g_quark)) {
|
||||||
|
gsize quark = (gsize) g_quark_from_static_string ("GstVaapiBufferProxy");
|
||||||
|
g_once_init_leave (&g_quark, quark);
|
||||||
|
}
|
||||||
|
return g_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstMemory *
|
||||||
|
gst_vaapi_dmabuf_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta)
|
||||||
|
{
|
||||||
|
GstMemory *mem;
|
||||||
|
GstVaapiDisplay *display;
|
||||||
|
GstVaapiSurface *surface;
|
||||||
|
GstVaapiSurfaceProxy *proxy;
|
||||||
|
GstVaapiBufferProxy *dmabuf_proxy;
|
||||||
|
const GstVideoInfo *vip;
|
||||||
|
guint flags;
|
||||||
|
|
||||||
|
g_return_val_if_fail (allocator != NULL, NULL);
|
||||||
|
g_return_val_if_fail (meta != NULL, NULL);
|
||||||
|
|
||||||
|
vip = gst_allocator_get_vaapi_video_info (allocator, &flags);
|
||||||
|
if (!vip)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
display = gst_vaapi_video_meta_get_display (meta);
|
||||||
|
if (!meta)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
surface = gst_vaapi_surface_new_full (display, vip, flags);
|
||||||
|
if (!surface)
|
||||||
|
goto error_create_surface;
|
||||||
|
|
||||||
|
proxy = gst_vaapi_surface_proxy_new (surface);
|
||||||
|
if (!proxy)
|
||||||
|
goto error_create_surface_proxy;
|
||||||
|
|
||||||
|
dmabuf_proxy = gst_vaapi_surface_get_dma_buf_handle (surface);
|
||||||
|
gst_vaapi_object_unref (surface);
|
||||||
|
if (!dmabuf_proxy)
|
||||||
|
goto error_create_dmabuf_proxy;
|
||||||
|
|
||||||
|
gst_vaapi_video_meta_set_surface_proxy (meta, proxy);
|
||||||
|
gst_vaapi_surface_proxy_unref (proxy);
|
||||||
|
|
||||||
|
mem = gst_dmabuf_allocator_alloc (allocator,
|
||||||
|
gst_vaapi_buffer_proxy_get_handle (dmabuf_proxy),
|
||||||
|
gst_vaapi_buffer_proxy_get_size (dmabuf_proxy));
|
||||||
|
if (!mem)
|
||||||
|
goto error_create_dmabuf_memory;
|
||||||
|
|
||||||
|
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem),
|
||||||
|
GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy,
|
||||||
|
(GDestroyNotify) gst_vaapi_buffer_proxy_unref);
|
||||||
|
return mem;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
error_create_surface:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to create VA surface (format:%s size:%ux%u)",
|
||||||
|
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)),
|
||||||
|
GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
error_create_surface_proxy:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to create VA surface proxy");
|
||||||
|
gst_vaapi_object_unref (surface);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
error_create_dmabuf_proxy:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to export VA surface to DMABUF");
|
||||||
|
gst_vaapi_surface_proxy_unref (proxy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
error_create_dmabuf_memory:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to create DMABUF memory");
|
||||||
|
gst_vaapi_buffer_proxy_unref (dmabuf_proxy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* --- GstVaapiDmaBufAllocator --- */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
GstAllocator *
|
||||||
|
gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display,
|
||||||
|
const GstVideoInfo * vip, guint flags)
|
||||||
|
{
|
||||||
|
GstAllocator *allocator = NULL;
|
||||||
|
GstVaapiSurface *surface = NULL;
|
||||||
|
GstVaapiImage *image = NULL;
|
||||||
|
GstVideoInfo alloc_info;
|
||||||
|
|
||||||
|
g_return_val_if_fail (display != NULL, NULL);
|
||||||
|
g_return_val_if_fail (vip != NULL, NULL);
|
||||||
|
|
||||||
|
do {
|
||||||
|
surface = gst_vaapi_surface_new_full (display, vip, flags);
|
||||||
|
if (!surface)
|
||||||
|
break;
|
||||||
|
|
||||||
|
image = gst_vaapi_surface_derive_image (surface);
|
||||||
|
if (!image || !gst_vaapi_image_map (image))
|
||||||
|
break;
|
||||||
|
|
||||||
|
gst_video_info_set_format (&alloc_info, GST_VIDEO_INFO_FORMAT (vip),
|
||||||
|
GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_HEIGHT (vip));
|
||||||
|
gst_video_info_update_from_image (&alloc_info, image);
|
||||||
|
gst_vaapi_image_unmap (image);
|
||||||
|
|
||||||
|
allocator = gst_dmabuf_allocator_new ();
|
||||||
|
if (!allocator)
|
||||||
|
break;
|
||||||
|
gst_allocator_set_vaapi_video_info (allocator, &alloc_info, flags);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
gst_vaapi_object_replace (&image, NULL);
|
||||||
|
gst_vaapi_object_replace (&surface, NULL);
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* --- GstVaapiVideoInfo = { GstVideoInfo, flags } --- */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
static GstVideoInfo *
|
||||||
|
gst_vaapi_video_info_copy (const GstVideoInfo * vip)
|
||||||
|
{
|
||||||
|
GstVideoInfo *out_vip;
|
||||||
|
|
||||||
|
out_vip = g_slice_new (GstVideoInfo);
|
||||||
|
if (!out_vip)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
gst_video_info_init (out_vip);
|
||||||
|
*out_vip = *vip;
|
||||||
|
return out_vip;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_vaapi_video_info_free (GstVideoInfo * vip)
|
||||||
|
{
|
||||||
|
g_slice_free (GstVideoInfo, vip);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GST_VAAPI_TYPE_VIDEO_INFO gst_vaapi_video_info_get_type ()
|
||||||
|
static GType
|
||||||
|
gst_vaapi_video_info_get_type (void)
|
||||||
|
{
|
||||||
|
static gsize g_type;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&g_type)) {
|
||||||
|
GType type;
|
||||||
|
type = g_boxed_type_register_static ("GstVaapiVideoInfo",
|
||||||
|
(GBoxedCopyFunc) gst_vaapi_video_info_copy,
|
||||||
|
(GBoxedFreeFunc) gst_vaapi_video_info_free);
|
||||||
|
g_once_init_leave (&g_type, type);
|
||||||
|
}
|
||||||
|
return (GType) g_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GST_VAAPI_VIDEO_INFO_QUARK gst_vaapi_video_info_quark_get ()
|
||||||
|
static GQuark
|
||||||
|
gst_vaapi_video_info_quark_get (void)
|
||||||
|
{
|
||||||
|
static gsize g_quark;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&g_quark)) {
|
||||||
|
gsize quark = (gsize) g_quark_from_static_string ("GstVaapiVideoInfo");
|
||||||
|
g_once_init_leave (&g_quark, quark);
|
||||||
|
}
|
||||||
|
return g_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INFO_QUARK info_quark_get ()
|
||||||
|
static GQuark
|
||||||
|
info_quark_get (void)
|
||||||
|
{
|
||||||
|
static gsize g_quark;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&g_quark)) {
|
||||||
|
gsize quark = (gsize) g_quark_from_static_string ("info");
|
||||||
|
g_once_init_leave (&g_quark, quark);
|
||||||
|
}
|
||||||
|
return g_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FLAGS_QUARK flags_quark_get ()
|
||||||
|
static GQuark
|
||||||
|
flags_quark_get (void)
|
||||||
|
{
|
||||||
|
static gsize g_quark;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&g_quark)) {
|
||||||
|
gsize quark = (gsize) g_quark_from_static_string ("flags");
|
||||||
|
g_once_init_leave (&g_quark, quark);
|
||||||
|
}
|
||||||
|
return g_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GstVideoInfo *
|
||||||
|
gst_allocator_get_vaapi_video_info (GstAllocator * allocator,
|
||||||
|
guint * out_flags_ptr)
|
||||||
|
{
|
||||||
|
const GstStructure *structure;
|
||||||
|
const GValue *value;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), NULL);
|
||||||
|
|
||||||
|
structure =
|
||||||
|
g_object_get_qdata (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK);
|
||||||
|
if (!structure)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (out_flags_ptr) {
|
||||||
|
value = gst_structure_id_get_value (structure, FLAGS_QUARK);
|
||||||
|
if (!value)
|
||||||
|
return NULL;
|
||||||
|
*out_flags_ptr = g_value_get_uint (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = gst_structure_id_get_value (structure, INFO_QUARK);
|
||||||
|
if (!value)
|
||||||
|
return NULL;
|
||||||
|
return g_value_get_boxed (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
||||||
|
const GstVideoInfo * vip, guint flags)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE);
|
||||||
|
g_return_val_if_fail (vip != NULL, FALSE);
|
||||||
|
|
||||||
|
g_object_set_qdata_full (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK,
|
||||||
|
gst_structure_new_id (GST_VAAPI_VIDEO_INFO_QUARK,
|
||||||
|
INFO_QUARK, GST_VAAPI_TYPE_VIDEO_INFO, vip,
|
||||||
|
FLAGS_QUARK, G_TYPE_UINT, flags, NULL),
|
||||||
|
(GDestroyNotify) gst_structure_free);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#include <gst/vaapi/gstvaapidisplay.h>
|
#include <gst/vaapi/gstvaapidisplay.h>
|
||||||
#include <gst/vaapi/gstvaapivideopool.h>
|
#include <gst/vaapi/gstvaapivideopool.h>
|
||||||
#include "gstvaapivideometa.h"
|
#include "gstvaapivideometa.h"
|
||||||
|
#if GST_CHECK_VERSION(1,1,0)
|
||||||
|
#include <gst/allocators/allocators.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -113,6 +116,10 @@ struct _GstVaapiVideoMemory
|
||||||
gboolean use_direct_rendering;
|
gboolean use_direct_rendering;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GQuark
|
||||||
|
gst_vaapi_video_memory_quark_get (void);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
GstMemory *
|
GstMemory *
|
||||||
gst_vaapi_video_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta);
|
gst_vaapi_video_memory_new (GstAllocator * allocator, GstVaapiVideoMeta * meta);
|
||||||
|
@ -189,6 +196,32 @@ GstAllocator *
|
||||||
gst_vaapi_video_allocator_new (GstVaapiDisplay * display,
|
gst_vaapi_video_allocator_new (GstVaapiDisplay * display,
|
||||||
const GstVideoInfo * vip, guint flags);
|
const GstVideoInfo * vip, guint flags);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* --- GstVaapiDmaBufMemory --- */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GstMemory *
|
||||||
|
gst_vaapi_dmabuf_memory_new (GstAllocator * allocator,
|
||||||
|
GstVaapiVideoMeta * meta);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* --- GstVaapiDmaBufAllocator --- */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GstAllocator *
|
||||||
|
gst_vaapi_dmabuf_allocator_new (GstVaapiDisplay * display,
|
||||||
|
const GstVideoInfo * vip, guint flags);
|
||||||
|
|
||||||
|
const GstVideoInfo *
|
||||||
|
gst_allocator_get_vaapi_video_info (GstAllocator * allocator,
|
||||||
|
guint * out_flags_ptr);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
||||||
|
const GstVideoInfo * vip, guint flags);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_VIDEO_MEMORY_H */
|
#endif /* GST_VAAPI_VIDEO_MEMORY_H */
|
||||||
|
|
Loading…
Reference in a new issue