diff options
author | Christian König <[email protected]> | 2015-12-16 20:58:49 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2016-01-12 13:26:24 +0100 |
commit | 8479782361ab58eeacee7f81b18d9597553859ce (patch) | |
tree | e47def598f93755990bf0abaa7af370bfc77758a /src/gallium/state_trackers/va/image.c | |
parent | 8926dc87af72e55128402209993971ee00ca00c6 (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.c | 68 |
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; } |