/***************************************************************************** * XvMC Wrapper including the Nonstandard VLD extension. * * Copyright (c) 2004 The Unichrome project. All rights reserved. * * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Thomas Hellström (2004) */ /* * BUGS: The wrapper really should maintain one symbol table per port. * This could possibly be implemented. To do that, the port-independent * symbols need to be lifted out, and one would have to create a number * of mapping tables: * * port -> symbol table * context -> port * surface -> port * subpicture -> port * * and reference the right table when needed. * This needs to be done only if there is a player that wants to access two * displays with different hardware simultaneously. Not likely as of today. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "X11/extensions/vldXvMC.h" #include #include #include #include #include typedef Bool (*XvMCQueryExtensionP) (Display *, int *, int *); typedef Status (*XvMCQueryVersionP) (Display *, int *, int *); typedef XvMCSurfaceInfo *(*XvMCListSurfaceTypesP) (Display *, XvPortID, int *); typedef Status (*XvMCCreateContextP) (Display *, XvPortID, int, int, int, int, XvMCContext *); typedef Status (*XvMCDestroyContextP) (Display *, XvMCContext *); typedef Status (*XvMCCreateSurfaceP) (Display *, XvMCContext *, XvMCSurface *); typedef Status (*XvMCDestroySurfaceP) (Display *, XvMCSurface *); typedef XvImageFormatValues *(*XvMCListSubpictureTypesP)(Display *, XvPortID, int, int *); typedef Status (*XvMCPutSurfaceP) (Display *, XvMCSurface *, Drawable, short, short, unsigned short, unsigned short, short, short, unsigned short, unsigned short, int); typedef Status (*XvMCHideSurfaceP) (Display *, XvMCSurface *); typedef Status (*XvMCCreateSubpictureP) (Display *, XvMCContext *, XvMCSubpicture *, unsigned short, unsigned short, int); typedef Status (*XvMCClearSubpictureP) (Display *, XvMCSubpicture *, short, short, unsigned short, unsigned short, unsigned int); typedef Status (*XvMCCompositeSubpictureP) (Display *, XvMCSubpicture *, XvImage *, short, short, unsigned short, unsigned short, short, short); typedef Status (*XvMCDestroySubpictureP) (Display *, XvMCSubpicture *); typedef Status (*XvMCSetSubpicturePaletteP) (Display *, XvMCSubpicture *, unsigned char *); typedef Status (*XvMCBlendSubpictureP) (Display * d, XvMCSurface *, XvMCSubpicture *, short, short, unsigned short, unsigned short, short, short, unsigned short, unsigned short); typedef Status (*XvMCBlendSubpicture2P) (Display *, XvMCSurface *, XvMCSurface *, XvMCSubpicture *, short, short, unsigned short, unsigned short, short, short, unsigned short, unsigned short); typedef Status (*XvMCSyncSurfaceP) (Display *, XvMCSurface *); typedef Status (*XvMCFlushSurfaceP) (Display *, XvMCSurface *); typedef Status (*XvMCGetSurfaceStatusP) (Display *, XvMCSurface *, int *); typedef Status (*XvMCRenderSurfaceP) (Display *, XvMCContext *, unsigned int, XvMCSurface *, XvMCSurface *, XvMCSurface *, unsigned int, unsigned int, unsigned int, XvMCMacroBlockArray *, XvMCBlockArray *); typedef Status (*XvMCSyncSubpictureP) (Display *, XvMCSubpicture *); typedef Status (*XvMCFlushSubpictureP) (Display *, XvMCSubpicture *); typedef Status (*XvMCGetSubpictureStatusP) (Display *, XvMCSubpicture *, int *); typedef Status (*XvMCCreateBlocksP) (Display *, XvMCContext *, unsigned int, XvMCBlockArray *); typedef Status (*XvMCDestroyBlocksP) (Display *, XvMCBlockArray *); typedef Status (*XvMCCreateMacroBlocksP) (Display *, XvMCContext *, unsigned int, XvMCMacroBlockArray *); typedef Status (*XvMCDestroyMacroBlocksP) (Display *, XvMCMacroBlockArray *); typedef XvAttribute *(*XvMCQueryAttributesP)(Display *, XvMCContext *, int *); typedef Status (*XvMCSetAttributeP) (Display *, XvMCContext *, Atom, int); typedef Status (*XvMCGetAttributeP) (Display *, XvMCContext *, Atom, int *); /* * Nonstandard VLD acceleration level: */ typedef Status (*XvMCBeginSurfaceP) (Display *, XvMCContext *, XvMCSurface *, XvMCSurface *, XvMCSurface * f, const XvMCMpegControl *); typedef Status (*XvMCLoadQMatrixP) (Display *, XvMCContext *, const XvMCQMatrix *); typedef Status (*XvMCPutSliceP) (Display *, XvMCContext *, char *, int); typedef Status (*XvMCPutSlice2P) (Display *, XvMCContext *, char *, int, int); typedef Status (*XvMCGetDRInfoP) (Display *, XvPortID, char **, char **, int *, int *, int *, int *); typedef struct { XvMCQueryExtensionP XvMCQueryExtension; XvMCQueryVersionP XvMCQueryVersion; XvMCListSurfaceTypesP XvMCListSurfaceTypes; XvMCCreateContextP XvMCCreateContext; XvMCDestroyContextP XvMCDestroyContext; XvMCCreateSurfaceP XvMCCreateSurface; XvMCDestroySurfaceP XvMCDestroySurface; XvMCListSubpictureTypesP XvMCListSubpictureTypes; XvMCPutSurfaceP XvMCPutSurface; XvMCHideSurfaceP XvMCHideSurface; XvMCCreateSubpictureP XvMCCreateSubpicture; XvMCClearSubpictureP XvMCClearSubpicture; XvMCCompositeSubpictureP XvMCCompositeSubpicture; XvMCDestroySubpictureP XvMCDestroySubpicture; XvMCSetSubpicturePaletteP XvMCSetSubpicturePalette; XvMCBlendSubpictureP XvMCBlendSubpicture; XvMCBlendSubpicture2P XvMCBlendSubpicture2; XvMCSyncSurfaceP XvMCSyncSurface; XvMCFlushSurfaceP XvMCFlushSurface; XvMCGetSurfaceStatusP XvMCGetSurfaceStatus; XvMCRenderSurfaceP XvMCRenderSurface; XvMCSyncSubpictureP XvMCSyncSubpicture; XvMCFlushSubpictureP XvMCFlushSubpicture; XvMCGetSubpictureStatusP XvMCGetSubpictureStatus; XvMCCreateBlocksP XvMCCreateBlocks; XvMCDestroyBlocksP XvMCDestroyBlocks; XvMCCreateMacroBlocksP XvMCCreateMacroBlocks; XvMCDestroyMacroBlocksP XvMCDestroyMacroBlocks; XvMCQueryAttributesP XvMCQueryAttributes; XvMCSetAttributeP XvMCSetAttribute; XvMCGetAttributeP XvMCGetAttribute; /* * Nonstandard VLD acceleration level: */ XvMCBeginSurfaceP XvMCBeginSurface; XvMCLoadQMatrixP XvMCLoadQMatrix; XvMCPutSliceP XvMCPutSlice; XvMCPutSlice2P XvMCPutSlice2; /* * Driver name function. */ XvMCGetDRInfoP XvMCGetDRInfo; int preInitialised; int initialised; int vldextension; } XvMCWrapper; static XvMCWrapper xW; static int wrapperInit = 0; static int wrapperPreInit = 0; static void *xvhandle; static void *handle2; #define BUFLEN 200 #define STRS(ARG) STR(ARG) #define STR(ARG) #ARG #define XW_RSYM(base,handle,handle2,pointer, retval) \ do { \ register char *symerr; \ base.pointer = (pointer##P) dlsym((handle),#pointer); \ if ((symerr = dlerror()) != NULL) { \ if (!handle2) { \ fprintf(stderr,"%s\n",symerr); return retval; \ } \ base.pointer = (pointer##P) dlsym((handle2),#pointer); \ if ((symerr = dlerror()) != NULL) { \ fprintf(stderr,"%s\n",symerr); return retval; \ } \ } \ } while (0); #define XW_RSYM2(base,handle,handle2,pointer) \ base.pointer = (pointer##P) dlsym((handle),#pointer); \ if (dlerror() != NULL) { \ base.pointer = (pointer##P) dlsym((handle2),#pointer); \ if (dlerror() != NULL) return; \ } /* * Try to dlopen a shared library, versionless first. */ static void * dlopenversion(const char *lib, const char *version, int flag) { void *ret; size_t curLen, verLen; char *curName; curLen = strlen(lib) + (verLen = strlen(version)) + 1; curName = (char *) malloc(curLen * sizeof(char)); strncpy(curName, lib, curLen); if (verLen > 1) { const char *tail = strstr(version + 1, "."); if (NULL != tail) { strncat(curName, version, (size_t) (tail - version)); } else { strncat(curName, version, verLen); } } ret = dlopen(curName, flag); free(curName); return ret; } static int preInitW(Display *dpy) { /* * Resolve functions that are not hw driver specific. */ void *handleZ = NULL; wrapperPreInit = 1; xW.preInitialised = 0; xW.initialised = 0; xvhandle = dlopenversion("libXv.so", XV_SOVERSION, RTLD_LAZY | RTLD_GLOBAL); if (!xvhandle) { fprintf(stderr, "XvMCWrapper: Warning! Could not open shared " "library \"libXv.so" XV_SOVERSION "\"\nThis may cause relocation " "errors later.\nError was: \"%s\".\n", dlerror()); } handle2 = dlopenversion("libXvMC.so", XVMC_SOVERSION, RTLD_LAZY | RTLD_GLOBAL); if (!handle2) { fprintf(stderr, "XvMCWrapper: Could not load XvMC " "library \"libXvMC.so" XVMC_SOVERSION "\". Failing\n"); fprintf(stderr, "%s\n", dlerror()); return 1; } XW_RSYM(xW, handle2, handleZ, XvMCQueryExtension, 1); XW_RSYM(xW, handle2, handleZ, XvMCQueryVersion, 1); xW.preInitialised = 1; return 0; } static void initW(Display *dpy, XvPortID port) { char nameBuffer[BUFLEN]; void *handle; char *clientName = NULL; char *err; size_t nameLen = 0; wrapperInit = 1; xW.initialised = 0; if (!wrapperPreInit) if (preInitW(dpy)) return; /* * Will the DDX tell us the client driver name? */ xW.XvMCGetDRInfo = (XvMCGetDRInfoP) dlsym(handle2, "XvMCGetDRInfo"); if ((err = dlerror()) == NULL) { int major, minor, patchLevel, isLocal; char *busID = NULL; if (0 == xW.XvMCGetDRInfo(dpy, port, &clientName, &busID, &major, &minor, &patchLevel, &isLocal)) { nameLen = strlen(clientName); XFree(busID); if (!isLocal) { fprintf(stderr, "XvMCWrapper: X server is not local. Cannot run XvMC.\n"); XFree(clientName); return; } } else { clientName = NULL; } } if (clientName && (nameLen < BUFLEN - 7) && (nameLen > 0)) { nameLen += 3; strncpy(nameBuffer, "lib", BUFLEN - 1); strncpy(nameBuffer + 3, clientName, BUFLEN - 4); strncpy(nameBuffer + nameLen, ".so", BUFLEN - nameLen - 1); nameBuffer[BUFLEN - 1] = 0; XFree(clientName); handle = dlopenversion(nameBuffer, XVMC_SOVERSION, RTLD_LAZY); } else { /* * No. Try to obtain it from the config file. */ size_t tmp; FILE *configFile; if (clientName) XFree(clientName); configFile = fopen(STRS(XVMC_CONFIGDIR) "/XvMCConfig", "r"); xW.initialised = 0; xW.vldextension = 0; if (NULL == configFile) { fprintf(stderr, "XvMCWrapper: Could not open config file \"%s\".\n", STRS(XVMC_CONFIGDIR) "/XvMCConfig"); perror("XvMCWrapper"); return; } if (NULL == fgets(nameBuffer, BUFLEN, configFile)) { fclose(configFile); fprintf(stderr, "XvMCWrapper: Could not read XvMC library name.\n"); perror("XvMCWrapper"); return; } fclose(configFile); if ((tmp = strlen(nameBuffer)) == 0) { fprintf(stderr, "XvMCWrapper: Zero length XvMC library name.\n"); fprintf(stderr, "%s\n", dlerror()); return; } /* * Skip trailing newlines and garbage. */ while (iscntrl(nameBuffer[tmp - 1])) { nameBuffer[tmp - 1] = 0; if (--tmp == 0) { fprintf(stderr, "XvMCWrapper: Zero length XvMC library name.\n"); return; } } handle = dlopen(nameBuffer, RTLD_LAZY); } if (!handle) { fprintf(stderr, "XvMCWrapper: Could not load hardware specific XvMC " "library \"%s\".\n", nameBuffer); fprintf(stderr, "%s\n", dlerror()); return; } XW_RSYM(xW, handle, handle2, XvMCListSurfaceTypes,); XW_RSYM(xW, handle, handle2, XvMCCreateContext,); XW_RSYM(xW, handle, handle2, XvMCDestroyContext,); XW_RSYM(xW, handle, handle2, XvMCCreateSurface,); XW_RSYM(xW, handle, handle2, XvMCDestroySurface,); XW_RSYM(xW, handle, handle2, XvMCListSubpictureTypes,); XW_RSYM(xW, handle, handle2, XvMCHideSurface,); XW_RSYM(xW, handle, handle2, XvMCCreateSubpicture,); XW_RSYM(xW, handle, handle2, XvMCClearSubpicture,); XW_RSYM(xW, handle, handle2, XvMCCompositeSubpicture,); XW_RSYM(xW, handle, handle2, XvMCDestroySubpicture,); XW_RSYM(xW, handle, handle2, XvMCSetSubpicturePalette,); XW_RSYM(xW, handle, handle2, XvMCBlendSubpicture,); XW_RSYM(xW, handle, handle2, XvMCBlendSubpicture2,); XW_RSYM(xW, handle, handle2, XvMCPutSurface,); XW_RSYM(xW, handle, handle2, XvMCSyncSurface,); XW_RSYM(xW, handle, handle2, XvMCFlushSurface,); XW_RSYM(xW, handle, handle2, XvMCGetSurfaceStatus,); XW_RSYM(xW, handle, handle2, XvMCRenderSurface,); XW_RSYM(xW, handle, handle2, XvMCSyncSubpicture,); XW_RSYM(xW, handle, handle2, XvMCFlushSubpicture,); XW_RSYM(xW, handle, handle2, XvMCGetSubpictureStatus,); XW_RSYM(xW, handle, handle2, XvMCCreateBlocks,); XW_RSYM(xW, handle, handle2, XvMCDestroyBlocks,); XW_RSYM(xW, handle, handle2, XvMCCreateMacroBlocks,); XW_RSYM(xW, handle, handle2, XvMCDestroyMacroBlocks,); XW_RSYM(xW, handle, handle2, XvMCQueryAttributes,); XW_RSYM(xW, handle, handle2, XvMCSetAttribute,); XW_RSYM(xW, handle, handle2, XvMCGetAttribute,); xW.initialised = 1; XW_RSYM2(xW, handle, handle2, XvMCBeginSurface); XW_RSYM(xW, handle, handle2, XvMCLoadQMatrix,); XW_RSYM(xW, handle, handle2, XvMCPutSlice,); XW_RSYM(xW, handle, handle2, XvMCPutSlice2,); xW.vldextension = 1; } Bool XvMCQueryExtension(Display *display, int *eventBase, int *errBase) { if (!wrapperPreInit) preInitW(display); if (!xW.preInitialised) return 0; return (*xW.XvMCQueryExtension) (display, eventBase, errBase); } Status XvMCQueryVersion(Display *display, int *major_versionp, int *minor_versionp) { if (!wrapperPreInit) preInitW(display); if (!xW.preInitialised) return 0; return (*xW.XvMCQueryVersion) (display, major_versionp, minor_versionp); } XvMCSurfaceInfo * XvMCListSurfaceTypes(Display *dpy, XvPortID port, int *num) { if (!wrapperInit) initW(dpy, port); if (!xW.initialised) return NULL; return (*xW.XvMCListSurfaceTypes) (dpy, port, num); } Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) { if (!wrapperInit) initW(display, port); if (!xW.initialised) return BadValue; return (*xW.XvMCCreateContext) (display, port, surface_type_id, width, height, flags, context); } Status XvMCDestroyContext(Display *display, XvMCContext *context) { if (!xW.initialised) return BadValue; return (*xW.XvMCDestroyContext) (display, context); } Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) { if (!xW.initialised) return BadValue; return (*xW.XvMCCreateSurface) (display, context, surface); } Status XvMCDestroySurface(Display *display, XvMCSurface *surface) { if (!xW.initialised) return BadValue; return (*xW.XvMCDestroySurface) (display, surface); } XvImageFormatValues * XvMCListSubpictureTypes(Display *display, XvPortID port, int surface_type_id, int *count_return) { if (!xW.initialised) return NULL; return (*xW.XvMCListSubpictureTypes) (display, port, surface_type_id, count_return); } Status XvMCPutSurface(Display *display, XvMCSurface * surface, Drawable draw, short srcx, short srcy, unsigned short srcw, unsigned short srch, short destx, short desty, unsigned short destw, unsigned short desth, int flags) { if (!xW.initialised) return BadValue; return (*xW.XvMCPutSurface) (display, surface, draw, srcx, srcy, srcw, srch, destx, desty, destw, desth, flags); } Status XvMCHideSurface(Display *display, XvMCSurface *surface) { if (!xW.initialised) return BadValue; return (*xW.XvMCHideSurface) (display, surface); } Status XvMCCreateSubpicture(Display *display, XvMCContext *context, XvMCSubpicture *subpicture, unsigned short width, unsigned short height, int xvimage_id) { if (!xW.initialised) return BadValue; return (*xW.XvMCCreateSubpicture) (display, context, subpicture, width, height, xvimage_id); } Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture, short x, short y, unsigned short width, unsigned short height, unsigned int color) { if (!xW.initialised) return BadValue; return (*xW.XvMCClearSubpicture) (display, subpicture, x, y, width, height, color); } Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture, XvImage *image, short srcx, short srcy, unsigned short width, unsigned short height, short dstx, short dsty) { if (!xW.initialised) return BadValue; return (*xW.XvMCCompositeSubpicture) (display, subpicture, image, srcx, srcy, width, height, dstx, dsty); } Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) { if (!xW.initialised) return BadValue; return (*xW.XvMCDestroySubpicture) (display, subpicture); } Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, unsigned char *palette) { if (!xW.initialised) return BadValue; return (*xW.XvMCSetSubpicturePalette) (display, subpicture, palette); } Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface, XvMCSubpicture *subpicture, short subx, short suby, unsigned short subw, unsigned short subh, short surfx, short surfy, unsigned short surfw, unsigned short surfh) { if (!xW.initialised) return BadValue; return (*xW.XvMCBlendSubpicture) (display, target_surface, subpicture, subx, suby, subw, subh, surfx, surfy, surfw, surfh); } Status XvMCBlendSubpicture2(Display *display, XvMCSurface *source_surface, XvMCSurface *target_surface, XvMCSubpicture *subpicture, short subx, short suby, unsigned short subw, unsigned short subh, short surfx, short surfy, unsigned short surfw, unsigned short surfh) { if (!xW.initialised) return BadValue; return (*xW.XvMCBlendSubpicture2) (display, source_surface, target_surface, subpicture, subx, suby, subw, subh, surfx, surfy, surfw, surfh); } Status XvMCSyncSurface(Display *display, XvMCSurface *surface) { if (!xW.initialised) return BadValue; return (*xW.XvMCSyncSurface) (display, surface); } Status XvMCFlushSurface(Display *display, XvMCSurface *surface) { if (!xW.initialised) return BadValue; return (*xW.XvMCFlushSurface) (display, surface); } Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) { if (!xW.initialised) return BadValue; return (*xW.XvMCGetSurfaceStatus) (display, surface, stat); } Status XvMCRenderSurface(Display *display, XvMCContext *context, unsigned int picture_structure, XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface, unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock, XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks) { if (!xW.initialised) return BadValue; return (*xW.XvMCRenderSurface) (display, context, picture_structure, target_surface, past_surface, future_surface, flags, num_macroblocks, first_macroblock, macroblock_array, blocks); } Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) { if (!xW.initialised) return BadValue; return (*xW.XvMCSyncSubpicture) (display, subpicture); } Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) { if (!xW.initialised) return BadValue; return (*xW.XvMCFlushSubpicture) (display, subpicture); } Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpic, int *stat) { if (!xW.initialised) return BadValue; return (*xW.XvMCGetSubpictureStatus) (display, subpic, stat); } Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *block) { if (!xW.initialised) return BadValue; return (*xW.XvMCCreateBlocks) (display, context, num_blocks, block); } Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) { if (!xW.initialised) return BadValue; return (*xW.XvMCDestroyBlocks) (display, block); } Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks) { if (!xW.initialised) return BadValue; return (*xW.XvMCCreateMacroBlocks) (display, context, num_blocks, blocks); } Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) { if (!xW.initialised) return BadValue; return (*xW.XvMCDestroyMacroBlocks) (display, block); } XvAttribute * XvMCQueryAttributes(Display *display, XvMCContext *context, int *number) { if (!xW.initialised) return NULL; return (*xW.XvMCQueryAttributes) (display, context, number); } Status XvMCSetAttribute(Display *display, XvMCContext *context, Atom attribute, int value) { if (!xW.initialised) return BadValue; return (*xW.XvMCSetAttribute) (display, context, attribute, value); } Status XvMCGetAttribute(Display *display, XvMCContext *context, Atom attribute, int *value) { if (!xW.initialised) return BadValue; return (*xW.XvMCGetAttribute) (display, context, attribute, value); } Status XvMCBeginSurface(Display *display, XvMCContext *context, XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface, const XvMCMpegControl *control) { if (!xW.vldextension) return BadValue; return (*xW.XvMCBeginSurface) (display, context, target_surface, past_surface, future_surface, control); } Status XvMCLoadQMatrix(Display *display, XvMCContext *context, const XvMCQMatrix *qmx) { if (!xW.vldextension) return BadValue; return (*xW.XvMCLoadQMatrix) (display, context, qmx); } Status XvMCPutSlice(Display *display, XvMCContext *context, char *slice, int nBytes) { if (!xW.vldextension) return BadValue; return (*xW.XvMCPutSlice) (display, context, slice, nBytes); } Status XvMCPutSlice2(Display *display, XvMCContext *context, char *slice, int nBytes, int sliceCode) { if (!xW.vldextension) return BadValue; return (*xW.XvMCPutSlice2) (display, context, slice, nBytes, sliceCode); }