mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-10 08:22:32 +00:00
d3d11upload,d3d11download: Use staging buffer pool
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1643>
This commit is contained in:
parent
b22aa14e43
commit
9518f15309
2 changed files with 45 additions and 322 deletions
|
@ -77,18 +77,12 @@ static GstStaticCaps src_template_caps =
|
||||||
struct _GstD3D11Download
|
struct _GstD3D11Download
|
||||||
{
|
{
|
||||||
GstD3D11BaseFilter parent;
|
GstD3D11BaseFilter parent;
|
||||||
|
|
||||||
GstBuffer *staging_buffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_d3d11_download_parent_class parent_class
|
#define gst_d3d11_download_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstD3D11Download, gst_d3d11_download,
|
G_DEFINE_TYPE (GstD3D11Download, gst_d3d11_download,
|
||||||
GST_TYPE_D3D11_BASE_FILTER);
|
GST_TYPE_D3D11_BASE_FILTER);
|
||||||
|
|
||||||
static void gst_d3d11_download_dispose (GObject * object);
|
|
||||||
static gboolean gst_d3d11_download_stop (GstBaseTransform * trans);
|
|
||||||
static gboolean gst_d3d11_download_sink_event (GstBaseTransform * trans,
|
|
||||||
GstEvent * event);
|
|
||||||
static GstCaps *gst_d3d11_download_transform_caps (GstBaseTransform * trans,
|
static GstCaps *gst_d3d11_download_transform_caps (GstBaseTransform * trans,
|
||||||
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
|
||||||
static gboolean gst_d3d11_download_propose_allocation (GstBaseTransform * trans,
|
static gboolean gst_d3d11_download_propose_allocation (GstBaseTransform * trans,
|
||||||
|
@ -97,21 +91,14 @@ static gboolean gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
static GstFlowReturn gst_d3d11_download_transform (GstBaseTransform * trans,
|
static GstFlowReturn gst_d3d11_download_transform (GstBaseTransform * trans,
|
||||||
GstBuffer * inbuf, GstBuffer * outbuf);
|
GstBuffer * inbuf, GstBuffer * outbuf);
|
||||||
static gboolean gst_d3d11_download_set_info (GstD3D11BaseFilter * filter,
|
|
||||||
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
|
|
||||||
GstVideoInfo * out_info);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
|
gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
|
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
|
||||||
GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass);
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
gobject_class->dispose = gst_d3d11_download_dispose;
|
|
||||||
|
|
||||||
caps = gst_d3d11_get_updated_template_caps (&sink_template_caps);
|
caps = gst_d3d11_get_updated_template_caps (&sink_template_caps);
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
|
||||||
|
@ -129,8 +116,6 @@ gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
|
||||||
|
|
||||||
trans_class->passthrough_on_same_caps = TRUE;
|
trans_class->passthrough_on_same_caps = TRUE;
|
||||||
|
|
||||||
trans_class->stop = GST_DEBUG_FUNCPTR (gst_d3d11_download_stop);
|
|
||||||
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_download_sink_event);
|
|
||||||
trans_class->transform_caps =
|
trans_class->transform_caps =
|
||||||
GST_DEBUG_FUNCPTR (gst_d3d11_download_transform_caps);
|
GST_DEBUG_FUNCPTR (gst_d3d11_download_transform_caps);
|
||||||
trans_class->propose_allocation =
|
trans_class->propose_allocation =
|
||||||
|
@ -139,8 +124,6 @@ gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
|
||||||
GST_DEBUG_FUNCPTR (gst_d3d11_download_decide_allocation);
|
GST_DEBUG_FUNCPTR (gst_d3d11_download_decide_allocation);
|
||||||
trans_class->transform = GST_DEBUG_FUNCPTR (gst_d3d11_download_transform);
|
trans_class->transform = GST_DEBUG_FUNCPTR (gst_d3d11_download_transform);
|
||||||
|
|
||||||
bfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_d3d11_download_set_info);
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_d3d11_download_debug,
|
GST_DEBUG_CATEGORY_INIT (gst_d3d11_download_debug,
|
||||||
"d3d11download", 0, "d3d11download Element");
|
"d3d11download", 0, "d3d11download Element");
|
||||||
}
|
}
|
||||||
|
@ -150,43 +133,6 @@ gst_d3d11_download_init (GstD3D11Download * download)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_d3d11_download_dispose (GObject * object)
|
|
||||||
{
|
|
||||||
GstD3D11Download *self = GST_D3D11_DOWNLOAD (object);
|
|
||||||
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_download_stop (GstBaseTransform * trans)
|
|
||||||
{
|
|
||||||
GstD3D11Download *self = GST_D3D11_DOWNLOAD (trans);
|
|
||||||
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
|
|
||||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_download_sink_event (GstBaseTransform * trans, GstEvent * event)
|
|
||||||
{
|
|
||||||
GstD3D11Download *self = GST_D3D11_DOWNLOAD (trans);
|
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
|
||||||
case GST_EVENT_EOS:
|
|
||||||
/* We don't need to hold this staging buffer after eos */
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_set_caps_features (const GstCaps * caps, const gchar * feature_name)
|
_set_caps_features (const GstCaps * caps, const gchar * feature_name)
|
||||||
{
|
{
|
||||||
|
@ -263,7 +209,6 @@ gst_d3d11_download_propose_allocation (GstBaseTransform * trans,
|
||||||
if (gst_query_get_n_allocation_pools (query) == 0) {
|
if (gst_query_get_n_allocation_pools (query) == 0) {
|
||||||
GstCapsFeatures *features;
|
GstCapsFeatures *features;
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
gboolean is_d3d11 = FALSE;
|
|
||||||
|
|
||||||
features = gst_caps_get_features (caps, 0);
|
features = gst_caps_get_features (caps, 0);
|
||||||
|
|
||||||
|
@ -271,9 +216,8 @@ gst_d3d11_download_propose_allocation (GstBaseTransform * trans,
|
||||||
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
||||||
GST_DEBUG_OBJECT (filter, "upstream support d3d11 memory");
|
GST_DEBUG_OBJECT (filter, "upstream support d3d11 memory");
|
||||||
pool = gst_d3d11_buffer_pool_new (filter->device);
|
pool = gst_d3d11_buffer_pool_new (filter->device);
|
||||||
is_d3d11 = TRUE;
|
|
||||||
} else {
|
} else {
|
||||||
pool = gst_video_buffer_pool_new ();
|
pool = gst_d3d11_staging_buffer_pool_new (filter->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
@ -281,34 +225,27 @@ gst_d3d11_download_propose_allocation (GstBaseTransform * trans,
|
||||||
gst_buffer_pool_config_add_option (config,
|
gst_buffer_pool_config_add_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
|
||||||
/* d3d11 pool does not support video alignment */
|
|
||||||
if (!is_d3d11) {
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = GST_VIDEO_INFO_SIZE (&info);
|
size = GST_VIDEO_INFO_SIZE (&info);
|
||||||
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
||||||
|
|
||||||
if (!gst_buffer_pool_set_config (pool, config))
|
if (!gst_buffer_pool_set_config (pool, config))
|
||||||
goto config_failed;
|
goto config_failed;
|
||||||
|
|
||||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
|
||||||
|
|
||||||
if (is_d3d11) {
|
|
||||||
/* d3d11 buffer pool will update buffer size based on allocated texture,
|
/* d3d11 buffer pool will update buffer size based on allocated texture,
|
||||||
* get size from config again */
|
* get size from config again */
|
||||||
config = gst_buffer_pool_get_config (pool);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
gst_buffer_pool_config_get_params (config, nullptr, &size, nullptr,
|
gst_buffer_pool_config_get_params (config,
|
||||||
nullptr);
|
nullptr, &size, nullptr, nullptr);
|
||||||
gst_structure_free (config);
|
gst_structure_free (config);
|
||||||
}
|
|
||||||
|
|
||||||
gst_query_add_allocation_pool (query, pool, size, 0, 0);
|
gst_query_add_allocation_pool (query, pool, size, 0, 0);
|
||||||
|
|
||||||
gst_object_unref (pool);
|
gst_object_unref (pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||||
|
gst_query_add_allocation_meta (query,
|
||||||
|
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -324,10 +261,12 @@ static gboolean
|
||||||
gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
|
gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
|
||||||
GstQuery * query)
|
GstQuery * query)
|
||||||
{
|
{
|
||||||
|
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
|
||||||
GstBufferPool *pool = NULL;
|
GstBufferPool *pool = NULL;
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
guint min, max, size;
|
guint min, max, size;
|
||||||
gboolean update_pool;
|
gboolean update_pool;
|
||||||
|
gboolean has_videometa;
|
||||||
GstCaps *outcaps = NULL;
|
GstCaps *outcaps = NULL;
|
||||||
|
|
||||||
if (gst_query_get_n_allocation_pools (query) > 0) {
|
if (gst_query_get_n_allocation_pools (query) > 0) {
|
||||||
|
@ -347,15 +286,30 @@ gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
|
||||||
update_pool = FALSE;
|
update_pool = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pool)
|
if (!outcaps)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
has_videometa = gst_query_find_allocation_meta (query,
|
||||||
|
GST_VIDEO_META_API_TYPE, nullptr);
|
||||||
|
|
||||||
|
if (!pool) {
|
||||||
|
if (has_videometa)
|
||||||
|
pool = gst_d3d11_staging_buffer_pool_new (filter->device);
|
||||||
|
else
|
||||||
pool = gst_video_buffer_pool_new ();
|
pool = gst_video_buffer_pool_new ();
|
||||||
|
}
|
||||||
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
if (outcaps)
|
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
|
||||||
gst_buffer_pool_config_set_params (config, outcaps, size, 0, 0);
|
|
||||||
gst_buffer_pool_set_config (pool, config);
|
gst_buffer_pool_set_config (pool, config);
|
||||||
|
|
||||||
|
/* d3d11 buffer pool will update buffer size based on allocated texture,
|
||||||
|
* get size from config again */
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
gst_buffer_pool_config_get_params (config, nullptr, &size, nullptr, nullptr);
|
||||||
|
gst_structure_free (config);
|
||||||
|
|
||||||
if (update_pool)
|
if (update_pool)
|
||||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||||
else
|
else
|
||||||
|
@ -367,99 +321,16 @@ gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
|
||||||
query);
|
query);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_download_can_use_staging_buffer (GstD3D11Download * self,
|
|
||||||
GstBuffer * inbuf)
|
|
||||||
{
|
|
||||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
|
|
||||||
ID3D11Device *device_handle =
|
|
||||||
gst_d3d11_device_get_device_handle (filter->device);
|
|
||||||
|
|
||||||
if (!gst_d3d11_buffer_can_access_device (inbuf, device_handle))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (self->staging_buffer)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
self->staging_buffer = gst_d3d11_allocate_staging_buffer_for (inbuf,
|
|
||||||
&filter->in_info, TRUE);
|
|
||||||
|
|
||||||
if (!self->staging_buffer) {
|
|
||||||
GST_WARNING_OBJECT (self, "Couldn't allocate staging buffer");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
||||||
GstBuffer * outbuf)
|
GstBuffer * outbuf)
|
||||||
{
|
{
|
||||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
|
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
|
||||||
GstD3D11Download *self = GST_D3D11_DOWNLOAD (trans);
|
|
||||||
GstVideoFrame in_frame, out_frame;
|
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
|
||||||
gboolean use_staging_buf;
|
|
||||||
GstBuffer *target_inbuf = inbuf;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
use_staging_buf = gst_d3d11_download_can_use_staging_buffer (self, inbuf);
|
if (!gst_d3d11_buffer_copy_into (outbuf, inbuf, &filter->in_info)) {
|
||||||
|
GST_ERROR_OBJECT (filter, "Failed to copy buffer");
|
||||||
if (use_staging_buf) {
|
|
||||||
GST_TRACE_OBJECT (self, "Copy input buffer to staging buffer");
|
|
||||||
|
|
||||||
/* Copy d3d11 texture to staging texture */
|
|
||||||
if (!gst_d3d11_buffer_copy_into (self->staging_buffer,
|
|
||||||
inbuf, &filter->in_info)) {
|
|
||||||
GST_ERROR_OBJECT (self,
|
|
||||||
"Failed to copy input buffer into staging texture");
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_inbuf = self->staging_buffer;
|
return GST_FLOW_OK;
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&in_frame, &filter->in_info, target_inbuf,
|
|
||||||
(GstMapFlags) (GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)))
|
|
||||||
goto invalid_buffer;
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
|
|
||||||
(GstMapFlags) (GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))) {
|
|
||||||
gst_video_frame_unmap (&in_frame);
|
|
||||||
goto invalid_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&in_frame); i++) {
|
|
||||||
if (!gst_video_frame_copy_plane (&out_frame, &in_frame, i)) {
|
|
||||||
GST_ERROR_OBJECT (filter, "Couldn't copy %dth plane", i);
|
|
||||||
ret = GST_FLOW_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_video_frame_unmap (&out_frame);
|
|
||||||
gst_video_frame_unmap (&in_frame);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
invalid_buffer:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_WARNING (filter, CORE, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("invalid video buffer received"));
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_download_set_info (GstD3D11BaseFilter * filter,
|
|
||||||
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
|
|
||||||
GstVideoInfo * out_info)
|
|
||||||
{
|
|
||||||
GstD3D11Download *self = GST_D3D11_DOWNLOAD (filter);
|
|
||||||
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,17 +73,11 @@ static GstStaticCaps src_template_caps =
|
||||||
struct _GstD3D11Upload
|
struct _GstD3D11Upload
|
||||||
{
|
{
|
||||||
GstD3D11BaseFilter parent;
|
GstD3D11BaseFilter parent;
|
||||||
|
|
||||||
GstBuffer *staging_buffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_d3d11_upload_parent_class parent_class
|
#define gst_d3d11_upload_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstD3D11Upload, gst_d3d11_upload, GST_TYPE_D3D11_BASE_FILTER);
|
G_DEFINE_TYPE (GstD3D11Upload, gst_d3d11_upload, GST_TYPE_D3D11_BASE_FILTER);
|
||||||
|
|
||||||
static void gst_d3d11_upload_dispose (GObject * object);
|
|
||||||
static gboolean gst_d3d11_upload_stop (GstBaseTransform * trans);
|
|
||||||
static gboolean gst_d3d11_upload_sink_event (GstBaseTransform * trans,
|
|
||||||
GstEvent * event);
|
|
||||||
static GstCaps *gst_d3d11_upload_transform_caps (GstBaseTransform * trans,
|
static GstCaps *gst_d3d11_upload_transform_caps (GstBaseTransform * trans,
|
||||||
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
|
||||||
static gboolean gst_d3d11_upload_propose_allocation (GstBaseTransform * trans,
|
static gboolean gst_d3d11_upload_propose_allocation (GstBaseTransform * trans,
|
||||||
|
@ -92,21 +86,14 @@ static gboolean gst_d3d11_upload_decide_allocation (GstBaseTransform * trans,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
static GstFlowReturn gst_d3d11_upload_transform (GstBaseTransform * trans,
|
static GstFlowReturn gst_d3d11_upload_transform (GstBaseTransform * trans,
|
||||||
GstBuffer * inbuf, GstBuffer * outbuf);
|
GstBuffer * inbuf, GstBuffer * outbuf);
|
||||||
static gboolean gst_d3d11_upload_set_info (GstD3D11BaseFilter * filter,
|
|
||||||
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
|
|
||||||
GstVideoInfo * out_info);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
|
gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
|
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
|
||||||
GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass);
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
gobject_class->dispose = gst_d3d11_upload_dispose;
|
|
||||||
|
|
||||||
caps = gst_d3d11_get_updated_template_caps (&sink_template_caps);
|
caps = gst_d3d11_get_updated_template_caps (&sink_template_caps);
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
|
||||||
|
@ -124,8 +111,6 @@ gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
|
||||||
|
|
||||||
trans_class->passthrough_on_same_caps = TRUE;
|
trans_class->passthrough_on_same_caps = TRUE;
|
||||||
|
|
||||||
trans_class->stop = GST_DEBUG_FUNCPTR (gst_d3d11_upload_stop);
|
|
||||||
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_upload_sink_event);
|
|
||||||
trans_class->transform_caps =
|
trans_class->transform_caps =
|
||||||
GST_DEBUG_FUNCPTR (gst_d3d11_upload_transform_caps);
|
GST_DEBUG_FUNCPTR (gst_d3d11_upload_transform_caps);
|
||||||
trans_class->propose_allocation =
|
trans_class->propose_allocation =
|
||||||
|
@ -134,8 +119,6 @@ gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
|
||||||
GST_DEBUG_FUNCPTR (gst_d3d11_upload_decide_allocation);
|
GST_DEBUG_FUNCPTR (gst_d3d11_upload_decide_allocation);
|
||||||
trans_class->transform = GST_DEBUG_FUNCPTR (gst_d3d11_upload_transform);
|
trans_class->transform = GST_DEBUG_FUNCPTR (gst_d3d11_upload_transform);
|
||||||
|
|
||||||
bfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_d3d11_upload_set_info);
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_d3d11_upload_debug,
|
GST_DEBUG_CATEGORY_INIT (gst_d3d11_upload_debug,
|
||||||
"d3d11upload", 0, "d3d11upload Element");
|
"d3d11upload", 0, "d3d11upload Element");
|
||||||
}
|
}
|
||||||
|
@ -145,43 +128,6 @@ gst_d3d11_upload_init (GstD3D11Upload * upload)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_d3d11_upload_dispose (GObject * object)
|
|
||||||
{
|
|
||||||
GstD3D11Upload *self = GST_D3D11_UPLOAD (object);
|
|
||||||
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_upload_stop (GstBaseTransform * trans)
|
|
||||||
{
|
|
||||||
GstD3D11Upload *self = GST_D3D11_UPLOAD (trans);
|
|
||||||
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
|
|
||||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_upload_sink_event (GstBaseTransform * trans, GstEvent * event)
|
|
||||||
{
|
|
||||||
GstD3D11Upload *self = GST_D3D11_UPLOAD (trans);
|
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
|
||||||
case GST_EVENT_EOS:
|
|
||||||
/* We don't need to hold this staging buffer after eos */
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
_set_caps_features (const GstCaps * caps, const gchar * feature_name)
|
_set_caps_features (const GstCaps * caps, const gchar * feature_name)
|
||||||
{
|
{
|
||||||
|
@ -296,17 +242,14 @@ gst_d3d11_upload_propose_allocation (GstBaseTransform * trans,
|
||||||
if (gst_query_get_n_allocation_pools (query) == 0) {
|
if (gst_query_get_n_allocation_pools (query) == 0) {
|
||||||
GstCapsFeatures *features;
|
GstCapsFeatures *features;
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
gboolean is_d3d11 = FALSE;
|
|
||||||
|
|
||||||
features = gst_caps_get_features (caps, 0);
|
features = gst_caps_get_features (caps, 0);
|
||||||
|
|
||||||
if (features && gst_caps_features_contains (features,
|
if (features && gst_caps_features_contains (features,
|
||||||
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) {
|
||||||
GST_DEBUG_OBJECT (filter, "upstream support d3d11 memory");
|
GST_DEBUG_OBJECT (filter, "upstream support d3d11 memory");
|
||||||
pool = gst_d3d11_buffer_pool_new (filter->device);
|
pool = gst_d3d11_buffer_pool_new (filter->device);
|
||||||
is_d3d11 = TRUE;
|
|
||||||
} else {
|
} else {
|
||||||
pool = gst_video_buffer_pool_new ();
|
pool = gst_d3d11_staging_buffer_pool_new (filter->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
@ -314,12 +257,6 @@ gst_d3d11_upload_propose_allocation (GstBaseTransform * trans,
|
||||||
gst_buffer_pool_config_add_option (config,
|
gst_buffer_pool_config_add_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
|
||||||
/* d3d11 pool does not support video alignment */
|
|
||||||
if (!is_d3d11) {
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = GST_VIDEO_INFO_SIZE (&info);
|
size = GST_VIDEO_INFO_SIZE (&info);
|
||||||
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
||||||
|
|
||||||
|
@ -328,12 +265,10 @@ gst_d3d11_upload_propose_allocation (GstBaseTransform * trans,
|
||||||
|
|
||||||
/* d3d11 buffer pool will update buffer size based on allocated texture,
|
/* d3d11 buffer pool will update buffer size based on allocated texture,
|
||||||
* get size from config again */
|
* get size from config again */
|
||||||
if (is_d3d11) {
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
gst_buffer_pool_config_get_params (config,
|
gst_buffer_pool_config_get_params (config,
|
||||||
nullptr, &size, nullptr, nullptr);
|
nullptr, &size, nullptr, nullptr);
|
||||||
gst_structure_free (config);
|
gst_structure_free (config);
|
||||||
}
|
|
||||||
|
|
||||||
gst_query_add_allocation_pool (query, pool, size, 0, 0);
|
gst_query_add_allocation_pool (query, pool, size, 0, 0);
|
||||||
gst_object_unref (pool);
|
gst_object_unref (pool);
|
||||||
|
@ -468,99 +403,16 @@ gst_d3d11_upload_decide_allocation (GstBaseTransform * trans, GstQuery * query)
|
||||||
query);
|
query);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_upload_can_use_staging_buffer (GstD3D11Upload * self,
|
|
||||||
GstBuffer * outbuf)
|
|
||||||
{
|
|
||||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
|
|
||||||
ID3D11Device *device_handle =
|
|
||||||
gst_d3d11_device_get_device_handle (filter->device);
|
|
||||||
|
|
||||||
if (!gst_d3d11_buffer_can_access_device (outbuf, device_handle))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (self->staging_buffer)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
self->staging_buffer = gst_d3d11_allocate_staging_buffer_for (outbuf,
|
|
||||||
&filter->out_info, TRUE);
|
|
||||||
|
|
||||||
if (!self->staging_buffer) {
|
|
||||||
GST_WARNING_OBJECT (self, "Couldn't allocate staging buffer");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_d3d11_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
gst_d3d11_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
||||||
GstBuffer * outbuf)
|
GstBuffer * outbuf)
|
||||||
{
|
{
|
||||||
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
|
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
|
||||||
GstD3D11Upload *self = GST_D3D11_UPLOAD (trans);
|
|
||||||
GstVideoFrame in_frame, out_frame;
|
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
|
||||||
gboolean use_staging_buf;
|
|
||||||
GstBuffer *target_outbuf = outbuf;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
use_staging_buf = gst_d3d11_upload_can_use_staging_buffer (self, outbuf);
|
if (!gst_d3d11_buffer_copy_into (outbuf, inbuf, &filter->in_info)) {
|
||||||
|
GST_ERROR_OBJECT (filter, "Failed to copy buffer");
|
||||||
if (use_staging_buf) {
|
|
||||||
GST_TRACE_OBJECT (self, "Copy input buffer to staging buffer");
|
|
||||||
target_outbuf = self->staging_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&in_frame, &filter->in_info, inbuf,
|
|
||||||
(GstMapFlags) (GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)))
|
|
||||||
goto invalid_buffer;
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&out_frame, &filter->out_info, target_outbuf,
|
|
||||||
(GstMapFlags) (GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))) {
|
|
||||||
gst_video_frame_unmap (&in_frame);
|
|
||||||
goto invalid_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&in_frame); i++) {
|
|
||||||
if (!gst_video_frame_copy_plane (&out_frame, &in_frame, i)) {
|
|
||||||
GST_ERROR_OBJECT (filter, "Couldn't copy plane %d", i);
|
|
||||||
ret = GST_FLOW_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_video_frame_unmap (&out_frame);
|
|
||||||
gst_video_frame_unmap (&in_frame);
|
|
||||||
|
|
||||||
/* Copy staging texture to d3d11 texture */
|
|
||||||
if (use_staging_buf) {
|
|
||||||
if (!gst_d3d11_buffer_copy_into (outbuf,
|
|
||||||
self->staging_buffer, &filter->out_info)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Cannot copy staging texture into texture");
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
invalid_buffer:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_WARNING (filter, CORE, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("invalid video buffer received"));
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3d11_upload_set_info (GstD3D11BaseFilter * filter,
|
|
||||||
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
|
|
||||||
GstVideoInfo * out_info)
|
|
||||||
{
|
|
||||||
GstD3D11Upload *self = GST_D3D11_UPLOAD (filter);
|
|
||||||
|
|
||||||
gst_clear_buffer (&self->staging_buffer);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue