mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 15:27:07 +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 =
|
||||
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
|
||||
GstVaapiVideoBufferPoolAcquireParams *const priv_params =
|
||||
(GstVaapiVideoBufferPoolAcquireParams *) params;
|
||||
GstVaapiVideoMeta *meta;
|
||||
GstMemory *mem;
|
||||
GstBuffer *buffer;
|
||||
|
@ -290,6 +292,9 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
|
|||
if (!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)
|
||||
mem = gst_vaapi_dmabuf_memory_new (priv->allocator, meta);
|
||||
else
|
||||
|
|
|
@ -945,6 +945,7 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator,
|
|||
gint dmabuf_fd;
|
||||
const GstVideoInfo *surface_info;
|
||||
guint surface_alloc_flags;
|
||||
gboolean needs_surface;
|
||||
GstVaapiDmaBufAllocator *const allocator =
|
||||
GST_VAAPI_DMABUF_ALLOCATOR_CAST (base_allocator);
|
||||
|
||||
|
@ -960,22 +961,36 @@ gst_vaapi_dmabuf_memory_new (GstAllocator * base_allocator,
|
|||
if (!display)
|
||||
return NULL;
|
||||
|
||||
surface = gst_vaapi_surface_new_full (display, surface_info,
|
||||
surface_alloc_flags);
|
||||
if (!surface)
|
||||
goto error_create_surface;
|
||||
proxy = gst_vaapi_video_meta_get_surface_proxy (meta);
|
||||
needs_surface = (proxy == NULL);
|
||||
|
||||
proxy = gst_vaapi_surface_proxy_new (surface);
|
||||
if (!proxy)
|
||||
goto error_create_surface_proxy;
|
||||
if (needs_surface) {
|
||||
/* When exporting output VPP surfaces, or when exporting input
|
||||
* 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);
|
||||
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);
|
||||
if (needs_surface) {
|
||||
/* 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
|
||||
* 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)
|
||||
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);
|
||||
if (needs_surface) {
|
||||
/* Just set the GstVaapiBufferProxy (dmabuf_proxy) as qdata and
|
||||
* 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
|
||||
* (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:
|
||||
{
|
||||
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;
|
||||
}
|
||||
error_create_dmabuf_handle:
|
||||
|
|
Loading…
Reference in a new issue