va: DMA allocator: Set the copied memory properly when popped from pool.

The current code does not set the copied memory correctly when it is popped
from the surface cache pool.
1. We forget to ref the allocator, which causes the allocator to be freed
   unexpected, and we get a crash later because of the memory violation.
2. We forget to add ref_mems_count, which causes the surface leak because
   the surface can not be pushed back to the cache pool again.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1373>
This commit is contained in:
He Junyan 2021-11-22 16:07:27 +08:00 committed by GStreamer Marge Bot
parent 285695ee52
commit 7f31dcf084

View file

@ -292,15 +292,25 @@ gst_va_dmabuf_mem_copy (GstMemory * gmem, gssize offset, gssize size)
/* @XXX: if one-memory buffer it's possible to copy */ /* @XXX: if one-memory buffer it's possible to copy */
if (offset == 0 && size == mem_size && buf->n_mems == 1) { if (offset == 0 && size == mem_size && buf->n_mems == 1) {
GstVaBufferSurface *buf_copy; GstVaBufferSurface *buf_copy = NULL;
GstMemory *copy; GstMemory *copy;
GST_VA_MEMORY_POOL_LOCK (&self->pool); GST_VA_MEMORY_POOL_LOCK (&self->pool);
copy = gst_va_memory_pool_pop (&self->pool); copy = gst_va_memory_pool_pop (&self->pool);
GST_VA_MEMORY_POOL_UNLOCK (&self->pool); GST_VA_MEMORY_POOL_UNLOCK (&self->pool);
if (!copy) { if (copy) {
gst_object_ref (copy->allocator);
buf_copy = gst_mini_object_get_qdata (GST_MINI_OBJECT (copy),
gst_va_buffer_surface_quark ());
g_assert (g_atomic_int_get (&buf_copy->ref_mems_count) == 0);
g_atomic_int_add (&buf_copy->ref_mems_count, 1);
} else {
GstBuffer *buffer = gst_buffer_new (); GstBuffer *buffer = gst_buffer_new ();
if (!gst_va_dmabuf_allocator_setup_buffer (gmem->allocator, buffer)) { if (!gst_va_dmabuf_allocator_setup_buffer (gmem->allocator, buffer)) {
GST_WARNING_OBJECT (self, "Failed to create a new dmabuf memory"); GST_WARNING_OBJECT (self, "Failed to create a new dmabuf memory");
return NULL; return NULL;
@ -308,10 +318,11 @@ gst_va_dmabuf_mem_copy (GstMemory * gmem, gssize offset, gssize size)
copy = gst_buffer_get_memory (buffer, 0); copy = gst_buffer_get_memory (buffer, 0);
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
}
buf_copy = gst_mini_object_get_qdata (GST_MINI_OBJECT (copy), buf_copy = gst_mini_object_get_qdata (GST_MINI_OBJECT (copy),
gst_va_buffer_surface_quark ()); gst_va_buffer_surface_quark ());
}
g_assert (buf_copy->n_mems == 1); g_assert (buf_copy->n_mems == 1);
if (!self->copy) if (!self->copy)