Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sub license, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  19.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  20.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #define _GNU_SOURCE 1
  26. #include "sysdeps.h"
  27. #include "va.h"
  28. #include "va_backend.h"
  29. #include "va_backend_vpp.h"
  30. #include "va_trace.h"
  31. #include "va_fool.h"
  32.  
  33. #include <assert.h>
  34. #include <stdarg.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <unistd.h>
  39. #include <kos32sys.h>
  40.  
  41. #define DRIVER_EXTENSION    "-video.dll"
  42. #define VA_DRIVERS_PATH     "/kolibrios/lib"
  43.  
  44. #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
  45. #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
  46.  
  47. #define ASSERT          assert
  48. #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable->va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
  49. #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
  50. #define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
  51.  
  52. /*
  53.  * read a config "env" for libva.conf or from environment setting
  54.  * liva.conf has higher priority
  55.  * return 0: the "env" is set, and the value is copied into env_value
  56.  *        1: the env is not set
  57.  */
  58. int va_parseConfig(char *env, char *env_value)
  59. {
  60.     char *token, *value, *saveptr;
  61.     char oneline[1024];
  62.     FILE *fp=NULL;
  63.  
  64.     if (env == NULL)
  65.         return 1;
  66.  
  67.     fp = fopen("/etc/libva.conf", "r");
  68.     while (fp && (fgets(oneline, 1024, fp) != NULL)) {
  69.         if (strlen(oneline) == 1)
  70.             continue;
  71.         token = strtok_r(oneline, "=\n", &saveptr);
  72.         value = strtok_r(NULL, "=\n", &saveptr);
  73.  
  74.         if (NULL == token || NULL == value)
  75.             continue;
  76.  
  77.         if (strcmp(token, env) == 0) {
  78.             if (env_value)
  79.                 strncpy(env_value,value, 1024);
  80.  
  81.             fclose(fp);
  82.  
  83.             return 0;
  84.         }
  85.     }
  86.     if (fp)
  87.         fclose(fp);
  88.  
  89.     /* no setting in config file, use env setting */
  90.     value = getenv(env);
  91.     if (value) {
  92.         if (env_value)
  93.             strncpy(env_value, value, 1024);
  94.         return 0;
  95.     }
  96.  
  97.     return 1;
  98. }
  99.  
  100. int vaDisplayIsValid(VADisplay dpy)
  101. {
  102.     VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
  103.     return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
  104. }
  105.  
  106. void va_errorMessage(const char *msg, ...)
  107. {
  108.     char buf[512], *dynbuf;
  109.     va_list args;
  110.     int n, len;
  111.  
  112.     va_start(args, msg);
  113.     len = vsnprintf(buf, sizeof(buf), msg, args);
  114.     va_end(args);
  115.  
  116.     if (len >= (int)sizeof(buf)) {
  117.         dynbuf = malloc(len + 1);
  118.         if (!dynbuf)
  119.             return;
  120.         va_start(args, msg);
  121.         n = vsnprintf(dynbuf, len + 1, msg, args);
  122.         va_end(args);
  123.         if (n == len)
  124.             va_log_error(dynbuf);
  125.         free(dynbuf);
  126.     }
  127.     else if (len > 0)
  128.         va_log_error(buf);
  129. }
  130.  
  131. void va_infoMessage(const char *msg, ...)
  132. {
  133.     char buf[512], *dynbuf;
  134.     va_list args;
  135.     int n, len;
  136.  
  137.     va_start(args, msg);
  138.     len = vsnprintf(buf, sizeof(buf), msg, args);
  139.     va_end(args);
  140.  
  141.     if (len >= (int)sizeof(buf)) {
  142.         dynbuf = malloc(len + 1);
  143.         if (!dynbuf)
  144.             return;
  145.         va_start(args, msg);
  146.         n = vsnprintf(dynbuf, len + 1, msg, args);
  147.         va_end(args);
  148.         if (n == len)
  149.             va_log_info(dynbuf);
  150.         free(dynbuf);
  151.     }
  152.     else if (len > 0)
  153.         va_log_info(buf);
  154. }
  155.  
  156. static bool va_checkVtable(void *ptr, char *function)
  157. {
  158.     if (!ptr) {
  159.         va_errorMessage("No valid vtable entry for va%s\n", function);
  160.         return false;
  161.     }
  162.     return true;
  163. }
  164.  
  165. static bool va_checkMaximum(int value, char *variable)
  166. {
  167.     if (!value) {
  168.         va_errorMessage("Failed to define max_%s in init\n", variable);
  169.         return false;
  170.     }
  171.     return true;
  172. }
  173.  
  174. static bool va_checkString(const char* value, char *variable)
  175. {
  176.     if (!value) {
  177.         va_errorMessage("Failed to define str_%s in init\n", variable);
  178.         return false;
  179.     }
  180.     return true;
  181. }
  182.  
  183. static inline int
  184. va_getDriverInitName(char *name, int namelen, int major, int minor)
  185. {
  186.     int ret = snprintf(name, namelen, "__vaDriverInit_%d_%d", major, minor);
  187.     return ret > 0 && ret < namelen;
  188. }
  189.  
  190. static VAStatus va_getDriverName(VADisplay dpy, char **driver_name)
  191. {
  192.     VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
  193.  
  194.     return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
  195. }
  196.  
  197. static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
  198. {
  199.     VADriverContextP ctx = CTX(dpy);
  200.     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
  201.     char *search_path = NULL;
  202.     char *saveptr;
  203.     char *driver_dir;
  204.  
  205.     if (!search_path)
  206.         search_path = VA_DRIVERS_PATH;
  207.  
  208.     search_path = strdup((const char *)search_path);
  209.     driver_dir = strtok_r(search_path, ":", &saveptr);
  210.     while (driver_dir) {
  211.         void *handle = NULL;
  212.         char *driver_path = (char *) malloc( strlen(driver_dir) +
  213.                                              strlen(driver_name) +
  214.                                              strlen(DRIVER_EXTENSION) + 2 );
  215.         if (!driver_path) {
  216.             va_errorMessage("%s L%d Out of memory!n",
  217.                                 __FUNCTION__, __LINE__);
  218.             free(search_path);
  219.             return VA_STATUS_ERROR_ALLOCATION_FAILED;
  220.         }
  221.  
  222.         strncpy( driver_path, driver_dir, strlen(driver_dir) + 1);
  223.         strncat( driver_path, "/", strlen("/") );
  224.         strncat( driver_path, driver_name, strlen(driver_name) );
  225.         strncat( driver_path, DRIVER_EXTENSION, strlen(DRIVER_EXTENSION) );
  226.  
  227.         va_infoMessage("Trying to open %s\n", driver_path);
  228.         handle = load_library( driver_path);
  229.         if (!handle) {
  230.             /* Don't give errors for non-existing files */
  231.             if (0 == access( driver_path, F_OK))
  232.                 va_errorMessage("load_library of %s failed\n", driver_path);
  233.         } else {
  234.             VADriverInit init_func = NULL;
  235.             char init_func_s[256];
  236.             int i;
  237.  
  238.             static const struct {
  239.                 int major;
  240.                 int minor;
  241.             } compatible_versions[] = {
  242.                 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
  243.                 { 0, 35 },
  244.                 { 0, 34 },
  245.                 { 0, 33 },
  246.                 { 0, 32 },
  247.                 { -1, }
  248.             };
  249.  
  250.             for (i = 0; compatible_versions[i].major >= 0; i++) {
  251.                 if (va_getDriverInitName(init_func_s, sizeof(init_func_s),
  252.                                          compatible_versions[i].major,
  253.                                          compatible_versions[i].minor)) {
  254.                     init_func = (VADriverInit)get_proc_address(handle, init_func_s);
  255.                     if (init_func) {
  256.                         va_infoMessage("Found init function %s\n", init_func_s);
  257.                         break;
  258.                     }
  259.                 }
  260.             }
  261.  
  262.             if (compatible_versions[i].major < 0) {
  263.                 va_errorMessage("%s has no function %s\n",
  264.                                 driver_path, init_func_s);
  265. //                dlclose(handle);
  266.             } else {
  267.                 struct VADriverVTable *vtable = ctx->vtable;
  268.                 struct VADriverVTableVPP *vtable_vpp = ctx->vtable_vpp;
  269.  
  270.                 vaStatus = VA_STATUS_SUCCESS;
  271.                 if (!vtable) {
  272.                     vtable = calloc(1, sizeof(*vtable));
  273.                     if (!vtable)
  274.                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
  275.                 }
  276.                 ctx->vtable = vtable;
  277.  
  278.                 if (!vtable_vpp) {
  279.                     vtable_vpp = calloc(1, sizeof(*vtable_vpp));
  280.                     if (vtable_vpp)
  281.                         vtable_vpp->version = VA_DRIVER_VTABLE_VPP_VERSION;
  282.                     else
  283.                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
  284.                 }
  285.                 ctx->vtable_vpp = vtable_vpp;
  286.  
  287.                 if (init_func && VA_STATUS_SUCCESS == vaStatus)
  288.                     vaStatus = (*init_func)(ctx);
  289.  
  290.                 if (VA_STATUS_SUCCESS == vaStatus) {
  291.                     CHECK_MAXIMUM(vaStatus, ctx, profiles);
  292.                     CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
  293.                     CHECK_MAXIMUM(vaStatus, ctx, attributes);
  294.                     CHECK_MAXIMUM(vaStatus, ctx, image_formats);
  295.                     CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
  296.                     CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
  297.                     CHECK_STRING(vaStatus, ctx, vendor);
  298.                     CHECK_VTABLE(vaStatus, ctx, Terminate);
  299.                     CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
  300.                     CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
  301.                     CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
  302.                     CHECK_VTABLE(vaStatus, ctx, CreateConfig);
  303.                     CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
  304.                     CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
  305.                     CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
  306.                     CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
  307.                     CHECK_VTABLE(vaStatus, ctx, CreateContext);
  308.                     CHECK_VTABLE(vaStatus, ctx, DestroyContext);
  309.                     CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
  310.                     CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
  311.                     CHECK_VTABLE(vaStatus, ctx, MapBuffer);
  312.                     CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
  313.                     CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
  314.                     CHECK_VTABLE(vaStatus, ctx, BeginPicture);
  315.                     CHECK_VTABLE(vaStatus, ctx, RenderPicture);
  316.                     CHECK_VTABLE(vaStatus, ctx, EndPicture);
  317.                     CHECK_VTABLE(vaStatus, ctx, SyncSurface);
  318.                     CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
  319.                     CHECK_VTABLE(vaStatus, ctx, PutSurface);
  320.                     CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
  321.                     CHECK_VTABLE(vaStatus, ctx, CreateImage);
  322.                     CHECK_VTABLE(vaStatus, ctx, DeriveImage);
  323.                     CHECK_VTABLE(vaStatus, ctx, DestroyImage);
  324.                     CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
  325.                     CHECK_VTABLE(vaStatus, ctx, GetImage);
  326.                     CHECK_VTABLE(vaStatus, ctx, PutImage);
  327.                     CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
  328.                     CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
  329.                     CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
  330.                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
  331.                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
  332.                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
  333.                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
  334.                     CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
  335.                     CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
  336.                     CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
  337.                     CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
  338.                 }
  339.                 if (VA_STATUS_SUCCESS != vaStatus) {
  340.                     va_errorMessage("%s init failed\n", driver_path);
  341. //                    dlclose(handle);
  342.                 }
  343.                 if (VA_STATUS_SUCCESS == vaStatus)
  344.                     ctx->handle = handle;
  345.                 free(driver_path);
  346.                 break;
  347.             }
  348.         }
  349.         free(driver_path);
  350.  
  351.         driver_dir = strtok_r(NULL, ":", &saveptr);
  352.     }
  353.  
  354.     free(search_path);
  355.  
  356.     return vaStatus;
  357. }
  358.  
  359. VAPrivFunc vaGetLibFunc(VADisplay dpy, const char *func)
  360. {
  361.     VADriverContextP ctx;
  362.     if (!vaDisplayIsValid(dpy))
  363.         return NULL;
  364.     ctx = CTX(dpy);
  365.  
  366.     if (NULL == ctx->handle)
  367.         return NULL;
  368.  
  369.     return (VAPrivFunc) get_proc_address(ctx->handle, func);
  370. }
  371.  
  372.  
  373. /*
  374.  * Returns a short english description of error_status
  375.  */
  376. const char *vaErrorStr(VAStatus error_status)
  377. {
  378.     switch(error_status) {
  379.         case VA_STATUS_SUCCESS:
  380.             return "success (no error)";
  381.         case VA_STATUS_ERROR_OPERATION_FAILED:
  382.             return "operation failed";
  383.         case VA_STATUS_ERROR_ALLOCATION_FAILED:
  384.             return "resource allocation failed";
  385.         case VA_STATUS_ERROR_INVALID_DISPLAY:
  386.             return "invalid VADisplay";
  387.         case VA_STATUS_ERROR_INVALID_CONFIG:
  388.             return "invalid VAConfigID";
  389.         case VA_STATUS_ERROR_INVALID_CONTEXT:
  390.             return "invalid VAContextID";
  391.         case VA_STATUS_ERROR_INVALID_SURFACE:
  392.             return "invalid VASurfaceID";
  393.         case VA_STATUS_ERROR_INVALID_BUFFER:
  394.             return "invalid VABufferID";
  395.         case VA_STATUS_ERROR_INVALID_IMAGE:
  396.             return "invalid VAImageID";
  397.         case VA_STATUS_ERROR_INVALID_SUBPICTURE:
  398.             return "invalid VASubpictureID";
  399.         case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
  400.             return "attribute not supported";
  401.         case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
  402.             return "list argument exceeds maximum number";
  403.         case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
  404.             return "the requested VAProfile is not supported";
  405.         case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
  406.             return "the requested VAEntryPoint is not supported";
  407.         case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
  408.             return "the requested RT Format is not supported";
  409.         case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
  410.             return "the requested VABufferType is not supported";
  411.         case VA_STATUS_ERROR_SURFACE_BUSY:
  412.             return "surface is in use";
  413.         case VA_STATUS_ERROR_FLAG_NOT_SUPPORTED:
  414.             return "flag not supported";
  415.         case VA_STATUS_ERROR_INVALID_PARAMETER:
  416.             return "invalid parameter";
  417.         case VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED:
  418.             return "resolution not supported";
  419.         case VA_STATUS_ERROR_UNIMPLEMENTED:
  420.             return "the requested function is not implemented";
  421.         case VA_STATUS_ERROR_SURFACE_IN_DISPLAYING:
  422.             return "surface is in displaying (may by overlay)" ;
  423.         case VA_STATUS_ERROR_INVALID_IMAGE_FORMAT:
  424.             return "invalid VAImageFormat";
  425.         case VA_STATUS_ERROR_INVALID_VALUE:
  426.             return "an invalid/unsupported value was supplied";
  427.         case VA_STATUS_ERROR_UNSUPPORTED_FILTER:
  428.             return "the requested filter is not supported";
  429.         case VA_STATUS_ERROR_INVALID_FILTER_CHAIN:
  430.             return "an invalid filter chain was supplied";
  431.         case VA_STATUS_ERROR_UNKNOWN:
  432.             return "unknown libva error";
  433.     }
  434.     return "unknown libva error / description missing";
  435. }
  436.  
  437. VAStatus vaInitialize (
  438.     VADisplay dpy,
  439.     int *major_version,  /* out */
  440.     int *minor_version   /* out */
  441. )
  442. {
  443.     char *driver_name = NULL;
  444.     VAStatus vaStatus;
  445.  
  446.     CHECK_DISPLAY(dpy);
  447.  
  448.     va_TraceInit(dpy);
  449.  
  450.     va_FoolInit(dpy);
  451.  
  452.     va_infoMessage("VA-API version %s\n", VA_VERSION_S);
  453.  
  454.     vaStatus = va_getDriverName(dpy, &driver_name);
  455.     va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
  456.  
  457.     if ((VA_STATUS_SUCCESS == vaStatus) && (driver_name != NULL)) {
  458.         vaStatus = va_openDriver(dpy, driver_name);
  459.         va_infoMessage("va_openDriver() returns %d\n", vaStatus);
  460.  
  461.         *major_version = VA_MAJOR_VERSION;
  462.         *minor_version = VA_MINOR_VERSION;
  463.     } else
  464.         va_errorMessage("va_getDriverName() failed with %s,driver_name=%s\n",
  465.                         vaErrorStr(vaStatus), driver_name);
  466.  
  467.     if (driver_name)
  468.         free(driver_name);
  469.  
  470.     VA_TRACE_LOG(va_TraceInitialize, dpy, major_version, minor_version);
  471.  
  472.     return vaStatus;
  473. }
  474.  
  475.  
  476. /*
  477.  * After this call, all library internal resources will be cleaned up
  478.  */
  479. VAStatus vaTerminate (
  480.     VADisplay dpy
  481. )
  482. {
  483.   VAStatus vaStatus = VA_STATUS_SUCCESS;
  484.   VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
  485.   VADriverContextP old_ctx;
  486.  
  487.   CHECK_DISPLAY(dpy);
  488.   old_ctx = CTX(dpy);
  489.  
  490.   if (old_ctx->handle) {
  491.       vaStatus = old_ctx->vtable->vaTerminate(old_ctx);
  492. //      dlclose(old_ctx->handle);
  493.       old_ctx->handle = NULL;
  494.   }
  495.   free(old_ctx->vtable);
  496.   old_ctx->vtable = NULL;
  497.   free(old_ctx->vtable_vpp);
  498.   old_ctx->vtable_vpp = NULL;
  499.  
  500.   VA_TRACE_LOG(va_TraceTerminate, dpy);
  501.  
  502.   va_TraceEnd(dpy);
  503.  
  504.   va_FoolEnd(dpy);
  505.  
  506.   if (VA_STATUS_SUCCESS == vaStatus)
  507.       pDisplayContext->vaDestroy(pDisplayContext);
  508.  
  509.   return vaStatus;
  510. }
  511.  
  512. /*
  513.  * vaQueryVendorString returns a pointer to a zero-terminated string
  514.  * describing some aspects of the VA implemenation on a specific
  515.  * hardware accelerator. The format of the returned string is:
  516.  * <vendorname>-<major_version>-<minor_version>-<addtional_info>
  517.  * e.g. for the Intel GMA500 implementation, an example would be:
  518.  * "IntelGMA500-1.0-0.2-patch3
  519.  */
  520. const char *vaQueryVendorString (
  521.     VADisplay dpy
  522. )
  523. {
  524.   if (!vaDisplayIsValid(dpy))
  525.       return NULL;
  526.  
  527.   return CTX(dpy)->str_vendor;
  528. }
  529.  
  530.  
  531. /* Get maximum number of profiles supported by the implementation */
  532. int vaMaxNumProfiles (
  533.     VADisplay dpy
  534. )
  535. {
  536.   if (!vaDisplayIsValid(dpy))
  537.       return 0;
  538.  
  539.   return CTX(dpy)->max_profiles;
  540. }
  541.  
  542. /* Get maximum number of entrypoints supported by the implementation */
  543. int vaMaxNumEntrypoints (
  544.     VADisplay dpy
  545. )
  546. {
  547.   if (!vaDisplayIsValid(dpy))
  548.       return 0;
  549.  
  550.   return CTX(dpy)->max_entrypoints;
  551. }
  552.  
  553.  
  554. /* Get maximum number of attributs supported by the implementation */
  555. int vaMaxNumConfigAttributes (
  556.     VADisplay dpy
  557. )
  558. {
  559.   if (!vaDisplayIsValid(dpy))
  560.       return 0;
  561.  
  562.   return CTX(dpy)->max_attributes;
  563. }
  564.  
  565. VAStatus vaQueryConfigEntrypoints (
  566.     VADisplay dpy,
  567.     VAProfile profile,
  568.     VAEntrypoint *entrypoints,  /* out */
  569.     int *num_entrypoints        /* out */
  570. )
  571. {
  572.   VADriverContextP ctx;
  573.   CHECK_DISPLAY(dpy);
  574.   ctx = CTX(dpy);
  575.  
  576.   return ctx->vtable->vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
  577. }
  578.  
  579. VAStatus vaGetConfigAttributes (
  580.     VADisplay dpy,
  581.     VAProfile profile,
  582.     VAEntrypoint entrypoint,
  583.     VAConfigAttrib *attrib_list, /* in/out */
  584.     int num_attribs
  585. )
  586. {
  587.   VADriverContextP ctx;
  588.   CHECK_DISPLAY(dpy);
  589.   ctx = CTX(dpy);
  590.  
  591.   return ctx->vtable->vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
  592. }
  593.  
  594. VAStatus vaQueryConfigProfiles (
  595.     VADisplay dpy,
  596.     VAProfile *profile_list,    /* out */
  597.     int *num_profiles           /* out */
  598. )
  599. {
  600.   VADriverContextP ctx;
  601.   CHECK_DISPLAY(dpy);
  602.   ctx = CTX(dpy);
  603.  
  604.   return ctx->vtable->vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
  605. }
  606.  
  607. VAStatus vaCreateConfig (
  608.     VADisplay dpy,
  609.     VAProfile profile,
  610.     VAEntrypoint entrypoint,
  611.     VAConfigAttrib *attrib_list,
  612.     int num_attribs,
  613.     VAConfigID *config_id /* out */
  614. )
  615. {
  616.   VADriverContextP ctx;
  617.   VAStatus vaStatus = VA_STATUS_SUCCESS;
  618.  
  619.   CHECK_DISPLAY(dpy);
  620.   ctx = CTX(dpy);
  621.  
  622.   vaStatus = ctx->vtable->vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
  623.  
  624.   /* record the current entrypoint for further trace/fool determination */
  625.   VA_TRACE_ALL(va_TraceCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
  626.   VA_FOOL_FUNC(va_FoolCreateConfig, dpy, profile, entrypoint, attrib_list, num_attribs, config_id);
  627.  
  628.   return vaStatus;
  629. }
  630.  
  631. VAStatus vaDestroyConfig (
  632.     VADisplay dpy,
  633.     VAConfigID config_id
  634. )
  635. {
  636.   VADriverContextP ctx;
  637.   CHECK_DISPLAY(dpy);
  638.   ctx = CTX(dpy);
  639.  
  640.   return ctx->vtable->vaDestroyConfig ( ctx, config_id );
  641. }
  642.  
  643. VAStatus vaQueryConfigAttributes (
  644.     VADisplay dpy,
  645.     VAConfigID config_id,
  646.     VAProfile *profile,         /* out */
  647.     VAEntrypoint *entrypoint,   /* out */
  648.     VAConfigAttrib *attrib_list,/* out */
  649.     int *num_attribs            /* out */
  650. )
  651. {
  652.   VADriverContextP ctx;
  653.   CHECK_DISPLAY(dpy);
  654.   ctx = CTX(dpy);
  655.  
  656.   return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
  657. }
  658.  
  659. /* XXX: this is a slow implementation that will be removed */
  660. static VAStatus
  661. va_impl_query_surface_attributes(
  662.     VADriverContextP    ctx,
  663.     VAConfigID          config,
  664.     VASurfaceAttrib    *out_attribs,
  665.     unsigned int       *out_num_attribs_ptr
  666. )
  667. {
  668.     VASurfaceAttrib *attribs = NULL;
  669.     unsigned int num_attribs, n;
  670.     VASurfaceAttrib *out_attrib;
  671.     unsigned int out_num_attribs;
  672.     VAImageFormat *image_formats = NULL;
  673.     int num_image_formats, i;
  674.     VAStatus va_status;
  675.  
  676.     /* List of surface attributes to query */
  677.     struct va_surface_attrib_map {
  678.         VASurfaceAttribType type;
  679.         VAGenericValueType  value_type;
  680.     };
  681.     static const struct va_surface_attrib_map attribs_map[] = {
  682.         { VASurfaceAttribMinWidth,      VAGenericValueTypeInteger },
  683.         { VASurfaceAttribMaxWidth,      VAGenericValueTypeInteger },
  684.         { VASurfaceAttribMinHeight,     VAGenericValueTypeInteger },
  685.         { VASurfaceAttribMaxHeight,     VAGenericValueTypeInteger },
  686.         { VASurfaceAttribMemoryType,    VAGenericValueTypeInteger },
  687.         { VASurfaceAttribNone, }
  688.     };
  689.  
  690.     if (!out_attribs || !out_num_attribs_ptr)
  691.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  692.     if (!ctx->vtable->vaGetSurfaceAttributes)
  693.         return VA_STATUS_ERROR_UNIMPLEMENTED;
  694.  
  695.     num_image_formats = ctx->max_image_formats;
  696.     image_formats = malloc(num_image_formats * sizeof(*image_formats));
  697.     if (!image_formats) {
  698.         va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
  699.         goto end;
  700.     }
  701.  
  702.     va_status = ctx->vtable->vaQueryImageFormats(
  703.         ctx, image_formats, &num_image_formats);
  704.     if (va_status != VA_STATUS_SUCCESS)
  705.         goto end;
  706.  
  707.     num_attribs = VASurfaceAttribCount + num_image_formats;
  708.     attribs = malloc(num_attribs * sizeof(*attribs));
  709.     if (!attribs) {
  710.         va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
  711.         goto end;
  712.     }
  713.  
  714.     /* Initialize with base surface attributes, except pixel-formats */
  715.     for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
  716.         VASurfaceAttrib * const attrib = &attribs[n];
  717.         attrib->type = attribs_map[n].type;
  718.         attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
  719.         attrib->value.type = attribs_map[n].value_type;
  720.     }
  721.  
  722.     /* Append image formats */
  723.     for (i = 0; i < num_image_formats; i++) {
  724.         VASurfaceAttrib * const attrib = &attribs[n];
  725.         attrib->type = VASurfaceAttribPixelFormat;
  726.         attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
  727.         attrib->value.type = VAGenericValueTypeInteger;
  728.         attrib->value.value.i = image_formats[i].fourcc;
  729.         if (++n == num_attribs) {
  730.             va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
  731.             goto end;
  732.         }
  733.     }
  734.     num_attribs = n;
  735.  
  736.     va_status = ctx->vtable->vaGetSurfaceAttributes(
  737.         ctx, config, attribs, num_attribs);
  738.     if (va_status != VA_STATUS_SUCCESS)
  739.         goto end;
  740.  
  741.     /* Remove invalid entries */
  742.     out_num_attribs = 0;
  743.     for (n = 0; n < num_attribs; n++) {
  744.         VASurfaceAttrib * const attrib = &attribs[n];
  745.  
  746.         if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
  747.             continue;
  748.  
  749.         // Accept all surface attributes that are not pixel-formats
  750.         if (attrib->type != VASurfaceAttribPixelFormat) {
  751.             out_num_attribs++;
  752.             continue;
  753.         }
  754.  
  755.         // Drop invalid pixel-format attribute
  756.         if (!attrib->value.value.i) {
  757.             attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  758.             continue;
  759.         }
  760.  
  761.         // Check for duplicates
  762.         int is_duplicate = 0;
  763.         for (i = n - 1; i >= 0 && !is_duplicate; i--) {
  764.             const VASurfaceAttrib * const prev_attrib = &attribs[i];
  765.             if (prev_attrib->type != VASurfaceAttribPixelFormat)
  766.                 break;
  767.             is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
  768.         }
  769.         if (is_duplicate)
  770.             attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  771.         else
  772.             out_num_attribs++;
  773.     }
  774.  
  775.     if (*out_num_attribs_ptr < out_num_attribs) {
  776.         *out_num_attribs_ptr = out_num_attribs;
  777.         va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  778.         goto end;
  779.     }
  780.  
  781.     out_attrib = out_attribs;
  782.     for (n = 0; n < num_attribs; n++) {
  783.         const VASurfaceAttrib * const attrib = &attribs[n];
  784.         if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
  785.             continue;
  786.         *out_attrib++ = *attrib;
  787.     }
  788.  
  789. end:
  790.     free(attribs);
  791.     free(image_formats);
  792.     return va_status;
  793. }
  794.  
  795. VAStatus
  796. vaQuerySurfaceAttributes(
  797.     VADisplay           dpy,
  798.     VAConfigID          config,
  799.     VASurfaceAttrib    *attrib_list,
  800.     unsigned int       *num_attribs
  801. )
  802. {
  803.     VADriverContextP ctx;
  804.     VAStatus vaStatus;
  805.  
  806.     CHECK_DISPLAY(dpy);
  807.     ctx = CTX(dpy);
  808.     if (!ctx)
  809.         return VA_STATUS_ERROR_INVALID_DISPLAY;
  810.  
  811.     if (!ctx->vtable->vaQuerySurfaceAttributes)
  812.         vaStatus = va_impl_query_surface_attributes(ctx, config,
  813.                                                     attrib_list, num_attribs);
  814.     else
  815.         vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
  816.                                                          attrib_list, num_attribs);
  817.  
  818.     VA_TRACE_LOG(va_TraceQuerySurfaceAttributes, dpy, config, attrib_list, num_attribs);
  819.  
  820.     return vaStatus;
  821. }
  822.  
  823. VAStatus
  824. vaCreateSurfaces(
  825.     VADisplay           dpy,
  826.     unsigned int        format,
  827.     unsigned int        width,
  828.     unsigned int        height,
  829.     VASurfaceID        *surfaces,
  830.     unsigned int        num_surfaces,
  831.     VASurfaceAttrib    *attrib_list,
  832.     unsigned int        num_attribs
  833. )
  834. {
  835.     VADriverContextP ctx;
  836.     VAStatus vaStatus;
  837.  
  838.     CHECK_DISPLAY(dpy);
  839.     ctx = CTX(dpy);
  840.     if (!ctx)
  841.         return VA_STATUS_ERROR_INVALID_DISPLAY;
  842.  
  843.     if (ctx->vtable->vaCreateSurfaces2)
  844.         vaStatus = ctx->vtable->vaCreateSurfaces2(ctx, format, width, height,
  845.                                               surfaces, num_surfaces,
  846.                                               attrib_list, num_attribs);
  847.     else if (attrib_list && num_attribs > 0)
  848.         vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
  849.     else
  850.         vaStatus = ctx->vtable->vaCreateSurfaces(ctx, width, height, format,
  851.                                                  num_surfaces, surfaces);
  852.     VA_TRACE_LOG(va_TraceCreateSurfaces,
  853.                  dpy, width, height, format, num_surfaces, surfaces,
  854.                  attrib_list, num_attribs);
  855.  
  856.     return vaStatus;
  857. }
  858.  
  859.  
  860. VAStatus vaDestroySurfaces (
  861.     VADisplay dpy,
  862.     VASurfaceID *surface_list,
  863.     int num_surfaces
  864. )
  865. {
  866.   VADriverContextP ctx;
  867.   VAStatus vaStatus;
  868.  
  869.   CHECK_DISPLAY(dpy);
  870.   ctx = CTX(dpy);
  871.  
  872.   VA_TRACE_LOG(va_TraceDestroySurfaces,
  873.                dpy, surface_list, num_surfaces);
  874.  
  875.   vaStatus = ctx->vtable->vaDestroySurfaces( ctx, surface_list, num_surfaces );
  876.  
  877.   return vaStatus;
  878. }
  879.  
  880. VAStatus vaCreateContext (
  881.     VADisplay dpy,
  882.     VAConfigID config_id,
  883.     int picture_width,
  884.     int picture_height,
  885.     int flag,
  886.     VASurfaceID *render_targets,
  887.     int num_render_targets,
  888.     VAContextID *context                /* out */
  889. )
  890. {
  891.   VADriverContextP ctx;
  892.   VAStatus vaStatus;
  893.  
  894.   CHECK_DISPLAY(dpy);
  895.   ctx = CTX(dpy);
  896.  
  897.   vaStatus = ctx->vtable->vaCreateContext( ctx, config_id, picture_width, picture_height,
  898.                                       flag, render_targets, num_render_targets, context );
  899.  
  900.   /* keep current encode/decode resoluton */
  901.   VA_TRACE_ALL(va_TraceCreateContext, dpy, config_id, picture_width, picture_height, flag, render_targets, num_render_targets, context);
  902.  
  903.   return vaStatus;
  904. }
  905.  
  906. VAStatus vaDestroyContext (
  907.     VADisplay dpy,
  908.     VAContextID context
  909. )
  910. {
  911.   VADriverContextP ctx;
  912.   CHECK_DISPLAY(dpy);
  913.   ctx = CTX(dpy);
  914.  
  915.   return ctx->vtable->vaDestroyContext( ctx, context );
  916. }
  917.  
  918. VAStatus vaCreateBuffer (
  919.     VADisplay dpy,
  920.     VAContextID context,        /* in */
  921.     VABufferType type,          /* in */
  922.     unsigned int size,          /* in */
  923.     unsigned int num_elements,  /* in */
  924.     void *data,                 /* in */
  925.     VABufferID *buf_id          /* out */
  926. )
  927. {
  928.   VADriverContextP ctx;
  929.   VAStatus vaStatus;
  930.  
  931.   CHECK_DISPLAY(dpy);
  932.   ctx = CTX(dpy);
  933.  
  934.   VA_FOOL_FUNC(va_FoolCreateBuffer, dpy, context, type, size, num_elements, data, buf_id);
  935.  
  936.   vaStatus = ctx->vtable->vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
  937.  
  938.   VA_TRACE_LOG(va_TraceCreateBuffer,
  939.                dpy, context, type, size, num_elements, data, buf_id);
  940.  
  941.   return vaStatus;
  942. }
  943.  
  944. VAStatus vaBufferSetNumElements (
  945.     VADisplay dpy,
  946.     VABufferID buf_id,  /* in */
  947.     unsigned int num_elements /* in */
  948. )
  949. {
  950.   VADriverContextP ctx;
  951.   CHECK_DISPLAY(dpy);
  952.   ctx = CTX(dpy);
  953.  
  954.   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
  955.  
  956.   return ctx->vtable->vaBufferSetNumElements( ctx, buf_id, num_elements );
  957. }
  958.  
  959.  
  960. VAStatus vaMapBuffer (
  961.     VADisplay dpy,
  962.     VABufferID buf_id,  /* in */
  963.     void **pbuf         /* out */
  964. )
  965. {
  966.   VADriverContextP ctx;
  967.   VAStatus va_status;
  968.  
  969.   CHECK_DISPLAY(dpy);
  970.   ctx = CTX(dpy);
  971.  
  972.   VA_FOOL_FUNC(va_FoolMapBuffer, dpy, buf_id, pbuf);
  973.  
  974.   va_status = ctx->vtable->vaMapBuffer( ctx, buf_id, pbuf );
  975.  
  976.   VA_TRACE_ALL(va_TraceMapBuffer, dpy, buf_id, pbuf);
  977.  
  978.   return va_status;
  979. }
  980.  
  981. VAStatus vaUnmapBuffer (
  982.     VADisplay dpy,
  983.     VABufferID buf_id   /* in */
  984. )
  985. {
  986.   VADriverContextP ctx;
  987.   CHECK_DISPLAY(dpy);
  988.   ctx = CTX(dpy);
  989.  
  990.   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
  991.  
  992.   return ctx->vtable->vaUnmapBuffer( ctx, buf_id );
  993. }
  994.  
  995. VAStatus vaDestroyBuffer (
  996.     VADisplay dpy,
  997.     VABufferID buffer_id
  998. )
  999. {
  1000.   VADriverContextP ctx;
  1001.   CHECK_DISPLAY(dpy);
  1002.   ctx = CTX(dpy);
  1003.  
  1004.   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
  1005.  
  1006.   VA_TRACE_LOG(va_TraceDestroyBuffer,
  1007.                dpy, buffer_id);
  1008.  
  1009.   return ctx->vtable->vaDestroyBuffer( ctx, buffer_id );
  1010. }
  1011.  
  1012. VAStatus vaBufferInfo (
  1013.     VADisplay dpy,
  1014.     VAContextID context,        /* in */
  1015.     VABufferID buf_id,          /* in */
  1016.     VABufferType *type,         /* out */
  1017.     unsigned int *size,         /* out */
  1018.     unsigned int *num_elements  /* out */
  1019. )
  1020. {
  1021.   VADriverContextP ctx;
  1022.  
  1023.   CHECK_DISPLAY(dpy);
  1024.   ctx = CTX(dpy);
  1025.  
  1026.   VA_FOOL_FUNC(va_FoolBufferInfo, dpy, buf_id, type, size, num_elements);
  1027.  
  1028.   return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements );
  1029. }
  1030.  
  1031. /* Locks buffer for external API usage */
  1032. VAStatus
  1033. vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info)
  1034. {
  1035.     VADriverContextP ctx;
  1036.  
  1037.     CHECK_DISPLAY(dpy);
  1038.     ctx = CTX(dpy);
  1039.  
  1040.     if (!ctx->vtable->vaAcquireBufferHandle)
  1041.         return VA_STATUS_ERROR_UNIMPLEMENTED;
  1042.     return ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info);
  1043. }
  1044.  
  1045. /* Unlocks buffer after usage from external API */
  1046. VAStatus
  1047. vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id)
  1048. {
  1049.     VADriverContextP ctx;
  1050.  
  1051.     CHECK_DISPLAY(dpy);
  1052.     ctx = CTX(dpy);
  1053.  
  1054.     if (!ctx->vtable->vaReleaseBufferHandle)
  1055.         return VA_STATUS_ERROR_UNIMPLEMENTED;
  1056.     return ctx->vtable->vaReleaseBufferHandle(ctx, buf_id);
  1057. }
  1058.  
  1059. VAStatus vaBeginPicture (
  1060.     VADisplay dpy,
  1061.     VAContextID context,
  1062.     VASurfaceID render_target
  1063. )
  1064. {
  1065.   VADriverContextP ctx;
  1066.   VAStatus va_status;
  1067.  
  1068.   CHECK_DISPLAY(dpy);
  1069.   ctx = CTX(dpy);
  1070.  
  1071.   VA_TRACE_ALL(va_TraceBeginPicture, dpy, context, render_target);
  1072.   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
  1073.  
  1074.   va_status = ctx->vtable->vaBeginPicture( ctx, context, render_target );
  1075.  
  1076.   return va_status;
  1077. }
  1078.  
  1079. VAStatus vaRenderPicture (
  1080.     VADisplay dpy,
  1081.     VAContextID context,
  1082.     VABufferID *buffers,
  1083.     int num_buffers
  1084. )
  1085. {
  1086.   VADriverContextP ctx;
  1087.  
  1088.   CHECK_DISPLAY(dpy);
  1089.   ctx = CTX(dpy);
  1090.  
  1091.   VA_TRACE_LOG(va_TraceRenderPicture, dpy, context, buffers, num_buffers);
  1092.   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
  1093.  
  1094.   return ctx->vtable->vaRenderPicture( ctx, context, buffers, num_buffers );
  1095. }
  1096.  
  1097. VAStatus vaEndPicture (
  1098.     VADisplay dpy,
  1099.     VAContextID context
  1100. )
  1101. {
  1102.   VAStatus va_status = VA_STATUS_SUCCESS;
  1103.   VADriverContextP ctx;
  1104.  
  1105.   CHECK_DISPLAY(dpy);
  1106.   ctx = CTX(dpy);
  1107.  
  1108.   VA_FOOL_FUNC(va_FoolCheckContinuity, dpy);
  1109.  
  1110.   va_status = ctx->vtable->vaEndPicture( ctx, context );
  1111.  
  1112.   /* dump surface content */
  1113.   VA_TRACE_ALL(va_TraceEndPicture, dpy, context, 1);
  1114.  
  1115.   return va_status;
  1116. }
  1117.  
  1118. VAStatus vaSyncSurface (
  1119.     VADisplay dpy,
  1120.     VASurfaceID render_target
  1121. )
  1122. {
  1123.   VAStatus va_status;
  1124.   VADriverContextP ctx;
  1125.  
  1126.   CHECK_DISPLAY(dpy);
  1127.   ctx = CTX(dpy);
  1128.  
  1129.   va_status = ctx->vtable->vaSyncSurface( ctx, render_target );
  1130.   VA_TRACE_LOG(va_TraceSyncSurface, dpy, render_target);
  1131.  
  1132.   return va_status;
  1133. }
  1134.  
  1135. VAStatus vaQuerySurfaceStatus (
  1136.     VADisplay dpy,
  1137.     VASurfaceID render_target,
  1138.     VASurfaceStatus *status     /* out */
  1139. )
  1140. {
  1141.   VAStatus va_status;
  1142.   VADriverContextP ctx;
  1143.   CHECK_DISPLAY(dpy);
  1144.   ctx = CTX(dpy);
  1145.  
  1146.   va_status = ctx->vtable->vaQuerySurfaceStatus( ctx, render_target, status );
  1147.  
  1148.   VA_TRACE_LOG(va_TraceQuerySurfaceStatus, dpy, render_target, status);
  1149.  
  1150.   return va_status;
  1151. }
  1152.  
  1153. VAStatus vaQuerySurfaceError (
  1154.         VADisplay dpy,
  1155.         VASurfaceID surface,
  1156.         VAStatus error_status,
  1157.         void **error_info /*out*/
  1158. )
  1159. {
  1160.   VAStatus va_status;
  1161.   VADriverContextP ctx;
  1162.   CHECK_DISPLAY(dpy);
  1163.   ctx = CTX(dpy);
  1164.  
  1165.   va_status = ctx->vtable->vaQuerySurfaceError( ctx, surface, error_status, error_info );
  1166.  
  1167.   VA_TRACE_LOG(va_TraceQuerySurfaceError, dpy, surface, error_status, error_info);
  1168.  
  1169.   return va_status;
  1170. }
  1171.  
  1172. /* Get maximum number of image formats supported by the implementation */
  1173. int vaMaxNumImageFormats (
  1174.     VADisplay dpy
  1175. )
  1176. {
  1177.   if (!vaDisplayIsValid(dpy))
  1178.       return 0;
  1179.  
  1180.   return CTX(dpy)->max_image_formats;
  1181. }
  1182.  
  1183. VAStatus vaQueryImageFormats (
  1184.     VADisplay dpy,
  1185.     VAImageFormat *format_list, /* out */
  1186.     int *num_formats            /* out */
  1187. )
  1188. {
  1189.   VADriverContextP ctx;
  1190.   CHECK_DISPLAY(dpy);
  1191.   ctx = CTX(dpy);
  1192.  
  1193.   return ctx->vtable->vaQueryImageFormats ( ctx, format_list, num_formats);
  1194. }
  1195.  
  1196. /*
  1197.  * The width and height fields returned in the VAImage structure may get
  1198.  * enlarged for some YUV formats. The size of the data buffer that needs
  1199.  * to be allocated will be given in the "data_size" field in VAImage.
  1200.  * Image data is not allocated by this function.  The client should
  1201.  * allocate the memory and fill in the VAImage structure's data field
  1202.  * after looking at "data_size" returned from the library.
  1203.  */
  1204. VAStatus vaCreateImage (
  1205.     VADisplay dpy,
  1206.     VAImageFormat *format,
  1207.     int width,
  1208.     int height,
  1209.     VAImage *image      /* out */
  1210. )
  1211. {
  1212.   VADriverContextP ctx;
  1213.   CHECK_DISPLAY(dpy);
  1214.   ctx = CTX(dpy);
  1215.  
  1216.   return ctx->vtable->vaCreateImage ( ctx, format, width, height, image);
  1217. }
  1218.  
  1219. /*
  1220.  * Should call DestroyImage before destroying the surface it is bound to
  1221.  */
  1222. VAStatus vaDestroyImage (
  1223.     VADisplay dpy,
  1224.     VAImageID image
  1225. )
  1226. {
  1227.   VADriverContextP ctx;
  1228.   CHECK_DISPLAY(dpy);
  1229.   ctx = CTX(dpy);
  1230.  
  1231.   return ctx->vtable->vaDestroyImage ( ctx, image);
  1232. }
  1233.  
  1234. VAStatus vaSetImagePalette (
  1235.     VADisplay dpy,
  1236.     VAImageID image,
  1237.     unsigned char *palette
  1238. )
  1239. {
  1240.   VADriverContextP ctx;
  1241.   CHECK_DISPLAY(dpy);
  1242.   ctx = CTX(dpy);
  1243.  
  1244.   return ctx->vtable->vaSetImagePalette ( ctx, image, palette);
  1245. }
  1246.  
  1247. /*
  1248.  * Retrieve surface data into a VAImage
  1249.  * Image must be in a format supported by the implementation
  1250.  */
  1251. VAStatus vaGetImage (
  1252.     VADisplay dpy,
  1253.     VASurfaceID surface,
  1254.     int x,      /* coordinates of the upper left source pixel */
  1255.     int y,
  1256.     unsigned int width, /* width and height of the region */
  1257.     unsigned int height,
  1258.     VAImageID image
  1259. )
  1260. {
  1261.   VADriverContextP ctx;
  1262.   CHECK_DISPLAY(dpy);
  1263.   ctx = CTX(dpy);
  1264.  
  1265.   return ctx->vtable->vaGetImage ( ctx, surface, x, y, width, height, image);
  1266. }
  1267.  
  1268. /*
  1269.  * Copy data from a VAImage to a surface
  1270.  * Image must be in a format supported by the implementation
  1271.  */
  1272. VAStatus vaPutImage (
  1273.     VADisplay dpy,
  1274.     VASurfaceID surface,
  1275.     VAImageID image,
  1276.     int src_x,
  1277.     int src_y,
  1278.     unsigned int src_width,
  1279.     unsigned int src_height,
  1280.     int dest_x,
  1281.     int dest_y,
  1282.     unsigned int dest_width,
  1283.     unsigned int dest_height
  1284. )
  1285. {
  1286.   VADriverContextP ctx;
  1287.   CHECK_DISPLAY(dpy);
  1288.   ctx = CTX(dpy);
  1289.  
  1290.   return ctx->vtable->vaPutImage ( ctx, surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height );
  1291. }
  1292.  
  1293. /*
  1294.  * Derive an VAImage from an existing surface.
  1295.  * This interface will derive a VAImage and corresponding image buffer from
  1296.  * an existing VA Surface. The image buffer can then be mapped/unmapped for
  1297.  * direct CPU access. This operation is only possible on implementations with
  1298.  * direct rendering capabilities and internal surface formats that can be
  1299.  * represented with a VAImage. When the operation is not possible this interface
  1300.  * will return VA_STATUS_ERROR_OPERATION_FAILED. Clients should then fall back
  1301.  * to using vaCreateImage + vaPutImage to accomplish the same task in an
  1302.  * indirect manner.
  1303.  *
  1304.  * Implementations should only return success when the resulting image buffer
  1305.  * would be useable with vaMap/Unmap.
  1306.  *
  1307.  * When directly accessing a surface special care must be taken to insure
  1308.  * proper synchronization with the graphics hardware. Clients should call
  1309.  * vaQuerySurfaceStatus to insure that a surface is not the target of concurrent
  1310.  * rendering or currently being displayed by an overlay.
  1311.  *
  1312.  * Additionally nothing about the contents of a surface should be assumed
  1313.  * following a vaPutSurface. Implementations are free to modify the surface for
  1314.  * scaling or subpicture blending within a call to vaPutImage.
  1315.  *
  1316.  * Calls to vaPutImage or vaGetImage using the same surface from which the image
  1317.  * has been derived will return VA_STATUS_ERROR_SURFACE_BUSY. vaPutImage or
  1318.  * vaGetImage with other surfaces is supported.
  1319.  *
  1320.  * An image created with vaDeriveImage should be freed with vaDestroyImage. The
  1321.  * image and image buffer structures will be destroyed; however, the underlying
  1322.  * surface will remain unchanged until freed with vaDestroySurfaces.
  1323.  */
  1324. VAStatus vaDeriveImage (
  1325.     VADisplay dpy,
  1326.     VASurfaceID surface,
  1327.     VAImage *image      /* out */
  1328. )
  1329. {
  1330.   VADriverContextP ctx;
  1331.   CHECK_DISPLAY(dpy);
  1332.   ctx = CTX(dpy);
  1333.  
  1334.   return ctx->vtable->vaDeriveImage ( ctx, surface, image );
  1335. }
  1336.  
  1337.  
  1338. /* Get maximum number of subpicture formats supported by the implementation */
  1339. int vaMaxNumSubpictureFormats (
  1340.     VADisplay dpy
  1341. )
  1342. {
  1343.   if (!vaDisplayIsValid(dpy))
  1344.       return 0;
  1345.  
  1346.   return CTX(dpy)->max_subpic_formats;
  1347. }
  1348.  
  1349. /*
  1350.  * Query supported subpicture formats
  1351.  * The caller must provide a "format_list" array that can hold at
  1352.  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag
  1353.  * for each format to indicate additional capabilities for that format. The actual
  1354.  * number of formats returned in "format_list" is returned in "num_formats".
  1355.  */
  1356. VAStatus vaQuerySubpictureFormats (
  1357.     VADisplay dpy,
  1358.     VAImageFormat *format_list, /* out */
  1359.     unsigned int *flags,        /* out */
  1360.     unsigned int *num_formats   /* out */
  1361. )
  1362. {
  1363.   VADriverContextP ctx;
  1364.  
  1365.   CHECK_DISPLAY(dpy);
  1366.   ctx = CTX(dpy);
  1367.  
  1368.   return ctx->vtable->vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
  1369. }
  1370.  
  1371. /*
  1372.  * Subpictures are created with an image associated.
  1373.  */
  1374. VAStatus vaCreateSubpicture (
  1375.     VADisplay dpy,
  1376.     VAImageID image,
  1377.     VASubpictureID *subpicture  /* out */
  1378. )
  1379. {
  1380.   VADriverContextP ctx;
  1381.   CHECK_DISPLAY(dpy);
  1382.   ctx = CTX(dpy);
  1383.  
  1384.   return ctx->vtable->vaCreateSubpicture ( ctx, image, subpicture );
  1385. }
  1386.  
  1387. /*
  1388.  * Destroy the subpicture before destroying the image it is assocated to
  1389.  */
  1390. VAStatus vaDestroySubpicture (
  1391.     VADisplay dpy,
  1392.     VASubpictureID subpicture
  1393. )
  1394. {
  1395.   VADriverContextP ctx;
  1396.   CHECK_DISPLAY(dpy);
  1397.   ctx = CTX(dpy);
  1398.  
  1399.   return ctx->vtable->vaDestroySubpicture ( ctx, subpicture);
  1400. }
  1401.  
  1402. VAStatus vaSetSubpictureImage (
  1403.     VADisplay dpy,
  1404.     VASubpictureID subpicture,
  1405.     VAImageID image
  1406. )
  1407. {
  1408.   VADriverContextP ctx;
  1409.   CHECK_DISPLAY(dpy);
  1410.   ctx = CTX(dpy);
  1411.  
  1412.   return ctx->vtable->vaSetSubpictureImage ( ctx, subpicture, image);
  1413. }
  1414.  
  1415.  
  1416. /*
  1417.  * If chromakey is enabled, then the area where the source value falls within
  1418.  * the chromakey [min, max] range is transparent
  1419.  */
  1420. VAStatus vaSetSubpictureChromakey (
  1421.     VADisplay dpy,
  1422.     VASubpictureID subpicture,
  1423.     unsigned int chromakey_min,
  1424.     unsigned int chromakey_max,
  1425.     unsigned int chromakey_mask
  1426. )
  1427. {
  1428.   VADriverContextP ctx;
  1429.   CHECK_DISPLAY(dpy);
  1430.   ctx = CTX(dpy);
  1431.  
  1432.   return ctx->vtable->vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
  1433. }
  1434.  
  1435.  
  1436. /*
  1437.  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and
  1438.  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
  1439.  * the overall alpha is per-pixel alpha multiplied by the global alpha
  1440.  */
  1441. VAStatus vaSetSubpictureGlobalAlpha (
  1442.     VADisplay dpy,
  1443.     VASubpictureID subpicture,
  1444.     float global_alpha
  1445. )
  1446. {
  1447.   VADriverContextP ctx;
  1448.   CHECK_DISPLAY(dpy);
  1449.   ctx = CTX(dpy);
  1450.  
  1451.   return ctx->vtable->vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
  1452. }
  1453.  
  1454. /*
  1455.   vaAssociateSubpicture associates the subpicture with the target_surface.
  1456.   It defines the region mapping between the subpicture and the target
  1457.   surface through source and destination rectangles (with the same width and height).
  1458.   Both will be displayed at the next call to vaPutSurface.  Additional
  1459.   associations before the call to vaPutSurface simply overrides the association.
  1460. */
  1461. VAStatus vaAssociateSubpicture (
  1462.     VADisplay dpy,
  1463.     VASubpictureID subpicture,
  1464.     VASurfaceID *target_surfaces,
  1465.     int num_surfaces,
  1466.     short src_x, /* upper left offset in subpicture */
  1467.     short src_y,
  1468.     unsigned short src_width,
  1469.     unsigned short src_height,
  1470.     short dest_x, /* upper left offset in surface */
  1471.     short dest_y,
  1472.     unsigned short dest_width,
  1473.     unsigned short dest_height,
  1474.     /*
  1475.      * whether to enable chroma-keying or global-alpha
  1476.      * see VA_SUBPICTURE_XXX values
  1477.      */
  1478.     unsigned int flags
  1479. )
  1480. {
  1481.   VADriverContextP ctx;
  1482.   CHECK_DISPLAY(dpy);
  1483.   ctx = CTX(dpy);
  1484.  
  1485.   return ctx->vtable->vaAssociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height, flags );
  1486. }
  1487.  
  1488. /*
  1489.  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
  1490.  */
  1491. VAStatus vaDeassociateSubpicture (
  1492.     VADisplay dpy,
  1493.     VASubpictureID subpicture,
  1494.     VASurfaceID *target_surfaces,
  1495.     int num_surfaces
  1496. )
  1497. {
  1498.   VADriverContextP ctx;
  1499.   CHECK_DISPLAY(dpy);
  1500.   ctx = CTX(dpy);
  1501.  
  1502.   return ctx->vtable->vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
  1503. }
  1504.  
  1505.  
  1506. /* Get maximum number of display attributes supported by the implementation */
  1507. int vaMaxNumDisplayAttributes (
  1508.     VADisplay dpy
  1509. )
  1510. {
  1511.   int tmp;
  1512.  
  1513.   if (!vaDisplayIsValid(dpy))
  1514.       return 0;
  1515.  
  1516.   tmp = CTX(dpy)->max_display_attributes;
  1517.  
  1518.   VA_TRACE_LOG(va_TraceMaxNumDisplayAttributes, dpy, tmp);
  1519.  
  1520.   return tmp;
  1521. }
  1522.  
  1523. /*
  1524.  * Query display attributes
  1525.  * The caller must provide a "attr_list" array that can hold at
  1526.  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
  1527.  * returned in "attr_list" is returned in "num_attributes".
  1528.  */
  1529. VAStatus vaQueryDisplayAttributes (
  1530.     VADisplay dpy,
  1531.     VADisplayAttribute *attr_list,      /* out */
  1532.     int *num_attributes                 /* out */
  1533. )
  1534. {
  1535.   VADriverContextP ctx;
  1536.   VAStatus va_status;
  1537.  
  1538.   CHECK_DISPLAY(dpy);
  1539.   ctx = CTX(dpy);
  1540.   va_status = ctx->vtable->vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
  1541.  
  1542.   VA_TRACE_LOG(va_TraceQueryDisplayAttributes, dpy, attr_list, num_attributes);
  1543.  
  1544.   return va_status;
  1545.  
  1546. }
  1547.  
  1548. /*
  1549.  * Get display attributes
  1550.  * This function returns the current attribute values in "attr_list".
  1551.  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
  1552.  * from vaQueryDisplayAttributes() can have their values retrieved.
  1553.  */
  1554. VAStatus vaGetDisplayAttributes (
  1555.     VADisplay dpy,
  1556.     VADisplayAttribute *attr_list,      /* in/out */
  1557.     int num_attributes
  1558. )
  1559. {
  1560.   VADriverContextP ctx;
  1561.   VAStatus va_status;
  1562.  
  1563.   CHECK_DISPLAY(dpy);
  1564.   ctx = CTX(dpy);
  1565.   va_status = ctx->vtable->vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
  1566.  
  1567.   VA_TRACE_LOG(va_TraceGetDisplayAttributes, dpy, attr_list, num_attributes);
  1568.  
  1569.   return va_status;
  1570. }
  1571.  
  1572. /*
  1573.  * Set display attributes
  1574.  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
  1575.  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or
  1576.  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
  1577.  */
  1578. VAStatus vaSetDisplayAttributes (
  1579.     VADisplay dpy,
  1580.     VADisplayAttribute *attr_list,
  1581.     int num_attributes
  1582. )
  1583. {
  1584.   VADriverContextP ctx;
  1585.   VAStatus va_status;
  1586.   CHECK_DISPLAY(dpy);
  1587.   ctx = CTX(dpy);
  1588.  
  1589.   va_status = ctx->vtable->vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
  1590.   VA_TRACE_LOG(va_TraceSetDisplayAttributes, dpy, attr_list, num_attributes);
  1591.  
  1592.   return va_status;
  1593. }
  1594.  
  1595. VAStatus vaLockSurface(VADisplay dpy,
  1596.     VASurfaceID surface,
  1597.     unsigned int *fourcc, /* following are output argument */
  1598.     unsigned int *luma_stride,
  1599.     unsigned int *chroma_u_stride,
  1600.     unsigned int *chroma_v_stride,
  1601.     unsigned int *luma_offset,
  1602.     unsigned int *chroma_u_offset,
  1603.     unsigned int *chroma_v_offset,
  1604.     unsigned int *buffer_name,
  1605.     void **buffer
  1606. )
  1607. {
  1608.   VADriverContextP ctx;
  1609.   CHECK_DISPLAY(dpy);
  1610.   ctx = CTX(dpy);
  1611.  
  1612.   return ctx->vtable->vaLockSurface( ctx, surface, fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset, chroma_v_offset, buffer_name, buffer);
  1613. }
  1614.  
  1615.  
  1616. VAStatus vaUnlockSurface(VADisplay dpy,
  1617.     VASurfaceID surface
  1618. )
  1619. {
  1620.   VADriverContextP ctx;
  1621.   CHECK_DISPLAY(dpy);
  1622.   ctx = CTX(dpy);
  1623.  
  1624.   return ctx->vtable->vaUnlockSurface( ctx, surface );
  1625. }
  1626.  
  1627. /* Video Processing */
  1628. #define VA_VPP_INIT_CONTEXT(ctx, dpy) do {              \
  1629.         CHECK_DISPLAY(dpy);                             \
  1630.         ctx = CTX(dpy);                                 \
  1631.         if (!ctx)                                       \
  1632.             return VA_STATUS_ERROR_INVALID_DISPLAY;     \
  1633.     } while (0)
  1634.  
  1635. #define VA_VPP_INVOKE(dpy, func, args) do {             \
  1636.         if (!ctx->vtable_vpp->va##func)                 \
  1637.             return VA_STATUS_ERROR_UNIMPLEMENTED;       \
  1638.         status = ctx->vtable_vpp->va##func args;        \
  1639.     } while (0)
  1640.  
  1641. VAStatus
  1642. vaQueryVideoProcFilters(
  1643.     VADisplay           dpy,
  1644.     VAContextID         context,
  1645.     VAProcFilterType   *filters,
  1646.     unsigned int       *num_filters
  1647. )
  1648. {
  1649.     VADriverContextP ctx;
  1650.     VAStatus status;
  1651.  
  1652.     VA_VPP_INIT_CONTEXT(ctx, dpy);
  1653.     VA_VPP_INVOKE(
  1654.         ctx,
  1655.         QueryVideoProcFilters,
  1656.         (ctx, context, filters, num_filters)
  1657.     );
  1658.     return status;
  1659. }
  1660.  
  1661. VAStatus
  1662. vaQueryVideoProcFilterCaps(
  1663.     VADisplay           dpy,
  1664.     VAContextID         context,
  1665.     VAProcFilterType    type,
  1666.     void               *filter_caps,
  1667.     unsigned int       *num_filter_caps
  1668. )
  1669. {
  1670.     VADriverContextP ctx;
  1671.     VAStatus status;
  1672.  
  1673.     VA_VPP_INIT_CONTEXT(ctx, dpy);
  1674.     VA_VPP_INVOKE(
  1675.         ctx,
  1676.         QueryVideoProcFilterCaps,
  1677.         (ctx, context, type, filter_caps, num_filter_caps)
  1678.     );
  1679.     return status;
  1680. }
  1681.  
  1682. VAStatus
  1683. vaQueryVideoProcPipelineCaps(
  1684.     VADisplay           dpy,
  1685.     VAContextID         context,
  1686.     VABufferID         *filters,
  1687.     unsigned int        num_filters,
  1688.     VAProcPipelineCaps *pipeline_caps
  1689. )
  1690. {
  1691.     VADriverContextP ctx;
  1692.     VAStatus status;
  1693.  
  1694.     VA_VPP_INIT_CONTEXT(ctx, dpy);
  1695.     VA_VPP_INVOKE(
  1696.         ctx,
  1697.         QueryVideoProcPipelineCaps,
  1698.         (ctx, context, filters, num_filters, pipeline_caps)
  1699.     );
  1700.     return status;
  1701. }
  1702.