mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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:
parent
4e7e390cab
commit
39b9f79e11
10 changed files with 1495 additions and 1138 deletions
|
@ -64,9 +64,13 @@ typedef struct _GstD3D11DevicePrivate GstD3D11DevicePrivate;
|
|||
typedef struct _GstD3D11AllocationParams GstD3D11AllocationParams;
|
||||
typedef struct _GstD3D11Memory GstD3D11Memory;
|
||||
typedef struct _GstD3D11MemoryPrivate GstD3D11MemoryPrivate;
|
||||
|
||||
typedef struct _GstD3D11Allocator GstD3D11Allocator;
|
||||
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 _GstD3D11BufferPoolClass GstD3D11BufferPoolClass;
|
||||
|
|
|
@ -45,14 +45,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_buffer_pool_debug);
|
|||
|
||||
struct _GstD3D11BufferPoolPrivate
|
||||
{
|
||||
GstD3D11Device *device;
|
||||
GstD3D11Allocator *allocator;
|
||||
GstD3D11Allocator *alloc[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
gboolean add_videometa;
|
||||
GstD3D11AllocationParams *d3d11_params;
|
||||
gboolean texture_array_pool;
|
||||
|
||||
gint stride[GST_VIDEO_MAX_PLANES];
|
||||
gsize size[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 gboolean gst_d3d11_buffer_pool_set_config (GstBufferPool * pool,
|
||||
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);
|
||||
static void gst_d3d11_buffer_pool_flush_start (GstBufferPool * pool);
|
||||
static void gst_d3d11_buffer_pool_flush_stop (GstBufferPool * pool);
|
||||
static GstFlowReturn gst_d3d11_buffer_pool_acquire_buffer (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
|
||||
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->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;
|
||||
bufferpool_class->alloc_buffer = gst_d3d11_buffer_pool_alloc_buffer;
|
||||
bufferpool_class->acquire_buffer = gst_d3d11_buffer_pool_acquire_buffer;
|
||||
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,
|
||||
"d3d11bufferpool object");
|
||||
|
@ -93,18 +97,29 @@ gst_d3d11_buffer_pool_init (GstD3D11BufferPool * 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
|
||||
gst_d3d11_buffer_pool_dispose (GObject * object)
|
||||
{
|
||||
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (object);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
|
||||
if (priv->d3d11_params)
|
||||
gst_d3d11_allocation_params_free (priv->d3d11_params);
|
||||
priv->d3d11_params = NULL;
|
||||
|
||||
gst_clear_object (&priv->device);
|
||||
gst_clear_object (&priv->allocator);
|
||||
g_clear_pointer (&priv->d3d11_params, gst_d3d11_allocation_params_free);
|
||||
gst_clear_object (&self->device);
|
||||
gst_d3d11_buffer_pool_clear_allocator (self);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
@ -118,79 +133,6 @@ gst_d3d11_buffer_pool_get_options (GstBufferPool * pool)
|
|||
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
|
||||
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;
|
||||
GstCaps *caps = NULL;
|
||||
guint min_buffers, max_buffers;
|
||||
GstAllocator *allocator = NULL;
|
||||
gboolean ret = TRUE;
|
||||
D3D11_TEXTURE2D_DESC *desc;
|
||||
GstBuffer *staging_buffer;
|
||||
const GstD3D11Format *format;
|
||||
gsize offset = 0;
|
||||
gint i;
|
||||
|
||||
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,
|
||||
caps);
|
||||
|
||||
if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL))
|
||||
goto wrong_config;
|
||||
gst_d3d11_buffer_pool_clear_allocator (self);
|
||||
|
||||
gst_clear_object (&priv->allocator);
|
||||
|
||||
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);
|
||||
memset (priv->stride, 0, sizeof (priv->stride));
|
||||
memset (priv->offset, 0, sizeof (priv->offset));
|
||||
|
||||
if (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) {
|
||||
/* allocate memory with resource format by default */
|
||||
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;
|
||||
|
@ -313,35 +241,71 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
|
|||
max_buffers, max_array_size);
|
||||
max_buffers = max_array_size;
|
||||
}
|
||||
|
||||
priv->texture_array_pool = TRUE;
|
||||
} else {
|
||||
priv->texture_array_pool = FALSE;
|
||||
}
|
||||
|
||||
staging_buffer = allocate_staging_buffer (priv->allocator,
|
||||
&info, priv->d3d11_params->d3d11_format, priv->d3d11_params->desc, TRUE);
|
||||
offset = 0;
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
GstD3D11Allocator *alloc;
|
||||
GstD3D11PoolAllocator *pool_alloc;
|
||||
GstFlowReturn flow_ret;
|
||||
GstMemory *mem = NULL;
|
||||
guint stride = 0;
|
||||
|
||||
if (!staging_buffer) {
|
||||
GST_ERROR_OBJECT (pool, "Couldn't allocated staging buffer");
|
||||
return FALSE;
|
||||
} else {
|
||||
GstVideoMeta *meta = gst_buffer_get_video_meta (staging_buffer);
|
||||
if (desc[i].Format == DXGI_FORMAT_UNKNOWN)
|
||||
break;
|
||||
|
||||
if (!meta) {
|
||||
GST_ERROR_OBJECT (pool, "Buffer doesn't have video meta");
|
||||
gst_buffer_unref (staging_buffer);
|
||||
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;
|
||||
}
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (staging_buffer); i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (staging_buffer, i);
|
||||
|
||||
priv->size[i] = gst_memory_get_sizes (mem, NULL, NULL);
|
||||
pool_alloc = GST_D3D11_POOL_ALLOCATOR (alloc);
|
||||
flow_ret = gst_d3d11_pool_allocator_acquire_memory (pool_alloc, &mem);
|
||||
if (flow_ret != GST_FLOW_OK) {
|
||||
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));
|
||||
memcpy (priv->stride, meta->stride, sizeof (priv->stride));
|
||||
if (!gst_d3d11_memory_get_texture_stride (GST_D3D11_MEMORY_CAST (mem),
|
||||
&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;
|
||||
}
|
||||
|
||||
priv->stride[i] = stride;
|
||||
priv->offset[i] = offset;
|
||||
offset += mem->size;
|
||||
|
||||
priv->alloc[i] = alloc;
|
||||
|
||||
gst_memory_unref (mem);
|
||||
}
|
||||
|
||||
self->buffer_size = gst_buffer_get_size (staging_buffer);
|
||||
gst_buffer_unref (staging_buffer);
|
||||
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,
|
||||
caps, self->buffer_size, min_buffers, max_buffers);
|
||||
|
@ -365,84 +329,172 @@ wrong_caps:
|
|||
"failed getting geometry from caps %" GST_PTR_FORMAT, caps);
|
||||
return FALSE;
|
||||
}
|
||||
wrong_allocator:
|
||||
{
|
||||
GST_WARNING_OBJECT (pool, "Incorrect allocator type for this pool");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_d3d11_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
||||
GstBufferPoolAcquireParams * params)
|
||||
gst_d3d11_buffer_pool_fill_buffer (GstD3D11BufferPool * self, GstBuffer * buf)
|
||||
{
|
||||
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
GstMemory *mem;
|
||||
GstBuffer *buf;
|
||||
GstD3D11AllocationParams *d3d11_params = priv->d3d11_params;
|
||||
GstVideoInfo *info = &d3d11_params->info;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
gint i;
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->alloc); i++) {
|
||||
GstMemory *mem = NULL;
|
||||
GstD3D11PoolAllocator *alloc = GST_D3D11_POOL_ALLOCATOR (priv->alloc[i]);
|
||||
|
||||
if (d3d11_params->d3d11_format->dxgi_format == DXGI_FORMAT_UNKNOWN) {
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
|
||||
mem = gst_d3d11_allocator_alloc (priv->allocator, &d3d11_params->desc[i],
|
||||
d3d11_params->flags, priv->size[i]);
|
||||
if (!mem)
|
||||
goto error;
|
||||
if (!alloc)
|
||||
break;
|
||||
|
||||
gst_buffer_append_memory (buf, mem);
|
||||
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;
|
||||
}
|
||||
} 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_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
|
||||
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
|
||||
priv->offset, priv->stride);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_d3d11_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
|
||||
GstBufferPoolAcquireParams * params)
|
||||
{
|
||||
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
GstD3D11AllocationParams *d3d11_params = priv->d3d11_params;
|
||||
GstVideoInfo *info = &d3d11_params->info;
|
||||
GstBuffer *buf;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
/* For texture-array case, we release memory in reset_buffer() so that it can
|
||||
* be returned to allocator. So our acquire_buffer() method is expecting
|
||||
* empty buffer in that case. Don't fill memory here for non-texture-array */
|
||||
if (!priv->texture_array_pool) {
|
||||
ret = gst_d3d11_buffer_pool_fill_buffer (self, buf);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
gst_buffer_unref (buf);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
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_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
|
||||
priv->offset, priv->stride);
|
||||
|
||||
*buffer = buf;
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
gst_buffer_unref (buf);
|
||||
static GstFlowReturn
|
||||
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
|
||||
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);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
|
||||
if (priv->allocator)
|
||||
gst_d3d11_allocator_set_flushing (priv->allocator, TRUE);
|
||||
/* if we are using texture array, return memory to allocator, so that
|
||||
* 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
|
||||
gst_d3d11_buffer_pool_flush_stop (GstBufferPool * pool)
|
||||
static gboolean
|
||||
gst_d3d11_buffer_pool_start (GstBufferPool * pool)
|
||||
{
|
||||
GstD3D11BufferPool *self = GST_D3D11_BUFFER_POOL (pool);
|
||||
GstD3D11BufferPoolPrivate *priv = self->priv;
|
||||
guint i;
|
||||
gboolean ret;
|
||||
|
||||
if (priv->allocator)
|
||||
gst_d3d11_allocator_set_flushing (priv->allocator, FALSE);
|
||||
GST_DEBUG_OBJECT (self, "Start");
|
||||
|
||||
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)
|
||||
{
|
||||
GstD3D11BufferPool *pool;
|
||||
GstD3D11Allocator *alloc;
|
||||
|
||||
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), 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->priv->allocator = alloc;
|
||||
pool->device = gst_object_ref (device);
|
||||
|
||||
return GST_BUFFER_POOL_CAST (pool);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ struct _GstD3D11BufferPool
|
|||
{
|
||||
GstBufferPool parent;
|
||||
|
||||
GstD3D11Device *device;
|
||||
|
||||
/* re-calculated buffer size based on d3d11 pitch and stride */
|
||||
guint buffer_size;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "gstd3d11utils.h"
|
||||
#include "gstd3d11format.h"
|
||||
#include "gstd3d11_private.h"
|
||||
#include "gstd3d11memory.h"
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -165,7 +166,10 @@ gst_d3d11_device_enable_d3d11_debug (void)
|
|||
g_once_init_leave (&_init, 1);
|
||||
}
|
||||
|
||||
return ! !d3d11_debug_module;
|
||||
if (d3d11_debug_module)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline GstDebugLevel
|
||||
|
@ -257,7 +261,8 @@ gst_d3d11_device_enable_dxgi_debug (void)
|
|||
if (dxgi_debug_module)
|
||||
g_module_symbol (dxgi_debug_module,
|
||||
"DXGIGetDebugInterface", (gpointer *) & GstDXGIGetDebugInterface);
|
||||
ret = ! !GstDXGIGetDebugInterface;
|
||||
if (GstDXGIGetDebugInterface)
|
||||
ret = TRUE;
|
||||
#elif (GST_D3D11_DXGI_HEADER_VERSION >= 3)
|
||||
ret = TRUE;
|
||||
#endif
|
||||
|
@ -402,6 +407,8 @@ gst_d3d11_device_class_init (GstD3D11DeviceClass * klass)
|
|||
g_param_spec_int64 ("adapter-luid", "Adapter LUID",
|
||||
"DXGI Adapter LUID (Locally Unique Identifier) of created device",
|
||||
0, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_d3d11_memory_init_once ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,14 +30,35 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
#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_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_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_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:
|
||||
*
|
||||
|
@ -100,11 +121,30 @@ struct _GstD3D11AllocationParams
|
|||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
GST_D3D11_API
|
||||
GType gst_d3d11_allocation_params_get_type (void);
|
||||
|
||||
GST_D3D11_API
|
||||
GstD3D11AllocationParams * gst_d3d11_allocation_params_new (GstD3D11Device * device,
|
||||
GstVideoInfo * info,
|
||||
GstD3D11AllocationFlags flags,
|
||||
guint bind_flags);
|
||||
|
||||
GST_D3D11_API
|
||||
GstD3D11AllocationParams * gst_d3d11_allocation_params_copy (GstD3D11AllocationParams * src);
|
||||
|
||||
GST_D3D11_API
|
||||
void gst_d3d11_allocation_params_free (GstD3D11AllocationParams * params);
|
||||
|
||||
GST_D3D11_API
|
||||
gboolean gst_d3d11_allocation_params_alignment (GstD3D11AllocationParams * parms,
|
||||
GstVideoAlignment * align);
|
||||
|
||||
struct _GstD3D11Memory
|
||||
{
|
||||
GstMemory mem;
|
||||
|
||||
/*< public > */
|
||||
/*< public >*/
|
||||
GstD3D11Device *device;
|
||||
|
||||
/*< private >*/
|
||||
|
@ -112,76 +152,26 @@ struct _GstD3D11Memory
|
|||
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
|
||||
GType gst_d3d11_memory_get_type (void);
|
||||
|
||||
GST_D3D11_API
|
||||
GType gst_d3d11_allocation_params_get_type (void);
|
||||
void gst_d3d11_memory_init_once (void);
|
||||
|
||||
GST_D3D11_API
|
||||
GstD3D11AllocationParams * gst_d3d11_allocation_params_new (GstD3D11Device * device,
|
||||
GstVideoInfo * info,
|
||||
GstD3D11AllocationFlags flags,
|
||||
guint bind_flags);
|
||||
gboolean gst_is_d3d11_memory (GstMemory * mem);
|
||||
|
||||
GST_D3D11_API
|
||||
GstD3D11AllocationParams * gst_d3d11_allocation_params_copy (GstD3D11AllocationParams * src);
|
||||
|
||||
GST_D3D11_API
|
||||
void gst_d3d11_allocation_params_free (GstD3D11AllocationParams * params);
|
||||
|
||||
GST_D3D11_API
|
||||
gboolean gst_d3d11_allocation_params_alignment (GstD3D11AllocationParams * parms,
|
||||
GstVideoAlignment * align);
|
||||
|
||||
GST_D3D11_API
|
||||
GType gst_d3d11_allocator_get_type (void);
|
||||
|
||||
GST_D3D11_API
|
||||
GstD3D11Allocator * gst_d3d11_allocator_new (GstD3D11Device *device);
|
||||
|
||||
GST_D3D11_API
|
||||
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
|
||||
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
|
||||
gboolean gst_is_d3d11_memory (GstMemory * mem);
|
||||
|
||||
GST_D3D11_API
|
||||
ID3D11Texture2D * gst_d3d11_memory_get_texture_handle (GstD3D11Memory * mem);
|
||||
ID3D11Texture2D * gst_d3d11_memory_get_texture_handle (GstD3D11Memory * mem);
|
||||
|
||||
GST_D3D11_API
|
||||
gboolean gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem,
|
||||
D3D11_TEXTURE2D_DESC * desc);
|
||||
|
||||
GST_D3D11_API
|
||||
gboolean gst_d3d11_memory_get_texture_stride (GstD3D11Memory * mem,
|
||||
guint * stride);
|
||||
|
||||
GST_D3D11_API
|
||||
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,
|
||||
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
|
||||
|
||||
#endif /* __GST_D3D11_MEMORY_H__ */
|
||||
|
|
|
@ -1531,7 +1531,10 @@ gst_d3d11_compositor_release_pad (GstElement * element, GstPad * pad)
|
|||
GST_OBJECT_NAME (pad));
|
||||
|
||||
gst_clear_buffer (&cpad->fallback_buf);
|
||||
gst_clear_object (&cpad->fallback_pool);
|
||||
if (cpad->fallback_pool) {
|
||||
gst_buffer_pool_set_active (cpad->fallback_pool, FALSE);
|
||||
gst_clear_object (&cpad->fallback_pool);
|
||||
}
|
||||
g_clear_pointer (&cpad->convert, gst_d3d11_converter_free);
|
||||
GST_D3D11_CLEAR_COM (cpad->blend);
|
||||
|
||||
|
|
|
@ -270,7 +270,10 @@ gst_d3d11_decoder_get_property (GObject * object, guint prop_id,
|
|||
static void
|
||||
gst_d3d11_decoder_clear_resource (GstD3D11Decoder * self)
|
||||
{
|
||||
gst_clear_object (&self->internal_pool);
|
||||
if (self->internal_pool) {
|
||||
gst_buffer_pool_set_active (self->internal_pool, FALSE);
|
||||
gst_clear_object (&self->internal_pool);
|
||||
}
|
||||
|
||||
GST_D3D11_CLEAR_COM (self->decoder_handle);
|
||||
GST_D3D11_CLEAR_COM (self->staging);
|
||||
|
@ -381,7 +384,10 @@ gst_d3d11_decoder_prepare_output_view_pool (GstD3D11Decoder * self)
|
|||
GstVideoInfo *info = &self->info;
|
||||
guint pool_size;
|
||||
|
||||
gst_clear_object (&self->internal_pool);
|
||||
if (self->internal_pool) {
|
||||
gst_buffer_pool_set_active (self->internal_pool, FALSE);
|
||||
gst_clear_object (&self->internal_pool);
|
||||
}
|
||||
|
||||
if (!self->use_array_of_texture) {
|
||||
alloc_flags = GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY;
|
||||
|
|
|
@ -571,78 +571,20 @@ gst_d3d11_find_swap_chain_color_space (GstVideoInfo * info,
|
|||
}
|
||||
#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)
|
||||
static void
|
||||
fill_staging_desc (const D3D11_TEXTURE2D_DESC * ref,
|
||||
D3D11_TEXTURE2D_DESC * staging)
|
||||
{
|
||||
GstBuffer *buffer;
|
||||
guint i;
|
||||
gint stride[GST_VIDEO_MAX_PLANES] = { 0, };
|
||||
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
|
||||
GstMemory *mem;
|
||||
memset (staging, 0, sizeof (D3D11_TEXTURE2D_DESC));
|
||||
|
||||
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],
|
||||
(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;
|
||||
staging->Width = ref->Width;
|
||||
staging->Height = ref->Height;
|
||||
staging->MipLevels = 1;
|
||||
staging->Format = ref->Format;
|
||||
staging->SampleDesc.Count = 1;
|
||||
staging->ArraySize = 1;
|
||||
staging->Usage = D3D11_USAGE_STAGING;
|
||||
staging->CPUAccessFlags = (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE);
|
||||
}
|
||||
|
||||
GstBuffer *
|
||||
|
@ -651,11 +593,14 @@ gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
|
|||
{
|
||||
GstD3D11Memory *dmem;
|
||||
GstD3D11Device *device;
|
||||
GstD3D11AllocationParams *params = NULL;
|
||||
GstD3D11Allocator *alloc = 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;
|
||||
gsize size = 0;
|
||||
const GstD3D11Format *format;
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
|
||||
for (i = 0; i < gst_buffer_n_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);
|
||||
device = dmem->device;
|
||||
|
||||
params = gst_d3d11_allocation_params_new (device, (GstVideoInfo *) info,
|
||||
(GstD3D11AllocationFlags) 0, 0);
|
||||
|
||||
if (!params) {
|
||||
GST_WARNING ("Couldn't create alloc params");
|
||||
goto done;
|
||||
format = gst_d3d11_device_format_from_gst (device,
|
||||
GST_VIDEO_INFO_FORMAT (info));
|
||||
if (!format) {
|
||||
GST_ERROR ("Unknown d3d11 format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
desc = ¶ms->desc[0];
|
||||
/* 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);
|
||||
alloc = (GstD3D11Allocator *) gst_allocator_find (GST_D3D11_MEMORY_NAME);
|
||||
if (!alloc) {
|
||||
GST_WARNING ("Couldn't create allocator");
|
||||
goto done;
|
||||
GST_ERROR ("D3D11 allocator is not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
staging_buffer = gst_d3d11_allocate_staging_buffer (alloc,
|
||||
info, params->d3d11_format, params->desc, add_videometa);
|
||||
staging_buffer = gst_buffer_new ();
|
||||
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)
|
||||
GST_WARNING ("Couldn't allocate staging buffer");
|
||||
guint cur_stride = 0;
|
||||
|
||||
done:
|
||||
if (params)
|
||||
gst_d3d11_allocation_params_free (params);
|
||||
gst_d3d11_memory_get_texture_desc (mem, &desc);
|
||||
fill_staging_desc (&desc, &staging_desc);
|
||||
|
||||
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)
|
||||
gst_object_unref (alloc);
|
||||
|
||||
return staging_buffer;
|
||||
|
||||
error:
|
||||
gst_clear_buffer (&staging_buffer);
|
||||
gst_clear_object (&alloc);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -77,12 +77,6 @@ const GstDxgiColorSpace * gst_d3d11_find_swap_chain_color_space (GstVideoInfo *
|
|||
gboolean use_hdr10);
|
||||
#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,
|
||||
const GstVideoInfo * info,
|
||||
gboolean add_videometa);
|
||||
|
|
Loading…
Reference in a new issue