diff options
author | Julien Isorce <j.isorce@samsung.com> | 2016-10-19 16:07:07 +0100 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <victorx.jaquez@intel.com> | 2017-02-03 16:18:08 +0100 |
commit | 9ed73e76afba6b88ca50b0b8c94cfecf6995f35e (patch) | |
tree | ed5758b76f9d9978c101736bae462ddbcdcdd8f9 | |
parent | 6a0375d96eae0378d19f5c450a278516e5d16305 (diff) |
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
-rw-r--r-- | gst/vaapi/gstvaapivideobufferpool.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/gst/vaapi/gstvaapivideobufferpool.c b/gst/vaapi/gstvaapivideobufferpool.c index 275ccc4f..6aec9653 100644 --- a/gst/vaapi/gstvaapivideobufferpool.c +++ b/gst/vaapi/gstvaapivideobufferpool.c @@ -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 gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, 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->set_config = gst_vaapi_video_buffer_pool_set_config; 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; /** |