mozva.c (17840B)
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:expandtab:shiftwidth=4:tabstop=4: 3 */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #pragma GCC visibility push(default) 9 #include <va/va.h> 10 #pragma GCC visibility pop 11 12 #include <dlfcn.h> 13 #include <pthread.h> 14 15 #define GET_FUNC(func, lib) (func##Fn = dlsym(lib, #func)) 16 17 #define IS_FUNC_LOADED(func) (func##Fn != NULL) 18 19 static VAStatus (*vaDestroyBufferFn)(VADisplay dpy, VABufferID buffer_id); 20 static VAStatus (*vaBeginPictureFn)(VADisplay dpy, VAContextID context, 21 VASurfaceID render_target); 22 static VAStatus (*vaEndPictureFn)(VADisplay dpy, VAContextID context); 23 static VAStatus (*vaRenderPictureFn)(VADisplay dpy, VAContextID context, 24 VABufferID* buffers, int num_buffers); 25 static int (*vaMaxNumProfilesFn)(VADisplay dpy); 26 static VAStatus (*vaCreateContextFn)(VADisplay dpy, VAConfigID config_id, 27 int picture_width, int picture_height, 28 int flag, VASurfaceID* render_targets, 29 int num_render_targets, 30 VAContextID* context /* out */); 31 static VAStatus (*vaDestroyContextFn)(VADisplay dpy, VAContextID context); 32 static VAStatus (*vaCreateBufferFn)(VADisplay dpy, VAContextID context, 33 VABufferType type, /* in */ 34 unsigned int size, /* in */ 35 unsigned int num_elements, /* in */ 36 void* data, /* in */ 37 VABufferID* buf_id /* out */); 38 static VAStatus (*vaQuerySurfaceAttributesFn)(VADisplay dpy, VAConfigID config, 39 VASurfaceAttrib* attrib_list, 40 unsigned int* num_attribs); 41 static VAStatus (*vaQueryConfigProfilesFn)(VADisplay dpy, 42 VAProfile* profile_list, /* out */ 43 int* num_profiles /* out */); 44 static const char* (*vaErrorStrFn)(VAStatus error_status); 45 static VAStatus (*vaCreateConfigFn)(VADisplay dpy, VAProfile profile, 46 VAEntrypoint entrypoint, 47 VAConfigAttrib* attrib_list, 48 int num_attribs, 49 VAConfigID* config_id /* out */); 50 static VAStatus (*vaDestroyConfigFn)(VADisplay dpy, VAConfigID config_id); 51 static int (*vaMaxNumImageFormatsFn)(VADisplay dpy); 52 static VAStatus (*vaQueryImageFormatsFn)(VADisplay dpy, 53 VAImageFormat* format_list, /* out */ 54 int* num_formats /* out */); 55 static const char* (*vaQueryVendorStringFn)(VADisplay dpy); 56 static VAStatus (*vaDestroySurfacesFn)(VADisplay dpy, VASurfaceID* surfaces, 57 int num_surfaces); 58 static VAStatus (*vaCreateSurfacesFn)(VADisplay dpy, unsigned int format, 59 unsigned int width, unsigned int height, 60 VASurfaceID* surfaces, 61 unsigned int num_surfaces, 62 VASurfaceAttrib* attrib_list, 63 unsigned int num_attribs); 64 static VAStatus (*vaDeriveImageFn)(VADisplay dpy, VASurfaceID surface, 65 VAImage* image /* out */); 66 static VAStatus (*vaDestroyImageFn)(VADisplay dpy, VAImageID image); 67 static VAStatus (*vaPutImageFn)(VADisplay dpy, VASurfaceID surface, 68 VAImageID image, int src_x, int src_y, 69 unsigned int src_width, unsigned int src_height, 70 int dest_x, int dest_y, unsigned int dest_width, 71 unsigned int dest_height); 72 static VAStatus (*vaSyncSurfaceFn)(VADisplay dpy, VASurfaceID render_target); 73 static VAStatus (*vaCreateImageFn)(VADisplay dpy, VAImageFormat* format, 74 int width, int height, 75 VAImage* image /* out */); 76 static VAStatus (*vaGetImageFn)( 77 VADisplay dpy, VASurfaceID surface, 78 int x, /* coordinates of the upper left source pixel */ 79 int y, unsigned int width, /* width and height of the region */ 80 unsigned int height, VAImageID image); 81 static VAStatus (*vaMapBufferFn)(VADisplay dpy, VABufferID buf_id, /* in */ 82 void** pbuf /* out */); 83 static VAStatus (*vaUnmapBufferFn)(VADisplay dpy, VABufferID buf_id /* in */); 84 static VAStatus (*vaTerminateFn)(VADisplay dpy); 85 static VAStatus (*vaInitializeFn)(VADisplay dpy, int* major_version, /* out */ 86 int* minor_version /* out */); 87 static VAStatus (*vaSetDriverNameFn)(VADisplay dpy, char* driver_name); 88 static int (*vaMaxNumEntrypointsFn)(VADisplay dpy); 89 static VAStatus (*vaQueryConfigEntrypointsFn)(VADisplay dpy, VAProfile profile, 90 VAEntrypoint* entrypoint_list, 91 int* num_entrypoints); 92 static VAMessageCallback (*vaSetErrorCallbackFn)(VADisplay dpy, 93 VAMessageCallback callback, 94 void* user_context); 95 static VAMessageCallback (*vaSetInfoCallbackFn)(VADisplay dpy, 96 VAMessageCallback callback, 97 void* user_context); 98 int LoadVALibrary() { 99 static pthread_mutex_t sVALock = PTHREAD_MUTEX_INITIALIZER; 100 static void* sVALib = NULL; 101 static int sVAInitialized = 0; 102 static int sVALoaded = 0; 103 104 pthread_mutex_lock(&sVALock); 105 106 if (!sVAInitialized) { 107 sVAInitialized = 1; 108 sVALib = dlopen("libva.so.2", RTLD_LAZY); 109 if (!sVALib) { 110 pthread_mutex_unlock(&sVALock); 111 return 0; 112 } 113 GET_FUNC(vaDestroyBuffer, sVALib); 114 GET_FUNC(vaBeginPicture, sVALib); 115 GET_FUNC(vaEndPicture, sVALib); 116 GET_FUNC(vaRenderPicture, sVALib); 117 GET_FUNC(vaMaxNumProfiles, sVALib); 118 GET_FUNC(vaCreateContext, sVALib); 119 GET_FUNC(vaDestroyContext, sVALib); 120 GET_FUNC(vaCreateBuffer, sVALib); 121 GET_FUNC(vaQuerySurfaceAttributes, sVALib); 122 GET_FUNC(vaQueryConfigProfiles, sVALib); 123 GET_FUNC(vaErrorStr, sVALib); 124 GET_FUNC(vaCreateConfig, sVALib); 125 GET_FUNC(vaDestroyConfig, sVALib); 126 GET_FUNC(vaMaxNumImageFormats, sVALib); 127 GET_FUNC(vaQueryImageFormats, sVALib); 128 GET_FUNC(vaQueryVendorString, sVALib); 129 GET_FUNC(vaDestroySurfaces, sVALib); 130 GET_FUNC(vaCreateSurfaces, sVALib); 131 GET_FUNC(vaDeriveImage, sVALib); 132 GET_FUNC(vaDestroyImage, sVALib); 133 GET_FUNC(vaPutImage, sVALib); 134 GET_FUNC(vaSyncSurface, sVALib); 135 GET_FUNC(vaCreateImage, sVALib); 136 GET_FUNC(vaGetImage, sVALib); 137 GET_FUNC(vaMapBuffer, sVALib); 138 GET_FUNC(vaUnmapBuffer, sVALib); 139 GET_FUNC(vaTerminate, sVALib); 140 GET_FUNC(vaInitialize, sVALib); 141 GET_FUNC(vaSetDriverName, sVALib); 142 GET_FUNC(vaMaxNumEntrypoints, sVALib); 143 GET_FUNC(vaQueryConfigEntrypoints, sVALib); 144 GET_FUNC(vaSetErrorCallback, sVALib); 145 GET_FUNC(vaSetInfoCallback, sVALib); 146 147 sVALoaded = 148 (IS_FUNC_LOADED(vaDestroyBuffer) && IS_FUNC_LOADED(vaBeginPicture) && 149 IS_FUNC_LOADED(vaEndPicture) && IS_FUNC_LOADED(vaRenderPicture) && 150 IS_FUNC_LOADED(vaMaxNumProfiles) && IS_FUNC_LOADED(vaCreateContext) && 151 IS_FUNC_LOADED(vaDestroyContext) && IS_FUNC_LOADED(vaCreateBuffer) && 152 IS_FUNC_LOADED(vaQuerySurfaceAttributes) && 153 IS_FUNC_LOADED(vaQueryConfigProfiles) && IS_FUNC_LOADED(vaErrorStr) && 154 IS_FUNC_LOADED(vaCreateConfig) && IS_FUNC_LOADED(vaDestroyConfig) && 155 IS_FUNC_LOADED(vaMaxNumImageFormats) && 156 IS_FUNC_LOADED(vaQueryImageFormats) && 157 IS_FUNC_LOADED(vaQueryVendorString) && 158 IS_FUNC_LOADED(vaDestroySurfaces) && 159 IS_FUNC_LOADED(vaCreateSurfaces) && IS_FUNC_LOADED(vaDeriveImage) && 160 IS_FUNC_LOADED(vaDestroyImage) && IS_FUNC_LOADED(vaPutImage) && 161 IS_FUNC_LOADED(vaSyncSurface) && IS_FUNC_LOADED(vaCreateImage) && 162 IS_FUNC_LOADED(vaGetImage) && IS_FUNC_LOADED(vaMapBuffer) && 163 IS_FUNC_LOADED(vaUnmapBuffer) && IS_FUNC_LOADED(vaTerminate) && 164 IS_FUNC_LOADED(vaInitialize) && IS_FUNC_LOADED(vaSetDriverName) && 165 IS_FUNC_LOADED(vaMaxNumEntrypoints) && 166 IS_FUNC_LOADED(vaQueryConfigEntrypoints) && 167 IS_FUNC_LOADED(vaSetErrorCallback) && 168 IS_FUNC_LOADED(vaSetInfoCallback)); 169 } 170 pthread_mutex_unlock(&sVALock); 171 return sVALoaded; 172 } 173 174 #pragma GCC visibility push(default) 175 176 VAStatus vaDestroyBuffer(VADisplay dpy, VABufferID buffer_id) { 177 if (LoadVALibrary()) { 178 return vaDestroyBufferFn(dpy, buffer_id); 179 } 180 return VA_STATUS_ERROR_UNIMPLEMENTED; 181 } 182 183 VAStatus vaBeginPicture(VADisplay dpy, VAContextID context, 184 VASurfaceID render_target) { 185 if (LoadVALibrary()) { 186 return vaBeginPictureFn(dpy, context, render_target); 187 } 188 return VA_STATUS_ERROR_UNIMPLEMENTED; 189 } 190 191 VAStatus vaEndPicture(VADisplay dpy, VAContextID context) { 192 if (LoadVALibrary()) { 193 return vaEndPictureFn(dpy, context); 194 } 195 return VA_STATUS_ERROR_UNIMPLEMENTED; 196 } 197 198 VAStatus vaRenderPicture(VADisplay dpy, VAContextID context, 199 VABufferID* buffers, int num_buffers) { 200 if (LoadVALibrary()) { 201 return vaRenderPictureFn(dpy, context, buffers, num_buffers); 202 } 203 return VA_STATUS_ERROR_UNIMPLEMENTED; 204 } 205 206 int vaMaxNumProfiles(VADisplay dpy) { 207 if (LoadVALibrary()) { 208 return vaMaxNumProfilesFn(dpy); 209 } 210 return 0; 211 } 212 213 VAStatus vaCreateContext(VADisplay dpy, VAConfigID config_id, int picture_width, 214 int picture_height, int flag, 215 VASurfaceID* render_targets, int num_render_targets, 216 VAContextID* context /* out */) { 217 if (LoadVALibrary()) { 218 return vaCreateContextFn(dpy, config_id, picture_width, picture_height, 219 flag, render_targets, num_render_targets, context); 220 } 221 *context = 0; 222 return VA_STATUS_ERROR_UNIMPLEMENTED; 223 } 224 225 VAStatus vaDestroyContext(VADisplay dpy, VAContextID context) { 226 if (LoadVALibrary()) { 227 return vaDestroyContextFn(dpy, context); 228 } 229 return VA_STATUS_ERROR_UNIMPLEMENTED; 230 } 231 232 VAStatus vaCreateBuffer(VADisplay dpy, VAContextID context, 233 VABufferType type, /* in */ 234 unsigned int size, /* in */ 235 unsigned int num_elements, /* in */ 236 void* data, /* in */ 237 VABufferID* buf_id /* out */) { 238 if (LoadVALibrary()) { 239 return vaCreateBufferFn(dpy, context, type, size, num_elements, data, 240 buf_id); 241 } 242 *buf_id = 0; 243 return VA_STATUS_ERROR_UNIMPLEMENTED; 244 } 245 246 VAStatus vaQuerySurfaceAttributes(VADisplay dpy, VAConfigID config, 247 VASurfaceAttrib* attrib_list, 248 unsigned int* num_attribs) { 249 if (LoadVALibrary()) { 250 return vaQuerySurfaceAttributesFn(dpy, config, attrib_list, num_attribs); 251 } 252 return VA_STATUS_ERROR_UNIMPLEMENTED; 253 } 254 255 VAStatus vaQueryConfigProfiles(VADisplay dpy, VAProfile* profile_list, /* out */ 256 int* num_profiles /* out */) { 257 if (LoadVALibrary()) { 258 return vaQueryConfigProfilesFn(dpy, profile_list, num_profiles); 259 } 260 *num_profiles = 0; 261 return VA_STATUS_ERROR_UNIMPLEMENTED; 262 } 263 264 const char* vaErrorStr(VAStatus error_status) { 265 if (LoadVALibrary()) { 266 return vaErrorStrFn(error_status); 267 } 268 static char tmp[] = "Unimplemented"; 269 return tmp; 270 } 271 272 VAStatus vaCreateConfig(VADisplay dpy, VAProfile profile, 273 VAEntrypoint entrypoint, VAConfigAttrib* attrib_list, 274 int num_attribs, VAConfigID* config_id /* out */) { 275 if (LoadVALibrary()) { 276 return vaCreateConfigFn(dpy, profile, entrypoint, attrib_list, num_attribs, 277 config_id); 278 } 279 *config_id = 0; 280 return VA_STATUS_ERROR_UNIMPLEMENTED; 281 } 282 283 VAStatus vaDestroyConfig(VADisplay dpy, VAConfigID config_id) { 284 if (LoadVALibrary()) { 285 return vaDestroyConfigFn(dpy, config_id); 286 } 287 return VA_STATUS_ERROR_UNIMPLEMENTED; 288 } 289 290 int vaMaxNumImageFormats(VADisplay dpy) { 291 if (LoadVALibrary()) { 292 return vaMaxNumImageFormatsFn(dpy); 293 } 294 return 0; 295 } 296 297 VAStatus vaQueryImageFormats(VADisplay dpy, VAImageFormat* format_list, 298 int* num_formats) { 299 if (LoadVALibrary()) { 300 return vaQueryImageFormatsFn(dpy, format_list, num_formats); 301 } 302 return VA_STATUS_ERROR_UNIMPLEMENTED; 303 } 304 305 const char* vaQueryVendorString(VADisplay dpy) { 306 if (LoadVALibrary()) { 307 return vaQueryVendorStringFn(dpy); 308 } 309 return NULL; 310 } 311 312 VAStatus vaDestroySurfaces(VADisplay dpy, VASurfaceID* surfaces, 313 int num_surfaces) { 314 if (LoadVALibrary()) { 315 return vaDestroySurfacesFn(dpy, surfaces, num_surfaces); 316 } 317 return VA_STATUS_ERROR_UNIMPLEMENTED; 318 } 319 320 VAStatus vaCreateSurfaces(VADisplay dpy, unsigned int format, 321 unsigned int width, unsigned int height, 322 VASurfaceID* surfaces, unsigned int num_surfaces, 323 VASurfaceAttrib* attrib_list, 324 unsigned int num_attribs) { 325 if (LoadVALibrary()) { 326 return vaCreateSurfacesFn(dpy, format, width, height, surfaces, 327 num_surfaces, attrib_list, num_attribs); 328 } 329 return VA_STATUS_ERROR_UNIMPLEMENTED; 330 } 331 332 VAStatus vaDeriveImage(VADisplay dpy, VASurfaceID surface, 333 VAImage* image /* out */) { 334 if (LoadVALibrary()) { 335 return vaDeriveImageFn(dpy, surface, image); 336 } 337 return VA_STATUS_ERROR_UNIMPLEMENTED; 338 } 339 340 VAStatus vaDestroyImage(VADisplay dpy, VAImageID image) { 341 if (LoadVALibrary()) { 342 return vaDestroyImageFn(dpy, image); 343 } 344 return VA_STATUS_ERROR_UNIMPLEMENTED; 345 } 346 347 VAStatus vaPutImage(VADisplay dpy, VASurfaceID surface, VAImageID image, 348 int src_x, int src_y, unsigned int src_width, 349 unsigned int src_height, int dest_x, int dest_y, 350 unsigned int dest_width, unsigned int dest_height) { 351 if (LoadVALibrary()) { 352 return vaPutImageFn(dpy, surface, image, src_x, src_y, src_width, 353 src_height, dest_x, dest_y, dest_width, dest_height); 354 } 355 return VA_STATUS_ERROR_UNIMPLEMENTED; 356 } 357 358 VAStatus vaSyncSurface(VADisplay dpy, VASurfaceID render_target) { 359 if (LoadVALibrary()) { 360 return vaSyncSurfaceFn(dpy, render_target); 361 } 362 return VA_STATUS_ERROR_UNIMPLEMENTED; 363 } 364 365 VAStatus vaCreateImage(VADisplay dpy, VAImageFormat* format, int width, 366 int height, VAImage* image /* out */) { 367 if (LoadVALibrary()) { 368 return vaCreateImageFn(dpy, format, width, height, image); 369 } 370 return VA_STATUS_ERROR_UNIMPLEMENTED; 371 } 372 373 VAStatus vaGetImage(VADisplay dpy, VASurfaceID surface, 374 int x, /* coordinates of the upper left source pixel */ 375 int y, 376 unsigned int width, /* width and height of the region */ 377 unsigned int height, VAImageID image) { 378 if (LoadVALibrary()) { 379 return vaGetImageFn(dpy, surface, x, y, width, height, image); 380 } 381 return VA_STATUS_ERROR_UNIMPLEMENTED; 382 } 383 384 VAStatus vaMapBuffer(VADisplay dpy, VABufferID buf_id, /* in */ 385 void** pbuf /* out */) { 386 if (LoadVALibrary()) { 387 return vaMapBufferFn(dpy, buf_id, pbuf); 388 } 389 return VA_STATUS_ERROR_UNIMPLEMENTED; 390 } 391 392 VAStatus vaUnmapBuffer(VADisplay dpy, VABufferID buf_id /* in */) { 393 if (LoadVALibrary()) { 394 return vaUnmapBufferFn(dpy, buf_id); 395 } 396 return VA_STATUS_ERROR_UNIMPLEMENTED; 397 } 398 399 VAStatus vaTerminate(VADisplay dpy) { 400 if (LoadVALibrary()) { 401 return vaTerminateFn(dpy); 402 } 403 return VA_STATUS_ERROR_UNIMPLEMENTED; 404 } 405 406 VAStatus vaInitialize(VADisplay dpy, int* major_version, /* out */ 407 int* minor_version /* out */) { 408 if (LoadVALibrary()) { 409 return vaInitializeFn(dpy, major_version, minor_version); 410 } 411 return VA_STATUS_ERROR_UNIMPLEMENTED; 412 } 413 414 VAStatus vaSetDriverName(VADisplay dpy, char* driver_name) { 415 if (LoadVALibrary()) { 416 return vaSetDriverNameFn(dpy, driver_name); 417 } 418 return VA_STATUS_ERROR_UNIMPLEMENTED; 419 } 420 421 int vaMaxNumEntrypoints(VADisplay dpy) { 422 if (LoadVALibrary()) { 423 return vaMaxNumEntrypointsFn(dpy); 424 } 425 return 0; 426 } 427 428 VAStatus vaQueryConfigEntrypoints(VADisplay dpy, VAProfile profile, 429 VAEntrypoint* entrypoint_list, 430 int* num_entrypoints) { 431 if (LoadVALibrary()) { 432 return vaQueryConfigEntrypointsFn(dpy, profile, entrypoint_list, 433 num_entrypoints); 434 } 435 return VA_STATUS_ERROR_UNIMPLEMENTED; 436 } 437 438 VAMessageCallback vaSetErrorCallback(VADisplay dpy, VAMessageCallback callback, 439 void* user_context) { 440 if (LoadVALibrary()) { 441 return vaSetErrorCallbackFn(dpy, callback, user_context); 442 } 443 return NULL; 444 } 445 446 VAMessageCallback vaSetInfoCallback(VADisplay dpy, VAMessageCallback callback, 447 void* user_context) { 448 if (LoadVALibrary()) { 449 return vaSetInfoCallbackFn(dpy, callback, user_context); 450 } 451 return NULL; 452 } 453 454 #pragma GCC visibility pop