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:
Julien Isorce 2016-10-19 16:05:04 +01:00 committed by Víctor Manuel Jáquez Leal
parent 9132510ce0
commit 6a0375d96e
2 changed files with 47 additions and 14 deletions

View file

@ -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

View file

@ -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: