diff options
Diffstat (limited to 'nx-X11/lib/XvMC/hw/via/viaXvMC.c')
-rw-r--r-- | nx-X11/lib/XvMC/hw/via/viaXvMC.c | 1964 |
1 files changed, 0 insertions, 1964 deletions
diff --git a/nx-X11/lib/XvMC/hw/via/viaXvMC.c b/nx-X11/lib/XvMC/hw/via/viaXvMC.c deleted file mode 100644 index eebc87ea8..000000000 --- a/nx-X11/lib/XvMC/hw/via/viaXvMC.c +++ /dev/null @@ -1,1964 +0,0 @@ -/***************************************************************************** - * VIA Unichrome XvMC extension client lib. - * - * Copyright (c) 2004-2005 Thomas Hellström. 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. - *Bugfixes by among others Pascal Brisset and Terry Barnaby. - *DRI protocol support by Thomas Hellström, 2005. - */ - -#undef WAITPAUSE - -#include "viaXvMCPriv.h" -#include "viaLowLevel.h" -#include <stdio.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <time.h> -#include <fourcc.h> -#include <X11/extensions/Xv.h> -#include <xf86drm.h> -#include <pthread.h> -#include <X11/extensions/vldXvMC.h> -#include "xf86dri.h" -#include "driDrawable.h" - -#define SAREAPTR(ctx) ((ViaXvMCSAreaPriv *) \ - (((CARD8 *)(ctx)->sAreaAddress) + \ - (ctx)->sAreaPrivOffset)) - - - -static int error_base; -static int event_base; -static unsigned numContexts = 0; -static int globalFD; -static drmAddress sAreaAddress; -static drmAddress fbAddress; -static drmAddress mmioAddress; - - -#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') - -#define ppthread_mutex_lock(arg) \ - { \ - pthread_mutex_lock(arg); \ - } \ - -#define ppthread_mutex_unlock(arg) \ - { \ - pthread_mutex_unlock(arg); \ - } \ - -static unsigned yOffs (ViaXvMCSurface *srf) -{ - return srf->offsets[0]; -} - -static unsigned vOffs (ViaXvMCSurface *srf) -{ - return srf->offsets[0] + srf->yStride * srf->height; -} - -static unsigned uOffs (ViaXvMCSurface *srf) -{ - return srf->offsets[0] + ( srf->yStride * srf->height) + - (srf->yStride >> 1) * (srf->height >> 1); -} - - -static void defaultQMatrices(ViaXvMCContext *ctx) -{ - int i; - - static const char intra[64] = { - 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, - 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, - 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, - 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 - }; - - for( i=0; i<64; ++i) { - ctx->intra_quantiser_matrix[i] = intra[i]; - ctx->non_intra_quantiser_matrix[i] = 16; - } - ctx->intraLoaded = 0; - ctx->nonIntraLoaded = 0; -} - - -static void releaseDecoder(ViaXvMCContext *ctx,int clearCtx) -{ - volatile ViaXvMCSAreaPriv *sAPriv; - - sAPriv = SAREAPTR(ctx); - UNICHROME_UNLOCK(ctx->fd, UNICHROME_LOCK_DECODER1, sAPriv, ctx->drmcontext); -} - - -static int grabDecoder( ViaXvMCContext *ctx, int *hadLastLock) -{ - volatile ViaXvMCSAreaPriv *sAPriv = SAREAPTR(ctx); - int retFtx, lc; - - /* - * Try to grab the decoder. If it is not available we will sleep until - * it becomes available or for a maximum of 20 ms. - * Then try to grab it again, unless a timeout occured. If the decoder is - * available, the lock should be reasonably fast. - */ - - if (ctx->haveDecoder) { - flushXvMCLowLevel(ctx->xl); /* Ignore errors here. */ - - /*fprintf(stderr,"ViaXvMC: ERROR: Trying to re-lock decoder.\n"); */ - *hadLastLock = 1; - return 0; - } - UNICHROME_LOCK(ctx->fd, UNICHROME_LOCK_DECODER1, sAPriv, ctx->drmcontext, lc, - retFtx); - *hadLastLock = (ctx->drmcontext == lc); - - return retFtx; -} - -static void setupAttribDesc(Display *display, XvPortID port, - const ViaXvMCAttrHolder *attrib, - XvAttribute attribDesc[]) -{ - XvAttribute *XvAttribs,*curAD; - int num; - unsigned i,j; - - XLockDisplay(display); - XvAttribs = XvQueryPortAttributes(display, port, &num); - for(i=0; i<attrib->numAttr; ++i) { - curAD = attribDesc + i; - curAD->flags = 0; - curAD->min_value = 0; - curAD->max_value = 0; - curAD->name = NULL; - for(j=0; j<num; ++j) { - if (attrib->attributes[i].attribute == - XInternAtom(display,XvAttribs[j].name,TRUE)) { - *curAD = XvAttribs[j]; - curAD->name = strdup(XvAttribs[j].name); - break; - } - } - } - if (XvAttribs) XFree(XvAttribs); - XUnlockDisplay(display); - -} - -static void releaseAttribDesc(int numAttr, XvAttribute attribDesc[]) -{ - int i; - - for (i=0; i<numAttr; ++i) { - if (attribDesc[i].name) - free(attribDesc[i].name); - } -} - -static Status releaseContextResources(Display *display, XvMCContext *context, - int freePrivate, Status errType) -{ - ViaXvMCContext *pViaXvMC = (ViaXvMCContext *) context->privData; - - switch(pViaXvMC->resources) { - case context_drawHash: - driDestroyHashContents( pViaXvMC->drawHash ); - drmHashDestroy( pViaXvMC->drawHash ); - case context_lowLevel: - closeXvMCLowLevel(pViaXvMC->xl); - case context_mutex: - pthread_mutex_destroy(&pViaXvMC->ctxMutex); - case context_drmContext: - XLockDisplay(display); - uniDRIDestroyContext(display, pViaXvMC->screen, pViaXvMC->id); - XUnlockDisplay(display); - case context_sAreaMap: - numContexts--; - if (numContexts == 0) - drmUnmap(pViaXvMC->sAreaAddress,pViaXvMC->sAreaSize); - case context_fbMap: - if (numContexts == 0) - drmUnmap(pViaXvMC->fbAddress,pViaXvMC->fbSize); - case context_mmioMap: - if (numContexts == 0) - drmUnmap(pViaXvMC->mmioAddress,pViaXvMC->mmioSize); - case context_fd: - if (numContexts == 0) { - if (pViaXvMC->fd >= 0) - drmClose(pViaXvMC->fd); - } - pViaXvMC->fd = -1; - case context_driConnection: - if (numContexts == 0) { - XLockDisplay(display); - uniDRICloseConnection(display, pViaXvMC->screen); - XUnlockDisplay(display); - } - case context_context: - XLockDisplay(display); - _xvmc_destroy_context(display, context); - XUnlockDisplay(display); - if (!freePrivate) break; - default: - free(pViaXvMC); - } - return errType; -} - -Status XvMCCreateContext(Display *display, XvPortID port, - int surface_type_id, int width, int height, int flags, - XvMCContext *context) -{ - ViaXvMCContext *pViaXvMC; - int priv_count; - uint *priv_data; - uint magic; - unsigned i; - Status ret; - int major, minor; - ViaXvMCCreateContextRec *tmpComm; - drmVersionPtr drmVer; - char *curBusID; - int isCapable; - - /* - * Verify Obvious things first - */ - - if(context == NULL) { - return XvMCBadContext; - } - - if(!(flags & XVMC_DIRECT)) { - fprintf(stderr,"Indirect Rendering not supported! Using Direct.\n"); - } - - /* - *FIXME: Check $DISPLAY for legal values here - */ - - context->surface_type_id = surface_type_id; - context->width = (unsigned short)((width + 15) & ~15); - context->height = (unsigned short)((height + 15) & ~15); - context->flags = flags; - context->port = port; - - /* - * Width, Height, and flags are checked against surface_type_id - * and port for validity inside the X server, no need to check - * here. - */ - - /* Allocate private Context data */ - context->privData = (void *)malloc(sizeof(ViaXvMCContext)); - if(!context->privData) { - fprintf(stderr,"Unable to allocate resources for XvMC context.\n"); - return BadAlloc; - } - - pViaXvMC = (ViaXvMCContext *)context->privData; - pViaXvMC->resources = context_none; - - /* Verify the XvMC extension exists */ - - XLockDisplay(display); - if(! XvMCQueryExtension(display, &event_base, - &error_base)) { - fprintf(stderr,"XvMC Extension is not available!\n"); - free(pViaXvMC); - XUnlockDisplay(display); - return BadAlloc; - } - - /* Verify XvMC version */ - ret = XvMCQueryVersion(display, &major, &minor); - if(ret) { - fprintf(stderr,"XvMCQuery Version Failed, unable to determine " - "protocol version!\n"); - } - XUnlockDisplay(display); - - /* FIXME: Check Major and Minor here */ - - XLockDisplay(display); - if((ret = _xvmc_create_context(display, context, &priv_count, - &priv_data))) { - XUnlockDisplay(display); - fprintf(stderr,"Unable to create XvMC Context.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - XUnlockDisplay(display); - - /* - * Check size and version of returned data. - */ - - tmpComm = ( ViaXvMCCreateContextRec *) priv_data; - if(priv_count != (sizeof(ViaXvMCCreateContextRec) >> 2)) { - fprintf(stderr,"_xvmc_create_context() returned incorrect " - "data size!\n"); - fprintf(stderr,"\tExpected %d, got %d\n", - (int) (sizeof(ViaXvMCCreateContextRec) >> 2), - (int) priv_count); - XFree(priv_data); - return releaseContextResources(display, context, 1, BadAlloc); - } - pViaXvMC->resources = context_context; - - if ((tmpComm->major != VIAXVMC_MAJOR) || - (tmpComm->minor != VIAXVMC_MINOR)) { - fprintf(stderr,"Version mismatch between the X via driver\n" - "and the XvMC library. Cannot continue!\n"); - XFree(priv_data); - return releaseContextResources(display, context, 1, BadAlloc); - } - - pViaXvMC->ctxNo = tmpComm->ctxNo; - pViaXvMC->fbOffset = tmpComm->fbOffset; - pViaXvMC->fbSize = tmpComm->fbSize; - pViaXvMC->mmioOffset = tmpComm->mmioOffset; - pViaXvMC->mmioSize = tmpComm->mmioSize; - pViaXvMC->sAreaSize = tmpComm->sAreaSize; - pViaXvMC->sAreaPrivOffset = tmpComm->sAreaPrivOffset; - pViaXvMC->decoderOn = 0; - pViaXvMC->xvMCPort = tmpComm->xvmc_port; - pViaXvMC->useAGP = tmpComm->useAGP; - pViaXvMC->attrib = tmpComm->initAttrs; - pViaXvMC->screen = tmpComm->screen; - pViaXvMC->depth = tmpComm->depth; - pViaXvMC->stride = tmpComm->stride; - pViaXvMC->chipId = tmpComm->chipId; - - /* - * Must free the private data we were passed from X - */ - - XFree(priv_data); - - /* - * Check for direct rendering capable, establish DRI and DRM connections, - * map framebuffer, DRI shared area and read-only register areas. - * Initial checking for drm has already been done by the server. - * Only do this for the first context we create. - */ - - if (numContexts == 0) { - XLockDisplay(display); - ret = uniDRIQueryDirectRenderingCapable(display, pViaXvMC->screen, &isCapable); - if (!ret || !isCapable) { - XUnlockDisplay(display); - fprintf(stderr,"Direct Rendering is not available on this system!\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - - if (!uniDRIOpenConnection(display, pViaXvMC->screen, &pViaXvMC->sAreaOffset, - &curBusID)) { - XUnlockDisplay(display); - fprintf(stderr,"Could not open DRI connection to X server!\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - XUnlockDisplay(display); - - strncpy(pViaXvMC->busIdString,curBusID,20); - pViaXvMC->busIdString[20] = '\0'; - XFree(curBusID); - - pViaXvMC->resources = context_driConnection; - - if((pViaXvMC->fd = drmOpen("via",pViaXvMC->busIdString)) < 0) { - fprintf(stderr,"DRM Device for via could not be opened.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - globalFD = pViaXvMC->fd; - pViaXvMC->resources = context_fd; - - if (NULL == (drmVer = drmGetVersion(pViaXvMC->fd))) { - fprintf(stderr, - "viaXvMC: Could not get drm version."); - return releaseContextResources(display, context, 1, BadAlloc); - } - if (((drmVer->version_major != 2 ) || (drmVer->version_minor < 0))) { - fprintf(stderr, - "viaXvMC: Kernel drm is not compatible with XvMC.\n"); - fprintf(stderr, - "viaXvMC: Kernel drm version: %d.%d.%d " - "and I need at least version 2.0.0.\n" - "Please update.\n", - drmVer->version_major,drmVer->version_minor, - drmVer->version_patchlevel); - drmFreeVersion(drmVer); - return releaseContextResources(display, context, 1, BadAlloc); - } - drmFreeVersion(drmVer); - drmGetMagic(pViaXvMC->fd,&magic); - - XLockDisplay(display); - if (!uniDRIAuthConnection(display, pViaXvMC->screen, magic)) { - XUnlockDisplay(display); - fprintf(stderr, "viaXvMC: X server did not allow DRI. Check permissions.\n"); - XFree(priv_data); - return releaseContextResources(display, context, 1, BadAlloc); - } - XUnlockDisplay(display); - - /* - * Map the register memory - */ - - if(drmMap(pViaXvMC->fd,pViaXvMC->mmioOffset, - pViaXvMC->mmioSize,&mmioAddress) < 0) { - fprintf(stderr,"Unable to map the display chip mmio registers.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - pViaXvMC->mmioAddress = mmioAddress; - pViaXvMC->resources = context_mmioMap; - - /* - * Map Framebuffer memory - */ - - if(drmMap(pViaXvMC->fd,pViaXvMC->fbOffset, - pViaXvMC->fbSize,&fbAddress) < 0) { - fprintf(stderr,"Unable to map XvMC Framebuffer.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - pViaXvMC->fbAddress = fbAddress; - pViaXvMC->resources = context_fbMap; - - - /* - * Map DRI Sarea. - */ - - if(drmMap(pViaXvMC->fd,pViaXvMC->sAreaOffset, - pViaXvMC->sAreaSize,&sAreaAddress) < 0) { - fprintf(stderr,"Unable to map DRI SAREA.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - } else { - pViaXvMC->fd = globalFD; - pViaXvMC->mmioAddress = mmioAddress; - pViaXvMC->fbAddress = fbAddress; - } - - pViaXvMC->sAreaAddress = sAreaAddress; - pViaXvMC->resources = context_sAreaMap; - numContexts++; - - /* - * Find a matching visual. Important only for direct drawing to the visible - * frame-buffer. - */ - - XLockDisplay(display); - ret = XMatchVisualInfo(display, pViaXvMC->screen, - (pViaXvMC->depth == 32) ? 24 : pViaXvMC->depth, TrueColor, - &pViaXvMC->visualInfo); - XUnlockDisplay(display); - if (!ret) { - fprintf(stderr, "viaXvMC: Could not find a matching TrueColor visual.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - - if (!uniDRICreateContext(display, pViaXvMC->screen, pViaXvMC->visualInfo.visual, - &pViaXvMC->id, &pViaXvMC->drmcontext)) { - - fprintf(stderr, "viaXvMC: Could not create DRI context.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - - pViaXvMC->resources = context_drmContext; - - for (i=0; i<VIA_MAX_RENDSURF; ++i) { - pViaXvMC->rendSurf[i] = 0; - } - pViaXvMC->lastSrfDisplaying = ~0; - setupAttribDesc(display, port, &pViaXvMC->attrib, pViaXvMC->attribDesc); - - pViaXvMC->hwLock = (drmLockPtr) pViaXvMC->sAreaAddress; - defaultQMatrices(pViaXvMC); - pViaXvMC->chromaIntraLoaded = 1; - pViaXvMC->chromaNonIntraLoaded = 1; - pViaXvMC->yStride = (width + 31) & ~31; - pViaXvMC->haveDecoder = 0; - pViaXvMC->attribChanged = 1; - pViaXvMC->haveXv = 0; - pViaXvMC->port = context->port; - pthread_mutex_init(&pViaXvMC->ctxMutex,NULL); - pViaXvMC->resources = context_mutex; - pViaXvMC->timeStamp = 0; - setRegion(0,0,-1,-1,pViaXvMC->sRegion); - setRegion(0,0,-1,-1,pViaXvMC->dRegion); - - if (NULL == (pViaXvMC->xl = - initXvMCLowLevel(pViaXvMC->fd, &pViaXvMC->drmcontext, - pViaXvMC->hwLock, pViaXvMC->mmioAddress, - pViaXvMC->fbAddress, pViaXvMC->stride, pViaXvMC->depth, - context->width, context->height, - pViaXvMC->useAGP, pViaXvMC->chipId))) { - - fprintf(stderr,"ViaXvMC: Could not allocate timestamp blit area.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - pViaXvMC->resources = context_lowLevel; - setAGPSyncLowLevel(pViaXvMC->xl, 1, 0); - - if (NULL == (pViaXvMC->drawHash = drmHashCreate())) { - fprintf(stderr,"ViaXvMC: Could not allocate drawable hash table.\n"); - return releaseContextResources(display, context, 1, BadAlloc); - } - pViaXvMC->resources = context_drawHash; - - - if (numContexts == 1) { - hwlLock(pViaXvMC->xl,1); - setLowLevelLocking(pViaXvMC->xl,0); - viaVideoSubPictureOffLocked(pViaXvMC->xl); - flushXvMCLowLevel(pViaXvMC->xl); - setLowLevelLocking(pViaXvMC->xl,1); - hwlUnlock(pViaXvMC->xl,1); - } - - return Success; -} - - -Status XvMCDestroyContext(Display *display, XvMCContext *context) -{ - ViaXvMCContext *pViaXvMC; - - - if(context == NULL) { - return (error_base + XvMCBadContext); - } - if(NULL == (pViaXvMC = context->privData)) { - return (error_base + XvMCBadContext); - } - - /* - * Release decoder if we have it. In case of crash or termination - * before XvMCDestroyContext, the X server will take care of this. - */ - - releaseAttribDesc(pViaXvMC->attrib.numAttr,pViaXvMC->attribDesc); - releaseDecoder(pViaXvMC,1); - return releaseContextResources(display, context, 1, Success); -} - -Status XvMCCreateSurface( Display *display, XvMCContext *context, - XvMCSurface *surface) -{ - ViaXvMCContext *pViaXvMC; - ViaXvMCSurface *pViaSurface; - int priv_count; - unsigned *priv_data; - unsigned i; - Status ret; - - if((surface == NULL) || (context == NULL) || (display == NULL)){ - return BadValue; - } - - pViaXvMC = (ViaXvMCContext *)context->privData; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - if(pViaXvMC == NULL) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return (error_base + XvMCBadContext); - } - - pViaSurface = surface->privData = (ViaXvMCSurface *)malloc(sizeof(ViaXvMCSurface)); - if(!surface->privData) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAlloc; - } - XLockDisplay(display); - if((ret = _xvmc_create_surface(display, context, surface, - &priv_count, &priv_data))) { - XUnlockDisplay(display); - free(pViaSurface); - fprintf(stderr,"Unable to create XvMC Surface.\n"); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return ret; - } - XUnlockDisplay(display); - - pViaSurface->srfNo = priv_data[0]; - - /* - * Store framebuffer offsets to the buffers allocated for this surface. - * For some chipset revisions, surfaces may be double-buffered. - */ - - pViaSurface->numBuffers = priv_data[1]; - for (i=0; i < pViaSurface->numBuffers; ++i) { - pViaSurface->offsets[i] = priv_data[i+2]; - } - pViaSurface->curBuf = 0; - - - /* Free data returned from xvmc_create_surface */ - - XFree(priv_data); - - pViaSurface->width = context->width; - pViaSurface->height = context->height; - pViaSurface->yStride = pViaXvMC->yStride; - pViaSurface->privContext = pViaXvMC; - pViaSurface->privSubPic = NULL; - pViaSurface->needsSync = 0; - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - -Status XvMCDestroySurface(Display *display, XvMCSurface *surface) -{ - ViaXvMCSurface *pViaSurface; - - if((display == NULL) || (surface == NULL)) { - return BadValue; - } - if(surface->privData == NULL) { - return (error_base + XvMCBadSurface); - } - - pViaSurface = (ViaXvMCSurface *)surface->privData; - - XLockDisplay(display); - _xvmc_destroy_surface(display,surface); - XUnlockDisplay(display); - - free(pViaSurface); - surface->privData = NULL; - return Success; -} - -Status XvMCPutSlice2(Display *display,XvMCContext *context, char *slice, - int nBytes, int sliceCode) -{ - ViaXvMCContext *pViaXvMC; - CARD32 sCode = 0x00010000 | (sliceCode & 0xFF) << 24; - - if((display == NULL) || (context == NULL)) { - return BadValue; - } - if(NULL == (pViaXvMC = context->privData)) { - return (error_base + XvMCBadContext); - } - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (!pViaXvMC->haveDecoder) { - fprintf(stderr,"XvMCPutSlice: This context does not own decoder!\n"); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAlloc; - } - - viaMpegWriteSlice(pViaXvMC->xl, (CARD8 *)slice, nBytes, sCode); - - flushPCIXvMCLowLevel(pViaXvMC->xl); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - -Status XvMCPutSlice(Display *display,XvMCContext *context, char *slice, - int nBytes) -{ - ViaXvMCContext *pViaXvMC; - - if((display == NULL) || (context == NULL)) { - return BadValue; - } - if(NULL == (pViaXvMC = context->privData)) { - return (error_base + XvMCBadContext); - } - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - if (!pViaXvMC->haveDecoder) { - fprintf(stderr,"XvMCPutSlice: This context does not own decoder!\n"); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAlloc; - } - - viaMpegWriteSlice(pViaXvMC->xl, (CARD8 *)slice, nBytes, 0); - flushPCIXvMCLowLevel(pViaXvMC->xl); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - - -static Status updateXVOverlay(Display *display,ViaXvMCContext *pViaXvMC, - ViaXvMCSurface *pViaSurface, Drawable draw, - short srcx, short srcy, unsigned short srcw, - unsigned short srch,short destx,short desty, - unsigned short destw,unsigned short desth) -{ - ViaXvMCCommandBuffer buf; - ViaXvMCSubPicture *pViaSubPic; - Status ret; - - if (!pViaXvMC->haveXv) { - pViaXvMC->xvImage = - XvCreateImage(display,pViaXvMC->port,FOURCC_XVMC, - (char *)&buf,pViaSurface->width, - pViaSurface->height); - pViaXvMC->gc = XCreateGC(display,draw,0,0); - pViaXvMC->haveXv = 1; - } - pViaXvMC->draw = draw; - pViaXvMC->xvImage->data = (char *)&buf; - - buf.command = (pViaXvMC->attribChanged) ? - VIA_XVMC_COMMAND_FDISPLAY : VIA_XVMC_COMMAND_DISPLAY; - buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; - buf.srfNo = pViaSurface->srfNo | VIA_XVMC_VALID; - pViaSubPic = pViaSurface->privSubPic; - buf.subPicNo = ((NULL == pViaSubPic) ? 0 : pViaSubPic->srfNo ) - | VIA_XVMC_VALID; - buf.attrib = pViaXvMC->attrib; - - XLockDisplay(display); - - if ((ret = XvPutImage(display,pViaXvMC->port,draw,pViaXvMC->gc, - pViaXvMC->xvImage,srcx,srcy,srcw,srch, - destx,desty,destw,desth))) { - XUnlockDisplay(display); - return ret; - } - XSync(display, 0); - XUnlockDisplay(display); - pViaXvMC->attribChanged = 0; - return Success; -} - - -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) -{ - /* - * This function contains some hairy locking logic. What we really want to - * do is to flip the picture ASAP, to get a low latency and smooth playback. - * However, if somebody else used the overlay since we used it last or if it is - * our first time, we'll have to call X to update the overlay first. Otherwise - * we'll do the overlay update once we've flipped. Since we release the hardware - * lock when we call X, X needs to verify using the SAREA that nobody else flipped - * in a picture between the lock release and the X server control. Similarly - * when the overlay update returns, we have to make sure that we still own the - * overlay. - */ - - ViaXvMCSurface *pViaSurface; - ViaXvMCContext *pViaXvMC; - ViaXvMCSubPicture *pViaSubPic; - volatile ViaXvMCSAreaPriv *sAPriv; - Status ret; - unsigned dispSurface, lastSurface; - int overlayUpdated; - drawableInfo *drawInfo; - XvMCRegion sReg, dReg; - Bool forceUpdate = FALSE; - - if((display == NULL) || (surface == NULL)) { - return BadValue; - } - if(NULL == (pViaSurface = surface->privData )) { - return (error_base + XvMCBadSurface); - } - if (NULL == (pViaXvMC = pViaSurface->privContext)) { - return (error_base + XvMCBadContext); - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - pViaSubPic = pViaSurface->privSubPic; - sAPriv = SAREAPTR( pViaXvMC ); - - setRegion(srcx, srcy, srcw, srch, sReg); - setRegion(destx, desty, destw, desth, dReg); - - - if ((!regionEqual(sReg, pViaXvMC->sRegion)) || - (!regionEqual(dReg, pViaXvMC->dRegion))) { - - /* - * Force update of the video overlay to match the new format. - */ - - pViaXvMC->sRegion = sReg; - pViaXvMC->dRegion = dReg; - forceUpdate = TRUE; - } - - - hwlLock(pViaXvMC->xl,1); - - if (getDRIDrawableInfoLocked(pViaXvMC->drawHash, display, pViaXvMC->screen, draw, 0, - pViaXvMC->fd, pViaXvMC->drmcontext, pViaXvMC->sAreaAddress, - FALSE, &drawInfo, sizeof(*drawInfo))) { - - hwlUnlock(pViaXvMC->xl,1); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAccess; - } - - setLowLevelLocking(pViaXvMC->xl,0); - - - /* - * Put a surface ID in the SAREA to "authenticate" to the - * X server. - */ - - dispSurface = sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]; - lastSurface = pViaXvMC->lastSrfDisplaying; - sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] = - pViaXvMC->lastSrfDisplaying = pViaSurface->srfNo | VIA_XVMC_VALID; - overlayUpdated = 0; - - viaVideoSetSWFLipLocked(pViaXvMC->xl, yOffs(pViaSurface), uOffs(pViaSurface), - vOffs(pViaSurface), pViaSurface->yStride, pViaSurface->yStride >> 1); - - while ((lastSurface != dispSurface) || forceUpdate) { - - forceUpdate = FALSE; - flushPCIXvMCLowLevel(pViaXvMC->xl); - setLowLevelLocking(pViaXvMC->xl,1); - hwlUnlock(pViaXvMC->xl,1); - - /* - * We weren't the last to display. Update the overlay before flipping. - */ - - ret = updateXVOverlay(display,pViaXvMC,pViaSurface,draw,srcx,srcy,srcw, - srch,destx,desty,destw,desth); - if (ret) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return ret; - } - - hwlLock(pViaXvMC->xl,1); - - if (getDRIDrawableInfoLocked(pViaXvMC->drawHash, display, pViaXvMC->screen, draw, 0, - pViaXvMC->fd, pViaXvMC->drmcontext, pViaXvMC->sAreaAddress, - FALSE, &drawInfo, sizeof(*drawInfo))) { - - hwlUnlock(pViaXvMC->xl,1); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAccess; - } - - setLowLevelLocking(pViaXvMC->xl,0); - lastSurface = pViaSurface->srfNo | VIA_XVMC_VALID; - dispSurface = sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort]; - overlayUpdated = 1; - } - - - /* - * Subpictures - */ - - if (NULL != pViaSubPic) { - if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] - != (pViaSubPic->srfNo | VIA_XVMC_VALID)) { - sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] = - pViaSubPic->srfNo | VIA_XVMC_VALID; - viaVideoSubPictureLocked(pViaXvMC->xl, pViaSubPic); - } - } else { - if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] & VIA_XVMC_VALID) { - viaVideoSubPictureOffLocked(pViaXvMC->xl); - sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] &= ~VIA_XVMC_VALID; - } - } - - /* - * Flip - */ - - viaVideoSWFlipLocked(pViaXvMC->xl, flags, pViaSurface->progressiveSequence); - flushXvMCLowLevel(pViaXvMC->xl); - - setLowLevelLocking(pViaXvMC->xl,1); - hwlUnlock(pViaXvMC->xl,1); - - if (overlayUpdated || !drawInfo->touched ) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - - /* - * Update overlay - */ - - ret = updateXVOverlay(display,pViaXvMC,pViaSurface,draw,srcx,srcy,srcw, - srch,destx,desty,destw,desth); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return ret; - -} - -Status XvMCBeginSurface(Display *display, - XvMCContext *context, - XvMCSurface *target_surface, - XvMCSurface *past_surface, - XvMCSurface *future_surface, - const XvMCMpegControl *control) -{ - ViaXvMCSurface *targS,*futS,*pastS; - ViaXvMCContext *pViaXvMC; - int hadDecoderLast; - CARD32 timeStamp; - - if((display == NULL) || (context == NULL) || (target_surface == NULL)) { - return BadValue; - } - - pViaXvMC = context->privData; - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (grabDecoder(pViaXvMC, &hadDecoderLast)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAlloc; - } - pViaXvMC->haveDecoder = 1; - - /* - * We need to wait for decoder idle at next flush, since hardware doesn't queue - * beginsurface requests until the decoder is idle. This is - * done by waiting on the last previous timestamp, or if there was another context - * having the decoder before us, by emitting a new one. - */ - - if (pViaXvMC->useAGP) { - if (!hadDecoderLast || pViaXvMC->timeStamp == 0) { - timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); - if (flushXvMCLowLevel(pViaXvMC->xl)) { - releaseDecoder(pViaXvMC, 0); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadAlloc; - } - pViaXvMC->timeStamp = timeStamp; - } else { - timeStamp = pViaXvMC->timeStamp; - } - setAGPSyncLowLevel(pViaXvMC->xl, 1, timeStamp); - } - - if (!hadDecoderLast || !pViaXvMC->decoderOn) { - pViaXvMC->intraLoaded = 0; - pViaXvMC->nonIntraLoaded = 0; - } - - viaMpegReset(pViaXvMC->xl); - - targS = (ViaXvMCSurface *)target_surface->privData; - futS = NULL; - pastS = NULL; - - - pViaXvMC->rendSurf[0] = targS->srfNo | VIA_XVMC_VALID; - if (future_surface) { - futS = (ViaXvMCSurface *)future_surface->privData; - futS->needsSync = 0; - } - if (past_surface) { - pastS = (ViaXvMCSurface *)past_surface->privData; - pastS->needsSync = 0; - } - - - targS->progressiveSequence = (control->flags & XVMC_PROGRESSIVE_SEQUENCE); - targS->topFieldFirst = (control->flags & XVMC_TOP_FIELD_FIRST); - targS->privSubPic = NULL; - - viaMpegSetSurfaceStride(pViaXvMC->xl,pViaXvMC); - - viaMpegSetFB(pViaXvMC->xl,0,yOffs(targS),uOffs(targS),vOffs(targS)); - if (past_surface) { - viaMpegSetFB(pViaXvMC->xl,1,yOffs(pastS),uOffs(pastS),vOffs(pastS)); - } else { - viaMpegSetFB(pViaXvMC->xl,1,0,0,0); - } - - if (future_surface) { - viaMpegSetFB(pViaXvMC->xl,2,yOffs(futS),uOffs(futS),vOffs(futS)); - } else { - viaMpegSetFB(pViaXvMC->xl,2,0,0,0); - } - - viaMpegBeginPicture(pViaXvMC->xl,pViaXvMC,context->width,context->height,control); - flushPCIXvMCLowLevel(pViaXvMC->xl); - targS->needsSync = 1; - targS->syncMode = LL_MODE_DECODER_IDLE; - pViaXvMC->decoderOn = 1; - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - - -Status XvMCSyncSurface(Display *display,XvMCSurface *surface) -{ - ViaXvMCSurface *pViaSurface; - ViaXvMCContext *pViaXvMC; - unsigned i; - - if((display == NULL) || (surface == NULL)) { - return BadValue; - } - if(surface->privData == NULL) { - return (error_base + XvMCBadSurface); - } - - pViaSurface = (ViaXvMCSurface *)surface->privData; - pViaXvMC = pViaSurface->privContext; - - if(pViaXvMC == NULL) { - return (error_base + XvMCBadSurface); - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - if (pViaSurface->needsSync) { - CARD32 timeStamp = pViaSurface->timeStamp; - int syncMode = pViaSurface->syncMode; - - if (pViaXvMC->useAGP) { - - syncMode = (pViaSurface->syncMode == LL_MODE_2D || - pViaSurface->timeStamp < pViaXvMC->timeStamp) ? - LL_MODE_2D : LL_MODE_DECODER_IDLE; - if (pViaSurface->syncMode != LL_MODE_2D) - timeStamp = pViaXvMC->timeStamp; - - } else if (syncMode != LL_MODE_2D && - pViaXvMC->rendSurf[0] != (pViaSurface->srfNo | VIA_XVMC_VALID)) { - - pViaSurface->needsSync = 0; - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - - if (syncXvMCLowLevel(pViaXvMC->xl, syncMode, 1, - pViaSurface->timeStamp)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadValue; - } - pViaSurface->needsSync = 0; - } - - if (pViaXvMC->rendSurf[0] == (pViaSurface->srfNo | VIA_XVMC_VALID)) { - pViaSurface->needsSync = 0; - for (i=0; i<VIA_MAX_RENDSURF; ++i) { - pViaXvMC->rendSurf[i] = 0; - } - } - - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - -Status XvMCLoadQMatrix(Display *display, XvMCContext *context, - const XvMCQMatrix *qmx) -{ - ViaXvMCContext - *pViaXvMC; - - if((display == NULL) || (context == NULL)) { - return BadValue; - } - if(NULL == (pViaXvMC = context->privData)) { - return (error_base + XvMCBadContext); - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (qmx->load_intra_quantiser_matrix) { - memcpy(pViaXvMC->intra_quantiser_matrix, - qmx->intra_quantiser_matrix, - sizeof(qmx->intra_quantiser_matrix)); - pViaXvMC->intraLoaded = 0; - } - - if (qmx->load_non_intra_quantiser_matrix) { - memcpy(pViaXvMC->non_intra_quantiser_matrix, - qmx->non_intra_quantiser_matrix, - sizeof(qmx->non_intra_quantiser_matrix)); - pViaXvMC->nonIntraLoaded = 0; - } - - if (qmx->load_chroma_intra_quantiser_matrix) { - memcpy(pViaXvMC->chroma_intra_quantiser_matrix, - qmx->chroma_intra_quantiser_matrix, - sizeof(qmx->chroma_intra_quantiser_matrix)); - pViaXvMC->chromaIntraLoaded = 0; - } - - if (qmx->load_chroma_non_intra_quantiser_matrix) { - memcpy(pViaXvMC->chroma_non_intra_quantiser_matrix, - qmx->chroma_non_intra_quantiser_matrix, - sizeof(qmx->chroma_non_intra_quantiser_matrix)); - pViaXvMC->chromaNonIntraLoaded = 0; - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - - return Success; -} - -/* - * Below, we provide functions unusable for this implementation, but for - * standard completeness. - */ - - -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 - ) -{ - return (error_base + XvMCBadContext); -} - -Status XvMCCreateBlocks -( - Display *display, - XvMCContext *context, - unsigned int num_blocks, - XvMCBlockArray * block - ) -{ - return (error_base + XvMCBadContext); -} - -Status XvMCDestroyBlocks (Display *display, XvMCBlockArray * block) -{ - return Success; -} - -Status XvMCCreateMacroBlocks -( - Display *display, - XvMCContext *context, - unsigned int num_blocks, - XvMCMacroBlockArray * blocks - ) -{ - return (error_base + XvMCBadContext); -} - -Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray * block) -{ - return (error_base + XvMCBadContext); -} - -Status XvMCCreateSubpicture( Display *display, - XvMCContext *context, - XvMCSubpicture *subpicture, - unsigned short width, - unsigned short height, - int xvimage_id) -{ - ViaXvMCContext *pViaXvMC; - ViaXvMCSubPicture *pViaSubPic; - int priv_count; - unsigned *priv_data; - Status ret; - - if((subpicture == NULL) || (context == NULL) || (display == NULL)){ - return BadValue; - } - - pViaXvMC = (ViaXvMCContext *)context->privData; - if(pViaXvMC == NULL) { - return (error_base + XvMCBadContext); - } - - subpicture->privData = (ViaXvMCSubPicture *) - malloc(sizeof(ViaXvMCSubPicture)); - if(!subpicture->privData) { - return BadAlloc; - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - subpicture->width = context->width; - subpicture->height = context->height; - subpicture->xvimage_id = xvimage_id; - pViaSubPic = (ViaXvMCSubPicture *)subpicture->privData; - - XLockDisplay(display); - if((ret = _xvmc_create_subpicture(display, context, subpicture, - &priv_count, &priv_data))) { - XUnlockDisplay(display); - free(pViaSubPic); - fprintf(stderr,"Unable to create XvMC Subpicture.\n"); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return ret; - } - XUnlockDisplay(display); - - - subpicture->num_palette_entries = VIA_SUBPIC_PALETTE_SIZE; - subpicture->entry_bytes = 3; - strncpy(subpicture->component_order,"YUV",4); - pViaSubPic->srfNo = priv_data[0]; - pViaSubPic->offset = priv_data[1]; - pViaSubPic->stride = (subpicture->width + 31) & ~31; - pViaSubPic->privContext = pViaXvMC; - pViaSubPic->ia44 = (xvimage_id == FOURCC_IA44); - pViaSubPic->needsSync = 0; - - /* Free data returned from _xvmc_create_subpicture */ - - XFree(priv_data); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - -Status -XvMCSetSubpicturePalette (Display *display, XvMCSubpicture *subpicture, - unsigned char *palette) -{ - ViaXvMCSubPicture *pViaSubPic; - ViaXvMCContext *pViaXvMC; - volatile ViaXvMCSAreaPriv *sAPriv; - unsigned i; - CARD32 tmp; - - if((subpicture == NULL) || (display == NULL)){ - return BadValue; - } - if(subpicture->privData == NULL) { - return (error_base + XvMCBadSubpicture); - } - pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; - for (i=0; i < VIA_SUBPIC_PALETTE_SIZE; ++i) { - tmp = *palette++ << 8; - tmp |= *palette++ << 16; - tmp |= *palette++ << 24; - tmp |= ((i & 0x0f) << 4) | 0x07; - pViaSubPic->palette[i] = tmp; - } - - pViaXvMC = pViaSubPic->privContext; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - sAPriv = SAREAPTR( pViaXvMC ); - hwlLock(pViaXvMC->xl,1); - setLowLevelLocking(pViaXvMC->xl,0); - - /* - * If the subpicture is displaying, Immeadiately update it with the - * new palette. - */ - - if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == - (pViaSubPic->srfNo | VIA_XVMC_VALID)) { - viaVideoSubPictureLocked(pViaXvMC->xl,pViaSubPic); - } - flushPCIXvMCLowLevel(pViaXvMC->xl); - setLowLevelLocking(pViaXvMC->xl,1); - hwlUnlock(pViaXvMC->xl,1); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - - -static int findOverlap(unsigned width,unsigned height, - short *dstX, short *dstY, - short *srcX, short *srcY, - unsigned short *areaW, unsigned short *areaH) -{ - int - w,h; - unsigned - mWidth,mHeight; - - w = *areaW; - h = *areaH; - - if ((*dstX >= width) || (*dstY >= height)) - return 1; - if (*dstX < 0) { - w += *dstX; - *srcX -= *dstX; - *dstX = 0; - } - if (*dstY < 0) { - h += *dstY; - *srcY -= *dstY; - *dstY = 0; - } - if ((w <= 0) || ((h <= 0))) - return 1; - mWidth = width - *dstX; - mHeight = height - *dstY; - *areaW = (w <= mWidth) ? w : mWidth; - *areaH = (h <= mHeight) ? h : mHeight; - return 0; -} - - - -Status XvMCClearSubpicture ( - Display *display, - XvMCSubpicture *subpicture, - short x, - short y, - unsigned short width, - unsigned short height, - unsigned int color - ) -{ - - ViaXvMCContext *pViaXvMC; - ViaXvMCSubPicture *pViaSubPic; - short dummyX,dummyY; - unsigned long bOffs; - - if((subpicture == NULL) || (display == NULL)) { - return BadValue; - } - if(subpicture->privData == NULL) { - return (error_base + XvMCBadSubpicture); - } - pViaSubPic = (ViaXvMCSubPicture *) subpicture->privData; - pViaXvMC = pViaSubPic->privContext; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - /* Clip clearing area so that it fits inside subpicture. */ - - if (findOverlap(subpicture->width, subpicture->height, &x, &y, - &dummyX, &dummyY, &width, &height)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - - bOffs = pViaSubPic->offset + y*pViaSubPic->stride + x; - viaBlit(pViaXvMC->xl, 8, 0, pViaSubPic->stride, bOffs, pViaSubPic->stride, - width, height, 1, 1, VIABLIT_FILL, color); - pViaSubPic->needsSync = 1; - pViaSubPic->timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); - if (flushXvMCLowLevel(pViaXvMC->xl)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadValue; - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - -Status -XvMCCompositeSubpicture ( - Display *display, - XvMCSubpicture *subpicture, - XvImage *image, - short srcx, - short srcy, - unsigned short width, - unsigned short height, - short dstx, - short dsty - ) -{ - - unsigned i; - ViaXvMCContext *pViaXvMC; - ViaXvMCSubPicture *pViaSubPic; - CARD8 *dAddr, *sAddr; - - if((subpicture == NULL) || (display == NULL) || (image == NULL)){ - return BadValue; - } - if(NULL == (pViaSubPic = (ViaXvMCSubPicture *)subpicture->privData)) { - return (error_base + XvMCBadSubpicture); - } - - pViaXvMC = pViaSubPic->privContext; - - - if (image->id != subpicture->xvimage_id) - return BadMatch; - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - - /* - * Clip copy area so that it fits inside subpicture and image. - */ - - if (findOverlap(subpicture->width, subpicture->height, - &dstx, &dsty, &srcx, &srcy, &width, &height)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - if (findOverlap(image->width, image->height, - &srcx, &srcy, &dstx, &dsty, &width, &height)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - - if (pViaSubPic->needsSync) { - if (syncXvMCLowLevel(pViaXvMC->xl, LL_MODE_2D, 0, pViaSubPic->timeStamp)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadValue; - } - pViaSubPic->needsSync = 0; - } - - for(i=0; i<height; ++i) { - dAddr = (((CARD8 *)pViaXvMC->fbAddress) + - (pViaSubPic->offset + (dsty+i)*pViaSubPic->stride + dstx)); - sAddr = (((CARD8 *)image->data) + - (image->offsets[0] + (srcy+i)*image->pitches[0] + srcx)); - memcpy(dAddr,sAddr,width); - } - - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - - - -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 - ) -{ - ViaXvMCSurface *pViaSurface; - ViaXvMCSubPicture *pViaSubPic; - - if((display == NULL) || target_surface == NULL){ - return BadValue; - } - - if (subx || suby || surfx || surfy || - (subw != surfw) || (subh != surfh)) { - fprintf(stderr,"ViaXvMC: Only completely overlapping subpicture " - "supported.\n"); - return BadValue; - } - - if(NULL == (pViaSurface = target_surface->privData)) { - return (error_base + XvMCBadSurface); - } - - if (subpicture) { - - if(NULL == (pViaSubPic = subpicture->privData)) { - return (error_base + XvMCBadSubpicture); - } - - pViaSurface->privSubPic = pViaSubPic; - } else { - pViaSurface->privSubPic = NULL; - } - return Success; -} - -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 - ) -{ - ViaXvMCSurface *pViaSurface,*pViaSSurface; - ViaXvMCSubPicture *pViaSubPic; - ViaXvMCContext *pViaXvMC; - - unsigned width,height; - - if((display == NULL) || target_surface == NULL || source_surface == NULL){ - return BadValue; - } - - if (subx || suby || surfx || surfy || - (subw != surfw) || (subh != surfh)) { - fprintf(stderr,"ViaXvMC: Only completely overlapping subpicture " - "supported.\n"); - return BadMatch; - } - - if(NULL == (pViaSurface = target_surface->privData)) { - return (error_base + XvMCBadSurface); - } - - if(NULL == (pViaSSurface = source_surface->privData)) { - return (error_base + XvMCBadSurface); - } - pViaXvMC = pViaSurface->privContext; - width = pViaSSurface->width; - height = pViaSSurface->height; - if (width != pViaSurface->width || height != pViaSSurface->height) { - return BadMatch; - } - - if (XvMCSyncSurface(display,source_surface)) { - return BadValue; - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - viaBlit(pViaXvMC->xl, 8, yOffs(pViaSSurface), pViaSSurface->yStride, - yOffs(pViaSurface), pViaSurface->yStride, - width, height, 1, 1, VIABLIT_COPY, 0); - flushPCIXvMCLowLevel(pViaXvMC->xl); - if (pViaXvMC->chipId != PCI_CHIP_VT3259) { - - /* - * YV12 Chroma blit. - */ - - viaBlit(pViaXvMC->xl, 8, uOffs(pViaSSurface), pViaSSurface->yStride >> 1, - uOffs(pViaSurface), pViaSurface->yStride >> 1, - width >> 1, height >> 1, 1, 1, VIABLIT_COPY, 0); - flushPCIXvMCLowLevel(pViaXvMC->xl); - viaBlit(pViaXvMC->xl, 8, vOffs(pViaSSurface), pViaSSurface->yStride >> 1, - vOffs(pViaSurface), pViaSurface->yStride >> 1, - width >> 1, height >> 1, 1, 1, VIABLIT_COPY, 0); - } else { - - /* - * NV12 Chroma blit. - */ - - viaBlit(pViaXvMC->xl, 8, vOffs(pViaSSurface), pViaSSurface->yStride, - vOffs(pViaSurface), pViaSurface->yStride, - width, height >> 1, 1, 1, VIABLIT_COPY, 0); - } - pViaSurface->needsSync = 1; - pViaSurface->syncMode = LL_MODE_2D; - pViaSurface->timeStamp = viaDMATimeStampLowLevel(pViaXvMC->xl); - if (flushXvMCLowLevel(pViaXvMC->xl)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadValue; - } - if (subpicture) { - - if(NULL == (pViaSubPic = subpicture->privData)) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return (error_base + XvMCBadSubpicture); - } - - pViaSurface->privSubPic = pViaSubPic; - } else { - pViaSurface->privSubPic = NULL; - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - - -Status -XvMCSyncSubpicture (Display *display, XvMCSubpicture *subpicture) -{ - ViaXvMCSubPicture *pViaSubPic; - ViaXvMCContext *pViaXvMC; - Status retVal=0; - - if((display == NULL) || subpicture == NULL){ - return BadValue; - } - if(NULL == (pViaSubPic = subpicture->privData)) { - return (error_base + XvMCBadSubpicture); - } - - pViaXvMC = pViaSubPic->privContext; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (pViaSubPic->needsSync) { - if (syncXvMCLowLevel(pViaXvMC->xl, LL_MODE_2D, - 0, pViaSubPic->timeStamp)) { - retVal = BadValue; - } - pViaSubPic->needsSync = 0; - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return retVal; -} - -Status -XvMCFlushSubpicture (Display *display, XvMCSubpicture *subpicture) -{ - ViaXvMCSubPicture *pViaSubPic; - - if((display == NULL) || subpicture == NULL){ - return BadValue; - } - if(NULL == (pViaSubPic = subpicture->privData)) { - return (error_base + XvMCBadSubpicture); - } - - return Success; -} - -Status -XvMCDestroySubpicture (Display *display, XvMCSubpicture *subpicture) -{ - ViaXvMCSubPicture *pViaSubPic; - ViaXvMCContext *pViaXvMC; - volatile ViaXvMCSAreaPriv *sAPriv; - - if((display == NULL) || subpicture == NULL){ - return BadValue; - } - if(NULL == (pViaSubPic = subpicture->privData)) { - return (error_base + XvMCBadSubpicture); - } - pViaXvMC = pViaSubPic->privContext; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - - sAPriv = SAREAPTR(pViaXvMC); - hwlLock(pViaXvMC->xl,1); - setLowLevelLocking(pViaXvMC->xl,0); - if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == - ( pViaSubPic->srfNo | VIA_XVMC_VALID )) { - viaVideoSubPictureOffLocked(pViaXvMC->xl); - sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] = 0; - } - flushPCIXvMCLowLevel(pViaXvMC->xl); - setLowLevelLocking(pViaXvMC->xl,1); - hwlUnlock(pViaXvMC->xl,1); - - XLockDisplay(display); - _xvmc_destroy_subpicture(display,subpicture); - XUnlockDisplay(display); - - free(pViaSubPic); - subpicture->privData = NULL; - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - - return Success; -} - -Status -XvMCGetSubpictureStatus (Display *display, XvMCSubpicture *subpic, int *stat) -{ - ViaXvMCSubPicture *pViaSubPic; - ViaXvMCContext *pViaXvMC; - volatile ViaXvMCSAreaPriv *sAPriv; - - - if((display == NULL) || subpic == NULL){ - return BadValue; - } - if(NULL == (pViaSubPic = subpic->privData)) { - return (error_base + XvMCBadSubpicture); - } - if (stat) { - *stat = 0; - pViaXvMC = pViaSubPic->privContext; - sAPriv = SAREAPTR( pViaXvMC ); - if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == - (pViaSubPic->srfNo | VIA_XVMC_VALID)) - *stat |= XVMC_DISPLAYING; - } - return Success; -} - -Status -XvMCFlushSurface (Display *display, XvMCSurface *surface) -{ - ViaXvMCSurface *pViaSurface; - ViaXvMCContext *pViaXvMC; - Status ret; - - if((display == NULL) || surface == NULL){ - return BadValue; - } - if(NULL == (pViaSurface = surface->privData)) { - return (error_base + XvMCBadSurface); - } - - pViaXvMC = pViaSurface->privContext; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (pViaSurface->needsSync) - pViaSurface->timeStamp = pViaXvMC->timeStamp = - viaDMATimeStampLowLevel(pViaXvMC->xl); - ret = (flushXvMCLowLevel(pViaXvMC->xl)) ? BadValue : Success; - if (pViaXvMC->rendSurf[0] == (pViaSurface->srfNo | VIA_XVMC_VALID)) { - hwlLock(pViaXvMC->xl,0); - pViaXvMC->haveDecoder = 0; - releaseDecoder(pViaXvMC, 0); - hwlUnlock(pViaXvMC->xl,0); - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return ret; -} - -Status -XvMCGetSurfaceStatus (Display *display, XvMCSurface *surface, int *stat) -{ - ViaXvMCSurface *pViaSurface; - ViaXvMCContext *pViaXvMC; - volatile ViaXvMCSAreaPriv *sAPriv; - unsigned i; - int ret = 0; - - if((display == NULL) || surface == NULL){ - return BadValue; - } - if(NULL == (pViaSurface = surface->privData)) { - return (error_base + XvMCBadSurface); - } - if (stat) { - *stat = 0; - pViaXvMC = pViaSurface->privContext; - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - sAPriv = SAREAPTR( pViaXvMC ); - if (sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] - == (pViaSurface->srfNo | VIA_XVMC_VALID)) - *stat |= XVMC_DISPLAYING; - for (i=0; i<VIA_MAX_RENDSURF; ++i) { - if(pViaXvMC->rendSurf[i] == - (pViaSurface->srfNo | VIA_XVMC_VALID)) { - *stat |= XVMC_RENDERING; - break; - } - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - } - return ret; -} - -XvAttribute * -XvMCQueryAttributes ( - Display *display, - XvMCContext *context, - int *number - ) -{ - ViaXvMCContext *pViaXvMC; - XvAttribute *ret; - unsigned long siz; - - *number = 0; - if ((display == NULL) || (context == NULL)) { - return NULL; - } - - if (NULL == (pViaXvMC = context->privData)) { - return NULL; - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (NULL != (ret = (XvAttribute *) - malloc(siz = VIA_NUM_XVMC_ATTRIBUTES*sizeof(XvAttribute)))) { - memcpy(ret,pViaXvMC->attribDesc,siz); - *number = VIA_NUM_XVMC_ATTRIBUTES; - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - - return ret; -} - -Status -XvMCSetAttribute ( - Display *display, - XvMCContext *context, - Atom attribute, - int value - ) -{ - int found; - unsigned i; - ViaXvMCContext *pViaXvMC; - ViaXvMCCommandBuffer buf; - - if ((display == NULL) || (context == NULL)) { - return (error_base + XvMCBadContext); - } - - if (NULL == (pViaXvMC = context->privData)) { - return (error_base + XvMCBadContext); - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - - found = 0; - for (i=0; i < pViaXvMC->attrib.numAttr; ++i) { - if (attribute == pViaXvMC->attrib.attributes[i].attribute) { - if ((!(pViaXvMC->attribDesc[i].flags & XvSettable)) || - value < pViaXvMC->attribDesc[i].min_value || - value > pViaXvMC->attribDesc[i].max_value) - return BadValue; - pViaXvMC->attrib.attributes[i].value = value; - found = 1; - pViaXvMC->attribChanged = 1; - break; - } - } - if (!found) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return BadMatch; - } - if (pViaXvMC->haveXv) { - buf.command = VIA_XVMC_COMMAND_ATTRIBUTES; - pViaXvMC->xvImage->data = (char *)&buf; - buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; - buf.attrib = pViaXvMC->attrib; - XLockDisplay(display); - pViaXvMC->attribChanged = - XvPutImage(display,pViaXvMC->port,pViaXvMC->draw, - pViaXvMC->gc, - pViaXvMC->xvImage,0,0,1,1,0,0,1,1); - XUnlockDisplay(display); - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} - - -Status -XvMCGetAttribute ( - Display *display, - XvMCContext *context, - Atom attribute, - int *value - ) -{ - int found; - unsigned i; - ViaXvMCContext *pViaXvMC; - - if ((display == NULL) || (context == NULL)) { - return (error_base + XvMCBadContext); - } - - if (NULL == (pViaXvMC = context->privData)) { - return (error_base + XvMCBadContext); - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - found = 0; - for (i=0; i < pViaXvMC->attrib.numAttr; ++i) { - if (attribute == pViaXvMC->attrib.attributes[i].attribute) { - if (pViaXvMC->attribDesc[i].flags & XvGettable) { - *value = pViaXvMC->attrib.attributes[i].value; - found = 1; - break; - } - } - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - - if (!found) - return BadMatch; - return Success; -} - - -Status XvMCHideSurface(Display *display,XvMCSurface *surface) -{ - - ViaXvMCSurface *pViaSurface; - ViaXvMCContext *pViaXvMC; - ViaXvMCSubPicture *pViaSubPic; - volatile ViaXvMCSAreaPriv *sAPriv; - ViaXvMCCommandBuffer buf; - Status ret; - - if ((display == NULL) || (surface == NULL)) { - return BadValue; - } - if (NULL == (pViaSurface = surface->privData )) { - return (error_base + XvMCBadSurface); - } - if (NULL == (pViaXvMC = pViaSurface->privContext)) { - return (error_base + XvMCBadContext); - } - - ppthread_mutex_lock( &pViaXvMC->ctxMutex ); - if (!pViaXvMC->haveXv) { - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - - sAPriv = SAREAPTR( pViaXvMC ); - hwlLock(pViaXvMC->xl,1); - - if (sAPriv->XvMCDisplaying[pViaXvMC->xvMCPort] != - (pViaSurface->srfNo | VIA_XVMC_VALID)) { - hwlUnlock(pViaXvMC->xl,1); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; - } - setLowLevelLocking(pViaXvMC->xl,0); - if (NULL != (pViaSubPic = pViaSurface->privSubPic)) { - if (sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] == - (pViaSubPic->srfNo | VIA_XVMC_VALID)) { - sAPriv->XvMCSubPicOn[pViaXvMC->xvMCPort] &= ~VIA_XVMC_VALID; - viaVideoSubPictureOffLocked(pViaXvMC->xl); - } - } - flushPCIXvMCLowLevel(pViaXvMC->xl); - setLowLevelLocking(pViaXvMC->xl,1); - hwlUnlock(pViaXvMC->xl,1); - - buf.command = VIA_XVMC_COMMAND_UNDISPLAY; - buf.ctxNo = pViaXvMC->ctxNo | VIA_XVMC_VALID; - buf.srfNo = pViaSurface->srfNo | VIA_XVMC_VALID; - pViaXvMC->xvImage->data = (char *)&buf; - if ((ret = XvPutImage(display,pViaXvMC->port,pViaXvMC->draw, - pViaXvMC->gc, - pViaXvMC->xvImage,0,0,1,1,0,0,1,1))) { - fprintf(stderr,"XvMCPutSurface: Hiding overlay failed.\n"); - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return ret; - } - ppthread_mutex_unlock( &pViaXvMC->ctxMutex ); - return Success; -} |