summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/va/image.c
diff options
context:
space:
mode:
authorChristian König <[email protected]>2015-12-16 20:58:49 +0100
committerChristian König <[email protected]>2016-01-12 13:26:24 +0100
commit8479782361ab58eeacee7f81b18d9597553859ce (patch)
treee47def598f93755990bf0abaa7af370bfc77758a /src/gallium/state_trackers/va/image.c
parent8926dc87af72e55128402209993971ee00ca00c6 (diff)
st/va: make the implementation thread safe v2
Otherwise we might crash with MPV. v2: minor cleanups suggested on the list. Signed-off-by: Christian König <[email protected]> Reviewed-by: Emil Velikov <[email protected]> Reviewed-by: Julien Isorce <[email protected]> Tested-by: Julien Isorce <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/va/image.c')
-rw-r--r--src/gallium/state_trackers/va/image.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
index ccc263f77a7..044ce3a1858 100644
--- a/src/gallium/state_trackers/va/image.c
+++ b/src/gallium/state_trackers/va/image.c
@@ -119,7 +119,9 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig
img = CALLOC(1, sizeof(VAImage));
if (!img)
return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ pipe_mutex_lock(drv->mutex);
img->image_id = handle_table_add(drv->htab, img);
+ pipe_mutex_unlock(drv->mutex);
img->format = *format;
img->width = width;
@@ -261,6 +263,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
+ pipe_mutex_lock(drv->mutex);
img->image_id = handle_table_add(drv->htab, img);
img_buf->type = VAImageBufferType;
@@ -270,6 +273,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture);
img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf);
+ pipe_mutex_unlock(drv->mutex);
*image = *img;
@@ -279,16 +283,22 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
VAStatus
vlVaDestroyImage(VADriverContextP ctx, VAImageID image)
{
+ vlVaDriver *drv;
VAImage *vaimage;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- vaimage = handle_table_get(VL_VA_DRIVER(ctx)->htab, image);
- if (!vaimage)
+ drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
+ vaimage = handle_table_get(drv->htab, image);
+ if (!vaimage) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
handle_table_remove(VL_VA_DRIVER(ctx)->htab, image);
+ pipe_mutex_unlock(drv->mutex);
FREE(vaimage);
return vlVaDestroyBuffer(ctx, vaimage->buf);
}
@@ -321,21 +331,30 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
surf = handle_table_get(drv->htab, surface);
- if (!surf || !surf->buffer)
+ if (!surf || !surf->buffer) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
vaimage = handle_table_get(drv->htab, image);
- if (!vaimage)
+ if (!vaimage) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
img_buf = handle_table_get(drv->htab, vaimage->buf);
- if (!img_buf)
+ if (!img_buf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
format = VaFourccToPipeFormat(vaimage->format.fourcc);
- if (format == PIPE_FORMAT_NONE)
+ if (format == PIPE_FORMAT_NONE) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
if (format != surf->buffer->buffer_format) {
/* support NV12 to YV12 and IYUV conversion now only */
@@ -344,13 +363,17 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
(format == PIPE_FORMAT_IYUV &&
surf->buffer->buffer_format == PIPE_FORMAT_NV12))
convert = true;
- else
+ else {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
}
views = surf->buffer->get_sampler_view_planes(surf->buffer);
- if (!views)
+ if (!views) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
for (i = 0; i < vaimage->num_planes; i++) {
data[i] = img_buf->data + vaimage->offsets[i];
@@ -377,8 +400,10 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
uint8_t *map;
map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0,
PIPE_TRANSFER_READ, &box, &transfer);
- if (!map)
+ if (!map) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
if (i == 1 && convert) {
u_copy_nv12_to_yv12(data, pitches, i, j,
@@ -393,6 +418,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
pipe_transfer_unmap(drv->pipe, transfer);
}
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
@@ -415,28 +441,38 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
return VA_STATUS_ERROR_INVALID_CONTEXT;
drv = VL_VA_DRIVER(ctx);
+ pipe_mutex_lock(drv->mutex);
surf = handle_table_get(drv->htab, surface);
- if (!surf || !surf->buffer)
+ if (!surf || !surf->buffer) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
vaimage = handle_table_get(drv->htab, image);
- if (!vaimage)
+ if (!vaimage) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_IMAGE;
+ }
img_buf = handle_table_get(drv->htab, vaimage->buf);
- if (!img_buf)
+ if (!img_buf) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
+ }
if (img_buf->derived_surface.resource) {
/* Attempting to transfer derived image to surface */
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
format = VaFourccToPipeFormat(vaimage->format.fourcc);
- if (format == PIPE_FORMAT_NONE)
+ if (format == PIPE_FORMAT_NONE) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
if (format != surf->buffer->buffer_format) {
struct pipe_video_buffer *tmp_buf;
@@ -447,6 +483,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
if (!tmp_buf) {
surf->templat.buffer_format = old_surf_format;
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
@@ -455,8 +492,10 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
}
views = surf->buffer->get_sampler_view_planes(surf->buffer);
- if (!views)
+ if (!views) {
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_ERROR_OPERATION_FAILED;
+ }
for (i = 0; i < vaimage->num_planes; i++) {
data[i] = img_buf->data + vaimage->offsets[i];
@@ -485,6 +524,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
pitches[i] * views[i]->texture->array_size, 0);
}
}
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}