cudabufferpool: Add support for virtual memory

Configure malloc or mmap allocator depending on config option

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4510>
This commit is contained in:
Seungha Yang 2023-06-04 00:53:40 +09:00 committed by GStreamer Marge Bot
parent 547b13c68f
commit 7b1e4d6051
2 changed files with 113 additions and 5 deletions

View file

@ -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)
{

View file

@ -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