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