msdk: Allow video and system memory share among buffers
authorSeungha Yang <seungha.yang@navercorp.com>
Wed, 4 Sep 2019 04:18:38 +0000 (13:18 +0900)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Tue, 10 Sep 2019 13:29:11 +0000 (13:29 +0000)
gst_buffer_make_writable() requires exclusive reference to the
GstMemory so the _make_writable() for the msdk buffer will result
to fallback system memory copy, because the msdk memory were initialized
with GST_MEMORY_FLAG_NO_SHARE flag.

Note that, disable sharing GstMemory brings high overhead but actually
the msdk memory objects can be shared over multiple buffers.
If the memory is not shareable, newly added GstAllocator::mem_copy will
create copied msdk memory.

sys/msdk/gstmsdksystemmemory.c
sys/msdk/gstmsdkvideomemory.c

index 8bb797c018cf6b2b59ee592630b6ab4c4fdcf928..6b7900f4a5b6a8a04283aa4e77fe5edd5a0bfd27 100644 (file)
@@ -35,6 +35,7 @@
 #endif
 #include <stdlib.h>
 #include "gstmsdksystemmemory.h"
+#include <string.h>
 
 #ifdef _WIN32
 #define posix_memalign(d, a, s) ((*((void**)d) = _aligned_malloc(s, a)) ? 0 : -1)
@@ -199,7 +200,7 @@ gst_msdk_system_memory_new (GstAllocator * base_allocator)
   mem->surface = gst_msdk_system_allocator_create_surface (base_allocator);
 
   vip = &allocator->image_info;
-  gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE,
+  gst_memory_init (&mem->parent_instance, 0,
       base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
       GST_VIDEO_INFO_SIZE (vip));
 
@@ -244,6 +245,28 @@ gst_msdk_system_memory_unmap (GstMemory * base_mem)
 {
 }
 
+static GstMemory *
+gst_msdk_system_memory_copy (GstMemory * base_mem, gssize offset, gssize size)
+{
+  GstMsdkSystemMemory *copy;
+  GstVideoInfo *info;
+  GstMsdkSystemAllocator *msdk_allocator;
+  gsize mem_size;
+
+  /* FIXME: can we consider offset and size here ? */
+  copy =
+      (GstMsdkSystemMemory *) gst_msdk_system_memory_new (base_mem->allocator);
+
+  msdk_allocator = GST_MSDK_SYSTEM_ALLOCATOR_CAST (base_mem->allocator);
+
+  info = &msdk_allocator->image_info;
+  mem_size = GST_VIDEO_INFO_SIZE (info);
+
+  memcpy (copy->cache, GST_MSDK_SYSTEM_MEMORY_CAST (base_mem)->cache, mem_size);
+
+  return GST_MEMORY_CAST (copy);
+}
+
 /* GstMsdkSystemAllocator */
 G_DEFINE_TYPE (GstMsdkSystemAllocator, gst_msdk_system_allocator,
     GST_TYPE_ALLOCATOR);
@@ -281,6 +304,7 @@ gst_msdk_system_allocator_init (GstMsdkSystemAllocator * allocator)
   base_allocator->mem_type = GST_MSDK_SYSTEM_MEMORY_NAME;
   base_allocator->mem_map_full = gst_msdk_system_memory_map_full;
   base_allocator->mem_unmap = gst_msdk_system_memory_unmap;
+  base_allocator->mem_copy = gst_msdk_system_memory_copy;
 
   GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
 }
index 2b85f308660a95d38b28ad5d6a23c46f0c113619..a59b68f3c4a119a110dc5a5eb31d1b705a5b2c04 100644 (file)
@@ -170,7 +170,7 @@ gst_msdk_video_memory_new (GstAllocator * base_allocator)
     return NULL;
 
   vip = &allocator->image_info;
-  gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE,
+  gst_memory_init (&mem->parent_instance, 0,
       base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
       GST_VIDEO_INFO_SIZE (vip));
 
@@ -313,6 +313,38 @@ gst_msdk_video_memory_unmap (GstMemory * base_mem)
       mem->surface->Data.MemId, &mem->surface->Data);
 }
 
+static GstMemory *
+gst_msdk_video_memory_copy (GstMemory * base_mem, gssize offset, gssize size)
+{
+  GstMemory *copy;
+  GstVideoInfo *info;
+  GstMsdkVideoAllocator *msdk_video_allocator;
+  gsize mem_size;
+  GstMapInfo src_map, dst_map;
+
+  /* FIXME: can we consider offset and size here ? */
+  copy = gst_msdk_video_memory_new (base_mem->allocator);
+
+  if (!copy) {
+    GST_ERROR_OBJECT (base_mem->allocator, "Failed to create new video memory");
+    return NULL;
+  }
+
+  msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (base_mem->allocator);
+
+  info = &msdk_video_allocator->image_info;
+  mem_size = GST_VIDEO_INFO_SIZE (info);
+
+  gst_memory_map (base_mem, &src_map, GST_MAP_READ);
+  gst_memory_map (copy, &dst_map, GST_MAP_WRITE);
+
+  memcpy (dst_map.data, src_map.data, mem_size);
+  gst_memory_unmap (copy, &dst_map);
+  gst_memory_unmap (base_mem, &src_map);
+
+  return copy;
+}
+
 /* GstMsdkVideoAllocator */
 G_DEFINE_TYPE (GstMsdkVideoAllocator, gst_msdk_video_allocator,
     GST_TYPE_ALLOCATOR);
@@ -352,6 +384,7 @@ gst_msdk_video_allocator_init (GstMsdkVideoAllocator * allocator)
   base_allocator->mem_type = GST_MSDK_VIDEO_MEMORY_NAME;
   base_allocator->mem_map_full = gst_msdk_video_memory_map_full;
   base_allocator->mem_unmap = gst_msdk_video_memory_unmap;
+  base_allocator->mem_copy = gst_msdk_video_memory_copy;
 
   GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
 }