Home | History | Annotate | Download | only in va
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 Thomas Balling Srensen & Orasanu Lucian.
      4  * Copyright 2014 Advanced Micro Devices, Inc.
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29 #include "util/u_memory.h"
     30 #include "util/u_handle_table.h"
     31 #include "util/u_sampler.h"
     32 
     33 #include "va_private.h"
     34 
     35 static VAImageFormat subpic_formats[] = {
     36    {
     37    .fourcc = VA_FOURCC_BGRA,
     38    .byte_order = VA_LSB_FIRST,
     39    .bits_per_pixel = 32,
     40    .depth = 32,
     41    .red_mask   = 0x00ff0000ul,
     42    .green_mask = 0x0000ff00ul,
     43    .blue_mask  = 0x000000fful,
     44    .alpha_mask = 0xff000000ul,
     45    },
     46 };
     47 
     48 VAStatus
     49 vlVaQuerySubpictureFormats(VADriverContextP ctx, VAImageFormat *format_list,
     50                            unsigned int *flags, unsigned int *num_formats)
     51 {
     52    if (!ctx)
     53       return VA_STATUS_ERROR_INVALID_CONTEXT;
     54 
     55    if (!(format_list && flags && num_formats))
     56       return VA_STATUS_ERROR_UNKNOWN;
     57 
     58    *num_formats = sizeof(subpic_formats)/sizeof(VAImageFormat);
     59    memcpy(format_list, subpic_formats, sizeof(subpic_formats));
     60 
     61    return VA_STATUS_SUCCESS;
     62 }
     63 
     64 VAStatus
     65 vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image,
     66                      VASubpictureID *subpicture)
     67 {
     68    vlVaDriver *drv;
     69    vlVaSubpicture *sub;
     70    VAImage *img;
     71 
     72    if (!ctx)
     73       return VA_STATUS_ERROR_INVALID_CONTEXT;
     74 
     75    drv = VL_VA_DRIVER(ctx);
     76    pipe_mutex_lock(drv->mutex);
     77    img = handle_table_get(drv->htab, image);
     78    if (!img) {
     79       pipe_mutex_unlock(drv->mutex);
     80       return VA_STATUS_ERROR_INVALID_IMAGE;
     81    }
     82 
     83    sub = CALLOC(1, sizeof(*sub));
     84    if (!sub) {
     85       pipe_mutex_unlock(drv->mutex);
     86       return VA_STATUS_ERROR_ALLOCATION_FAILED;
     87    }
     88 
     89    sub->image = img;
     90    *subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub);
     91    pipe_mutex_unlock(drv->mutex);
     92 
     93    return VA_STATUS_SUCCESS;
     94 }
     95 
     96 VAStatus
     97 vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture)
     98 {
     99    vlVaDriver *drv;
    100    vlVaSubpicture *sub;
    101 
    102    if (!ctx)
    103       return VA_STATUS_ERROR_INVALID_CONTEXT;
    104 
    105    drv = VL_VA_DRIVER(ctx);
    106    pipe_mutex_lock(drv->mutex);
    107 
    108    sub = handle_table_get(drv->htab, subpicture);
    109    if (!sub) {
    110       pipe_mutex_unlock(drv->mutex);
    111       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
    112    }
    113 
    114    FREE(sub);
    115    handle_table_remove(drv->htab, subpicture);
    116    pipe_mutex_unlock(drv->mutex);
    117 
    118    return VA_STATUS_SUCCESS;
    119 }
    120 
    121 VAStatus
    122 vlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image)
    123 {
    124    vlVaDriver *drv;
    125    vlVaSubpicture *sub;
    126    VAImage *img;
    127 
    128    if (!ctx)
    129       return VA_STATUS_ERROR_INVALID_CONTEXT;
    130 
    131    drv = VL_VA_DRIVER(ctx);
    132    pipe_mutex_lock(drv->mutex);
    133 
    134    img = handle_table_get(drv->htab, image);
    135    if (!img) {
    136       pipe_mutex_unlock(drv->mutex);
    137       return VA_STATUS_ERROR_INVALID_IMAGE;
    138    }
    139 
    140    sub = handle_table_get(drv->htab, subpicture);
    141    pipe_mutex_unlock(drv->mutex);
    142    if (!sub)
    143       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
    144 
    145    sub->image = img;
    146 
    147    return VA_STATUS_SUCCESS;
    148 }
    149 
    150 VAStatus
    151 vlVaSetSubpictureChromakey(VADriverContextP ctx, VASubpictureID subpicture,
    152                            unsigned int chromakey_min, unsigned int chromakey_max, unsigned int chromakey_mask)
    153 {
    154    if (!ctx)
    155       return VA_STATUS_ERROR_INVALID_CONTEXT;
    156 
    157    return VA_STATUS_ERROR_UNIMPLEMENTED;
    158 }
    159 
    160 VAStatus
    161 vlVaSetSubpictureGlobalAlpha(VADriverContextP ctx, VASubpictureID subpicture, float global_alpha)
    162 {
    163    if (!ctx)
    164       return VA_STATUS_ERROR_INVALID_CONTEXT;
    165 
    166    return VA_STATUS_ERROR_UNIMPLEMENTED;
    167 }
    168 
    169 VAStatus
    170 vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
    171                         VASurfaceID *target_surfaces, int num_surfaces,
    172                         short src_x, short src_y, unsigned short src_width,
    173                         unsigned short src_height, short dest_x, short dest_y,
    174                         unsigned short dest_width, unsigned short dest_height,
    175                         unsigned int flags)
    176 {
    177    vlVaSubpicture *sub;
    178    struct pipe_resource tex_temp, *tex;
    179    struct pipe_sampler_view sampler_templ;
    180    vlVaDriver *drv;
    181    vlVaSurface *surf;
    182    int i;
    183    struct u_rect src_rect = {src_x, src_x + src_width, src_y, src_y + src_height};
    184    struct u_rect dst_rect = {dest_x, dest_x + dest_width, dest_y, dest_y + dest_height};
    185 
    186    if (!ctx)
    187       return VA_STATUS_ERROR_INVALID_CONTEXT;
    188    drv = VL_VA_DRIVER(ctx);
    189    pipe_mutex_lock(drv->mutex);
    190 
    191    sub = handle_table_get(drv->htab, subpicture);
    192    if (!sub) {
    193       pipe_mutex_unlock(drv->mutex);
    194       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
    195    }
    196 
    197    for (i = 0; i < num_surfaces; i++) {
    198       surf = handle_table_get(drv->htab, target_surfaces[i]);
    199       if (!surf) {
    200          pipe_mutex_unlock(drv->mutex);
    201          return VA_STATUS_ERROR_INVALID_SURFACE;
    202       }
    203    }
    204 
    205    sub->src_rect = src_rect;
    206    sub->dst_rect = dst_rect;
    207 
    208    memset(&tex_temp, 0, sizeof(tex_temp));
    209    tex_temp.target = PIPE_TEXTURE_2D;
    210    tex_temp.format = PIPE_FORMAT_B8G8R8A8_UNORM;
    211    tex_temp.last_level = 0;
    212    tex_temp.width0 = src_width;
    213    tex_temp.height0 = src_height;
    214    tex_temp.depth0 = 1;
    215    tex_temp.array_size = 1;
    216    tex_temp.usage = PIPE_USAGE_DYNAMIC;
    217    tex_temp.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
    218    tex_temp.flags = 0;
    219    if (!drv->pipe->screen->is_format_supported(
    220           drv->pipe->screen, tex_temp.format, tex_temp.target,
    221           tex_temp.nr_samples, tex_temp.bind)) {
    222       pipe_mutex_unlock(drv->mutex);
    223       return VA_STATUS_ERROR_ALLOCATION_FAILED;
    224    }
    225 
    226    tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp);
    227 
    228    memset(&sampler_templ, 0, sizeof(sampler_templ));
    229    u_sampler_view_default_template(&sampler_templ, tex, tex->format);
    230    sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ);
    231    pipe_resource_reference(&tex, NULL);
    232    if (!sub->sampler) {
    233       pipe_mutex_unlock(drv->mutex);
    234       return VA_STATUS_ERROR_ALLOCATION_FAILED;
    235    }
    236 
    237    for (i = 0; i < num_surfaces; i++) {
    238       surf = handle_table_get(drv->htab, target_surfaces[i]);
    239       util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub);
    240    }
    241    pipe_mutex_unlock(drv->mutex);
    242 
    243    return VA_STATUS_SUCCESS;
    244 }
    245 
    246 VAStatus
    247 vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
    248                           VASurfaceID *target_surfaces, int num_surfaces)
    249 {
    250    int i;
    251    int j;
    252    vlVaSurface *surf;
    253    vlVaSubpicture *sub, **array;
    254    vlVaDriver *drv;
    255 
    256    if (!ctx)
    257       return VA_STATUS_ERROR_INVALID_CONTEXT;
    258    drv = VL_VA_DRIVER(ctx);
    259    pipe_mutex_lock(drv->mutex);
    260 
    261    sub = handle_table_get(drv->htab, subpicture);
    262    if (!sub) {
    263       pipe_mutex_unlock(drv->mutex);
    264       return VA_STATUS_ERROR_INVALID_SUBPICTURE;
    265    }
    266 
    267    for (i = 0; i < num_surfaces; i++) {
    268       surf = handle_table_get(drv->htab, target_surfaces[i]);
    269       if (!surf) {
    270          pipe_mutex_unlock(drv->mutex);
    271          return VA_STATUS_ERROR_INVALID_SURFACE;
    272       }
    273 
    274       array = surf->subpics.data;
    275       if (!array)
    276          continue;
    277 
    278       for (j = 0; j < surf->subpics.size/sizeof(vlVaSubpicture *); j++) {
    279          if (array[j] == sub)
    280             array[j] = NULL;
    281       }
    282 
    283       while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL)
    284          (void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *);
    285    }
    286    pipe_mutex_unlock(drv->mutex);
    287 
    288    return VA_STATUS_SUCCESS;
    289 }
    290