diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp index 5372c2af35..26c36eee92 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.cpp @@ -26,6 +26,8 @@ #include "gstcuda-private.h" #include +#include +#include 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 diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h index 9c82f0dc6d..c222faab01 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudamemory.h @@ -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: * diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp index 95e5608866..bc6d74086c 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.cpp @@ -24,6 +24,7 @@ #include "gstcudautils.h" #include "gstcudacontext.h" #include "gstcuda-private.h" +#include #ifdef HAVE_NVCODEC_GST_GL #include @@ -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); +} diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.h b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.h index c8d5893a3b..b93fe494b7 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/cuda/gstcudautils.h @@ -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 diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp index ccefdc32cd..eafb3d5442 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp @@ -27,6 +27,8 @@ #include "gstd3d11device.h" #include "gstd3d11utils.h" #include "gstd3d11-private.h" +#include +#include /** * 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); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h index e0cf3ce69e..8d4c3f1585 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h @@ -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: * diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.cpp index b311af3a44..23ad2cbd08 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.cpp @@ -28,6 +28,7 @@ #include #include #include +#include /** * 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); +} diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.h index 8a33747fc5..de2ed95412 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11utils.h @@ -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,