From d4112d3d7b6f2a54cabb50d695b1837c21231011 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Wed, 4 Sep 2019 13:18:38 +0900 Subject: [PATCH] msdk: Allow video and system memory share among buffers 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 | 26 +++++++++++++++++++++++++- sys/msdk/gstmsdkvideomemory.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/sys/msdk/gstmsdksystemmemory.c b/sys/msdk/gstmsdksystemmemory.c index 8bb797c..6b7900f 100644 --- a/sys/msdk/gstmsdksystemmemory.c +++ b/sys/msdk/gstmsdksystemmemory.c @@ -35,6 +35,7 @@ #endif #include #include "gstmsdksystemmemory.h" +#include #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); } diff --git a/sys/msdk/gstmsdkvideomemory.c b/sys/msdk/gstmsdkvideomemory.c index 2b85f30..a59b68f 100644 --- a/sys/msdk/gstmsdkvideomemory.c +++ b/sys/msdk/gstmsdkvideomemory.c @@ -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); } -- 2.7.4