d3d11screencapturesrc: Use staging buffer pool for performance

By using staging pool/buffer, we can avoid per frame
staging texture -> system memory copy.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1756>
This commit is contained in:
Seungha Yang 2022-02-20 23:59:46 +09:00 committed by GStreamer Marge Bot
parent 3d2eb5a04c
commit 8ff5f10a40

View file

@ -383,6 +383,7 @@ gst_d3d11_screen_capture_src_decide_allocation (GstBaseSrc * bsrc,
guint min, max, size; guint min, max, size;
gboolean update_pool; gboolean update_pool;
GstVideoInfo vinfo; GstVideoInfo vinfo;
gboolean has_videometa;
if (self->pool) { if (self->pool) {
gst_buffer_pool_set_active (self->pool, FALSE); gst_buffer_pool_set_active (self->pool, FALSE);
@ -391,6 +392,9 @@ gst_d3d11_screen_capture_src_decide_allocation (GstBaseSrc * bsrc,
gst_query_parse_allocation (query, &caps, NULL); gst_query_parse_allocation (query, &caps, NULL);
has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, nullptr);
if (!caps) { if (!caps) {
GST_ERROR_OBJECT (self, "No output caps"); GST_ERROR_OBJECT (self, "No output caps");
return FALSE; return FALSE;
@ -408,19 +412,26 @@ gst_d3d11_screen_capture_src_decide_allocation (GstBaseSrc * bsrc,
update_pool = FALSE; update_pool = FALSE;
} }
if (pool && self->downstream_supports_d3d11) { if (pool) {
if (!GST_IS_D3D11_BUFFER_POOL (pool)) { if (self->downstream_supports_d3d11) {
gst_clear_object (&pool); if (!GST_IS_D3D11_BUFFER_POOL (pool)) {
} else {
GstD3D11BufferPool *dpool = GST_D3D11_BUFFER_POOL (pool);
if (dpool->device != self->device)
gst_clear_object (&pool); gst_clear_object (&pool);
} else {
GstD3D11BufferPool *dpool = GST_D3D11_BUFFER_POOL (pool);
if (dpool->device != self->device)
gst_clear_object (&pool);
}
} else if (has_videometa) {
/* We will use staging buffer pool for better performance */
gst_clear_object (&pool);
} }
} }
if (!pool) { if (!pool) {
if (self->downstream_supports_d3d11) if (self->downstream_supports_d3d11)
pool = gst_d3d11_buffer_pool_new (self->device); pool = gst_d3d11_buffer_pool_new (self->device);
else if (has_videometa)
pool = gst_d3d11_staging_buffer_pool_new (self->device);
else else
pool = gst_video_buffer_pool_new (); pool = gst_video_buffer_pool_new ();
} }
@ -449,14 +460,14 @@ gst_d3d11_screen_capture_src_decide_allocation (GstBaseSrc * bsrc,
goto error; goto error;
} }
if (self->downstream_supports_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,
gst_buffer_pool_config_get_params (config, nullptr, &size, nullptr, nullptr);
nullptr, &size, nullptr, nullptr); gst_structure_free (config);
gst_structure_free (config);
} else { if (!self->downstream_supports_d3d11) {
self->pool = gst_d3d11_buffer_pool_new (self->device); self->pool = gst_d3d11_buffer_pool_new (self->device);
config = gst_buffer_pool_get_config (self->pool); config = gst_buffer_pool_get_config (self->pool);
@ -842,9 +853,6 @@ again:
} }
if (!self->downstream_supports_d3d11) { if (!self->downstream_supports_d3d11) {
GstVideoFrame src_frame, dst_frame;
gboolean copy_ret;
ret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc, ret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc,
offset, size, &sysmem_buf); offset, size, &sysmem_buf);
if (ret != GST_FLOW_OK) { if (ret != GST_FLOW_OK) {
@ -852,24 +860,7 @@ again:
goto out; goto out;
} }
if (!gst_video_frame_map (&src_frame, &self->video_info, buffer, if (!gst_d3d11_buffer_copy_into (sysmem_buf, buffer, &self->video_info)) {
GST_MAP_READ)) {
GST_ERROR_OBJECT (self, "Failed to map d3d11 buffer");
goto error;
}
if (!gst_video_frame_map (&dst_frame, &self->video_info, sysmem_buf,
GST_MAP_WRITE)) {
GST_ERROR_OBJECT (self, "Failed to map sysmem buffer");
gst_video_frame_unmap (&src_frame);
goto error;
}
copy_ret = gst_video_frame_copy (&dst_frame, &src_frame);
gst_video_frame_unmap (&dst_frame);
gst_video_frame_unmap (&src_frame);
if (!copy_ret) {
GST_ERROR_OBJECT (self, "Failed to copy frame"); GST_ERROR_OBJECT (self, "Failed to copy frame");
goto error; goto error;
} }