mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
dmabuf: share the mapping with shared copies of the memory
With lots of shared memory instances (e.g. created by a RTP payloader) the overhead of duplicating the file descriptor and creating extra mappings is significant. To avoid this, the parent memory maps the whole region and the shared copies just reuse the same mapping. https://bugzilla.gnome.org/show_bug.cgi?id=730441
This commit is contained in:
parent
d8a1dc5ea8
commit
b60888fd4b
1 changed files with 14 additions and 9 deletions
|
@ -53,7 +53,6 @@ typedef struct
|
|||
gpointer data;
|
||||
gint mmapping_flags;
|
||||
gint mmap_count;
|
||||
gsize mmap_size;
|
||||
GMutex lock;
|
||||
} GstDmaBufMemory;
|
||||
|
||||
|
@ -68,9 +67,10 @@ gst_dmabuf_allocator_free (GstAllocator * allocator, GstMemory * gmem)
|
|||
|
||||
if (mem->data) {
|
||||
g_warning (G_STRLOC ":%s: Freeing memory %p still mapped", G_STRFUNC, mem);
|
||||
munmap ((void *) mem->data, mem->mmap_size);
|
||||
munmap ((void *) mem->data, gmem->maxsize);
|
||||
}
|
||||
close (mem->fd);
|
||||
if (mem->fd >= 0)
|
||||
close (mem->fd);
|
||||
g_mutex_clear (&mem->lock);
|
||||
g_slice_free (GstDmaBufMemory, mem);
|
||||
GST_DEBUG ("%p: freed", mem);
|
||||
|
@ -85,6 +85,9 @@ gst_dmabuf_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
|
|||
gint prot;
|
||||
gpointer ret = NULL;
|
||||
|
||||
if (gmem->parent)
|
||||
return gst_dmabuf_mem_map (gmem->parent, maxsize, flags);
|
||||
|
||||
g_mutex_lock (&mem->lock);
|
||||
|
||||
prot = flags & GST_MAP_READ ? PROT_READ : 0;
|
||||
|
@ -94,7 +97,7 @@ gst_dmabuf_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
|
|||
if (mem->data) {
|
||||
/* only return address if mapping flags are a subset
|
||||
* of the previous flags */
|
||||
if ((mem->mmapping_flags & prot) && (mem->mmap_size >= maxsize)) {
|
||||
if (mem->mmapping_flags & prot) {
|
||||
ret = mem->data;
|
||||
mem->mmap_count++;
|
||||
}
|
||||
|
@ -103,7 +106,7 @@ gst_dmabuf_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
|
|||
}
|
||||
|
||||
if (mem->fd != -1) {
|
||||
mem->data = mmap (0, maxsize, prot, MAP_SHARED, mem->fd, 0);
|
||||
mem->data = mmap (0, gmem->maxsize, prot, MAP_SHARED, mem->fd, 0);
|
||||
if (mem->data == MAP_FAILED) {
|
||||
mem->data = NULL;
|
||||
GST_ERROR ("%p: fd %d: mmap failed: %s", mem, mem->fd,
|
||||
|
@ -116,7 +119,6 @@ gst_dmabuf_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
|
|||
|
||||
if (mem->data) {
|
||||
mem->mmapping_flags = prot;
|
||||
mem->mmap_size = maxsize;
|
||||
mem->mmap_count++;
|
||||
ret = mem->data;
|
||||
}
|
||||
|
@ -134,12 +136,15 @@ gst_dmabuf_mem_unmap (GstMemory * gmem)
|
|||
{
|
||||
#ifdef HAVE_MMAP
|
||||
GstDmaBufMemory *mem = (GstDmaBufMemory *) gmem;
|
||||
|
||||
if (gmem->parent)
|
||||
return gst_dmabuf_mem_unmap (gmem->parent);
|
||||
|
||||
g_mutex_lock (&mem->lock);
|
||||
|
||||
if (mem->data && !(--mem->mmap_count)) {
|
||||
munmap ((void *) mem->data, mem->mmap_size);
|
||||
munmap ((void *) mem->data, gmem->maxsize);
|
||||
mem->data = NULL;
|
||||
mem->mmap_size = 0;
|
||||
mem->mmapping_flags = 0;
|
||||
GST_DEBUG ("%p: fd %d unmapped", mem, mem->fd);
|
||||
}
|
||||
|
@ -171,7 +176,7 @@ gst_dmabuf_mem_share (GstMemory * gmem, gssize offset, gssize size)
|
|||
GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent,
|
||||
mem->mem.maxsize, mem->mem.align, mem->mem.offset + offset, size);
|
||||
|
||||
sub->fd = dup (mem->fd);
|
||||
sub->fd = -1;
|
||||
g_mutex_init (&sub->lock);
|
||||
|
||||
return GST_MEMORY_CAST (sub);
|
||||
|
|
Loading…
Reference in a new issue