diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.cpp index 6dd1b7bb9a..3ad88aac4a 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.cpp @@ -534,6 +534,113 @@ gst_d3d12_create_user_token (void) return user_token.fetch_add (1); } +static gboolean +gst_d3d12_buffer_copy_into_fallback (GstBuffer * dst, GstBuffer * src, + const GstVideoInfo * info) +{ + GstVideoFrame in_frame, out_frame; + gboolean ret; + + if (!gst_video_frame_map (&in_frame, (GstVideoInfo *) info, src, + (GstMapFlags) (GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))) { + GST_ERROR ("Couldn't map src frame"); + return FALSE; + } + + if (!gst_video_frame_map (&out_frame, (GstVideoInfo *) info, dst, + (GstMapFlags) (GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))) { + GST_ERROR ("Couldn't map dst frame"); + gst_video_frame_unmap (&in_frame); + return FALSE; + } + + ret = gst_video_frame_copy (&out_frame, &in_frame); + + gst_video_frame_unmap (&in_frame); + gst_video_frame_unmap (&out_frame); + + return ret; +} + +static GstD3D12Device * +get_device_from_buffer (GstBuffer * buffer) +{ + GstD3D12Device *device = nullptr; + for (guint i = 0; i < gst_buffer_n_memory (buffer); i++) { + auto mem = gst_buffer_peek_memory (buffer, i); + if (!gst_is_d3d12_memory (mem)) + return nullptr; + + auto dmem = GST_D3D12_MEMORY_CAST (mem); + if (!device) + device = dmem->device; + else if (!gst_d3d12_device_is_equal (device, dmem->device)) + return nullptr; + } + + return device; +} + +/** + * gst_d3d12_buffer_copy_into: + * @dest: a #GstBuffer + * @src: a #GstBuffer + * @info: a #GstVideoInfo + * + * Copy @src data into @dest. This method executes only memory copy. + * Use gst_buffer_copy_into() method for metadata copy + * + * Since: 1.26 + */ +gboolean +gst_d3d12_buffer_copy_into (GstBuffer * dest, GstBuffer * src, + const GstVideoInfo * info) +{ + g_return_val_if_fail (GST_IS_BUFFER (dest), FALSE); + g_return_val_if_fail (GST_IS_BUFFER (src), FALSE); + g_return_val_if_fail (info, FALSE); + + auto num_mem = gst_buffer_n_memory (dest); + if (gst_buffer_n_memory (src) != num_mem) + return gst_d3d12_buffer_copy_into_fallback (dest, src, info); + + auto dest_device = get_device_from_buffer (dest); + auto src_device = get_device_from_buffer (src); + + if (!dest_device || !src_device || + !gst_d3d12_device_is_equal (dest_device, src_device)) { + return gst_d3d12_buffer_copy_into_fallback (dest, src, info); + } + + GstD3D12Frame src_frame, dest_frame; + if (!gst_d3d12_frame_map (&src_frame, info, src, GST_MAP_READ_D3D12, + GST_D3D12_FRAME_MAP_FLAG_NONE)) { + GST_ERROR ("Couldn't map src buffer"); + return FALSE; + } + + if (!gst_d3d12_frame_map (&dest_frame, info, dest, GST_MAP_WRITE_D3D12, + GST_D3D12_FRAME_MAP_FLAG_NONE)) { + GST_ERROR ("Couldn't map dest buffer"); + gst_d3d12_frame_unmap (&src_frame); + return FALSE; + } + + guint64 fence_val = 0; + auto ret = gst_d3d12_frame_copy (&dest_frame, &src_frame, &fence_val); + gst_d3d12_frame_unmap (&dest_frame); + gst_d3d12_frame_unmap (&src_frame); + + if (ret) { + for (guint i = 0; i < num_mem; i++) { + auto dmem = (GstD3D12Memory *) gst_buffer_peek_memory (dest, i); + dmem->fence_value = fence_val; + } + } + + return ret; +} + /** * _gst_d3d12_result: * @result: HRESULT D3D12 API return code diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.h index e1bc38c35c..aac185d172 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12utils.h @@ -60,6 +60,11 @@ GstContext * gst_d3d12_context_new (GstD3D12Device * device); GST_D3D12_API gint64 gst_d3d12_create_user_token (void); +GST_D3D12_API +gboolean gst_d3d12_buffer_copy_into (GstBuffer * dest, + GstBuffer * src, + const GstVideoInfo * info); + GST_D3D12_API gboolean _gst_d3d12_result (HRESULT hr, GstD3D12Device * device, diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.cpp index f6cfdfd8eb..b0ad739845 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.cpp @@ -143,147 +143,3 @@ gst_d3d12_need_transform (gfloat rotation_x, gfloat rotation_y, return FALSE; } - -static gboolean -gst_d3d12_buffer_copy_into_fallback (GstBuffer * dst, GstBuffer * src, - const GstVideoInfo * info) -{ - GstVideoFrame in_frame, out_frame; - gboolean ret; - - if (!gst_video_frame_map (&in_frame, (GstVideoInfo *) info, src, - (GstMapFlags) (GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))) { - GST_ERROR ("Couldn't map src frame"); - return FALSE; - } - - if (!gst_video_frame_map (&out_frame, (GstVideoInfo *) info, dst, - (GstMapFlags) (GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))) { - GST_ERROR ("Couldn't map dst frame"); - gst_video_frame_unmap (&in_frame); - return FALSE; - } - - ret = gst_video_frame_copy (&out_frame, &in_frame); - - gst_video_frame_unmap (&in_frame); - gst_video_frame_unmap (&out_frame); - - return ret; -} - -static gboolean -gst_is_d3d12_buffer (GstBuffer * buffer) -{ - auto size = gst_buffer_n_memory (buffer); - if (size == 0) - return FALSE; - - for (guint i = 0; i < size; i++) { - auto mem = gst_buffer_peek_memory (buffer, i); - if (!gst_is_d3d12_memory (mem)) - return FALSE; - } - - return TRUE; -} - -gboolean -gst_d3d12_buffer_copy_into (GstBuffer * dst, GstBuffer * src, - const GstVideoInfo * info) -{ - g_return_val_if_fail (GST_IS_BUFFER (dst), FALSE); - g_return_val_if_fail (GST_IS_BUFFER (src), FALSE); - g_return_val_if_fail (info, FALSE); - - auto num_mem = gst_buffer_n_memory (dst); - - if (gst_buffer_n_memory (src) != num_mem) { - GST_LOG ("different memory layout, perform fallback copy"); - return gst_d3d12_buffer_copy_into_fallback (dst, src, info); - } - - if (!gst_is_d3d12_buffer (dst) || !gst_is_d3d12_buffer (src)) { - GST_LOG ("non-d3d12 memory, perform fallback copy"); - return gst_d3d12_buffer_copy_into_fallback (dst, src, info); - } - - std::vector < GstD3D12CopyTextureRegionArgs > copy_args; - D3D12_BOX src_box[4]; - guint resource_idx = 0; - GstD3D12Device *device = nullptr; - - for (guint i = 0; i < num_mem; i++) { - auto dst_mem = gst_buffer_peek_memory (dst, i); - auto src_mem = gst_buffer_peek_memory (src, i); - - auto dst_dmem = GST_D3D12_MEMORY_CAST (dst_mem); - auto src_dmem = GST_D3D12_MEMORY_CAST (src_mem); - - device = dst_dmem->device; - if (!gst_d3d12_device_is_equal (device, src_dmem->device)) { - GST_LOG ("different device, perform fallback copy"); - return gst_d3d12_buffer_copy_into_fallback (dst, src, info); - } - - /* Map memory to execute pending upload and wait for external fence */ - GstMapInfo map_info; - if (!gst_memory_map (src_mem, &map_info, GST_MAP_READ_D3D12)) { - GST_ERROR ("Cannot map src d3d12 memory"); - return FALSE; - } - gst_memory_unmap (src_mem, &map_info); - - if (!gst_memory_map (dst_mem, &map_info, GST_MAP_WRITE_D3D12)) { - GST_ERROR ("Cannot map dst d3d12 memory"); - return FALSE; - } - gst_memory_unmap (dst_mem, &map_info); - - auto num_planes = gst_d3d12_memory_get_plane_count (src_dmem); - - for (guint j = 0; j < num_planes; j++) { - GstD3D12CopyTextureRegionArgs args = { }; - D3D12_RECT src_rect; - D3D12_RECT dst_rect; - - gst_d3d12_memory_get_plane_rectangle (src_dmem, j, &src_rect); - gst_d3d12_memory_get_plane_rectangle (dst_dmem, j, &dst_rect); - - auto src_handle = gst_d3d12_memory_get_resource_handle (src_dmem); - auto dst_handle = gst_d3d12_memory_get_resource_handle (dst_dmem); - - guint src_subresource; - guint dst_subresource; - gst_d3d12_memory_get_subresource_index (src_dmem, j, &src_subresource); - gst_d3d12_memory_get_subresource_index (dst_dmem, j, &dst_subresource); - - args.src = CD3DX12_TEXTURE_COPY_LOCATION (src_handle, src_subresource); - args.dst = CD3DX12_TEXTURE_COPY_LOCATION (dst_handle, dst_subresource); - - src_box[resource_idx].front = 0; - src_box[resource_idx].back = 1; - src_box[resource_idx].left = 0; - src_box[resource_idx].top = 0; - src_box[resource_idx].right = MIN (src_rect.right, dst_rect.right); - src_box[resource_idx].bottom = MIN (src_rect.bottom, dst_rect.bottom); - - args.src_box = &src_box[resource_idx]; - resource_idx++; - copy_args.push_back (args); - } - } - - g_assert (device); - - guint64 fence_val; - if (!gst_d3d12_device_copy_texture_region (device, copy_args.size (), - copy_args.data (), D3D12_COMMAND_LIST_TYPE_DIRECT, &fence_val)) { - GST_ERROR ("Couldn't copy texture"); - return FALSE; - } - - gst_d3d12_buffer_after_write (dst, fence_val); - - return TRUE; -} diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.h index bcc7542950..88bcb7e925 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.h +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12pluginutils.h @@ -58,8 +58,4 @@ gboolean gst_d3d12_need_transform (gfloat rotation_x, gfloat scale_x, gfloat scale_y); -gboolean gst_d3d12_buffer_copy_into (GstBuffer * dst, - GstBuffer * src, - const GstVideoInfo * info); - G_END_DECLS