mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 19:50:40 +00:00
vaapivideomemory: export surface if it is provided
gst_vaapi_dmabuf_memory_new() always exports a surface. Previously, it had to create that surface. Now it can also export an already provided surface. It is useful to export decoder's surfaces (from VA context). https://bugzilla.gnome.org/show_bug.cgi?id=755072
This commit is contained in:
parent
9132510ce0
commit
6a0375d96e
2 changed files with 47 additions and 14 deletions
|
@ -267,6 +267,8 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
|
||||||
{
|
{
|
||||||
GstVaapiVideoBufferPoolPrivate *const priv =
|
GstVaapiVideoBufferPoolPrivate *const priv =
|
||||||
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
|
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
|
||||||
|
GstVaapiVideoBufferPoolAcquireParams *const priv_params =
|
||||||
|
(GstVaapiVideoBufferPoolAcquireParams *) params;
|
||||||
GstVaapiVideoMeta *meta;
|
GstVaapiVideoMeta *meta;
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
@ -290,6 +292,9 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
goto error_create_buffer;
|
goto error_create_buffer;
|
||||||
|
|
||||||
|
if (priv_params && priv_params->proxy)
|
||||||
|
gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy);
|
||||||
|
|
||||||
if (priv->use_dmabuf_memory)
|
if (priv->use_dmabuf_memory)
|
||||||
mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta);
|
mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta);
|
||||||
else
|
else
|
||||||
|
|
|
@ -945,6 +945,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator,
|
||||||
gint dmabuf_fd;
|
gint dmabuf_fd;
|
||||||
const GstVideoInfo *surface_info;
|
const GstVideoInfo *surface_info;
|
||||||
guint surface_alloc_flags;
|
guint surface_alloc_flags;
|
||||||
|
gboolean needs_surface;
|
||||||
GstVaapiDmaBufAllocator *const allocator =
|
GstVaapiDmaBufAllocator *const allocator =
|
||||||
GST_VAAPI_DMABUF_ALLOCATOR_CAST (base_allocator);
|
GST_VAAPI_DMABUF_ALLOCATOR_CAST (base_allocator);
|
||||||
|
|
||||||
|
@ -960,22 +961,36 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator,
|
||||||
if (!display)
|
if (!display)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
surface = gst_vaapi_surface_new_full (display, surface_info,
|
proxy = gst_vaapi_video_meta_get_surface_proxy (meta);
|
||||||
surface_alloc_flags);
|
needs_surface = (proxy == NULL);
|
||||||
if (!surface)
|
|
||||||
goto error_create_surface;
|
|
||||||
|
|
||||||
proxy = gst_vaapi_surface_proxy_new (surface);
|
if (needs_surface) {
|
||||||
if (!proxy)
|
/* When exporting output VPP surfaces, or when exporting input
|
||||||
goto error_create_surface_proxy;
|
* surfaces to be filled/imported by an upstream element, such as
|
||||||
|
* v4l2src, we have to instantiate a VA surface to store it. */
|
||||||
|
surface = gst_vaapi_surface_new_full (display, surface_info,
|
||||||
|
surface_alloc_flags);
|
||||||
|
if (!surface)
|
||||||
|
goto error_create_surface;
|
||||||
|
proxy = gst_vaapi_surface_proxy_new (surface);
|
||||||
|
if (!proxy)
|
||||||
|
goto error_create_surface_proxy;
|
||||||
|
} else {
|
||||||
|
/* When exporting existing surfaces that come from decoder's
|
||||||
|
* context. */
|
||||||
|
surface = GST_VAAPI_SURFACE_PROXY_SURFACE (proxy);
|
||||||
|
}
|
||||||
|
|
||||||
dmabuf_proxy = gst_vaapi_surface_get_dma_buf_handle (surface);
|
dmabuf_proxy = gst_vaapi_surface_get_dma_buf_handle (surface);
|
||||||
gst_vaapi_object_unref (surface);
|
|
||||||
if (!dmabuf_proxy)
|
if (!dmabuf_proxy)
|
||||||
goto error_create_dmabuf_proxy;
|
goto error_create_dmabuf_proxy;
|
||||||
|
|
||||||
gst_vaapi_video_meta_set_surface_proxy (meta, proxy);
|
if (needs_surface) {
|
||||||
gst_vaapi_surface_proxy_unref (proxy);
|
/* The proxy has incremented the surface ref count. */
|
||||||
|
gst_vaapi_object_unref (surface);
|
||||||
|
gst_vaapi_video_meta_set_surface_proxy (meta, proxy);
|
||||||
|
gst_vaapi_surface_proxy_unref (proxy);
|
||||||
|
}
|
||||||
|
|
||||||
/* Need dup because GstDmabufMemory creates the GstFdMemory with flag
|
/* Need dup because GstDmabufMemory creates the GstFdMemory with flag
|
||||||
* GST_FD_MEMORY_FLAG_NONE. So when being freed it calls close on the fd
|
* GST_FD_MEMORY_FLAG_NONE. So when being freed it calls close on the fd
|
||||||
|
@ -989,9 +1004,19 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator,
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto error_create_dmabuf_memory;
|
goto error_create_dmabuf_memory;
|
||||||
|
|
||||||
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem),
|
if (needs_surface) {
|
||||||
GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy,
|
/* Just set the GstVaapiBufferProxy (dmabuf_proxy) as qdata and
|
||||||
(GDestroyNotify) gst_vaapi_buffer_proxy_unref);
|
* forget about it. */
|
||||||
|
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem),
|
||||||
|
GST_VAAPI_BUFFER_PROXY_QUARK, dmabuf_proxy,
|
||||||
|
(GDestroyNotify) gst_vaapi_buffer_proxy_unref);
|
||||||
|
} else {
|
||||||
|
/* When not allocating the surface from this pool, so when
|
||||||
|
* exporting from the decoder's VA context, we need to know which
|
||||||
|
* GstMemory belongs to a provided surface. */
|
||||||
|
gst_vaapi_buffer_proxy_set_mem (dmabuf_proxy, mem);
|
||||||
|
gst_vaapi_surface_set_buffer_proxy (surface, dmabuf_proxy);
|
||||||
|
}
|
||||||
|
|
||||||
/* When a VA surface is going to be filled by a VAAPI element
|
/* When a VA surface is going to be filled by a VAAPI element
|
||||||
* (decoder or VPP), it has _not_ be marked as busy in the driver.
|
* (decoder or VPP), it has _not_ be marked as busy in the driver.
|
||||||
|
@ -1020,7 +1045,10 @@ error_create_surface_proxy:
|
||||||
error_create_dmabuf_proxy:
|
error_create_dmabuf_proxy:
|
||||||
{
|
{
|
||||||
GST_ERROR ("failed to export VA surface to DMABUF");
|
GST_ERROR ("failed to export VA surface to DMABUF");
|
||||||
gst_vaapi_surface_proxy_unref (proxy);
|
if (surface)
|
||||||
|
gst_vaapi_object_unref (surface);
|
||||||
|
if (proxy)
|
||||||
|
gst_vaapi_surface_proxy_unref (proxy);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
error_create_dmabuf_handle:
|
error_create_dmabuf_handle:
|
||||||
|
|
Loading…
Reference in a new issue