d3d11memory: Protect view object with lock

Make resource allocation more thread-safe

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1718>
This commit is contained in:
Seungha Yang 2020-10-24 20:59:55 +09:00
parent 969ab3e664
commit 9d810bbd81
2 changed files with 135 additions and 72 deletions

View file

@ -29,6 +29,15 @@
GST_DEBUG_CATEGORY_STATIC (gst_d3d11_allocator_debug); GST_DEBUG_CATEGORY_STATIC (gst_d3d11_allocator_debug);
#define GST_CAT_DEFAULT gst_d3d11_allocator_debug #define GST_CAT_DEFAULT gst_d3d11_allocator_debug
#define GST_D3D11_ALLOCATOR_GET_LOCK(a) (&(GST_D3D11_ALLOCATOR_CAST(a)->priv->lock))
#define GST_D3D11_ALLOCATOR_LOCK(a) g_mutex_lock(GST_D3D11_ALLOCATOR_GET_LOCK(a))
#define GST_D3D11_ALLOCATOR_UNLOCK(a) g_mutex_unlock(GST_D3D11_ALLOCATOR_GET_LOCK(a))
#define GST_D3D11_MEMORY_CAST(m) ((GstD3D11Memory *) m)
#define GST_D3D11_MEMORY_GET_LOCK(m) (&(GST_D3D11_MEMORY_CAST(m)->lock))
#define GST_D3D11_MEMORY_LOCK(m) g_mutex_lock(GST_D3D11_MEMORY_GET_LOCK(m))
#define GST_D3D11_MEMORY_UNLOCK(m) g_mutex_unlock(GST_D3D11_MEMORY_GET_LOCK(m))
GstD3D11AllocationParams * GstD3D11AllocationParams *
gst_d3d11_allocation_params_new (GstD3D11Device * device, GstVideoInfo * info, gst_d3d11_allocation_params_new (GstD3D11Device * device, GstVideoInfo * info,
GstD3D11AllocationFlags flags, gint bind_flags) GstD3D11AllocationFlags flags, gint bind_flags)
@ -268,7 +277,7 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
{ {
GstD3D11Memory *dmem = (GstD3D11Memory *) mem; GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
g_mutex_lock (&dmem->lock); GST_D3D11_MEMORY_LOCK (dmem);
if (dmem->cpu_map_count == 0) { if (dmem->cpu_map_count == 0) {
ID3D11DeviceContext *device_context = ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (dmem->device); gst_d3d11_device_get_device_context_handle (dmem->device);
@ -289,13 +298,13 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
gst_d3d11_device_unlock (dmem->device); gst_d3d11_device_unlock (dmem->device);
if (!ret) { if (!ret) {
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return NULL; return NULL;
} }
} }
dmem->cpu_map_count++; dmem->cpu_map_count++;
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return dmem->map.pData; return dmem->map.pData;
} }
@ -312,7 +321,7 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
return gst_d3d11_memory_map_staging (mem, flags); return gst_d3d11_memory_map_staging (mem, flags);
} }
g_mutex_lock (&dmem->lock); GST_D3D11_MEMORY_LOCK (dmem);
if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11) { if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
if (dmem->staging && if (dmem->staging &&
GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD)) { GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD)) {
@ -332,7 +341,7 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
g_assert (dmem->texture != NULL); g_assert (dmem->texture != NULL);
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return dmem->texture; return dmem->texture;
} }
@ -358,7 +367,7 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
if (!map_cpu_access_data (dmem, map_type)) { if (!map_cpu_access_data (dmem, map_type)) {
GST_ERROR_OBJECT (mem->allocator, "Couldn't map staging texture"); GST_ERROR_OBJECT (mem->allocator, "Couldn't map staging texture");
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return NULL; return NULL;
} }
@ -370,7 +379,7 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
GST_MEMORY_FLAG_UNSET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); GST_MEMORY_FLAG_UNSET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
dmem->cpu_map_count++; dmem->cpu_map_count++;
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return dmem->map.pData; return dmem->map.pData;
} }
@ -395,13 +404,13 @@ gst_d3d11_memory_unmap_full (GstMemory * mem, GstMapInfo * info)
{ {
GstD3D11Memory *dmem = (GstD3D11Memory *) mem; GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
g_mutex_lock (&dmem->lock); GST_D3D11_MEMORY_LOCK (dmem);
if ((info->flags & GST_MAP_D3D11) == GST_MAP_D3D11) { if ((info->flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
if (dmem->type != GST_D3D11_MEMORY_TYPE_STAGING && if (dmem->type != GST_D3D11_MEMORY_TYPE_STAGING &&
(info->flags & GST_MAP_WRITE) == GST_MAP_WRITE) (info->flags & GST_MAP_WRITE) == GST_MAP_WRITE)
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return; return;
} }
@ -411,13 +420,13 @@ gst_d3d11_memory_unmap_full (GstMemory * mem, GstMapInfo * info)
dmem->cpu_map_count--; dmem->cpu_map_count--;
if (dmem->cpu_map_count > 0) { if (dmem->cpu_map_count > 0) {
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
return; return;
} }
unmap_cpu_access_data (dmem); unmap_cpu_access_data (dmem);
g_mutex_unlock (&dmem->lock); GST_D3D11_MEMORY_UNLOCK (dmem);
} }
static GstMemory * static GstMemory *
@ -443,10 +452,10 @@ gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
gint i; gint i;
if (priv->array_in_use) { if (priv->array_in_use) {
g_mutex_lock (&priv->lock); GST_D3D11_ALLOCATOR_LOCK (self);
g_array_index (priv->array_in_use, guint8, dmem->subresource_index) = 0; g_array_index (priv->array_in_use, guint8, dmem->subresource_index) = 0;
g_cond_broadcast (&priv->cond); g_cond_broadcast (&priv->cond);
g_mutex_unlock (&priv->lock); GST_D3D11_ALLOCATOR_UNLOCK (self);
} }
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) { for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
@ -594,7 +603,7 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
return ret; return ret;
} }
static void static gboolean
create_shader_resource_views (GstD3D11Memory * mem) create_shader_resource_views (GstD3D11Memory * mem)
{ {
gint i; gint i;
@ -637,7 +646,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
break; return FALSE;
} }
if ((mem->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) == if ((mem->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) ==
@ -659,9 +668,11 @@ create_shader_resource_views (GstD3D11Memory * mem)
} }
mem->num_shader_resource_views = num_views; mem->num_shader_resource_views = num_views;
return TRUE;
} }
return; return FALSE;
error: error:
for (i = 0; i < num_views; i++) { for (i = 0; i < num_views; i++) {
@ -671,9 +682,11 @@ error:
} }
mem->num_shader_resource_views = 0; mem->num_shader_resource_views = 0;
return FALSE;
} }
static void static gboolean
create_render_target_views (GstD3D11Memory * mem) create_render_target_views (GstD3D11Memory * mem)
{ {
gint i; gint i;
@ -713,7 +726,7 @@ create_render_target_views (GstD3D11Memory * mem)
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
break; return FALSE;
} }
if ((mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET) == if ((mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET) ==
@ -735,9 +748,11 @@ create_render_target_views (GstD3D11Memory * mem)
} }
mem->num_render_target_views = num_views; mem->num_render_target_views = num_views;
return TRUE;
} }
return; return FALSE;
error: error:
for (i = 0; i < num_views; i++) { for (i = 0; i < num_views; i++) {
@ -747,6 +762,8 @@ error:
} }
mem->num_render_target_views = 0; mem->num_render_target_views = 0;
return FALSE;
} }
static void static void
@ -806,10 +823,10 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
gint i; gint i;
do_again: do_again:
g_mutex_lock (&priv->lock); GST_D3D11_ALLOCATOR_LOCK (allocator);
if (priv->flushing) { if (priv->flushing) {
GST_DEBUG_OBJECT (allocator, "we are flushing"); GST_DEBUG_OBJECT (allocator, "we are flushing");
g_mutex_unlock (&priv->lock); GST_D3D11_ALLOCATOR_UNLOCK (allocator);
return NULL; return NULL;
} }
@ -847,13 +864,13 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
if (i == desc->ArraySize) { if (i == desc->ArraySize) {
GST_DEBUG_OBJECT (allocator, "All elements in array are used now"); GST_DEBUG_OBJECT (allocator, "All elements in array are used now");
g_cond_wait (&priv->cond, &priv->lock); g_cond_wait (&priv->cond, &priv->lock);
g_mutex_unlock (&priv->lock); GST_D3D11_ALLOCATOR_UNLOCK (allocator);
goto do_again; goto do_again;
} }
g_array_index (priv->array_in_use, guint8, index_to_use) = 1; g_array_index (priv->array_in_use, guint8, index_to_use) = 1;
g_mutex_unlock (&priv->lock); GST_D3D11_ALLOCATOR_UNLOCK (allocator);
if (!priv->texture) { if (!priv->texture) {
priv->texture = gst_d3d11_device_create_texture (device, desc, NULL); priv->texture = gst_d3d11_device_create_texture (device, desc, NULL);
@ -958,10 +975,10 @@ gst_d3d11_allocator_set_flushing (GstD3D11Allocator * allocator,
priv = allocator->priv; priv = allocator->priv;
g_mutex_lock (&priv->lock); GST_D3D11_ALLOCATOR_LOCK (allocator);
priv->flushing = flushing; priv->flushing = flushing;
g_cond_broadcast (&priv->cond); g_cond_broadcast (&priv->cond);
g_mutex_unlock (&priv->lock); GST_D3D11_ALLOCATOR_UNLOCK (allocator);
} }
gboolean gboolean
@ -974,41 +991,55 @@ gst_is_d3d11_memory (GstMemory * mem)
gboolean gboolean
gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem) gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem)
{ {
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); gboolean ret = FALSE;
if (mem->num_shader_resource_views) g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
return TRUE;
if (!(mem->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) { if (!(mem->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) {
GST_WARNING_OBJECT (GST_MEMORY_CAST (mem)->allocator, GST_WARNING_OBJECT (GST_MEMORY_CAST (mem)->allocator,
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags); "Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
return FALSE; return FALSE;
} }
create_shader_resource_views (mem); GST_D3D11_MEMORY_LOCK (mem);
if (mem->num_shader_resource_views) {
ret = TRUE;
goto done;
}
return ! !mem->num_shader_resource_views; ret = create_shader_resource_views (mem);
done:
GST_D3D11_MEMORY_UNLOCK (mem);
return ret;
} }
gboolean gboolean
gst_d3d11_memory_ensure_render_target_view (GstD3D11Memory * mem) gst_d3d11_memory_ensure_render_target_view (GstD3D11Memory * mem)
{ {
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); gboolean ret = FALSE;
if (mem->num_render_target_views) g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
return TRUE;
if (!(mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) { if (!(mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) {
GST_WARNING_OBJECT (GST_MEMORY_CAST (mem)->allocator, GST_WARNING_OBJECT (GST_MEMORY_CAST (mem)->allocator,
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags); "Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
return FALSE; return FALSE;
} }
create_render_target_views (mem); GST_D3D11_MEMORY_LOCK (mem);
if (mem->num_render_target_views) {
ret = TRUE;
goto done;
}
return ! !mem->num_render_target_views; ret = create_render_target_views (mem);
done:
GST_D3D11_MEMORY_UNLOCK (mem);
return ret;
} }
gboolean gboolean
@ -1020,6 +1051,7 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC desc; D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC desc;
ID3D11VideoDecoderOutputView *view = NULL; ID3D11VideoDecoderOutputView *view = NULL;
HRESULT hr; HRESULT hr;
gboolean ret = FALSE;
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
g_return_val_if_fail (video_device != NULL, FALSE); g_return_val_if_fail (video_device != NULL, FALSE);
@ -1028,10 +1060,17 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator); allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
priv = allocator->priv; priv = allocator->priv;
if (!(mem->desc.BindFlags & D3D11_BIND_DECODER)) {
GST_WARNING_OBJECT (allocator,
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
return FALSE;
}
GST_D3D11_MEMORY_LOCK (mem);
if (mem->decoder_output_view) { if (mem->decoder_output_view) {
ID3D11VideoDecoderOutputView_GetDesc (mem->decoder_output_view, &desc); ID3D11VideoDecoderOutputView_GetDesc (mem->decoder_output_view, &desc);
if (IsEqualGUID (&desc.DecodeProfile, decoder_profile)) { if (IsEqualGUID (&desc.DecodeProfile, decoder_profile)) {
return TRUE; goto succeeded;
} else { } else {
/* Shouldn't happen, but try again anyway */ /* Shouldn't happen, but try again anyway */
GST_WARNING_OBJECT (allocator, GST_WARNING_OBJECT (allocator,
@ -1041,14 +1080,8 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
} }
} }
if (!(mem->desc.BindFlags & D3D11_BIND_DECODER)) {
GST_WARNING_OBJECT (allocator,
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
return FALSE;
}
if (priv->decoder_output_view_array) { if (priv->decoder_output_view_array) {
GST_D3D11_ALLOCATOR_LOCK (allocator);
view = g_array_index (priv->decoder_output_view_array, view = g_array_index (priv->decoder_output_view_array,
ID3D11VideoDecoderOutputView *, mem->subresource_index); ID3D11VideoDecoderOutputView *, mem->subresource_index);
@ -1063,17 +1096,17 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
view = NULL; view = NULL;
g_array_index (priv->decoder_output_view_array, g_array_index (priv->decoder_output_view_array,
ID3D11VideoDecoderOutputView *, mem->subresource_index) = NULL; ID3D11VideoDecoderOutputView *, mem->subresource_index) = NULL;
} } else {
}
}
/* Increase refcount and reuse existing view */ /* Increase refcount and reuse existing view */
if (view) {
mem->decoder_output_view = view; mem->decoder_output_view = view;
ID3D11VideoDecoderOutputView_AddRef (view); ID3D11VideoDecoderOutputView_AddRef (view);
return TRUE;
} }
}
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
}
if (mem->decoder_output_view)
goto succeeded;
desc.DecodeProfile = *decoder_profile; desc.DecodeProfile = *decoder_profile;
desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D; desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
@ -1082,13 +1115,14 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView (video_device, hr = ID3D11VideoDevice_CreateVideoDecoderOutputView (video_device,
(ID3D11Resource *) mem->texture, &desc, &mem->decoder_output_view); (ID3D11Resource *) mem->texture, &desc, &mem->decoder_output_view);
if (!gst_d3d11_result (hr, mem->device)) { if (!gst_d3d11_result (hr, mem->device)) {
GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator, GST_ERROR_OBJECT (allocator,
"Could not create decoder output view, hr: 0x%x", (guint) hr); "Could not create decoder output view, hr: 0x%x", (guint) hr);
return FALSE; goto done;
} }
/* Store view array for later reuse */ /* Store view array for later reuse */
if (priv->decoder_output_view_array) { if (priv->decoder_output_view_array) {
GST_D3D11_ALLOCATOR_LOCK (allocator);
view = g_array_index (priv->decoder_output_view_array, view = g_array_index (priv->decoder_output_view_array,
ID3D11VideoDecoderOutputView *, mem->subresource_index); ID3D11VideoDecoderOutputView *, mem->subresource_index);
@ -1099,9 +1133,16 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem,
ID3D11VideoDecoderOutputView *, mem->subresource_index) = ID3D11VideoDecoderOutputView *, mem->subresource_index) =
mem->decoder_output_view; mem->decoder_output_view;
ID3D11VideoDecoderOutputView_AddRef (mem->decoder_output_view); ID3D11VideoDecoderOutputView_AddRef (mem->decoder_output_view);
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
} }
return TRUE; succeeded:
ret = TRUE;
done:
GST_D3D11_MEMORY_UNLOCK (mem);
return ret;
} }
gboolean gboolean
@ -1114,6 +1155,7 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC desc; D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC desc;
ID3D11VideoProcessorInputView *view = NULL; ID3D11VideoProcessorInputView *view = NULL;
HRESULT hr; HRESULT hr;
gboolean ret = FALSE;
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
g_return_val_if_fail (video_device != NULL, FALSE); g_return_val_if_fail (video_device != NULL, FALSE);
@ -1122,27 +1164,31 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator); allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
priv = allocator->priv; priv = allocator->priv;
if (mem->processor_input_view)
return TRUE;
if (!check_bind_flags_for_processor_input_view (mem->desc.BindFlags)) { if (!check_bind_flags_for_processor_input_view (mem->desc.BindFlags)) {
GST_WARNING_OBJECT (allocator, GST_WARNING_OBJECT (allocator,
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags); "Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
return FALSE; return FALSE;
} }
GST_D3D11_MEMORY_LOCK (mem);
if (mem->processor_input_view)
goto succeeded;
if (priv->processor_input_view_array) { if (priv->processor_input_view_array) {
GST_D3D11_ALLOCATOR_LOCK (allocator);
view = g_array_index (priv->processor_input_view_array, view = g_array_index (priv->processor_input_view_array,
ID3D11VideoProcessorInputView *, mem->subresource_index); ID3D11VideoProcessorInputView *, mem->subresource_index);
}
/* Increase refcount and reuse existing view */ /* Increase refcount and reuse existing view */
if (view) { if (view) {
mem->processor_input_view = view; mem->processor_input_view = view;
ID3D11VideoProcessorInputView_AddRef (view); ID3D11VideoProcessorInputView_AddRef (view);
return TRUE;
} }
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
}
if (mem->processor_input_view)
goto succeeded;
desc.FourCC = 0; desc.FourCC = 0;
desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
@ -1155,11 +1201,12 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
if (!gst_d3d11_result (hr, mem->device)) { if (!gst_d3d11_result (hr, mem->device)) {
GST_ERROR_OBJECT (allocator, GST_ERROR_OBJECT (allocator,
"Could not create processor input view, hr: 0x%x", (guint) hr); "Could not create processor input view, hr: 0x%x", (guint) hr);
return FALSE; goto done;
} }
/* Store view array for later reuse */ /* Store view array for later reuse */
if (priv->processor_input_view_array) { if (priv->processor_input_view_array) {
GST_D3D11_ALLOCATOR_LOCK (allocator);
view = g_array_index (priv->processor_input_view_array, view = g_array_index (priv->processor_input_view_array,
ID3D11VideoProcessorInputView *, mem->subresource_index); ID3D11VideoProcessorInputView *, mem->subresource_index);
@ -1170,9 +1217,16 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem,
ID3D11VideoProcessorInputView *, mem->subresource_index) = ID3D11VideoProcessorInputView *, mem->subresource_index) =
mem->processor_input_view; mem->processor_input_view;
ID3D11VideoProcessorInputView_AddRef (mem->processor_input_view); ID3D11VideoProcessorInputView_AddRef (mem->processor_input_view);
GST_D3D11_ALLOCATOR_UNLOCK (allocator);
} }
return TRUE; succeeded:
ret = TRUE;
done:
GST_D3D11_MEMORY_UNLOCK (mem);
return ret;
} }
gboolean gboolean
@ -1183,6 +1237,7 @@ gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem,
GstD3D11Allocator *allocator; GstD3D11Allocator *allocator;
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC desc = { 0, }; D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC desc = { 0, };
HRESULT hr; HRESULT hr;
gboolean ret;
g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE);
g_return_val_if_fail (video_device != NULL, FALSE); g_return_val_if_fail (video_device != NULL, FALSE);
@ -1190,9 +1245,6 @@ gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem,
allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator); allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator);
if (mem->processor_output_view)
return TRUE;
if (!(mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) { if (!(mem->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) {
GST_WARNING_OBJECT (allocator, GST_WARNING_OBJECT (allocator,
"Need BindFlags, current flag 0x%x", mem->desc.BindFlags); "Need BindFlags, current flag 0x%x", mem->desc.BindFlags);
@ -1206,6 +1258,10 @@ gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem,
return FALSE; return FALSE;
} }
GST_D3D11_MEMORY_LOCK (mem);
if (mem->processor_output_view)
goto succeeded;
desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = 0; desc.Texture2D.MipSlice = 0;
@ -1215,8 +1271,14 @@ gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem,
if (!gst_d3d11_result (hr, mem->device)) { if (!gst_d3d11_result (hr, mem->device)) {
GST_ERROR_OBJECT (allocator, GST_ERROR_OBJECT (allocator,
"Could not create processor input view, hr: 0x%x", (guint) hr); "Could not create processor input view, hr: 0x%x", (guint) hr);
return FALSE; goto done;
} }
return TRUE; succeeded:
ret = TRUE;
done:
GST_D3D11_MEMORY_UNLOCK (mem);
return ret;
} }

View file

@ -36,6 +36,7 @@ G_BEGIN_DECLS
#define GST_IS_D3D11_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_D3D11_ALLOCATOR)) #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_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_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_ALLOCATOR, GstD3D11AllocatorClass))
#define GST_D3D11_ALLOCATOR_CAST(obj) ((GstD3D11Allocator *)obj)
#define GST_D3D11_MEMORY_NAME "D3D11Memory" #define GST_D3D11_MEMORY_NAME "D3D11Memory"