mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-01 21:18:52 +00:00
vaapivideomemory: lock map and unmap operations
In order to avoid race condition when two threads call map/unmap the same VA surface, this patch mutex these operations. https://bugzilla.gnome.org/show_bug.cgi?id=774213
This commit is contained in:
parent
4ae9428072
commit
3fa9af225f
2 changed files with 30 additions and 11 deletions
|
@ -294,6 +294,7 @@ gboolean
|
||||||
gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane,
|
gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane,
|
||||||
GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
|
GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
|
||||||
{
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
GstVaapiVideoMemory *const mem =
|
GstVaapiVideoMemory *const mem =
|
||||||
GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
|
GST_VAAPI_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
|
||||||
|
@ -303,13 +304,14 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane,
|
||||||
g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE);
|
g_return_val_if_fail (GST_VAAPI_IS_VIDEO_ALLOCATOR (allocator), FALSE);
|
||||||
g_return_val_if_fail (mem->meta, FALSE);
|
g_return_val_if_fail (mem->meta, FALSE);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR)
|
if (mem->map_type && mem->map_type != GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR)
|
||||||
goto error_incompatible_map;
|
goto error_incompatible_map;
|
||||||
|
|
||||||
/* Map for writing */
|
/* Map for writing */
|
||||||
if (mem->map_count == 0) {
|
if (mem->map_count == 0) {
|
||||||
if (!map_vaapi_memory (mem, flags))
|
if (!map_vaapi_memory (mem, flags))
|
||||||
return FALSE;
|
goto out;
|
||||||
mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR;
|
mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR;
|
||||||
}
|
}
|
||||||
mem->map_count++;
|
mem->map_count++;
|
||||||
|
@ -317,13 +319,17 @@ gst_video_meta_map_vaapi_memory (GstVideoMeta * meta, guint plane,
|
||||||
*data = gst_vaapi_image_get_plane (mem->image, plane);
|
*data = gst_vaapi_image_get_plane (mem->image, plane);
|
||||||
*stride = gst_vaapi_image_get_pitch (mem->image, plane);
|
*stride = gst_vaapi_image_get_pitch (mem->image, plane);
|
||||||
info->flags = flags;
|
info->flags = flags;
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
error_incompatible_map:
|
error_incompatible_map:
|
||||||
{
|
{
|
||||||
GST_ERROR ("incompatible map type (%d)", mem->map_type);
|
GST_ERROR ("incompatible map type (%d)", mem->map_type);
|
||||||
return FALSE;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +348,7 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane,
|
||||||
g_return_val_if_fail (mem->surface, FALSE);
|
g_return_val_if_fail (mem->surface, FALSE);
|
||||||
g_return_val_if_fail (mem->image, FALSE);
|
g_return_val_if_fail (mem->image, FALSE);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
if (--mem->map_count == 0) {
|
if (--mem->map_count == 0) {
|
||||||
mem->map_type = 0;
|
mem->map_type = 0;
|
||||||
|
|
||||||
|
@ -349,6 +356,7 @@ gst_video_meta_unmap_vaapi_memory (GstVideoMeta * meta, guint plane,
|
||||||
if (info->flags & GST_MAP_READWRITE)
|
if (info->flags & GST_MAP_READWRITE)
|
||||||
unmap_vaapi_memory (mem, info->flags);
|
unmap_vaapi_memory (mem, info->flags);
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,6 +389,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator,
|
||||||
mem->map_type = 0;
|
mem->map_type = 0;
|
||||||
mem->map_count = 0;
|
mem->map_count = 0;
|
||||||
mem->usage_flag = allocator->usage_flag;
|
mem->usage_flag = allocator->usage_flag;
|
||||||
|
g_mutex_init (&mem->lock);
|
||||||
|
|
||||||
GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem,
|
GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem,
|
||||||
GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT);
|
GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT);
|
||||||
|
@ -395,6 +404,7 @@ gst_vaapi_video_memory_free (GstVaapiVideoMemory * mem)
|
||||||
gst_vaapi_surface_proxy_replace (&mem->proxy, NULL);
|
gst_vaapi_surface_proxy_replace (&mem->proxy, NULL);
|
||||||
gst_vaapi_video_meta_replace (&mem->meta, NULL);
|
gst_vaapi_video_meta_replace (&mem->meta, NULL);
|
||||||
gst_object_unref (GST_MEMORY_CAST (mem)->allocator);
|
gst_object_unref (GST_MEMORY_CAST (mem)->allocator);
|
||||||
|
g_mutex_clear (&mem->lock);
|
||||||
g_slice_free (GstVaapiVideoMemory, mem);
|
g_slice_free (GstVaapiVideoMemory, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,11 +452,12 @@ static gpointer
|
||||||
gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize,
|
gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize,
|
||||||
guint flags)
|
guint flags)
|
||||||
{
|
{
|
||||||
gpointer data;
|
gpointer data = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (mem, NULL);
|
g_return_val_if_fail (mem, NULL);
|
||||||
g_return_val_if_fail (mem->meta, NULL);
|
g_return_val_if_fail (mem->meta, NULL);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
if (mem->map_count == 0) {
|
if (mem->map_count == 0) {
|
||||||
switch (flags & GST_MAP_READWRITE) {
|
switch (flags & GST_MAP_READWRITE) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -461,7 +472,7 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize,
|
||||||
break;
|
break;
|
||||||
case GST_MAP_READ:
|
case GST_MAP_READ:
|
||||||
if (!map_vaapi_memory (mem, flags))
|
if (!map_vaapi_memory (mem, flags))
|
||||||
return NULL;
|
goto out;
|
||||||
mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR;
|
mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_LINEAR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -484,39 +495,43 @@ gst_vaapi_video_memory_map (GstVaapiVideoMemory * mem, gsize maxsize,
|
||||||
goto error_unsupported_map_type;
|
goto error_unsupported_map_type;
|
||||||
}
|
}
|
||||||
mem->map_count++;
|
mem->map_count++;
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
error_unsupported_map:
|
error_unsupported_map:
|
||||||
{
|
{
|
||||||
GST_ERROR ("unsupported map flags (0x%x)", flags);
|
GST_ERROR ("unsupported map flags (0x%x)", flags);
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
error_unsupported_map_type:
|
error_unsupported_map_type:
|
||||||
{
|
{
|
||||||
GST_ERROR ("unsupported map type (%d)", mem->map_type);
|
GST_ERROR ("unsupported map type (%d)", mem->map_type);
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
error_no_surface_proxy:
|
error_no_surface_proxy:
|
||||||
{
|
{
|
||||||
GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta");
|
GST_ERROR ("failed to extract GstVaapiSurfaceProxy from video meta");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
error_no_current_surface:
|
error_no_current_surface:
|
||||||
{
|
{
|
||||||
GST_ERROR ("failed to make surface current");
|
GST_ERROR ("failed to make surface current");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
error_no_image:
|
error_no_image:
|
||||||
{
|
{
|
||||||
GST_ERROR ("failed to extract VA image from video buffer");
|
GST_ERROR ("failed to extract VA image from video buffer");
|
||||||
return NULL;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info)
|
gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info)
|
||||||
{
|
{
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
if (mem->map_count == 1) {
|
if (mem->map_count == 1) {
|
||||||
switch (mem->map_type) {
|
switch (mem->map_type) {
|
||||||
case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE:
|
case GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_SURFACE:
|
||||||
|
@ -531,13 +546,16 @@ gst_vaapi_video_memory_unmap_full (GstVaapiVideoMemory * mem, GstMapInfo * info)
|
||||||
mem->map_type = 0;
|
mem->map_type = 0;
|
||||||
}
|
}
|
||||||
mem->map_count--;
|
mem->map_count--;
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
error_incompatible_map:
|
error_incompatible_map:
|
||||||
{
|
{
|
||||||
GST_ERROR ("incompatible map type (%d)", mem->map_type);
|
GST_ERROR ("incompatible map type (%d)", mem->map_type);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,7 @@ struct _GstVaapiVideoMemory
|
||||||
guint map_type;
|
guint map_type;
|
||||||
gint map_count;
|
gint map_count;
|
||||||
GstVaapiImageUsageFlags usage_flag;
|
GstVaapiImageUsageFlags usage_flag;
|
||||||
|
GMutex lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
|
|
Loading…
Reference in a new issue