v4l2allocator: Fix freeing of shared memory
authorNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Sun, 15 Feb 2015 20:51:55 +0000 (15:51 -0500)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Sun, 15 Feb 2015 21:21:55 +0000 (16:21 -0500)
When memory (that has been shared using gst_memory_share()) are freed,
the memory (or the DMABUF FD) should not bee freed. These memories have
a parent. This also removes the extra _v4l2mem_free function and avoid
calling close twice on the DMABUF FD.

https://bugzilla.gnome.org/show_bug.cgi?id=744573

sys/v4l2/gstv4l2allocator.c

index 76986ba..4688a2a 100644 (file)
@@ -145,14 +145,6 @@ _v4l2mem_dispose (GstV4l2Memory * mem)
   return ret;
 }
 
-static void
-_v4l2mem_free (GstV4l2Memory * mem)
-{
-  if (mem->dmafd >= 0)
-    close (mem->dmafd);
-  g_slice_free (GstV4l2Memory, mem);
-}
-
 static inline GstV4l2Memory *
 _v4l2mem_new (GstMemoryFlags flags, GstAllocator * allocator,
     GstMemory * parent, gsize maxsize, gsize align, gsize offset, gsize size,
@@ -388,23 +380,22 @@ gst_v4l2_allocator_free (GstAllocator * gallocator, GstMemory * gmem)
   GstV4l2Memory *mem = (GstV4l2Memory *) gmem;
   GstV4l2MemoryGroup *group = mem->group;
 
-  GST_LOG_OBJECT (allocator, "freeing plane %i of buffer %u",
-      mem->plane, group->buffer.index);
+  /* Only free unparented memory */
+  if (mem->mem.parent == NULL) {
+    GST_LOG_OBJECT (allocator, "freeing plane %i of buffer %u",
+        mem->plane, group->buffer.index);
 
-  switch (allocator->memory) {
-    case V4L2_MEMORY_MMAP:
-      if (mem->data) {
+    if (allocator->memory == V4L2_MEMORY_MMAP) {
+      if (mem->data)
         v4l2_munmap (mem->data, group->planes[mem->plane].length);
-      } else if (group->planes[mem->plane].m.fd > 0) {
-        close (group->planes[mem->plane].m.fd);
-      }
-      break;
-    default:
-      /* Nothing to do */
-      break;
+    }
+
+    /* This apply for both mmap with expbuf, and dmabuf imported memory */
+    if (mem->dmafd >= 0)
+      close (mem->dmafd);
   }
 
-  _v4l2mem_free (mem);
+  g_slice_free (GstV4l2Memory, mem);
 }
 
 static void