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
@ -63,6 +63,7 @@ typedef struct _GstD3D11AllocationParams GstD3D11AllocationParams;
|
|||||||
typedef struct _GstD3D11Memory GstD3D11Memory;
|
typedef struct _GstD3D11Memory GstD3D11Memory;
|
||||||
typedef struct _GstD3D11Allocator GstD3D11Allocator;
|
typedef struct _GstD3D11Allocator GstD3D11Allocator;
|
||||||
typedef struct _GstD3D11AllocatorClass GstD3D11AllocatorClass;
|
typedef struct _GstD3D11AllocatorClass GstD3D11AllocatorClass;
|
||||||
|
typedef struct _GstD3D11AllocatorPrivate GstD3D11AllocatorPrivate;
|
||||||
|
|
||||||
typedef struct _GstD3D11BufferPool GstD3D11BufferPool;
|
typedef struct _GstD3D11BufferPool GstD3D11BufferPool;
|
||||||
typedef struct _GstD3D11BufferPoolClass GstD3D11BufferPoolClass;
|
typedef struct _GstD3D11BufferPoolClass GstD3D11BufferPoolClass;
|
||||||
|
@ -50,6 +50,8 @@ static gboolean gst_d3d11_buffer_pool_set_config (GstBufferPool * pool,
|
|||||||
GstStructure * config);
|
GstStructure * config);
|
||||||
static GstFlowReturn gst_d3d11_buffer_pool_alloc (GstBufferPool * pool,
|
static GstFlowReturn gst_d3d11_buffer_pool_alloc (GstBufferPool * pool,
|
||||||
GstBuffer ** buffer, GstBufferPoolAcquireParams * params);
|
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
|
static void
|
||||||
gst_d3d11_buffer_pool_class_init (GstD3D11BufferPoolClass * klass)
|
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->get_options = gst_d3d11_buffer_pool_get_options;
|
||||||
bufferpool_class->set_config = gst_d3d11_buffer_pool_set_config;
|
bufferpool_class->set_config = gst_d3d11_buffer_pool_set_config;
|
||||||
bufferpool_class->alloc_buffer = gst_d3d11_buffer_pool_alloc;
|
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,
|
GST_DEBUG_CATEGORY_INIT (gst_d3d11_buffer_pool_debug, "d3d11bufferpool", 0,
|
||||||
"d3d11bufferpool object");
|
"d3d11bufferpool object");
|
||||||
@ -311,6 +315,26 @@ error:
|
|||||||
return GST_FLOW_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 *
|
GstBufferPool *
|
||||||
gst_d3d11_buffer_pool_new (GstD3D11Device * device)
|
gst_d3d11_buffer_pool_new (GstD3D11Device * device)
|
||||||
{
|
{
|
||||||
|
@ -146,8 +146,21 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (GstD3D11AllocationParams,
|
|||||||
(GBoxedFreeFunc) gst_d3d11_allocation_params_free,
|
(GBoxedFreeFunc) gst_d3d11_allocation_params_free,
|
||||||
_init_alloc_params (g_define_type_id));
|
_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
|
#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
|
static inline D3D11_MAP
|
||||||
gst_map_flags_to_d3d11 (GstMapFlags flags)
|
gst_map_flags_to_d3d11 (GstMapFlags flags)
|
||||||
@ -337,9 +350,16 @@ gst_d3d11_allocator_dummy_alloc (GstAllocator * allocator, gsize size,
|
|||||||
static void
|
static void
|
||||||
gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
||||||
{
|
{
|
||||||
|
GstD3D11Allocator *self = GST_D3D11_ALLOCATOR (allocator);
|
||||||
|
GstD3D11AllocatorPrivate *priv = self->priv;
|
||||||
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
|
||||||
gint i;
|
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++) {
|
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||||
if (dmem->render_target_view[i])
|
if (dmem->render_target_view[i])
|
||||||
ID3D11RenderTargetView_Release (dmem->render_target_view[i]);
|
ID3D11RenderTargetView_Release (dmem->render_target_view[i]);
|
||||||
@ -366,10 +386,11 @@ static void
|
|||||||
gst_d3d11_allocator_dispose (GObject * object)
|
gst_d3d11_allocator_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GstD3D11Allocator *alloc = GST_D3D11_ALLOCATOR (object);
|
GstD3D11Allocator *alloc = GST_D3D11_ALLOCATOR (object);
|
||||||
|
GstD3D11AllocatorPrivate *priv = alloc->priv;
|
||||||
|
|
||||||
if (alloc->device && alloc->texture) {
|
if (alloc->device && priv->texture) {
|
||||||
gst_d3d11_device_release_texture (alloc->device, alloc->texture);
|
gst_d3d11_device_release_texture (alloc->device, priv->texture);
|
||||||
alloc->texture = NULL;
|
priv->texture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_clear_object (&alloc->device);
|
gst_clear_object (&alloc->device);
|
||||||
@ -377,6 +398,18 @@ gst_d3d11_allocator_dispose (GObject * object)
|
|||||||
G_OBJECT_CLASS (parent_class)->dispose (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
|
static void
|
||||||
gst_d3d11_allocator_class_init (GstD3D11AllocatorClass * klass)
|
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);
|
GstAllocatorClass *allocator_class = GST_ALLOCATOR_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->dispose = gst_d3d11_allocator_dispose;
|
gobject_class->dispose = gst_d3d11_allocator_dispose;
|
||||||
|
gobject_class->finalize = gst_d3d11_allocator_finalize;
|
||||||
|
|
||||||
allocator_class->alloc = gst_d3d11_allocator_dummy_alloc;
|
allocator_class->alloc = gst_d3d11_allocator_dummy_alloc;
|
||||||
allocator_class->free = gst_d3d11_allocator_free;
|
allocator_class->free = gst_d3d11_allocator_free;
|
||||||
@ -396,6 +430,7 @@ static void
|
|||||||
gst_d3d11_allocator_init (GstD3D11Allocator * allocator)
|
gst_d3d11_allocator_init (GstD3D11Allocator * allocator)
|
||||||
{
|
{
|
||||||
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
|
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
|
||||||
|
GstD3D11AllocatorPrivate *priv;
|
||||||
|
|
||||||
alloc->mem_type = GST_D3D11_MEMORY_NAME;
|
alloc->mem_type = GST_D3D11_MEMORY_NAME;
|
||||||
alloc->mem_map = gst_d3d11_memory_map;
|
alloc->mem_map = gst_d3d11_memory_map;
|
||||||
@ -404,6 +439,12 @@ gst_d3d11_allocator_init (GstD3D11Allocator * allocator)
|
|||||||
/* fallback copy */
|
/* fallback copy */
|
||||||
|
|
||||||
GST_OBJECT_FLAG_SET (alloc, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
|
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 *
|
GstD3D11Allocator *
|
||||||
@ -614,11 +655,13 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
|||||||
gsize *size;
|
gsize *size;
|
||||||
gboolean is_first = FALSE;
|
gboolean is_first = FALSE;
|
||||||
guint index_to_use = 0;
|
guint index_to_use = 0;
|
||||||
|
GstD3D11AllocatorPrivate *priv;
|
||||||
GstD3D11MemoryType type = GST_D3D11_MEMORY_TYPE_TEXTURE;
|
GstD3D11MemoryType type = GST_D3D11_MEMORY_TYPE_TEXTURE;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
|
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
|
||||||
g_return_val_if_fail (params != NULL, NULL);
|
g_return_val_if_fail (params != NULL, NULL);
|
||||||
|
|
||||||
|
priv = allocator->priv;
|
||||||
device = allocator->device;
|
device = allocator->device;
|
||||||
desc = ¶ms->desc[params->plane];
|
desc = ¶ms->desc[params->plane];
|
||||||
size = ¶ms->size[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)) {
|
if ((params->flags & GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY)) {
|
||||||
gint i;
|
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++) {
|
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;
|
index_to_use = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == desc->ArraySize) {
|
if (i == desc->ArraySize) {
|
||||||
GST_ERROR_OBJECT (allocator, "All elements in array are used now");
|
GST_DEBUG_OBJECT (allocator, "All elements in array are used now");
|
||||||
goto error;
|
g_cond_wait (&priv->cond, &priv->lock);
|
||||||
|
g_mutex_unlock (&priv->lock);
|
||||||
|
goto do_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allocator->texture) {
|
priv->array_in_use[index_to_use] = 1;
|
||||||
allocator->texture = gst_d3d11_device_create_texture (device, desc, NULL);
|
|
||||||
if (!allocator->texture) {
|
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");
|
GST_ERROR_OBJECT (allocator, "Couldn't create texture");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11Texture2D_AddRef (allocator->texture);
|
ID3D11Texture2D_AddRef (priv->texture);
|
||||||
texture = allocator->texture;
|
texture = priv->texture;
|
||||||
|
|
||||||
type = GST_D3D11_MEMORY_TYPE_ARRAY;
|
type = GST_D3D11_MEMORY_TYPE_ARRAY;
|
||||||
} else {
|
} else {
|
||||||
@ -701,8 +760,6 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
|||||||
mem->device = gst_object_ref (device);
|
mem->device = gst_object_ref (device);
|
||||||
mem->type = type;
|
mem->type = type;
|
||||||
mem->subresource_index = index_to_use;
|
mem->subresource_index = index_to_use;
|
||||||
if (type == GST_D3D11_MEMORY_TYPE_ARRAY)
|
|
||||||
allocator->array_in_use[index_to_use] = 1;
|
|
||||||
|
|
||||||
if (staging)
|
if (staging)
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||||
@ -719,6 +776,22 @@ error:
|
|||||||
return NULL;
|
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
|
gboolean
|
||||||
gst_is_d3d11_memory (GstMemory * mem)
|
gst_is_d3d11_memory (GstMemory * mem)
|
||||||
{
|
{
|
||||||
|
@ -140,11 +140,8 @@ struct _GstD3D11Allocator
|
|||||||
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
|
|
||||||
/* parent textrure when array typed memory is used */
|
|
||||||
ID3D11Texture2D *texture;
|
|
||||||
guint8 array_in_use [D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION];
|
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
GstD3D11AllocatorPrivate *priv;
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,6 +171,9 @@ GstD3D11Allocator * gst_d3d11_allocator_new (GstD3D11Device *device);
|
|||||||
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
||||||
GstD3D11AllocationParams * params);
|
GstD3D11AllocationParams * params);
|
||||||
|
|
||||||
|
void gst_d3d11_allocator_set_flushing (GstD3D11Allocator * allocator,
|
||||||
|
gboolean flushing);
|
||||||
|
|
||||||
gboolean gst_is_d3d11_memory (GstMemory * mem);
|
gboolean gst_is_d3d11_memory (GstMemory * mem);
|
||||||
|
|
||||||
gboolean gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem);
|
gboolean gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user