d3d11: Implement memory pool

Major changes:
* GstD3D11Allocator: This allocator is now device-independent object
  which can allocate GstD3D11Memory object for any GstD3D11Device.
  User can get this object via gst_allocator_find(GST_D3D11_MEMORY_NAME)
* GstD3D11PoolAllocator: A new allocator implementation for texture pool.
  From now on GstD3D11BufferPool will make use of this memory pool allocator
  to avoid frequent texture reallocation. That usually happens because
  of buffer copy (gst_buffer_make_writable for example)

In addition to that, GstD3D11BufferPool will provide GstBuffer with
GstVideoMeta, because CPU access to a GstD3D11Memory without GstVideoMeta
is almost impossible since GPU drivers needs padding for stride alignment.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2097>
This commit is contained in:
Seungha Yang 2021-03-18 22:31:55 +09:00 committed by GStreamer Marge Bot
parent 4e7e390cab
commit 39b9f79e11
10 changed files with 1495 additions and 1138 deletions

View file

@ -64,9 +64,13 @@ typedef struct _GstD3D11DevicePrivate GstD3D11DevicePrivate;
typedef struct _GstD3D11AllocationParams GstD3D11AllocationParams; typedef struct _GstD3D11AllocationParams GstD3D11AllocationParams;
typedef struct _GstD3D11Memory GstD3D11Memory; typedef struct _GstD3D11Memory GstD3D11Memory;
typedef struct _GstD3D11MemoryPrivate GstD3D11MemoryPrivate; typedef struct _GstD3D11MemoryPrivate GstD3D11MemoryPrivate;
typedef struct _GstD3D11Allocator GstD3D11Allocator; typedef struct _GstD3D11Allocator GstD3D11Allocator;
typedef struct _GstD3D11AllocatorClass GstD3D11AllocatorClass; typedef struct _GstD3D11AllocatorClass GstD3D11AllocatorClass;
typedef struct _GstD3D11AllocatorPrivate GstD3D11AllocatorPrivate;
typedef struct _GstD3D11PoolAllocator GstD3D11PoolAllocator;
typedef struct _GstD3D11PoolAllocatorClass GstD3D11PoolAllocatorClass;
typedef struct _GstD3D11PoolAllocatorPrivate GstD3D11PoolAllocatorPrivate;
typedef struct _GstD3D11BufferPool GstD3D11BufferPool; typedef struct _GstD3D11BufferPool GstD3D11BufferPool;
typedef struct _GstD3D11BufferPoolClass GstD3D11BufferPoolClass; typedef struct _GstD3D11BufferPoolClass GstD3D11BufferPoolClass;

View file

@ -45,14 +45,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_buffer_pool_debug);
struct _GstD3D11BufferPoolPrivate struct _GstD3D11BufferPoolPrivate
{ {
GstD3D11Device *device; GstD3D11Allocator *alloc[GST_VIDEO_MAX_PLANES];
GstD3D11Allocator *allocator;
gboolean add_videometa;
GstD3D11AllocationParams *d3d11_params; GstD3D11AllocationParams *d3d11_params;
gboolean texture_array_pool;
gint stride[GST_VIDEO_MAX_PLANES]; gint stride[GST_VIDEO_MAX_PLANES];
gsize size[GST_VIDEO_MAX_PLANES];
gsize offset[GST_VIDEO_MAX_PLANES]; gsize offset[GST_VIDEO_MAX_PLANES];
}; };
@ -64,10 +62,14 @@ static void gst_d3d11_buffer_pool_dispose (GObject * object);
static const gchar **gst_d3d11_buffer_pool_get_options (GstBufferPool * pool); static const gchar **gst_d3d11_buffer_pool_get_options (GstBufferPool * pool);
static gboolean gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, 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_buffer (GstBufferPool * pool,
GstBuffer ** buffer, GstBufferPoolAcquireParams * params); GstBuffer ** buffer, GstBufferPoolAcquireParams * params);
static void gst_d3d11_buffer_pool_flush_start (GstBufferPool * pool); static GstFlowReturn gst_d3d11_buffer_pool_acquire_buffer (GstBufferPool * pool,
static void gst_d3d11_buffer_pool_flush_stop (GstBufferPool * pool); GstBuffer ** buffer, GstBufferPoolAcquireParams * params);
static void gst_d3d11_buffer_pool_reset_buffer (GstBufferPool * pool,
GstBuffer * buffer);
static gboolean gst_d3d11_buffer_pool_start (GstBufferPool * pool);
static gboolean gst_d3d11_buffer_pool_stop (GstBufferPool * pool);
static void static void
gst_d3d11_buffer_pool_class_init (GstD3D11BufferPoolClass * klass) gst_d3d11_buffer_pool_class_init (GstD3D11BufferPoolClass * klass)
@ -79,9 +81,11 @@ 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_buffer;
bufferpool_class->flush_start = gst_d3d11_buffer_pool_flush_start; bufferpool_class->acquire_buffer = gst_d3d11_buffer_pool_acquire_buffer;
bufferpool_class->flush_stop = gst_d3d11_buffer_pool_flush_stop; bufferpool_class->reset_buffer = gst_d3d11_buffer_pool_reset_buffer;
bufferpool_class->start = gst_d3d11_buffer_pool_start;
bufferpool_class->stop = gst_d3d11_buffer_pool_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");
@ -93,18 +97,29 @@ gst_d3d11_buffer_pool_init (GstD3D11BufferPool * self)
self->priv = gst_d3d11_buffer_pool_get_instance_private (self); self->priv = gst_d3d11_buffer_pool_get_instance_private (self);
} }
static void
gst_d3d11_buffer_pool_clear_allocator (GstD3D11BufferPool * self)
{
GstD3D11BufferPoolPrivate *priv = self->priv;
guint i;
for (i = 0; i < G_N_ELEMENTS (priv->alloc); i++) {
if (priv->alloc[i]) {
gst_d3d11_allocator_set_active (priv->alloc[i], FALSE);
gst_clear_object (&priv->alloc[i]);
}
}
}
static void static void
gst_d3d11_buffer_pool_dispose (GObject * object) gst_d3d11_buffer_pool_dispose (GObject * object)
{ {
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (object); GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (object);
GstD3D11BufferPoolPrivate *priv = self->priv; GstD3D11BufferPoolPrivate *priv = self->priv;
if (priv->d3d11_params) g_clear_pointer (&priv->d3d11_params, gst_d3d11_allocation_params_free);
gst_d3d11_allocation_params_free (priv->d3d11_params); gst_clear_object (&self->device);
priv->d3d11_params = NULL; gst_d3d11_buffer_pool_clear_allocator (self);
gst_clear_object (&priv->device);
gst_clear_object (&priv->allocator);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -118,79 +133,6 @@ gst_d3d11_buffer_pool_get_options (GstBufferPool * pool)
return options; return options;
} }
static GstBuffer *
allocate_staging_buffer (GstD3D11Allocator * allocator,
const GstVideoInfo * info, const GstD3D11Format * format,
const D3D11_TEXTURE2D_DESC desc[GST_VIDEO_MAX_PLANES],
gboolean add_videometa)
{
GstBuffer *buffer;
gint i;
gint stride[GST_VIDEO_MAX_PLANES] = { 0, };
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
GstMemory *mem;
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (desc != NULL, NULL);
buffer = gst_buffer_new ();
if (format->dxgi_format == DXGI_FORMAT_UNKNOWN) {
gsize size[GST_VIDEO_MAX_PLANES] = { 0, };
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
mem = gst_d3d11_allocator_alloc_staging (allocator, &desc[i], 0,
&stride[i]);
if (!mem) {
GST_ERROR_OBJECT (allocator, "Couldn't allocate memory for plane %d",
i);
goto error;
}
size[i] = gst_memory_get_sizes (mem, NULL, NULL);
if (i > 0)
offset[i] = offset[i - 1] + size[i - 1];
gst_buffer_append_memory (buffer, mem);
}
} else {
/* must be YUV semi-planar or single plane */
g_assert (GST_VIDEO_INFO_N_PLANES (info) <= 2);
mem = gst_d3d11_allocator_alloc_staging (allocator, &desc[0], 0,
&stride[0]);
if (!mem) {
GST_ERROR_OBJECT (allocator, "Couldn't allocate memory");
goto error;
}
gst_memory_get_sizes (mem, NULL, NULL);
gst_buffer_append_memory (buffer, mem);
if (GST_VIDEO_INFO_N_PLANES (info) == 2) {
stride[1] = stride[0];
offset[1] = stride[0] * desc[0].Height;
}
}
if (add_videometa) {
gst_buffer_add_video_meta_full (buffer, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
offset, stride);
}
return buffer;
error:
gst_buffer_unref (buffer);
return NULL;
}
static gboolean static gboolean
gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
{ {
@ -199,10 +141,10 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
GstVideoInfo info; GstVideoInfo info;
GstCaps *caps = NULL; GstCaps *caps = NULL;
guint min_buffers, max_buffers; guint min_buffers, max_buffers;
GstAllocator *allocator = NULL;
gboolean ret = TRUE; gboolean ret = TRUE;
D3D11_TEXTURE2D_DESC *desc; D3D11_TEXTURE2D_DESC *desc;
GstBuffer *staging_buffer; const GstD3D11Format *format;
gsize offset = 0;
gint i; gint i;
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers, if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers,
@ -219,24 +161,10 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height, GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height,
caps); caps);
if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL)) gst_d3d11_buffer_pool_clear_allocator (self);
goto wrong_config;
gst_clear_object (&priv->allocator); memset (priv->stride, 0, sizeof (priv->stride));
memset (priv->offset, 0, sizeof (priv->offset));
if (allocator) {
if (!GST_IS_D3D11_ALLOCATOR (allocator)) {
goto wrong_allocator;
} else {
priv->allocator = gst_object_ref (allocator);
}
} else {
priv->allocator = gst_d3d11_allocator_new (priv->device);
g_assert (priv->allocator);
}
priv->add_videometa = gst_buffer_pool_config_has_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
if (priv->d3d11_params) if (priv->d3d11_params)
gst_d3d11_allocation_params_free (priv->d3d11_params); gst_d3d11_allocation_params_free (priv->d3d11_params);
@ -245,7 +173,7 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
if (!priv->d3d11_params) { if (!priv->d3d11_params) {
/* allocate memory with resource format by default */ /* allocate memory with resource format by default */
priv->d3d11_params = priv->d3d11_params =
gst_d3d11_allocation_params_new (priv->device, &info, 0, 0); gst_d3d11_allocation_params_new (self->device, &info, 0, 0);
} }
desc = priv->d3d11_params->desc; desc = priv->d3d11_params->desc;
@ -313,35 +241,71 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
max_buffers, max_array_size); max_buffers, max_array_size);
max_buffers = max_array_size; max_buffers = max_array_size;
} }
}
staging_buffer = allocate_staging_buffer (priv->allocator, priv->texture_array_pool = TRUE;
&info, priv->d3d11_params->d3d11_format, priv->d3d11_params->desc, TRUE);
if (!staging_buffer) {
GST_ERROR_OBJECT (pool, "Couldn't allocated staging buffer");
return FALSE;
} else { } else {
GstVideoMeta *meta = gst_buffer_get_video_meta (staging_buffer); priv->texture_array_pool = FALSE;
}
if (!meta) { offset = 0;
GST_ERROR_OBJECT (pool, "Buffer doesn't have video meta"); for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
gst_buffer_unref (staging_buffer); GstD3D11Allocator *alloc;
GstD3D11PoolAllocator *pool_alloc;
GstFlowReturn flow_ret;
GstMemory *mem = NULL;
guint stride = 0;
if (desc[i].Format == DXGI_FORMAT_UNKNOWN)
break;
alloc =
(GstD3D11Allocator *) gst_d3d11_pool_allocator_new (self->device,
&desc[i]);
if (!gst_d3d11_allocator_set_active (alloc, TRUE)) {
GST_ERROR_OBJECT (self, "Failed to activate allocator");
gst_object_unref (alloc);
return FALSE; return FALSE;
} }
for (i = 0; i < gst_buffer_n_memory (staging_buffer); i++) { pool_alloc = GST_D3D11_POOL_ALLOCATOR (alloc);
GstMemory *mem = gst_buffer_peek_memory (staging_buffer, i); flow_ret = gst_d3d11_pool_allocator_acquire_memory (pool_alloc, &mem);
if (flow_ret != GST_FLOW_OK) {
priv->size[i] = gst_memory_get_sizes (mem, NULL, NULL); GST_ERROR_OBJECT (self, "Failed to allocate initial memory");
gst_d3d11_allocator_set_active (alloc, FALSE);
gst_object_unref (alloc);
return FALSE;
} }
memcpy (priv->offset, meta->offset, sizeof (priv->offset)); if (!gst_d3d11_memory_get_texture_stride (GST_D3D11_MEMORY_CAST (mem),
memcpy (priv->stride, meta->stride, sizeof (priv->stride)); &stride) || stride < desc[i].Width) {
GST_ERROR_OBJECT (self, "Failed to calculate stride");
gst_d3d11_allocator_set_active (alloc, FALSE);
gst_object_unref (alloc);
gst_memory_unref (mem);
return FALSE;
} }
self->buffer_size = gst_buffer_get_size (staging_buffer); priv->stride[i] = stride;
gst_buffer_unref (staging_buffer); priv->offset[i] = offset;
offset += mem->size;
priv->alloc[i] = alloc;
gst_memory_unref (mem);
}
g_assert (priv->d3d11_params->d3d11_format != NULL);
format = priv->d3d11_params->d3d11_format;
/* single texture semi-planar formats */
if (format->dxgi_format != DXGI_FORMAT_UNKNOWN &&
GST_VIDEO_INFO_N_PLANES (&info) == 2) {
priv->stride[1] = priv->stride[0];
priv->offset[1] = priv->stride[0] * desc[0].Height;
}
self->buffer_size = offset;
gst_buffer_pool_config_set_params (config, gst_buffer_pool_config_set_params (config,
caps, self->buffer_size, min_buffers, max_buffers); caps, self->buffer_size, min_buffers, max_buffers);
@ -365,84 +329,172 @@ wrong_caps:
"failed getting geometry from caps %" GST_PTR_FORMAT, caps); "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
return FALSE; return FALSE;
} }
wrong_allocator:
{
GST_WARNING_OBJECT (pool, "Incorrect allocator type for this pool");
return FALSE;
}
} }
static GstFlowReturn static GstFlowReturn
gst_d3d11_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, gst_d3d11_buffer_pool_fill_buffer (GstD3D11BufferPool * self, GstBuffer * buf)
{
GstD3D11BufferPoolPrivate *priv = self->priv;
GstFlowReturn ret = GST_FLOW_OK;
gint i;
for (i = 0; i < G_N_ELEMENTS (priv->alloc); i++) {
GstMemory *mem = NULL;
GstD3D11PoolAllocator *alloc = GST_D3D11_POOL_ALLOCATOR (priv->alloc[i]);
if (!alloc)
break;
ret = gst_d3d11_pool_allocator_acquire_memory (alloc, &mem);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to acquire memory, ret %s",
gst_flow_get_name (ret));
return ret;
}
gst_buffer_append_memory (buf, mem);
}
return GST_FLOW_OK;
}
static GstFlowReturn
gst_d3d11_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
GstBufferPoolAcquireParams * params) GstBufferPoolAcquireParams * params)
{ {
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool); GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
GstD3D11BufferPoolPrivate *priv = self->priv; GstD3D11BufferPoolPrivate *priv = self->priv;
GstMemory *mem;
GstBuffer *buf;
GstD3D11AllocationParams *d3d11_params = priv->d3d11_params; GstD3D11AllocationParams *d3d11_params = priv->d3d11_params;
GstVideoInfo *info = &d3d11_params->info; GstVideoInfo *info = &d3d11_params->info;
gint i; GstBuffer *buf;
GstFlowReturn ret = GST_FLOW_OK;
buf = gst_buffer_new (); buf = gst_buffer_new ();
/* For texture-array case, we release memory in reset_buffer() so that it can
if (d3d11_params->d3d11_format->dxgi_format == DXGI_FORMAT_UNKNOWN) { * be returned to allocator. So our acquire_buffer() method is expecting
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) { * empty buffer in that case. Don't fill memory here for non-texture-array */
mem = gst_d3d11_allocator_alloc (priv->allocator, &d3d11_params->desc[i], if (!priv->texture_array_pool) {
d3d11_params->flags, priv->size[i]); ret = gst_d3d11_buffer_pool_fill_buffer (self, buf);
if (!mem) if (ret != GST_FLOW_OK) {
goto error; gst_buffer_unref (buf);
return ret;
gst_buffer_append_memory (buf, mem);
} }
} else {
mem = gst_d3d11_allocator_alloc (priv->allocator, &d3d11_params->desc[0],
d3d11_params->flags, priv->size[0]);
if (!mem)
goto error;
gst_buffer_append_memory (buf, mem);
} }
if (priv->add_videometa) {
GST_DEBUG_OBJECT (self, "adding GstVideoMeta");
gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE, gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info), GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
priv->offset, priv->stride); priv->offset, priv->stride);
}
*buffer = buf; *buffer = buf;
return GST_FLOW_OK; return GST_FLOW_OK;
}
error: static GstFlowReturn
gst_buffer_unref (buf); gst_d3d11_buffer_pool_acquire_buffer (GstBufferPool * pool,
GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
{
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
GstD3D11BufferPoolPrivate *priv = self->priv;
GstFlowReturn ret;
GST_ERROR_OBJECT (self, "cannot create texture memory"); ret = GST_BUFFER_POOL_CLASS (parent_class)->acquire_buffer (pool,
buffer, params);
return GST_FLOW_ERROR; if (ret != GST_FLOW_OK)
return ret;
/* Don't need special handling for non-texture-array case */
if (!priv->texture_array_pool)
return ret;
/* Baseclass will hold empty buffer in this case, fill GstMemory */
g_assert (gst_buffer_n_memory (*buffer) == 0);
return gst_d3d11_buffer_pool_fill_buffer (self, *buffer);
} }
static void static void
gst_d3d11_buffer_pool_flush_start (GstBufferPool * pool) gst_d3d11_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer)
{ {
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool); GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
GstD3D11BufferPoolPrivate *priv = self->priv; GstD3D11BufferPoolPrivate *priv = self->priv;
if (priv->allocator) /* if we are using texture array, return memory to allocator, so that
gst_d3d11_allocator_set_flushing (priv->allocator, TRUE); * memory pool allocator can wake up if it's waiting for available memory */
if (priv->texture_array_pool) {
GST_LOG_OBJECT (self, "Returning memory to allocator");
gst_buffer_remove_all_memory (buffer);
}
GST_BUFFER_POOL_CLASS (parent_class)->reset_buffer (pool, buffer);
GST_BUFFER_FLAGS (buffer) = 0;
} }
static void static gboolean
gst_d3d11_buffer_pool_flush_stop (GstBufferPool * pool) gst_d3d11_buffer_pool_start (GstBufferPool * pool)
{ {
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool); GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
GstD3D11BufferPoolPrivate *priv = self->priv; GstD3D11BufferPoolPrivate *priv = self->priv;
guint i;
gboolean ret;
if (priv->allocator) GST_DEBUG_OBJECT (self, "Start");
gst_d3d11_allocator_set_flushing (priv->allocator, FALSE);
for (i = 0; i < G_N_ELEMENTS (priv->alloc); i++) {
GstD3D11Allocator *alloc = priv->alloc[i];
if (!alloc)
break;
if (!gst_d3d11_allocator_set_active (alloc, TRUE)) {
GST_ERROR_OBJECT (self, "Failed to activate allocator");
return FALSE;
}
}
ret = GST_BUFFER_POOL_CLASS (parent_class)->start (pool);
if (!ret) {
GST_ERROR_OBJECT (self, "Failed to start");
for (i = 0; i < G_N_ELEMENTS (priv->alloc); i++) {
GstD3D11Allocator *alloc = priv->alloc[i];
if (!alloc)
break;
gst_d3d11_allocator_set_active (alloc, FALSE);
}
return FALSE;
}
return TRUE;
}
static gboolean
gst_d3d11_buffer_pool_stop (GstBufferPool * pool)
{
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
GstD3D11BufferPoolPrivate *priv = self->priv;
guint i;
GST_DEBUG_OBJECT (self, "Stop");
for (i = 0; i < G_N_ELEMENTS (priv->alloc); i++) {
GstD3D11Allocator *alloc = priv->alloc[i];
if (!alloc)
break;
if (!gst_d3d11_allocator_set_active (alloc, FALSE)) {
GST_ERROR_OBJECT (self, "Failed to deactivate allocator");
return FALSE;
}
}
return GST_BUFFER_POOL_CLASS (parent_class)->stop (pool);
} }
/** /**
@ -457,15 +509,13 @@ GstBufferPool *
gst_d3d11_buffer_pool_new (GstD3D11Device * device) gst_d3d11_buffer_pool_new (GstD3D11Device * device)
{ {
GstD3D11BufferPool *pool; GstD3D11BufferPool *pool;
GstD3D11Allocator *alloc;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL); g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
pool = g_object_new (GST_TYPE_D3D11_BUFFER_POOL, NULL); pool = g_object_new (GST_TYPE_D3D11_BUFFER_POOL, NULL);
alloc = gst_d3d11_allocator_new (device); gst_object_ref_sink (pool);
pool->priv->device = gst_object_ref (device); pool->device = gst_object_ref (device);
pool->priv->allocator = alloc;
return GST_BUFFER_POOL_CAST (pool); return GST_BUFFER_POOL_CAST (pool);
} }

View file

@ -39,6 +39,8 @@ struct _GstD3D11BufferPool
{ {
GstBufferPool parent; GstBufferPool parent;
GstD3D11Device *device;
/* re-calculated buffer size based on d3d11 pitch and stride */ /* re-calculated buffer size based on d3d11 pitch and stride */
guint buffer_size; guint buffer_size;

View file

@ -26,6 +26,7 @@
#include "gstd3d11utils.h" #include "gstd3d11utils.h"
#include "gstd3d11format.h" #include "gstd3d11format.h"
#include "gstd3d11_private.h" #include "gstd3d11_private.h"
#include "gstd3d11memory.h"
#include <gmodule.h> #include <gmodule.h>
#include <windows.h> #include <windows.h>
@ -165,7 +166,10 @@ gst_d3d11_device_enable_d3d11_debug (void)
g_once_init_leave (&_init, 1); g_once_init_leave (&_init, 1);
} }
return ! !d3d11_debug_module; if (d3d11_debug_module)
return TRUE;
return FALSE;
} }
static inline GstDebugLevel static inline GstDebugLevel
@ -257,7 +261,8 @@ gst_d3d11_device_enable_dxgi_debug (void)
if (dxgi_debug_module) if (dxgi_debug_module)
g_module_symbol (dxgi_debug_module, g_module_symbol (dxgi_debug_module,
"DXGIGetDebugInterface", (gpointer *) & GstDXGIGetDebugInterface); "DXGIGetDebugInterface", (gpointer *) & GstDXGIGetDebugInterface);
ret = ! !GstDXGIGetDebugInterface; if (GstDXGIGetDebugInterface)
ret = TRUE;
#elif (GST_D3D11_DXGI_HEADER_VERSION >= 3) #elif (GST_D3D11_DXGI_HEADER_VERSION >= 3)
ret = TRUE; ret = TRUE;
#endif #endif
@ -402,6 +407,8 @@ gst_d3d11_device_class_init (GstD3D11DeviceClass * klass)
g_param_spec_int64 ("adapter-luid", "Adapter LUID", g_param_spec_int64 ("adapter-luid", "Adapter LUID",
"DXGI Adapter LUID (Locally Unique Identifier) of created device", "DXGI Adapter LUID (Locally Unique Identifier) of created device",
0, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); 0, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
gst_d3d11_memory_init_once ();
} }
static void static void

File diff suppressed because it is too large Load diff

View file

@ -30,14 +30,35 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_D3D11_ALLOCATION_PARAMS (gst_d3d11_allocation_params_get_type()) #define GST_TYPE_D3D11_ALLOCATION_PARAMS (gst_d3d11_allocation_params_get_type())
#define GST_TYPE_D3D11_MEMORY (gst_d3d11_memory_get_type())
#define GST_D3D11_MEMORY_CAST(obj) ((GstD3D11Memory *)obj)
#define GST_TYPE_D3D11_ALLOCATOR (gst_d3d11_allocator_get_type()) #define GST_TYPE_D3D11_ALLOCATOR (gst_d3d11_allocator_get_type())
#define GST_D3D11_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_D3D11_ALLOCATOR, GstD3D11Allocator)) #define GST_D3D11_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_D3D11_ALLOCATOR, GstD3D11Allocator))
#define GST_D3D11_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS((klass), GST_TYPE_D3D11_ALLOCATOR, GstD3D11AllocatorClass)) #define GST_D3D11_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_D3D11_ALLOCATOR, GstD3D11AllocatorClass))
#define GST_IS_D3D11_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_D3D11_ALLOCATOR)) #define GST_IS_D3D11_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_D3D11_ALLOCATOR))
#define GST_IS_D3D11_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_ALLOCATOR)) #define GST_IS_D3D11_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_ALLOCATOR))
#define GST_D3D11_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_ALLOCATOR, GstD3D11AllocatorClass)) #define GST_D3D11_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_ALLOCATOR, GstD3D11AllocatorClass))
#define GST_D3D11_ALLOCATOR_CAST(obj) ((GstD3D11Allocator *)obj) #define GST_D3D11_ALLOCATOR_CAST(obj) ((GstD3D11Allocator *)obj)
#define GST_TYPE_D3D11_POOL_ALLOCATOR (gst_d3d11_pool_allocator_get_type())
#define GST_D3D11_POOL_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_D3D11_POOL_ALLOCATOR, GstD3D11PoolAllocator))
#define GST_D3D11_POOL_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_D3D11_POOL_ALLOCATOR, GstD3D11PoolAllocatorClass))
#define GST_IS_D3D11_POOL_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_D3D11_POOL_ALLOCATOR))
#define GST_IS_D3D11_POOL_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_POOL_ALLOCATOR))
#define GST_D3D11_POOL_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_POOL_ALLOCATOR, GstD3D11PoolAllocatorClass))
#define GST_D3D11_POOL_ALLOCATOR_CAST(obj) ((GstD3D11PoolAllocator *)obj)
/**
* GST_D3D11_MEMORY_NAME:
*
* The name of the Direct3D11 memory
*
* Since: 1.20
*/
#define GST_D3D11_MEMORY_NAME "D3D11Memory"
/** /**
* GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY: * GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY:
* *
@ -100,37 +121,6 @@ struct _GstD3D11AllocationParams
gpointer _gst_reserved[GST_PADDING_LARGE]; gpointer _gst_reserved[GST_PADDING_LARGE];
}; };
struct _GstD3D11Memory
{
GstMemory mem;
/*< public > */
GstD3D11Device *device;
/*< private >*/
GstD3D11MemoryPrivate *priv;
gpointer _gst_reserved[GST_PADDING];
};
struct _GstD3D11Allocator
{
GstAllocator parent;
GstD3D11Device *device;
/*< private >*/
GstD3D11AllocatorPrivate *priv;
gpointer _gst_reserved[GST_PADDING];
};
struct _GstD3D11AllocatorClass
{
GstAllocatorClass allocator_class;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
GST_D3D11_API GST_D3D11_API
GType gst_d3d11_allocation_params_get_type (void); GType gst_d3d11_allocation_params_get_type (void);
@ -150,27 +140,23 @@ GST_D3D11_API
gboolean gst_d3d11_allocation_params_alignment (GstD3D11AllocationParams * parms, gboolean gst_d3d11_allocation_params_alignment (GstD3D11AllocationParams * parms,
GstVideoAlignment * align); GstVideoAlignment * align);
GST_D3D11_API struct _GstD3D11Memory
GType gst_d3d11_allocator_get_type (void); {
GstMemory mem;
/*< public >*/
GstD3D11Device *device;
/*< private >*/
GstD3D11MemoryPrivate *priv;
gpointer _gst_reserved[GST_PADDING];
};
GST_D3D11_API GST_D3D11_API
GstD3D11Allocator * gst_d3d11_allocator_new (GstD3D11Device *device); GType gst_d3d11_memory_get_type (void);
GST_D3D11_API GST_D3D11_API
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator, void gst_d3d11_memory_init_once (void);
const D3D11_TEXTURE2D_DESC * desc,
GstD3D11AllocationFlags flags,
gsize size);
GST_D3D11_API
GstMemory * gst_d3d11_allocator_alloc_staging (GstD3D11Allocator * allocator,
const D3D11_TEXTURE2D_DESC * desc,
GstD3D11AllocationFlags flags,
gint * stride);
GST_D3D11_API
void gst_d3d11_allocator_set_flushing (GstD3D11Allocator * allocator,
gboolean flushing);
GST_D3D11_API GST_D3D11_API
gboolean gst_is_d3d11_memory (GstMemory * mem); gboolean gst_is_d3d11_memory (GstMemory * mem);
@ -182,6 +168,10 @@ GST_D3D11_API
gboolean gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem, gboolean gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem,
D3D11_TEXTURE2D_DESC * desc); D3D11_TEXTURE2D_DESC * desc);
GST_D3D11_API
gboolean gst_d3d11_memory_get_texture_stride (GstD3D11Memory * mem,
guint * stride);
GST_D3D11_API GST_D3D11_API
guint gst_d3d11_memory_get_subresource_index (GstD3D11Memory * mem); guint gst_d3d11_memory_get_subresource_index (GstD3D11Memory * mem);
@ -214,6 +204,69 @@ ID3D11VideoProcessorOutputView * gst_d3d11_memory_get_processor_output_view (Gs
ID3D11VideoDevice * video_device, ID3D11VideoDevice * video_device,
ID3D11VideoProcessorEnumerator * enumerator); ID3D11VideoProcessorEnumerator * enumerator);
struct _GstD3D11Allocator
{
GstAllocator allocator;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
struct _GstD3D11AllocatorClass
{
GstAllocatorClass allocator_class;
gboolean (*set_actvie) (GstD3D11Allocator * allocator,
gboolean active);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
};
GST_D3D11_API
GType gst_d3d11_allocator_get_type (void);
GST_D3D11_API
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
GstD3D11Device * device,
const D3D11_TEXTURE2D_DESC * desc);
GST_D3D11_API
gboolean gst_d3d11_allocator_set_active (GstD3D11Allocator * allocator,
gboolean active);
struct _GstD3D11PoolAllocator
{
GstD3D11Allocator allocator;
/*< public >*/
GstD3D11Device *device;
/*< private >*/
GstD3D11PoolAllocatorPrivate *priv;
gpointer _gst_reserved[GST_PADDING];
};
struct _GstD3D11PoolAllocatorClass
{
GstD3D11AllocatorClass allocator_class;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
GST_D3D11_API
GType gst_d3d11_pool_allocator_get_type (void);
GST_D3D11_API
GstD3D11PoolAllocator * gst_d3d11_pool_allocator_new (GstD3D11Device * device,
const D3D11_TEXTURE2D_DESC * desc);
GST_D3D11_API
GstFlowReturn gst_d3d11_pool_allocator_acquire_memory (GstD3D11PoolAllocator * allocator,
GstMemory ** memory);
G_END_DECLS G_END_DECLS
#endif /* __GST_D3D11_MEMORY_H__ */ #endif /* __GST_D3D11_MEMORY_H__ */

View file

@ -1531,7 +1531,10 @@ gst_d3d11_compositor_release_pad (GstElement * element, GstPad * pad)
GST_OBJECT_NAME (pad)); GST_OBJECT_NAME (pad));
gst_clear_buffer (&cpad->fallback_buf); gst_clear_buffer (&cpad->fallback_buf);
if (cpad->fallback_pool) {
gst_buffer_pool_set_active (cpad->fallback_pool, FALSE);
gst_clear_object (&cpad->fallback_pool); gst_clear_object (&cpad->fallback_pool);
}
g_clear_pointer (&cpad->convert, gst_d3d11_converter_free); g_clear_pointer (&cpad->convert, gst_d3d11_converter_free);
GST_D3D11_CLEAR_COM (cpad->blend); GST_D3D11_CLEAR_COM (cpad->blend);

View file

@ -270,7 +270,10 @@ gst_d3d11_decoder_get_property (GObject * object, guint prop_id,
static void static void
gst_d3d11_decoder_clear_resource (GstD3D11Decoder * self) gst_d3d11_decoder_clear_resource (GstD3D11Decoder * self)
{ {
if (self->internal_pool) {
gst_buffer_pool_set_active (self->internal_pool, FALSE);
gst_clear_object (&self->internal_pool); gst_clear_object (&self->internal_pool);
}
GST_D3D11_CLEAR_COM (self->decoder_handle); GST_D3D11_CLEAR_COM (self->decoder_handle);
GST_D3D11_CLEAR_COM (self->staging); GST_D3D11_CLEAR_COM (self->staging);
@ -381,7 +384,10 @@ gst_d3d11_decoder_prepare_output_view_pool (GstD3D11Decoder * self)
GstVideoInfo *info = &self->info; GstVideoInfo *info = &self->info;
guint pool_size; guint pool_size;
if (self->internal_pool) {
gst_buffer_pool_set_active (self->internal_pool, FALSE);
gst_clear_object (&self->internal_pool); gst_clear_object (&self->internal_pool);
}
if (!self->use_array_of_texture) { if (!self->use_array_of_texture) {
alloc_flags = GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY; alloc_flags = GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY;

View file

@ -571,78 +571,20 @@ gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
} }
#endif #endif
GstBuffer * static void
gst_d3d11_allocate_staging_buffer (GstD3D11Allocator * allocator, fill_staging_desc (const D3D11_TEXTURE2D_DESC * ref,
const GstVideoInfo * info, const GstD3D11Format * format, D3D11_TEXTURE2D_DESC * staging)
const D3D11_TEXTURE2D_DESC desc[GST_VIDEO_MAX_PLANES],
gboolean add_videometa)
{ {
GstBuffer *buffer; memset (staging, 0, sizeof (D3D11_TEXTURE2D_DESC));
guint i;
gint stride[GST_VIDEO_MAX_PLANES] = { 0, };
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
GstMemory *mem;
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL); staging->Width = ref->Width;
g_return_val_if_fail (info != NULL, NULL); staging->Height = ref->Height;
g_return_val_if_fail (format != NULL, NULL); staging->MipLevels = 1;
g_return_val_if_fail (desc != NULL, NULL); staging->Format = ref->Format;
staging->SampleDesc.Count = 1;
buffer = gst_buffer_new (); staging->ArraySize = 1;
staging->Usage = D3D11_USAGE_STAGING;
if (format->dxgi_format == DXGI_FORMAT_UNKNOWN) { staging->CPUAccessFlags = (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE);
gsize size[GST_VIDEO_MAX_PLANES] = { 0, };
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
mem =
gst_d3d11_allocator_alloc_staging (allocator, &desc[i],
(GstD3D11AllocationFlags) 0, &stride[i]);
if (!mem) {
GST_ERROR_OBJECT (allocator, "Couldn't allocate memory for plane %d",
i);
goto error;
}
size[i] = gst_memory_get_sizes (mem, NULL, NULL);
if (i > 0)
offset[i] = offset[i - 1] + size[i - 1];
gst_buffer_append_memory (buffer, mem);
}
} else {
/* must be YUV semi-planar or single plane */
g_assert (GST_VIDEO_INFO_N_PLANES (info) <= 2);
mem = gst_d3d11_allocator_alloc_staging (allocator, &desc[0],
(GstD3D11AllocationFlags) 0, &stride[0]);
if (!mem) {
GST_ERROR_OBJECT (allocator, "Couldn't allocate memory");
goto error;
}
gst_memory_get_sizes (mem, NULL, NULL);
gst_buffer_append_memory (buffer, mem);
if (GST_VIDEO_INFO_N_PLANES (info) == 2) {
stride[1] = stride[0];
offset[1] = stride[0] * desc[0].Height;
}
}
if (add_videometa) {
gst_buffer_add_video_meta_full (buffer, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
offset, stride);
}
return buffer;
error:
gst_buffer_unref (buffer);
return NULL;
} }
GstBuffer * GstBuffer *
@ -651,11 +593,14 @@ gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
{ {
GstD3D11Memory *dmem; GstD3D11Memory *dmem;
GstD3D11Device *device; GstD3D11Device *device;
GstD3D11AllocationParams *params = NULL;
GstD3D11Allocator *alloc = NULL; GstD3D11Allocator *alloc = NULL;
GstBuffer *staging_buffer = NULL; GstBuffer *staging_buffer = NULL;
D3D11_TEXTURE2D_DESC *desc; gint stride[GST_VIDEO_MAX_PLANES] = { 0, };
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
guint i; guint i;
gsize size = 0;
const GstD3D11Format *format;
D3D11_TEXTURE2D_DESC desc;
for (i = 0; i < gst_buffer_n_memory (buffer); i++) { for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
GstMemory *mem = gst_buffer_peek_memory (buffer, i); GstMemory *mem = gst_buffer_peek_memory (buffer, i);
@ -669,54 +614,73 @@ gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
dmem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0); dmem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0);
device = dmem->device; device = dmem->device;
format = gst_d3d11_device_format_from_gst (device,
params = gst_d3d11_allocation_params_new (device, (GstVideoInfo *) info, GST_VIDEO_INFO_FORMAT (info));
(GstD3D11AllocationFlags) 0, 0); if (!format) {
GST_ERROR ("Unknown d3d11 format");
if (!params) { return NULL;
GST_WARNING ("Couldn't create alloc params");
goto done;
} }
desc = &params->desc[0]; alloc = (GstD3D11Allocator *) gst_allocator_find (GST_D3D11_MEMORY_NAME);
/* resolution of semi-planar formats must be multiple of 2 */
if (desc[0].Format == DXGI_FORMAT_NV12 || desc[0].Format == DXGI_FORMAT_P010
|| desc[0].Format == DXGI_FORMAT_P016) {
if (desc[0].Width % 2 || desc[0].Height % 2) {
gint width, height;
GstVideoAlignment align;
width = GST_ROUND_UP_2 (desc[0].Width);
height = GST_ROUND_UP_2 (desc[0].Height);
gst_video_alignment_reset (&align);
align.padding_right = width - desc[0].Width;
align.padding_bottom = height - desc[0].Height;
gst_d3d11_allocation_params_alignment (params, &align);
}
}
alloc = gst_d3d11_allocator_new (device);
if (!alloc) { if (!alloc) {
GST_WARNING ("Couldn't create allocator"); GST_ERROR ("D3D11 allocator is not available");
goto done; return NULL;
} }
staging_buffer = gst_d3d11_allocate_staging_buffer (alloc, staging_buffer = gst_buffer_new ();
info, params->d3d11_format, params->desc, add_videometa); for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
D3D11_TEXTURE2D_DESC staging_desc;
GstD3D11Memory *mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, i);
GstD3D11Memory *new_mem;
if (!staging_buffer) guint cur_stride = 0;
GST_WARNING ("Couldn't allocate staging buffer");
done: gst_d3d11_memory_get_texture_desc (mem, &desc);
if (params) fill_staging_desc (&desc, &staging_desc);
gst_d3d11_allocation_params_free (params);
new_mem = (GstD3D11Memory *)
gst_d3d11_allocator_alloc (alloc, mem->device, &staging_desc);
if (!new_mem) {
GST_ERROR ("Failed to allocate memory");
goto error;
}
if (!gst_d3d11_memory_get_texture_stride (new_mem, &cur_stride) ||
cur_stride < staging_desc.Width) {
GST_ERROR ("Failed to calculate memory size");
gst_memory_unref (GST_MEMORY_CAST (mem));
goto error;
}
offset[i] = size;
stride[i] = cur_stride;
size += GST_MEMORY_CAST (new_mem)->size;
gst_buffer_append_memory (staging_buffer, GST_MEMORY_CAST (new_mem));
}
/* single texture semi-planar formats */
if (format->dxgi_format != DXGI_FORMAT_UNKNOWN &&
GST_VIDEO_INFO_N_PLANES (info) == 2) {
stride[1] = stride[0];
offset[1] = stride[0] * desc.Height;
}
gst_buffer_add_video_meta_full (staging_buffer, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
offset, stride);
if (alloc) if (alloc)
gst_object_unref (alloc); gst_object_unref (alloc);
return staging_buffer; return staging_buffer;
error:
gst_clear_buffer (&staging_buffer);
gst_clear_object (&alloc);
return NULL;
} }
static gboolean static gboolean

View file

@ -77,12 +77,6 @@ const GstDxgiColorSpace * gst_d3d11_find_swap_chain_color_space (GstVideoInfo *
gboolean use_hdr10); gboolean use_hdr10);
#endif #endif
GstBuffer * gst_d3d11_allocate_staging_buffer (GstD3D11Allocator * allocator,
const GstVideoInfo * info,
const GstD3D11Format * format,
const D3D11_TEXTURE2D_DESC desc[GST_VIDEO_MAX_PLANES],
gboolean add_videometa);
GstBuffer * gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer, GstBuffer * gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
const GstVideoInfo * info, const GstVideoInfo * info,
gboolean add_videometa); gboolean add_videometa);