mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
d3d11allocator: Work as if buffer pool when running on texture array mode
Because the size of texture array cannot be updated dynamically, allocator should block the allocation request. This cannot be done at buffer pool side if this d3d11 memory is shared among multiple buffer objects. Note that setting NO_SHARE flag to d3d11 memory is very inefficient. It would cause most likey copy of the d3d11 texture.
This commit is contained in:
parent
4d02858f66
commit
8ff667e463
4 changed files with 116 additions and 18 deletions
|
@ -63,6 +63,7 @@ typedef struct _GstD3D11AllocationParams GstD3D11AllocationParams;
|
|||
typedef struct _GstD3D11Memory GstD3D11Memory;
|
||||
typedef struct _GstD3D11Allocator GstD3D11Allocator;
|
||||
typedef struct _GstD3D11AllocatorClass GstD3D11AllocatorClass;
|
||||
typedef struct _GstD3D11AllocatorPrivate GstD3D11AllocatorPrivate;
|
||||
|
||||
typedef struct _GstD3D11BufferPool GstD3D11BufferPool;
|
||||
typedef struct _GstD3D11BufferPoolClass GstD3D11BufferPoolClass;
|
||||
|
|
|
@ -50,6 +50,8 @@ static gboolean gst_d3d11_buffer_pool_set_config (GstBufferPool * pool,
|
|||
GstStructure * config);
|
||||
static GstFlowReturn gst_d3d11_buffer_pool_alloc (GstBufferPool * pool,
|
||||
GstBuffer ** buffer, GstBufferPoolAcquireParams * params);
|
||||
static void gst_d3d11_buffer_pool_flush_start (GstBufferPool * pool);
|
||||
static void gst_d3d11_buffer_pool_flush_stop (GstBufferPool * pool);
|
||||
|
||||
static void
|
||||
gst_d3d11_buffer_pool_class_init (GstD3D11BufferPoolClass * klass)
|
||||
|
@ -62,6 +64,8 @@ gst_d3d11_buffer_pool_class_init (GstD3D11BufferPoolClass * klass)
|
|||
bufferpool_class->get_options = gst_d3d11_buffer_pool_get_options;
|
||||
bufferpool_class->set_config = gst_d3d11_buffer_pool_set_config;
|
||||
bufferpool_class->alloc_buffer = gst_d3d11_buffer_pool_alloc;
|
||||
bufferpool_class->flush_start = gst_d3d11_buffer_pool_flush_start;
|
||||
bufferpool_class->flush_stop = gst_d3d11_buffer_pool_flush_stop;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_d3d11_buffer_pool_debug, "d3d11bufferpool", 0,
|
||||
"d3d11bufferpool object");
|
||||
|
@ -311,6 +315,26 @@ error:
|
|||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_buffer_pool_flush_start (GstBufferPool * pool)
|
||||
{
|
||||
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
|
||||
if (priv->allocator)
|
||||
gst_d3d11_allocator_set_flushing (priv->allocator, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_buffer_pool_flush_stop (GstBufferPool * pool)
|
||||
{
|
||||
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
|
||||
if (priv->allocator)
|
||||
gst_d3d11_allocator_set_flushing (priv->allocator, FALSE);
|
||||
}
|
||||
|
||||
GstBufferPool *
|
||||
gst_d3d11_buffer_pool_new (GstD3D11Device * device)
|
||||
{
|
||||
|
|
|
@ -146,8 +146,21 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (GstD3D11AllocationParams,
|
|||
(GBoxedFreeFunc) gst_d3d11_allocation_params_free,
|
||||
_init_alloc_params (g_define_type_id));
|
||||
|
||||
struct _GstD3D11AllocatorPrivate
|
||||
{
|
||||
/* parent textrure when array typed memory is used */
|
||||
ID3D11Texture2D *texture;
|
||||
guint8 array_in_use[D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION];
|
||||
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
|
||||
gboolean flushing;
|
||||
};
|
||||
|
||||
#define gst_d3d11_allocator_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstD3D11Allocator, gst_d3d11_allocator, GST_TYPE_ALLOCATOR);
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstD3D11Allocator,
|
||||
gst_d3d11_allocator, GST_TYPE_ALLOCATOR);
|
||||
|
||||
static inline D3D11_MAP
|
||||
gst_map_flags_to_d3d11 (GstMapFlags flags)
|
||||
|
@ -337,9 +350,16 @@ gst_d3d11_allocator_dummy_alloc (GstAllocator * allocator, gsize size,
|
|||
static void
|
||||
gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
||||
{
|
||||
GstD3D11Allocator *self = GST_D3D11_ALLOCATOR (allocator);
|
||||
GstD3D11AllocatorPrivate *priv = self->priv;
|
||||
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
||||
gint i;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
priv->array_in_use[dmem->subresource_index] = 0;
|
||||
g_cond_broadcast (&priv->cond);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
if (dmem->render_target_view[i])
|
||||
ID3D11RenderTargetView_Release (dmem->render_target_view[i]);
|
||||
|
@ -366,10 +386,11 @@ static void
|
|||
gst_d3d11_allocator_dispose (GObject * object)
|
||||
{
|
||||
GstD3D11Allocator *alloc = GST_D3D11_ALLOCATOR (object);
|
||||
GstD3D11AllocatorPrivate *priv = alloc->priv;
|
||||
|
||||
if (alloc->device && alloc->texture) {
|
||||
gst_d3d11_device_release_texture (alloc->device, alloc->texture);
|
||||
alloc->texture = NULL;
|
||||
if (alloc->device && priv->texture) {
|
||||
gst_d3d11_device_release_texture (alloc->device, priv->texture);
|
||||
priv->texture = NULL;
|
||||
}
|
||||
|
||||
gst_clear_object (&alloc->device);
|
||||
|
@ -377,6 +398,18 @@ gst_d3d11_allocator_dispose (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_allocator_finalize (GObject * object)
|
||||
{
|
||||
GstD3D11Allocator *alloc = GST_D3D11_ALLOCATOR (object);
|
||||
GstD3D11AllocatorPrivate *priv = alloc->priv;
|
||||
|
||||
g_mutex_clear (&priv->lock);
|
||||
g_cond_clear (&priv->cond);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_allocator_class_init (GstD3D11AllocatorClass * klass)
|
||||
{
|
||||
|
@ -384,6 +417,7 @@ gst_d3d11_allocator_class_init (GstD3D11AllocatorClass * klass)
|
|||
GstAllocatorClass *allocator_class = GST_ALLOCATOR_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gst_d3d11_allocator_dispose;
|
||||
gobject_class->finalize = gst_d3d11_allocator_finalize;
|
||||
|
||||
allocator_class->alloc = gst_d3d11_allocator_dummy_alloc;
|
||||
allocator_class->free = gst_d3d11_allocator_free;
|
||||
|
@ -396,6 +430,7 @@ static void
|
|||
gst_d3d11_allocator_init (GstD3D11Allocator * allocator)
|
||||
{
|
||||
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
|
||||
GstD3D11AllocatorPrivate *priv;
|
||||
|
||||
alloc->mem_type = GST_D3D11_MEMORY_NAME;
|
||||
alloc->mem_map = gst_d3d11_memory_map;
|
||||
|
@ -404,6 +439,12 @@ gst_d3d11_allocator_init (GstD3D11Allocator * allocator)
|
|||
/* fallback copy */
|
||||
|
||||
GST_OBJECT_FLAG_SET (alloc, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
|
||||
|
||||
priv = gst_d3d11_allocator_get_instance_private (allocator);
|
||||
g_mutex_init (&priv->lock);
|
||||
g_cond_init (&priv->cond);
|
||||
|
||||
allocator->priv = priv;
|
||||
}
|
||||
|
||||
GstD3D11Allocator *
|
||||
|
@ -614,11 +655,13 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
|||
gsize *size;
|
||||
gboolean is_first = FALSE;
|
||||
guint index_to_use = 0;
|
||||
GstD3D11AllocatorPrivate *priv;
|
||||
GstD3D11MemoryType type = GST_D3D11_MEMORY_TYPE_TEXTURE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
|
||||
g_return_val_if_fail (params != NULL, NULL);
|
||||
|
||||
priv = allocator->priv;
|
||||
device = allocator->device;
|
||||
desc = ¶ms->desc[params->plane];
|
||||
size = ¶ms->size[params->plane];
|
||||
|
@ -628,28 +671,44 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
|||
|
||||
if ((params->flags & GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY)) {
|
||||
gint i;
|
||||
|
||||
do_again:
|
||||
g_mutex_lock (&priv->lock);
|
||||
if (priv->flushing) {
|
||||
GST_DEBUG_OBJECT (allocator, "we are flushing");
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->ArraySize; i++) {
|
||||
if (allocator->array_in_use[i] == 0) {
|
||||
if (priv->array_in_use[i] == 0) {
|
||||
index_to_use = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == desc->ArraySize) {
|
||||
GST_ERROR_OBJECT (allocator, "All elements in array are used now");
|
||||
goto error;
|
||||
GST_DEBUG_OBJECT (allocator, "All elements in array are used now");
|
||||
g_cond_wait (&priv->cond, &priv->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
goto do_again;
|
||||
}
|
||||
|
||||
if (!allocator->texture) {
|
||||
allocator->texture = gst_d3d11_device_create_texture (device, desc, NULL);
|
||||
if (!allocator->texture) {
|
||||
priv->array_in_use[index_to_use] = 1;
|
||||
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
if (!priv->texture) {
|
||||
priv->texture = gst_d3d11_device_create_texture (device, desc, NULL);
|
||||
if (!priv->texture) {
|
||||
GST_ERROR_OBJECT (allocator, "Couldn't create texture");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11Texture2D_AddRef (allocator->texture);
|
||||
texture = allocator->texture;
|
||||
ID3D11Texture2D_AddRef (priv->texture);
|
||||
texture = priv->texture;
|
||||
|
||||
type = GST_D3D11_MEMORY_TYPE_ARRAY;
|
||||
} else {
|
||||
|
@ -701,8 +760,6 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
|||
mem->device = gst_object_ref (device);
|
||||
mem->type = type;
|
||||
mem->subresource_index = index_to_use;
|
||||
if (type == GST_D3D11_MEMORY_TYPE_ARRAY)
|
||||
allocator->array_in_use[index_to_use] = 1;
|
||||
|
||||
if (staging)
|
||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||
|
@ -719,6 +776,22 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gst_d3d11_allocator_set_flushing (GstD3D11Allocator * allocator,
|
||||
gboolean flushing)
|
||||
{
|
||||
GstD3D11AllocatorPrivate *priv;
|
||||
|
||||
g_return_if_fail (GST_IS_D3D11_ALLOCATOR (allocator));
|
||||
|
||||
priv = allocator->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
priv->flushing = flushing;
|
||||
g_cond_broadcast (&priv->cond);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_is_d3d11_memory (GstMemory * mem)
|
||||
{
|
||||
|
|
|
@ -140,11 +140,8 @@ struct _GstD3D11Allocator
|
|||
|
||||
GstD3D11Device *device;
|
||||
|
||||
/* parent textrure when array typed memory is used */
|
||||
ID3D11Texture2D *texture;
|
||||
guint8 array_in_use [D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION];
|
||||
|
||||
/*< private >*/
|
||||
GstD3D11AllocatorPrivate *priv;
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
|
@ -174,6 +171,9 @@ GstD3D11Allocator * gst_d3d11_allocator_new (GstD3D11Device *device);
|
|||
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
||||
GstD3D11AllocationParams * params);
|
||||
|
||||
void gst_d3d11_allocator_set_flushing (GstD3D11Allocator * allocator,
|
||||
gboolean flushing);
|
||||
|
||||
gboolean gst_is_d3d11_memory (GstMemory * mem);
|
||||
|
||||
gboolean gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem);
|
||||
|
|
Loading…
Reference in a new issue