cudamemory, d3d11memory: Add memory_{get,set}_token_data() methods

Similar to GstMiniObject qdata but new methods will use int64
token value and per object lock, instead of GQuark with global
mutex in qdata

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3884>
This commit is contained in:
Seungha Yang 2023-02-08 02:47:45 +09:00 committed by GStreamer Marge Bot
parent 03425bc702
commit ff3120a38c
8 changed files with 263 additions and 18 deletions

View file

@ -26,6 +26,8 @@
#include "gstcuda-private.h"
#include <string.h>
#include <map>
#include <memory>
GST_DEBUG_CATEGORY_STATIC (cuda_allocator_debug);
#define GST_CAT_DEFAULT cuda_allocator_debug
@ -33,6 +35,23 @@ GST_DEBUG_CATEGORY_STATIC (cuda_allocator_debug);
static GstAllocator *_gst_cuda_allocator = nullptr;
/* *INDENT-OFF* */
struct GstCudaMemoryTokenData
{
GstCudaMemoryTokenData (gpointer data, GDestroyNotify notify_func)
:user_data (data), notify (notify_func)
{
}
~GstCudaMemoryTokenData ()
{
if (notify)
notify (user_data);
}
gpointer user_data;
GDestroyNotify notify;
};
struct _GstCudaMemoryPrivate
{
_GstCudaMemoryPrivate ()
@ -59,6 +78,8 @@ struct _GstCudaMemoryPrivate
gboolean saw_io = FALSE;
std::map < gint64, std::unique_ptr < GstCudaMemoryTokenData >> token_map;
gpointer user_data = nullptr;
GDestroyNotify notify = nullptr;
};
@ -261,6 +282,8 @@ gst_cuda_allocator_free (GstAllocator * allocator, GstMemory * memory)
CuStreamSynchronize (gst_cuda_stream_get_handle (priv->stream));
}
priv->token_map.clear ();
for (guint i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
for (guint j = 0; j < 2; j++) {
if (priv->texture[i][j]) {
@ -781,6 +804,67 @@ gst_cuda_memory_get_user_data (GstCudaMemory * mem)
return mem->priv->user_data;
}
/**
* gst_cuda_memory_set_token_data:
* @mem: a #GstCudaMemory
* @token: an user token
* @data: an user data
* @notify: function to invoke with @data as argument, when @data needs to be
* freed
*
* Sets an opaque user data on a #GstCudaMemory
*
* Since: 1.24
*/
void
gst_cuda_memory_set_token_data (GstCudaMemory * mem, gint64 token,
gpointer data, GDestroyNotify notify)
{
GstCudaMemoryPrivate *priv;
g_return_if_fail (gst_is_cuda_memory (GST_MEMORY_CAST (mem)));
priv = mem->priv;
std::lock_guard < std::mutex > lk (priv->lock);
auto old_token = priv->token_map.find (token);
if (old_token != priv->token_map.end ())
priv->token_map.erase (old_token);
if (data) {
priv->token_map[token] =
std::unique_ptr < GstCudaMemoryTokenData >
(new GstCudaMemoryTokenData (data, notify));
}
}
/**
* gst_cuda_memory_get_token_data:
* @mem: a #GstCudaMemory
* @token: an user token
*
* Gets back user data pointer stored via gst_cuda_memory_set_token_data()
*
* Returns: (transfer none) (nullable): user data pointer or %NULL
*
* Since: 1.24
*/
gpointer
gst_cuda_memory_get_token_data (GstCudaMemory * mem, gint64 token)
{
GstCudaMemoryPrivate *priv;
gpointer ret = nullptr;
g_return_val_if_fail (gst_is_cuda_memory (GST_MEMORY_CAST (mem)), nullptr);
priv = mem->priv;
std::lock_guard < std::mutex > lk (priv->lock);
auto old_token = priv->token_map.find (token);
if (old_token != priv->token_map.end ())
ret = old_token->second->user_data;
return ret;
}
/**
* gst_cuda_allocator_alloc:
* @allocator: (transfer none) (allow-none): a #GstCudaAllocator

View file

@ -174,6 +174,16 @@ gboolean gst_cuda_memory_get_texture (GstCudaMemory * mem,
GST_CUDA_API
gpointer gst_cuda_memory_get_user_data (GstCudaMemory * mem);
GST_CUDA_API
void gst_cuda_memory_set_token_data (GstCudaMemory * mem,
gint64 token,
gpointer data,
GDestroyNotify notify);
GST_CUDA_API
gpointer gst_cuda_memory_get_token_data (GstCudaMemory * mem,
gint64 token);
/**
* GstCudaAllocator:
*

View file

@ -24,6 +24,7 @@
#include "gstcudautils.h"
#include "gstcudacontext.h"
#include "gstcuda-private.h"
#include <atomic>
#ifdef HAVE_NVCODEC_GST_GL
#include <gst/gl/gl.h>
@ -1651,3 +1652,22 @@ gst_cuda_buffer_copy (GstBuffer * dst, GstCudaBufferCopyType dst_type,
return ret;
}
/**
* gst_cuda_create_user_token:
*
* Creates new user token value
*
* Returns: user token value
*
* Since: 1.24
*/
gint64
gst_cuda_create_user_token (void)
{
/* *INDENT-OFF* */
static std::atomic < gint64 > user_token { 0 };
/* *INDENT-ON* */
return user_token.fetch_add (1);
}

View file

@ -176,5 +176,8 @@ void gst_cuda_graphics_resource_unmap (GstCudaGraphicsResource * reso
GST_CUDA_API
void gst_cuda_graphics_resource_free (GstCudaGraphicsResource * resource);
GST_CUDA_API
gint64 gst_cuda_create_user_token (void);
G_END_DECLS

View file

@ -27,6 +27,8 @@
#include "gstd3d11device.h"
#include "gstd3d11utils.h"
#include "gstd3d11-private.h"
#include <map>
#include <memory>
/**
* SECTION:gstd3d11memory
@ -304,39 +306,67 @@ gst_d3d11_allocation_params_init (GType type)
/* GstD3D11Memory */
#define GST_D3D11_MEMORY_GET_LOCK(m) (&(GST_D3D11_MEMORY_CAST(m)->priv->lock))
struct GstD3D11MemoryTokenData
{
GstD3D11MemoryTokenData (gpointer data, GDestroyNotify notify_func)
:user_data (data), notify (notify_func)
{
}
~GstD3D11MemoryTokenData ()
{
if (notify)
notify (user_data);
}
gpointer user_data;
GDestroyNotify notify;
};
struct _GstD3D11MemoryPrivate
{
ID3D11Texture2D *texture;
ID3D11Buffer *buffer;
_GstD3D11MemoryPrivate ()
{
for (guint i = 0; i < GST_VIDEO_MAX_PLANES; i++)
{
shader_resource_view[i] = nullptr;
render_target_view[i] = nullptr;
}
}
GstD3D11MemoryNativeType native_type;
ID3D11Texture2D *texture = nullptr;
ID3D11Buffer *buffer = nullptr;
GstD3D11MemoryNativeType native_type = GST_D3D11_MEMORY_NATIVE_TYPE_INVALID;
D3D11_TEXTURE2D_DESC desc;
D3D11_BUFFER_DESC buffer_desc;
guint subresource_index;
guint subresource_index = 0;
/* protected by device lock */
ID3D11Resource *staging;
ID3D11Resource *staging = nullptr;
D3D11_MAPPED_SUBRESOURCE map;
gint cpu_map_count;
gint cpu_map_count = 0;
/* protects resource objects */
SRWLOCK lock;
SRWLOCK lock = SRWLOCK_INIT;
ID3D11ShaderResourceView *shader_resource_view[GST_VIDEO_MAX_PLANES];
guint num_shader_resource_views;
guint num_shader_resource_views = 0;
ID3D11RenderTargetView *render_target_view[GST_VIDEO_MAX_PLANES];
guint num_render_target_views;
guint num_render_target_views = 0;
ID3D11VideoDecoderOutputView *decoder_output_view;
ID3D11VideoDecoder *decoder_handle;
ID3D11VideoDecoderOutputView *decoder_output_view = nullptr;
ID3D11VideoDecoder *decoder_handle = nullptr;
ID3D11VideoProcessorInputView *processor_input_view;
ID3D11VideoProcessorOutputView *processor_output_view;
ID3D11VideoProcessorInputView *processor_input_view = nullptr;
ID3D11VideoProcessorOutputView *processor_output_view = nullptr;
GDestroyNotify notify;
gpointer user_data;
std::map < gint64, std::unique_ptr < GstD3D11MemoryTokenData >> token_map;
GDestroyNotify notify = nullptr;
gpointer user_data = nullptr;
};
static inline D3D11_MAP
@ -1266,6 +1296,67 @@ gst_d3d11_memory_get_processor_output_view (GstD3D11Memory * mem,
return mem->priv->processor_output_view;
}
/**
* gst_d3d11_memory_set_token_data:
* @mem: a #GstD3D11Memory
* @token: an user token
* @data: an user data
* @notify: function to invoke with @data as argument, when @data needs to be
* freed
*
* Sets an opaque user data on a #GstD3D11Memory
*
* Since: 1.24
*/
void
gst_d3d11_memory_set_token_data (GstD3D11Memory * mem, gint64 token,
gpointer data, GDestroyNotify notify)
{
GstD3D11MemoryPrivate *priv;
g_return_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)));
priv = mem->priv;
GstD3D11SRWLockGuard lk (GST_D3D11_MEMORY_GET_LOCK (mem));
auto old_token = priv->token_map.find (token);
if (old_token != priv->token_map.end ())
priv->token_map.erase (old_token);
if (data) {
priv->token_map[token] =
std::unique_ptr < GstD3D11MemoryTokenData >
(new GstD3D11MemoryTokenData (data, notify));
}
}
/**
* gst_d3d11_memory_get_token_data:
* @mem: a #GstD3D11Memory
* @token: an user token
*
* Gets back user data pointer stored via gst_d3d11_memory_set_token_data()
*
* Returns: (transfer none) (nullable): user data pointer or %NULL
*
* Since: 1.24
*/
gpointer
gst_d3d11_memory_get_token_data (GstD3D11Memory * mem, gint64 token)
{
GstD3D11MemoryPrivate *priv;
gpointer ret = nullptr;
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), nullptr);
priv = mem->priv;
GstD3D11SRWLockGuard lk (GST_D3D11_MEMORY_GET_LOCK (mem));
auto old_token = priv->token_map.find (token);
if (old_token != priv->token_map.end ())
ret = old_token->second->user_data;
return ret;
}
/* GstD3D11Allocator */
struct _GstD3D11AllocatorPrivate
{
@ -1397,6 +1488,8 @@ gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
GST_LOG_OBJECT (allocator, "Free memory %p", mem);
dmem_priv->token_map.clear ();
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
GST_D3D11_CLEAR_COM (dmem_priv->render_target_view[i]);
GST_D3D11_CLEAR_COM (dmem_priv->shader_resource_view[i]);
@ -1416,7 +1509,8 @@ gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
if (dmem_priv->notify)
dmem_priv->notify (dmem_priv->user_data);
g_free (dmem->priv);
delete dmem->priv;
g_free (dmem);
}
@ -1428,7 +1522,7 @@ gst_d3d11_allocator_alloc_wrapped_internal (GstD3D11Allocator * self,
GstD3D11Memory *mem;
mem = g_new0 (GstD3D11Memory, 1);
mem->priv = g_new0 (GstD3D11MemoryPrivate, 1);
mem->priv = new GstD3D11MemoryPrivate ();
gst_memory_init (GST_MEMORY_CAST (mem),
(GstMemoryFlags) 0, GST_ALLOCATOR_CAST (self), NULL, 0, 0, 0, 0);
@ -1601,7 +1695,7 @@ gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator,
}
mem = g_new0 (GstD3D11Memory, 1);
mem->priv = g_new0 (GstD3D11MemoryPrivate, 1);
mem->priv = new GstD3D11MemoryPrivate ();
gst_memory_init (GST_MEMORY_CAST (mem),
(GstMemoryFlags) 0, GST_ALLOCATOR_CAST (allocator), nullptr, 0, 0, 0, 0);

View file

@ -249,6 +249,17 @@ ID3D11VideoProcessorOutputView * gst_d3d11_memory_get_processor_output_view (Gs
ID3D11VideoDevice * video_device,
ID3D11VideoProcessorEnumerator * enumerator);
GST_D3D11_API
void gst_d3d11_memory_set_token_data (GstD3D11Memory * mem,
gint64 token,
gpointer data,
GDestroyNotify notify);
GST_D3D11_API
gpointer gst_d3d11_memory_get_token_data (GstD3D11Memory * mem,
gint64 token);
/**
* GstD3D11Allocator:
*

View file

@ -28,6 +28,7 @@
#include <windows.h>
#include <versionhelpers.h>
#include <mutex>
#include <atomic>
/**
* SECTION:gstd3d11utils
@ -597,3 +598,22 @@ _gst_d3d11_result (HRESULT hr, GstD3D11Device * device, GstDebugCategory * cat,
return SUCCEEDED (hr);
#endif
}
/**
* gst_d3d11_create_user_token:
*
* Creates new user token value
*
* Returns: user token value
*
* Since: 1.24
*/
gint64
gst_d3d11_create_user_token (void)
{
/* *INDENT-OFF* */
static std::atomic < gint64 > user_token { 0 };
/* *INDENT-ON* */
return user_token.fetch_add (1);
}

View file

@ -57,6 +57,9 @@ GstContext * gst_d3d11_context_new (GstD3D11Device * device);
GST_D3D11_API
gint64 gst_d3d11_luid_to_int64 (const LUID * luid);
GST_D3D11_API
gint64 gst_d3d11_create_user_token (void);
GST_D3D11_API
gboolean _gst_d3d11_result (HRESULT hr,
GstD3D11Device * device,