diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h index 3aff9c8598..872b1698e3 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h @@ -41,16 +41,6 @@ void gst_d3d11_device_dxgi_debug (GstD3D11Device * device, const gchar * function, gint line); -/* Memory allocated by this method does not hold correct size. - * So this is private method and only plugins in -bad are expected to call - * this method */ -GST_D3D11_API -GstMemory * gst_d3d11_allocator_alloc_wrapped_native_size (GstD3D11Allocator * allocator, - GstD3D11Device * device, - ID3D11Texture2D * texture, - gpointer user_data, - GDestroyNotify notify); - #define GST_D3D11_CLEAR_COM(obj) G_STMT_START { \ if (obj) { \ (obj)->Release (); \ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp index 8a1ceb90ef..bf7b42e42c 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp @@ -1639,12 +1639,21 @@ gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator, * @allocator: a #GstD3D11Allocator * @device: a #GstD3D11Device * @texture: a ID3D11Texture2D + * @size: CPU accessible memory size * @user_data: (allow-none): user data * @notify: (allow-none): called with @user_data when the memory is freed * * Allocates memory object with @texture. The refcount of @texture * will be increased by one. * + * Caller should set valid CPU acessible memory value to @size + * (which is typically calculated by using staging texture and Map/Unmap) + * or zero is allowed. In that case, allocator will create a temporary staging + * texture to get the size and the temporary staging texture will be released. + * + * Caller must not be confused that @size is CPU accessible size, not raw + * texture size. + * * Returns: a newly allocated #GstD3D11Memory with given @texture * if successful, or %NULL if @texture is not a valid handle or configuration * is not supported. @@ -1653,8 +1662,8 @@ gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator, */ GstMemory * gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator, - GstD3D11Device * device, ID3D11Texture2D * texture, gpointer user_data, - GDestroyNotify notify) + GstD3D11Device * device, ID3D11Texture2D * texture, gsize size, + gpointer user_data, GDestroyNotify notify) { GstMemory *mem; GstD3D11Memory *dmem; @@ -1678,10 +1687,14 @@ gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator, if (!mem) return nullptr; - if (!gst_d3d11_memory_update_size (mem)) { - GST_ERROR_OBJECT (allocator, "Failed to calculate size"); - gst_memory_unref (mem); - return nullptr; + if (size == 0) { + if (!gst_d3d11_memory_update_size (mem)) { + GST_ERROR_OBJECT (allocator, "Failed to calculate size"); + gst_memory_unref (mem); + return nullptr; + } + } else { + mem->maxsize = mem->size = size; } dmem = GST_D3D11_MEMORY_CAST (mem); @@ -1692,46 +1705,6 @@ gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator, return mem; } -GstMemory * -gst_d3d11_allocator_alloc_wrapped_native_size (GstD3D11Allocator * allocator, - GstD3D11Device * device, ID3D11Texture2D * texture, gpointer user_data, - GDestroyNotify notify) -{ - GstMemory *mem; - GstD3D11Memory *dmem; - D3D11_TEXTURE2D_DESC desc = { 0, }; - ID3D11Texture2D *tex = nullptr; - HRESULT hr; - gsize size; - - g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), nullptr); - g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr); - g_return_val_if_fail (texture != nullptr, nullptr); - - hr = texture->QueryInterface (IID_PPV_ARGS (&tex)); - if (FAILED (hr)) { - GST_WARNING_OBJECT (allocator, "Not a valid texture handle"); - return nullptr; - } - - tex->GetDesc (&desc); - mem = gst_d3d11_allocator_alloc_internal (allocator, device, &desc, tex); - - if (!mem) - return nullptr; - - /* XXX: This is not correct memory size */ - size = desc.Width * desc.Height; - mem->maxsize = mem->size = size; - - dmem = GST_D3D11_MEMORY_CAST (mem); - - dmem->priv->user_data = user_data; - dmem->priv->notify = notify; - - return mem; -} - /** * gst_d3d11_allocator_set_active: * @allocator: a #GstD3D11Allocator diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h index 0219672ad4..dca39a537e 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h @@ -263,6 +263,7 @@ GST_D3D11_API GstMemory * gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator, GstD3D11Device * device, ID3D11Texture2D * texture, + gsize size, gpointer user_data, GDestroyNotify notify); diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp index 484ff79be6..7b3b35b07c 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp @@ -281,6 +281,7 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width, GstMemory *mem; GstD3D11Memory *dmem; ID3D11RenderTargetView *rtv; + gsize size; gst_d3d11_device_lock (device); @@ -304,8 +305,19 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width, goto done; } - mem = gst_d3d11_allocator_alloc_wrapped_native_size (self->allocator, - self->device, backbuffer.Get (), nullptr, nullptr); + backbuffer->GetDesc (&desc); + size = desc.Width * desc.Height; + /* flip mode swapchain supports only 4 formats, rgba/bgra/rgb10a2/rgba64. + * The size passed in alloc_wrapped() is not important here, since we never + * try mapping this for CPU access */ + if (desc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT) { + size *= 8; + } else { + size *= 4; + } + + mem = gst_d3d11_allocator_alloc_wrapped (self->allocator, + self->device, backbuffer.Get (), size, nullptr, nullptr); if (!mem) { GST_ERROR_OBJECT (self, "Couldn't allocate wrapped memory"); goto done; @@ -322,7 +334,6 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width, self->backbuffer = gst_buffer_new (); gst_buffer_append_memory (self->backbuffer, mem); - backbuffer->GetDesc (&desc); self->surface_width = desc.Width; self->surface_height = desc.Height; diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp index cb1d6968d4..595e40a17e 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp @@ -238,8 +238,8 @@ gst_d3d11_window_dummy_open_shared_handle (GstD3D11Window * window, } } - mem = gst_d3d11_allocator_alloc_wrapped_native_size (window->allocator, - device, texture.Get (), nullptr, nullptr); + mem = gst_d3d11_allocator_alloc_wrapped (window->allocator, + device, texture.Get (), desc.Width * desc.Height * 4, nullptr, nullptr); if (!mem) { GST_ERROR_OBJECT (window, "Couldn't allocate memory"); return FALSE; diff --git a/subprojects/gst-plugins-bad/tests/examples/d3d11/d3d11videosink-appsrc.cpp b/subprojects/gst-plugins-bad/tests/examples/d3d11/d3d11videosink-appsrc.cpp index 053833371b..54fce35212 100644 --- a/subprojects/gst-plugins-bad/tests/examples/d3d11/d3d11videosink-appsrc.cpp +++ b/subprojects/gst-plugins-bad/tests/examples/d3d11/d3d11videosink-appsrc.cpp @@ -42,6 +42,7 @@ typedef struct ID3D11Device *device; ID3D11DeviceContext *context; + gsize mem_size; D3D11_TEXTURE2D_DESC desc; GstVideoInfo video_info; @@ -282,7 +283,8 @@ on_need_data (GstAppSrc * appsrc, guint length, gpointer user_data) * ID3D11Texture2D object, but in this example, we pass ownership via * user data */ mem = gst_d3d11_allocator_alloc_wrapped (allocator, app_data->d3d11_device, - texture, memory_data, (GDestroyNotify) on_memory_freed); + texture, app_data->mem_size, memory_data, + (GDestroyNotify) on_memory_freed); gst_object_unref (allocator); if (!mem) { @@ -290,6 +292,10 @@ on_need_data (GstAppSrc * appsrc, guint length, gpointer user_data) exit (1); } + /* update memory size with calculated value by allocator, and reuse it + * for later alloc_wrapped() call to avoid allocating staging texture */ + app_data->mem_size = mem->size; + /* Calculates CPU accessible (via staging texture) memory layout. * GstD3D11Memory allows CPU access but application must calculate the layout * pitch would be likely different from width */