mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
vaapivideobufferpool: override acquire_buffer()
Overriding the vmethod acquire_buffer() it is possible to attach the right GstMemory to the current acquired buffer. As a matter of fact, this acquired buffer may contain any instantiated GstFdmemory, since this buffer have been popped out from the buffer pool, which is a FIFO queue. So there is no garantee that this buffer matches with the current processed surface. Evenmore, the VA driver might not use a FIFO queue. Therefore, it is no way to guess on the ordering. In short, acquire_buffer on the VA driver and on the buffer pool return none matching data, we have to manually attach the right GstFdMemory to the acquired GstBuffer. The right GstMemory is the one associated with the current surface. https://bugzilla.gnome.org/show_bug.cgi?id=755072
This commit is contained in:
parent
6a0375d96e
commit
9ed73e76af
1 changed files with 70 additions and 0 deletions
|
@ -353,6 +353,75 @@ error_create_memory:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_vaapi_video_buffer_pool_acquire_buffer (GstBufferPool * pool,
|
||||||
|
GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params)
|
||||||
|
{
|
||||||
|
GstVaapiVideoBufferPoolPrivate *const priv =
|
||||||
|
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
|
||||||
|
GstVaapiVideoBufferPoolAcquireParams *const priv_params =
|
||||||
|
(GstVaapiVideoBufferPoolAcquireParams *) params;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
GstMemory *mem;
|
||||||
|
GstVaapiVideoMeta *meta;
|
||||||
|
GstVaapiSurface *surface;
|
||||||
|
GstVaapiBufferProxy *dmabuf_proxy;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
GST_BUFFER_POOL_CLASS
|
||||||
|
(gst_vaapi_video_buffer_pool_parent_class)->acquire_buffer (pool, &buffer,
|
||||||
|
params);
|
||||||
|
|
||||||
|
if (!priv->use_dmabuf_memory || !params || !priv_params->proxy
|
||||||
|
|| ret != GST_FLOW_OK) {
|
||||||
|
*out_buffer_ptr = buffer;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The point of the following dance is to attach the right GstMemory to the
|
||||||
|
* current acquired buffer. Indeed this buffer can contain any of the
|
||||||
|
* GstFdmemory since this buffer have been popped out from the buffer pool's
|
||||||
|
* FIFO. So there is no garantee that this matches the current surface. The
|
||||||
|
* va decoder driver might not even use a FIFO. So there is no way to guess
|
||||||
|
* on the ordering. In short acquire_current_buffer on the va driver and on
|
||||||
|
* the buffer pool return none matching data. So we have to manually attach
|
||||||
|
* the right GstFdMemory to the acquired GstBuffer. The right GstMemory is
|
||||||
|
* the one associated with the current surface. */
|
||||||
|
g_assert (gst_buffer_n_memory (buffer) == 1);
|
||||||
|
|
||||||
|
/* Find the cached memory associated with the given surface. */
|
||||||
|
surface = GST_VAAPI_SURFACE_PROXY_SURFACE (priv_params->proxy);
|
||||||
|
dmabuf_proxy = gst_vaapi_surface_peek_buffer_proxy (surface);
|
||||||
|
if (dmabuf_proxy) {
|
||||||
|
mem = gst_vaapi_buffer_proxy_peek_mem (dmabuf_proxy);
|
||||||
|
if (mem == gst_buffer_peek_memory (buffer, 0))
|
||||||
|
mem = NULL;
|
||||||
|
else
|
||||||
|
mem = gst_memory_ref (mem);
|
||||||
|
} else {
|
||||||
|
/* The given surface has not been exported yet. */
|
||||||
|
meta = gst_buffer_get_vaapi_video_meta (buffer);
|
||||||
|
if (gst_vaapi_video_meta_get_surface_proxy (meta))
|
||||||
|
gst_vaapi_video_meta_set_surface_proxy (meta, priv_params->proxy);
|
||||||
|
|
||||||
|
mem =
|
||||||
|
gst_vaapi_dmabuf_memory_new (priv->allocator,
|
||||||
|
gst_buffer_get_vaapi_video_meta (buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach the GstFdMemory to the output buffer. */
|
||||||
|
if (mem) {
|
||||||
|
GST_DEBUG_OBJECT (pool, "assigning memory %p to acquired buffer %p", mem,
|
||||||
|
buffer);
|
||||||
|
gst_buffer_replace_memory (buffer, 0, mem);
|
||||||
|
gst_buffer_unset_flags (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_ptr = buffer;
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool,
|
gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
|
@ -384,6 +453,7 @@ gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass)
|
||||||
pool_class->get_options = gst_vaapi_video_buffer_pool_get_options;
|
pool_class->get_options = gst_vaapi_video_buffer_pool_get_options;
|
||||||
pool_class->set_config = gst_vaapi_video_buffer_pool_set_config;
|
pool_class->set_config = gst_vaapi_video_buffer_pool_set_config;
|
||||||
pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer;
|
pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer;
|
||||||
|
pool_class->acquire_buffer = gst_vaapi_video_buffer_pool_acquire_buffer;
|
||||||
pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer;
|
pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue