diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/state_trackers/va/subpicture.c | 162 | ||||
-rw-r--r-- | src/gallium/state_trackers/va/va_private.h | 12 |
2 files changed, 161 insertions, 13 deletions
diff --git a/src/gallium/state_trackers/va/subpicture.c b/src/gallium/state_trackers/va/subpicture.c index b88511e4270..f1461894699 100644 --- a/src/gallium/state_trackers/va/subpicture.c +++ b/src/gallium/state_trackers/va/subpicture.c @@ -26,8 +26,25 @@ * **************************************************************************/ +#include "util/u_memory.h" +#include "util/u_handle_table.h" +#include "util/u_sampler.h" + #include "va_private.h" +static VAImageFormat subpic_formats[] = { + { + .fourcc = VA_FOURCC_BGRA, + .byte_order = VA_LSB_FIRST, + .bits_per_pixel = 32, + .depth = 32, + .red_mask = 0x00ff0000ul, + .green_mask = 0x0000ff00ul, + .blue_mask = 0x000000fful, + .alpha_mask = 0xff000000ul, + }, +}; + VAStatus vlVaQuerySubpictureFormats(VADriverContextP ctx, VAImageFormat *format_list, unsigned int *flags, unsigned int *num_formats) @@ -38,36 +55,74 @@ vlVaQuerySubpictureFormats(VADriverContextP ctx, VAImageFormat *format_list, if (!(format_list && flags && num_formats)) return VA_STATUS_ERROR_UNKNOWN; - *num_formats = 0; + *num_formats = sizeof(subpic_formats)/sizeof(VAImageFormat); + memcpy(format_list, subpic_formats, sizeof(subpic_formats)); return VA_STATUS_SUCCESS; } VAStatus -vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image, VASubpictureID *subpicture) +vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image, + VASubpictureID *subpicture) { + vlVaSubpicture *sub; + VAImage *img; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); + if (!img) + return VA_STATUS_ERROR_INVALID_IMAGE; + + sub = CALLOC(1, sizeof(*sub)); + if (!sub) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + sub->image = img; + *subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub); + + return VA_STATUS_SUCCESS; } VAStatus vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture) { + vlVaSubpicture *sub; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture); + if (!sub) + return VA_STATUS_ERROR_INVALID_SUBPICTURE; + + FREE(sub); + handle_table_remove(VL_VA_DRIVER(ctx)->htab, subpicture); + + return VA_STATUS_SUCCESS; } VAStatus vlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image) { + vlVaSubpicture *sub; + VAImage *img; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); + if (!img) + return VA_STATUS_ERROR_INVALID_IMAGE; + + sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture); + if (!sub) + return VA_STATUS_ERROR_INVALID_SUBPICTURE; + + sub->image = img; + + return VA_STATUS_SUCCESS; } VAStatus @@ -90,26 +145,107 @@ vlVaSetSubpictureGlobalAlpha(VADriverContextP ctx, VASubpictureID subpicture, fl } VAStatus -vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, VASurfaceID *target_surfaces, - int num_surfaces, short src_x, short src_y, - unsigned short src_width, unsigned short src_height, - short dest_x, short dest_y, - unsigned short dest_width, - unsigned short dest_height, +vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, + VASurfaceID *target_surfaces, int num_surfaces, + short src_x, short src_y, unsigned short src_width, + unsigned short src_height, short dest_x, short dest_y, + unsigned short dest_width, unsigned short dest_height, unsigned int flags) { + vlVaSubpicture *sub; + struct pipe_resource tex_temp, *tex; + struct pipe_sampler_view sampler_templ; + vlVaDriver *drv; + vlVaSurface *surf; + int i; + struct u_rect src_rect = {src_x, src_x + src_width, src_y, src_y + src_height}; + struct u_rect dst_rect = {dest_x, dest_x + dest_width, dest_y, dest_y + dest_height}; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + sub = handle_table_get(drv->htab, subpicture); + if (!sub) + return VA_STATUS_ERROR_INVALID_SUBPICTURE; + + for (i = 0; i < num_surfaces; i++) { + surf = handle_table_get(drv->htab, target_surfaces[i]); + if (!surf) + return VA_STATUS_ERROR_INVALID_SURFACE; + } + + sub->src_rect = src_rect; + sub->dst_rect = dst_rect; + + memset(&tex_temp, 0, sizeof(tex_temp)); + tex_temp.target = PIPE_TEXTURE_2D; + tex_temp.format = PIPE_FORMAT_B8G8R8A8_UNORM; + tex_temp.last_level = 0; + tex_temp.width0 = src_width; + tex_temp.height0 = src_height; + tex_temp.depth0 = 1; + tex_temp.array_size = 1; + tex_temp.usage = PIPE_USAGE_DYNAMIC; + tex_temp.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; + tex_temp.flags = 0; + if (!drv->pipe->screen->is_format_supported( + drv->pipe->screen, tex_temp.format, tex_temp.target, + tex_temp.nr_samples, tex_temp.bind)) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp); + + memset(&sampler_templ, 0, sizeof(sampler_templ)); + u_sampler_view_default_template(&sampler_templ, tex, tex->format); + sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ); + pipe_resource_reference(&tex, NULL); + if (!sub->sampler) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + for (i = 0; i < num_surfaces; i++) { + surf = handle_table_get(drv->htab, target_surfaces[i]); + util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub); + } - return VA_STATUS_ERROR_UNIMPLEMENTED; + return VA_STATUS_SUCCESS; } VAStatus vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, VASurfaceID *target_surfaces, int num_surfaces) { + int i; + int j; + vlVaSurface *surf; + vlVaSubpicture *sub, **array; + vlVaDriver *drv; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); - return VA_STATUS_ERROR_UNIMPLEMENTED; + sub = handle_table_get(drv->htab, subpicture); + if (!sub) + return VA_STATUS_ERROR_INVALID_SUBPICTURE; + + for (i = 0; i < num_surfaces; i++) { + surf = handle_table_get(drv->htab, target_surfaces[i]); + if (!surf) + return VA_STATUS_ERROR_INVALID_SURFACE; + + array = surf->subpics.data; + if (!array) + continue; + + for (j = 0; j < surf->subpics.size/sizeof(vlVaSubpicture *); j++) { + if (array[j] == sub) + array[j] = NULL; + } + + while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL) + (void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *); + } + + return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index f250f74d2ef..1ea7be79aa3 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -41,6 +41,8 @@ #include "vl/vl_compositor.h" #include "vl/vl_csc.h" +#include "util/u_dynarray.h" + #define VL_VA_DRIVER(ctx) ((vlVaDriver *)ctx->pDriverData) #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) @@ -155,6 +157,15 @@ typedef struct { } vlVaDriver; typedef struct { + VAImage *image; + + struct u_rect src_rect; + struct u_rect dst_rect; + + struct pipe_sampler_view *sampler; +} vlVaSubpicture; + +typedef struct { struct pipe_video_codec *decoder; struct pipe_video_buffer *target; union { @@ -185,6 +196,7 @@ typedef struct { typedef struct { struct pipe_video_buffer templat, *buffer; struct pipe_fence_handle *fence; + struct util_dynarray subpics; /* vlVaSubpicture */ } vlVaSurface; // Public functions: |