summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Isorce <j.isorce@samsung.com>2016-10-19 16:07:07 +0100
committerVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>2017-02-03 16:18:08 +0100
commit9ed73e76afba6b88ca50b0b8c94cfecf6995f35e (patch)
treeed5758b76f9d9978c101736bae462ddbcdcdd8f9
parent6a0375d96eae0378d19f5c450a278516e5d16305 (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.c70
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;
/**