1/************************************************************************** 2 * 3 * Copyright 2010 Thomas Balling Sørensen & 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 35static 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 48VAStatus 49vlVaQuerySubpictureFormats(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 64VAStatus 65vlVaCreateSubpicture(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 96VAStatus 97vlVaDestroySubpicture(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 121VAStatus 122vlVaSubpictureImage(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 150VAStatus 151vlVaSetSubpictureChromakey(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 160VAStatus 161vlVaSetSubpictureGlobalAlpha(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 169VAStatus 170vlVaAssociateSubpicture(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 246VAStatus 247vlVaDeassociateSubpicture(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