diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2016-05-29 10:22:51 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2016-05-29 10:22:51 +0000 |
commit | c9223eed3c16cd3e98a8f56dda953d8f299de0e3 (patch) | |
tree | 53e2a1c3f13bcf6b4ed201d7bc135e7213c94ebe /lib/mesa/src/gallium/state_trackers/va/image.c | |
parent | 6e8f2d062ab9c198239b9283b2b7ed12f4ea17d8 (diff) |
Import Mesa 11.2.2
Diffstat (limited to 'lib/mesa/src/gallium/state_trackers/va/image.c')
-rw-r--r-- | lib/mesa/src/gallium/state_trackers/va/image.c | 215 |
1 files changed, 179 insertions, 36 deletions
diff --git a/lib/mesa/src/gallium/state_trackers/va/image.c b/lib/mesa/src/gallium/state_trackers/va/image.c index 5877299e0..92d014c3d 100644 --- a/lib/mesa/src/gallium/state_trackers/va/image.c +++ b/lib/mesa/src/gallium/state_trackers/va/image.c @@ -34,17 +34,25 @@ #include "util/u_video.h" #include "vl/vl_winsys.h" +#include "vl/vl_video_buffer.h" #include "va_private.h" -static const VAImageFormat formats[VL_VA_MAX_IMAGE_FORMATS] = +static const VAImageFormat formats[] = { {VA_FOURCC('N','V','1','2')}, {VA_FOURCC('I','4','2','0')}, {VA_FOURCC('Y','V','1','2')}, {VA_FOURCC('Y','U','Y','V')}, {VA_FOURCC('U','Y','V','Y')}, - {VA_FOURCC('B','G','R','A')} + {.fourcc = VA_FOURCC('B','G','R','A'), .byte_order = VA_LSB_FIRST, 32, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, + {.fourcc = VA_FOURCC('R','G','B','A'), .byte_order = VA_LSB_FIRST, 32, 32, + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000}, + {.fourcc = VA_FOURCC('B','G','R','X'), .byte_order = VA_LSB_FIRST, 32, 24, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, + {.fourcc = VA_FOURCC('R','G','B','X'), .byte_order = VA_LSB_FIRST, 32, 24, + 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000} }; static void @@ -54,15 +62,9 @@ vlVaVideoSurfaceSize(vlVaSurface *p_surf, int component, *width = p_surf->templat.width; *height = p_surf->templat.height; - if (component > 0) { - if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - *width /= 2; - *height /= 2; - } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) - *width /= 2; - } - if (p_surf->templat.interlaced) - *height /= 2; + vl_video_buffer_adjust_size(width, height, component, + p_surf->templat.chroma_format, + p_surf->templat.interlaced); } VAStatus @@ -72,6 +74,8 @@ vlVaQueryImageFormats(VADriverContextP ctx, VAImageFormat *format_list, int *num enum pipe_format format; int i; + STATIC_ASSERT(ARRAY_SIZE(formats) == VL_VA_MAX_IMAGE_FORMATS); + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -80,8 +84,8 @@ vlVaQueryImageFormats(VADriverContextP ctx, VAImageFormat *format_list, int *num *num_formats = 0; pscreen = VL_VA_PSCREEN(ctx); - for (i = 0; i < VL_VA_MAX_IMAGE_FORMATS; ++i) { - format = YCbCrToPipe(formats[i].fourcc); + for (i = 0; i < ARRAY_SIZE(formats); ++i) { + format = VaFourccToPipeFormat(formats[i].fourcc); if (pscreen->is_video_format_supported(pscreen, format, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_BITSTREAM)) @@ -110,7 +114,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; @@ -149,6 +155,9 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig break; case VA_FOURCC('B','G','R','A'): + case VA_FOURCC('R','G','B','A'): + case VA_FOURCC('B','G','R','X'): + case VA_FOURCC('R','G','B','X'): img->num_planes = 1; img->pitches[0] = w * 4; img->offsets[0] = 0; @@ -172,27 +181,123 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig VAStatus vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) { + vlVaDriver *drv; + vlVaSurface *surf; + vlVaBuffer *img_buf; + VAImage *img; + struct pipe_surface **surfaces; + int w; + int h; + int i; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + surf = handle_table_get(drv->htab, surface); + + if (!surf || !surf->buffer || surf->buffer->interlaced) + return VA_STATUS_ERROR_INVALID_SURFACE; + + surfaces = surf->buffer->get_surfaces(surf->buffer); + if (!surfaces || !surfaces[0]->texture) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + img = CALLOC(1, sizeof(VAImage)); + if (!img) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + img->format.fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format); + img->buf = VA_INVALID_ID; + img->width = surf->buffer->width; + img->height = surf->buffer->height; + img->num_palette_entries = 0; + img->entry_bytes = 0; + w = align(surf->buffer->width, 2); + h = align(surf->buffer->height, 2); + + for (i = 0; i < ARRAY_SIZE(formats); ++i) { + if (img->format.fourcc == formats[i].fourcc) { + img->format = formats[i]; + break; + } + } + + switch (img->format.fourcc) { + case VA_FOURCC('U','Y','V','Y'): + case VA_FOURCC('Y','U','Y','V'): + img->num_planes = 1; + img->pitches[0] = w * 2; + img->offsets[0] = 0; + img->data_size = w * h * 2; + break; + + case VA_FOURCC('B','G','R','A'): + case VA_FOURCC('R','G','B','A'): + case VA_FOURCC('B','G','R','X'): + case VA_FOURCC('R','G','B','X'): + img->num_planes = 1; + img->pitches[0] = w * 4; + img->offsets[0] = 0; + img->data_size = w * h * 4; + break; + + default: + /* VaDeriveImage is designed for contiguous planes. */ + FREE(img); + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; + } + + img_buf = CALLOC(1, sizeof(vlVaBuffer)); + if (!img_buf) { + FREE(img); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + + pipe_mutex_lock(drv->mutex); + img->image_id = handle_table_add(drv->htab, img); + + img_buf->type = VAImageBufferType; + img_buf->size = img->data_size; + img_buf->num_elements = 1; + + 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; + + return VA_STATUS_SUCCESS; } VAStatus vlVaDestroyImage(VADriverContextP ctx, VAImageID image) { + vlVaDriver *drv; VAImage *vaimage; + VAStatus status; 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); + status = vlVaDestroyBuffer(ctx, vaimage->buf); FREE(vaimage); - return vlVaDestroyBuffer(ctx, vaimage->buf); + return status; } VAStatus @@ -223,34 +328,49 @@ 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 = YCbCrToPipe(vaimage->format.fourcc); - if (format == PIPE_FORMAT_NONE) + format = VaFourccToPipeFormat(vaimage->format.fourcc); + 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 conversion now only */ - if (format == PIPE_FORMAT_YV12 && - surf->buffer->buffer_format == PIPE_FORMAT_NV12) + /* support NV12 to YV12 and IYUV conversion now only */ + if ((format == PIPE_FORMAT_YV12 && + surf->buffer->buffer_format == PIPE_FORMAT_NV12) || + (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]; @@ -277,8 +397,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, @@ -293,6 +415,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; } @@ -315,22 +438,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; + } - format = YCbCrToPipe(vaimage->format.fourcc); - if (format == PIPE_FORMAT_NONE) + 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) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (format != surf->buffer->buffer_format) { struct pipe_video_buffer *tmp_buf; @@ -340,8 +479,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, tmp_buf = drv->pipe->create_video_buffer(drv->pipe, &surf->templat); if (!tmp_buf) { - surf->templat.buffer_format = old_surf_format; - return VA_STATUS_ERROR_ALLOCATION_FAILED; + surf->templat.buffer_format = old_surf_format; + pipe_mutex_unlock(drv->mutex); + return VA_STATUS_ERROR_ALLOCATION_FAILED; } surf->buffer->destroy(surf->buffer); @@ -349,8 +489,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]; @@ -379,6 +521,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; } |