From 7b1e4d6051cce5e2f0440ed0ec2ddc14cb50ba1e Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 4 Jun 2023 00:53:40 +0900 Subject: [PATCH] cudabufferpool: Add support for virtual memory Configure malloc or mmap allocator depending on config option Part-of: --- .../gst-libs/gst/cuda/gstcudabufferpool.cpp | 111 +++++++++++++++++- .../gst-libs/gst/cuda/gstcudabufferpool.h | 7 ++ 2 files changed, 113 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.cpp index 64ee134352..6ea111f6e6 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.cpp @@ -24,6 +24,7 @@ #include "gstcudabufferpool.h" #include "gstcudacontext.h" #include "gstcudamemory.h" +#include "gstcuda-private.h" GST_DEBUG_CATEGORY_STATIC (gst_cuda_buffer_pool_debug); #define GST_CAT_DEFAULT gst_cuda_buffer_pool_debug @@ -33,6 +34,8 @@ struct _GstCudaBufferPoolPrivate GstVideoInfo info; GstCudaStream *stream; GstCudaPoolAllocator *alloc; + GstCudaMemoryAllocMethod alloc_method; + CUmemAllocationProp prop; }; #define gst_cuda_buffer_pool_parent_class parent_class @@ -48,6 +51,41 @@ gst_cuda_buffer_pool_get_options (GstBufferPool * pool) return options; } +static gboolean +gst_cuda_buffer_pool_update_alloc_prop (GstCudaBufferPool * self) +{ + GstCudaBufferPoolPrivate *priv = self->priv; + gboolean virtual_mem_supported; + gboolean os_handle_supported; + guint device; + + g_object_get (self->context, "cuda-device-id", &device, + "virtual-memory", &virtual_mem_supported, + "os-handle", &os_handle_supported, nullptr); + + if (!virtual_mem_supported) { + GST_DEBUG_OBJECT (self, "Virtual memory management is not supported"); + return FALSE; + } + + if (!os_handle_supported) { + GST_DEBUG_OBJECT (self, "OS handle is not supported");; + return FALSE; + } + + priv->prop.type = CU_MEM_ALLOCATION_TYPE_PINNED; + priv->prop.location.type = CU_MEM_LOCATION_TYPE_DEVICE; + priv->prop.location.id = (int) device; +#ifdef G_OS_WIN32 + priv->prop.requestedHandleTypes = CU_MEM_HANDLE_TYPE_WIN32; + priv->prop.win32HandleMetaData = gst_cuda_get_win32_handle_metadata (); +#else + priv->prop.requestedHandleTypes = CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR; +#endif + + return TRUE; +} + static gboolean gst_cuda_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { @@ -56,7 +94,7 @@ gst_cuda_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) GstCaps *caps = nullptr; guint size, min_buffers, max_buffers; GstVideoInfo info; - GstMemory *mem; + GstMemory *mem = nullptr; GstCudaMemory *cmem; if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, @@ -77,19 +115,40 @@ gst_cuda_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) if (priv->alloc) { gst_cuda_allocator_set_active (GST_CUDA_ALLOCATOR (priv->alloc), FALSE); - gst_object_unref (priv->alloc); + gst_clear_object (&priv->alloc); } gst_clear_cuda_stream (&priv->stream); priv->stream = gst_buffer_pool_config_get_cuda_stream (config); - priv->alloc = gst_cuda_pool_allocator_new (self->context, priv->stream, - &info); + priv->alloc_method = gst_buffer_pool_config_get_cuda_alloc_method (config); + if (priv->alloc_method == GST_CUDA_MEMORY_ALLOC_UNKNOWN) + priv->alloc_method = GST_CUDA_MEMORY_ALLOC_MALLOC; + + if (priv->alloc_method == GST_CUDA_MEMORY_ALLOC_MMAP) { + if (!gst_cuda_buffer_pool_update_alloc_prop (self)) { + GST_ERROR_OBJECT (self, "Virtual memory management is not supported"); + return FALSE; + } + + priv->alloc = gst_cuda_pool_allocator_new_for_virtual_memory (self->context, + priv->stream, &info, &priv->prop, CU_MEM_ALLOC_GRANULARITY_MINIMUM); + } else { + priv->alloc = gst_cuda_pool_allocator_new (self->context, priv->stream, + &info); + } + if (!priv->alloc) { GST_ERROR_OBJECT (self, "Couldn't create allocator"); return FALSE; } - mem = gst_cuda_allocator_alloc (nullptr, self->context, nullptr, &info); + if (!gst_cuda_allocator_set_active (GST_CUDA_ALLOCATOR (priv->alloc), TRUE)) { + GST_ERROR_OBJECT (self, "Couldn't set active"); + return FALSE; + } + + gst_cuda_pool_allocator_acquire_memory (priv->alloc, &mem); + gst_cuda_allocator_set_active (GST_CUDA_ALLOCATOR (priv->alloc), FALSE); if (!mem) { GST_WARNING_OBJECT (self, "Failed to allocate memory"); return FALSE; @@ -187,6 +246,7 @@ gst_cuda_buffer_pool_new (GstCudaContext * context) gst_object_ref_sink (self); self->context = (GstCudaContext *) gst_object_ref (context); + self->priv->alloc_method = GST_CUDA_MEMORY_ALLOC_MALLOC; return GST_BUFFER_POOL_CAST (self); } @@ -233,6 +293,47 @@ gst_buffer_pool_config_set_cuda_stream (GstStructure * config, "cuda-stream", GST_TYPE_CUDA_STREAM, stream, nullptr); } +/** + * gst_buffer_pool_config_get_cuda_alloc_method: + * @config: a buffer pool config + * + * Gets configured allocation method + * + * Since: 1.24 + */ +GstCudaMemoryAllocMethod +gst_buffer_pool_config_get_cuda_alloc_method (GstStructure * config) +{ + GstCudaMemoryAllocMethod type; + + g_return_val_if_fail (config, GST_CUDA_MEMORY_ALLOC_UNKNOWN); + + if (gst_structure_get_enum (config, "cuda-alloc-method", + GST_TYPE_CUDA_MEMORY_ALLOC_METHOD, (gint *) & type)) { + return type; + } + + return GST_CUDA_MEMORY_ALLOC_UNKNOWN; +} + +/** + * gst_buffer_pool_config_set_cuda_alloc_method: + * @config: a buffer pool config + * + * Sets allocation method + * + * Since: 1.24 + */ +void +gst_buffer_pool_config_set_cuda_alloc_method (GstStructure * config, + GstCudaMemoryAllocMethod method) +{ + g_return_if_fail (config); + + gst_structure_set (config, "cuda-alloc-method", + GST_TYPE_CUDA_MEMORY_ALLOC_METHOD, method, nullptr); +} + static void gst_cuda_buffer_pool_dispose (GObject * object) { diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.h b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.h index e3f6d161b0..1ae7b5dbcf 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudabufferpool.h @@ -79,5 +79,12 @@ GST_CUDA_API void gst_buffer_pool_config_set_cuda_stream (GstStructure * config, GstCudaStream * stream); +GST_CUDA_API +GstCudaMemoryAllocMethod gst_buffer_pool_config_get_cuda_alloc_method (GstStructure * config); + +GST_CUDA_API +void gst_buffer_pool_config_set_cuda_alloc_method (GstStructure * config, + GstCudaMemoryAllocMethod method); + G_END_DECLS