diff options
Diffstat (limited to 'nx-X11/lib/XvMC/hw/i810/I810XvMC.c')
-rw-r--r-- | nx-X11/lib/XvMC/hw/i810/I810XvMC.c | 4507 |
1 files changed, 0 insertions, 4507 deletions
diff --git a/nx-X11/lib/XvMC/hw/i810/I810XvMC.c b/nx-X11/lib/XvMC/hw/i810/I810XvMC.c deleted file mode 100644 index 89aa3ea4b..000000000 --- a/nx-X11/lib/XvMC/hw/i810/I810XvMC.c +++ /dev/null @@ -1,4507 +0,0 @@ -/*************************************************************************** - -Copyright 2001 Intel Corporation. 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, sub license, 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 (including the -next paragraph) 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 NON-INFRINGEMENT. -IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS 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. - -**************************************************************************/ - -/************************************************************************* -** File libI810XvMC.c -** -** Authors: -** Matt Sottek <matthew.j.sottek@intel.com> -** Bob Paauwe <bob.j.paauwe@intel.com> -** -** -***************************************************************************/ -/* $XFree86: xc/lib/XvMC/hw/i810/I810XvMC.c,v 1.10 2002/10/30 12:52:01 alanh Exp $ */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <fcntl.h> -#include <dirent.h> -#include <string.h> - -#include <sys/ioctl.h> -#include <X11/Xlibint.h> -#include <fourcc.h> -#include <X11/extensions/Xv.h> -#include <X11/extensions/Xvlib.h> -#include <X11/extensions/XvMC.h> -#include <X11/extensions/XvMClib.h> -#include "I810XvMC.h" - -static int error_base; -static int event_base; - -/*************************************************************************** -// Function: i810_get_free_buffer -// Description: Allocates a free dma page using kernel ioctls, then -// programs the data into the already allocated dma buffer list. -// Arguments: pI810XvMC private data structure from the current context. -// Notes: We faked the drmMapBufs for the i810's security so now we have -// to insert an allocated page into the correct spot in the faked -// list to keep up appearences. -// Concept for this function was taken from Mesa sources. -// Returns: drmBufPtr containing the information about the allocated page. -***************************************************************************/ -drmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC) { - drmI810DMA dma; - drmBufPtr buf; - - dma.granted = 0; - dma.request_size = 4096; - while(!dma.granted) { - if(GET_BUFFER(pI810XvMC, dma) || !dma.granted) - FLUSH(pI810XvMC); - } /* No DMA granted */ - - buf = &(pI810XvMC->dmabufs->list[dma.request_idx]); - buf->idx = dma.request_idx; - buf->used = 0; - buf->total = dma.request_size; - buf->address = (drmAddress)dma.virtual; - return buf; -} - -/*************************************************************************** -// Function: free_privContext -// Description: Free's the private context structure if the reference -// count is 0. -***************************************************************************/ -void i810_free_privContext(i810XvMCContext *pI810XvMC) { - - I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); - - - pI810XvMC->ref--; - if(!pI810XvMC->ref) { - drmUnmapBufs(pI810XvMC->dmabufs); - drmUnmap(pI810XvMC->overlay.address,pI810XvMC->overlay.size); - drmUnmap(pI810XvMC->surfaces.address,pI810XvMC->surfaces.size); - drmClose(pI810XvMC->fd); - - free(pI810XvMC->dmabufs->list); - free(pI810XvMC); - } - - I810_UNLOCK(pI810XvMC); -} - - -/*************************************************************************** -// Function: XvMCCreateContext -// Description: Create a XvMC context for the given surface parameters. -// Arguments: -// display - Connection to the X server. -// port - XvPortID to use as avertised by the X connection. -// surface_type_id - Unique identifier for the Surface type. -// width - Width of the surfaces. -// height - Height of the surfaces. -// flags - one or more of the following -// XVMC_DIRECT - A direct rendered context is requested. -// -// Notes: surface_type_id and width/height parameters must match those -// returned by XvMCListSurfaceTypes. -// Returns: Status -***************************************************************************/ -Status XvMCCreateContext(Display *display, XvPortID port, - int surface_type_id, int width, int height, int flags, - XvMCContext *context) { - i810XvMCContext *pI810XvMC; - char busIdString[10]; - int priv_count; - uint *priv_data; - uint magic; - Status ret; - int major, minor; - - /* Verify Obvious things first */ - if(context == NULL) { - return XvMCBadContext; - } - - if(!(flags & XVMC_DIRECT)) { - /* Indirect */ - printf("Indirect Rendering not supported!\nUsing Direct."); - } - - /* Limit use to root for now */ - if(geteuid()) { - printf("Use of XvMC on i810 is currently limited to root\n"); - return BadAccess; - } - - /* FIXME: Check $DISPLAY for legal values here */ - - context->surface_type_id = surface_type_id; - context->width = (unsigned short)width; - context->height = (unsigned short)height; - 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(i810XvMCContext)); - if(!context->privData) { - printf("Unable to allocate resources for XvMC context.\n"); - return BadAlloc; - } - pI810XvMC = (i810XvMCContext *)context->privData; - - - /* Verify the XvMC extension exists */ - if(! XvMCQueryExtension(display, &event_base, - &error_base)) { - printf("XvMC Extension is not available!\n"); - return BadAlloc; - } - /* Verify XvMC version */ - ret = XvMCQueryVersion(display, &major, &minor); - if(ret) { - printf("XvMCQuery Version Failed, unable to determine protocol version\n"); - } - /* FIXME: Check Major and Minor here */ - - /* Check for drm */ - if(! drmAvailable()) { - printf("Direct Rendering is not avilable on this system!\n"); - return BadAlloc; - } - - /* - Build the Attribute Atoms, and Initialize the ones that exist - in Xv. - */ - pI810XvMC->xv_colorkey = XInternAtom(display,"XV_COLORKEY",0); - if(!pI810XvMC->xv_colorkey) { - return XvBadPort; - } - ret = XvGetPortAttribute(display,port,pI810XvMC->xv_colorkey, - &pI810XvMC->colorkey); - if(ret) { - return ret; - } - pI810XvMC->xv_brightness = XInternAtom(display,"XV_BRIGHTNESS",0); - pI810XvMC->xv_saturation = XInternAtom(display,"XV_SATURATION",0); - pI810XvMC->xv_contrast = XInternAtom(display,"XV_CONTRAST",0); - pI810XvMC->brightness = 0; - pI810XvMC->saturation = 0x80; /* 1.0 in 3.7 format */ - pI810XvMC->contrast = 0x40; /* 1.0 in 3.6 format */ - - /* Open DRI Device */ - if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) { - printf("DRM Device for i810 could not be opened.\n"); - free(busIdString); - free(pI810XvMC); - return BadAccess; - } /* !pI810XvMC->fd */ - - /* Get magic number and put it in privData for passing */ - drmGetMagic(pI810XvMC->fd,&magic); - context->flags = (unsigned long)magic; - - /* - Pass control to the X server to create a drm_context_t for us and - validate the with/height and flags. - */ - if((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { - printf("Unable to create XvMC Context.\n"); - return ret; - } - - /* - X server returns a structure like this: - drm_context_t - fbBase - OverlayOffset - OverlaySize - SurfacesOffset - SurfacesSize - busIdString = 9 char + 1 - */ - if(priv_count != 9) { - printf("_xvmc_create_context() returned incorrect data size!\n"); - printf("\tExpected 9, got %d\n",priv_count); - _xvmc_destroy_context(display, context); - free(pI810XvMC); - return BadAlloc; - } - pI810XvMC->drmcontext = priv_data[0]; - pI810XvMC->fb_base = priv_data[1]; - pI810XvMC->overlay.offset = priv_data[2] + priv_data[1]; - pI810XvMC->overlay.size = priv_data[3]; - pI810XvMC->surfaces.offset = priv_data[4] + priv_data[1]; - pI810XvMC->surfaces.size = priv_data[5]; - strncpy(pI810XvMC->busIdString,(char *)&priv_data[6],9); - pI810XvMC->busIdString[9] = '\0'; - - /* Must free the private data we were passed from X */ - free(priv_data); - - /* Initialize private context values */ - pI810XvMC->current = 0; - pI810XvMC->lock = 0; - pI810XvMC->last_flip = 0; - pI810XvMC->dual_prime = 0; - - /* - Map dma Buffers: Not really, this would be a drmMapBufs - but due to the i810 security model we have to just create an - empty data structure to fake it. - */ - pI810XvMC->dmabufs = (drmBufMapPtr)malloc(sizeof(drmBufMap)); - if(pI810XvMC->dmabufs == NULL) { - printf("Dma Bufs could not be mapped.\n"); - _xvmc_destroy_context(display, context); - free(pI810XvMC); - return BadAlloc; - } /* pI810XvMC->dmabufs == NULL */ - memset(pI810XvMC->dmabufs, 0, sizeof(drmBufMap)); - pI810XvMC->dmabufs->list = (drmBufPtr)malloc(sizeof(drmBuf) * - I810_DMA_BUF_NR); - if(pI810XvMC->dmabufs->list == NULL) { - printf("Dma Bufs could not be mapped.\n"); - _xvmc_destroy_context(display, context); - free(pI810XvMC); - return BadAlloc; - } /* pI810XvMC->dmabufs->list == NULL */ - memset(pI810XvMC->dmabufs->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR); - - /* Map the Overlay memory */ - if(drmMap(pI810XvMC->fd,pI810XvMC->overlay.offset, - pI810XvMC->overlay.size,&(pI810XvMC->overlay.address)) < 0) { - printf("Unable to map Overlay at offset 0x%x and size 0x%x\n", - (unsigned int)pI810XvMC->overlay.offset,pI810XvMC->overlay.size); - _xvmc_destroy_context(display, context); - free(pI810XvMC->dmabufs->list); - free(pI810XvMC); - return BadAlloc; - } /* drmMap() < 0 */ - - /* Overlay Regs are offset 1024 into Overlay Map */ - pI810XvMC->oregs = (i810OverlayRec *) - ((unsigned char *)pI810XvMC->overlay.address + 1024); - - /* Map Surfaces */ - if(drmMap(pI810XvMC->fd,pI810XvMC->surfaces.offset, - pI810XvMC->surfaces.size,&(pI810XvMC->surfaces.address)) < 0) { - printf("Unable to map XvMC Surfaces.\n"); - _xvmc_destroy_context(display, context); - free(pI810XvMC->dmabufs->list); - free(pI810XvMC); - return BadAlloc; - } /* drmMap() < 0 */ - - /* - There is a tiny chance that someone was using the overlay and - issued a flip that hasn't finished. To be 100% sure I'll just - take the lock and sleep for the worst case time for a flip. - */ - I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); - usleep(20000); /* 1/50th Sec for 50hz refresh */ - - /* Set up Overlay regs with Initial Values */ - pI810XvMC->oregs->YRGB_VPH = 0; - pI810XvMC->oregs->UV_VPH = 0; - pI810XvMC->oregs->HORZ_PH = 0; - pI810XvMC->oregs->INIT_PH = 0; - pI810XvMC->oregs->DWINPOS = 0; - pI810XvMC->oregs->DWINSZ = (I810_XVMC_MAXHEIGHT << 16) | - I810_XVMC_MAXWIDTH; - pI810XvMC->oregs->SWID = I810_XVMC_MAXWIDTH | (I810_XVMC_MAXWIDTH << 15); - pI810XvMC->oregs->SWIDQW = (I810_XVMC_MAXWIDTH >> 3) | - (I810_XVMC_MAXWIDTH << 12); - pI810XvMC->oregs->SHEIGHT = I810_XVMC_MAXHEIGHT | - (I810_XVMC_MAXHEIGHT << 15); - pI810XvMC->oregs->YRGBSCALE = 0x80004000; /* scale factor 1 */ - pI810XvMC->oregs->UVSCALE = 0x80004000; /* scale factor 1 */ - pI810XvMC->oregs->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */ - pI810XvMC->oregs->OV0CLRC1 = 0x80; /* saturation: bypass */ - - /* Destination Colorkey Setup */ - pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey); - pI810XvMC->oregs->DCLRKM = 0x80070307; - - - pI810XvMC->oregs->SCLRKVH = 0; - pI810XvMC->oregs->SCLRKVL = 0; - pI810XvMC->oregs->SCLRKM = 0; /* source color key disable */ - pI810XvMC->oregs->OV0CONF = 0; /* two 720 pixel line buffers */ - - pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | - Y_ADJUST | YUV_420; - - pI810XvMC->ref = 1; - - I810_UNLOCK(pI810XvMC); - - return Success; - -} - -/*************************************************************************** -// Function: XvMCDestroyContext -// Description: Destorys the specified context. -// -// Arguments: -// display - Specifies the connection to the server. -// context - The context to be destroyed. -// -// Returns: Status -***************************************************************************/ -Status XvMCDestroyContext(Display *display, XvMCContext *context) { - i810XvMCContext *pI810XvMC; - - if(context == NULL) { - return (error_base + XvMCBadContext); - } - if(context->privData == NULL) { - return (error_base + XvMCBadContext); - } - pI810XvMC = (i810XvMCContext *)context->privData; - - /* Turn off the overlay */ - if(pI810XvMC->last_flip) { - I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); - - /* Make sure last flip is done */ - BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); - - pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | - Y_ADJUST; - pI810XvMC->current = !pI810XvMC->current; - if(pI810XvMC->current == 1) { - pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0; - } - else { - pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0; - } - OVERLAY_FLIP(pI810XvMC); - pI810XvMC->last_flip++; - - /* Wait for the flip */ - BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); - - I810_UNLOCK(pI810XvMC); - } - - /* Pass Control to the X server to destroy the drm_context_t */ - _xvmc_destroy_context(display, context); - - i810_free_privContext(pI810XvMC); - context->privData = NULL; - - return Success; -} - - -/*************************************************************************** -// Function: XvMCCreateSurface -***************************************************************************/ -Status XvMCCreateSurface( Display *display, XvMCContext *context, - XvMCSurface *surface) { - i810XvMCContext *pI810XvMC; - i810XvMCSurface *pI810Surface; - int priv_count; - uint *priv_data; - Status ret; - - if((surface == NULL) || (context == NULL) || (display == NULL)){ - return BadValue; - } - - pI810XvMC = (i810XvMCContext *)context->privData; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadContext); - } - - - surface->privData = (i810XvMCSurface *)malloc(sizeof(i810XvMCSurface)); - if(!surface->privData) { - return BadAlloc; - } - pI810Surface = (i810XvMCSurface *)surface->privData; - - /* Initialize private values */ - pI810Surface->privContext = pI810XvMC; - pI810Surface->last_render = 0; - pI810Surface->last_flip = 0; - pI810Surface->second_field = 0; - - if((ret = _xvmc_create_surface(display, context, surface, - &priv_count, &priv_data))) { - free(pI810Surface); - printf("Unable to create XvMCSurface.\n"); - return ret; - } - - /* - _xvmc_create_subpicture returns 2 uints with the offset into - the DRM map for the Y surface and UV surface. - */ - if(priv_count != 2) { - printf("_xvmc_create_surface() return incorrect data size.\n"); - printf("Expected 2 got %d\n",priv_count); - free(priv_data); - free(pI810Surface); - return BadAlloc; - } - /* Data == Client Address, offset == Physical address offset */ - pI810Surface->data = pI810XvMC->surfaces.address; - pI810Surface->offset = pI810XvMC->surfaces.offset; - - - /* - i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch - and the Tiler need 512k aligned surfaces, basically we are - stuck with fixed memory with pitch 1024 for Y data. UV = 512. - */ - pI810Surface->pitch = 10; - if((surface->surface_type_id == FOURCC_UYVY) || - (surface->surface_type_id == FOURCC_YUY2)) { - /* This is not implemented server side. */ - pI810Surface->pitch++; - } - - /* - offsets[0,1,2] == Offsets from either data or offset for the Y - U and V surfaces. - */ - pI810Surface->offsets[0] = priv_data[0]; - if(((unsigned long)pI810Surface->data + pI810Surface->offsets[0]) & 4095) { - printf("XvMCCreateSurface: Surface offset 0 is not 4096 aligned\n"); - } - - if((surface->surface_type_id == FOURCC_UYVY) || - (surface->surface_type_id == FOURCC_YUY2)) { - /* Packed surface, not fully implemented */ - pI810Surface->offsets[1] = 0; - pI810Surface->offsets[2] = 0; - } - else { - /* Planar surface */ - pI810Surface->offsets[1] = priv_data[1]; - if(((unsigned long)pI810Surface->data + pI810Surface->offsets[1]) & 2047) { - printf("XvMCCreateSurface: Surface offset 1 is not 2048 aligned\n"); - } - - pI810Surface->offsets[2] = ((unsigned long)pI810Surface->offsets[1] + - (1<<(pI810Surface->pitch - 1)) * 288); - if(((unsigned long)pI810Surface->data + pI810Surface->offsets[2]) & 2047) { - printf("XvMCCreateSurface: Surface offset 2 is not 2048 aligned\n"); - } - - } - - /* Free data returned from xvmc_create_surface */ - free(priv_data); - - /* Clear the surface to 0 */ - memset((void *)((unsigned long)pI810Surface->data + (unsigned long)pI810Surface->offsets[0]), - 0, ((1<<pI810Surface->pitch) * surface->height)); - - switch(surface->surface_type_id) { - case FOURCC_YV12: - case FOURCC_I420: - /* Destination buffer info command */ - pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset + - pI810Surface->offsets[0]) & ~0xfc000fff) | - (pI810Surface->pitch - 9)); - pI810Surface->dbi1u = ((((unsigned int)pI810Surface->offset + - pI810Surface->offsets[1]) & ~0xfc000fff) | - (pI810Surface->pitch - 10)); - pI810Surface->dbi1v = ((((unsigned int)pI810Surface->offset + - pI810Surface->offsets[2]) & ~0xfc000fff) | - (pI810Surface->pitch - 10)); - - /* Destination buffer variables command */ - pI810Surface->dbv1 = (0x8<<20) | (0x8<<16); - /* Map info command */ - pI810Surface->mi1y = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 3); - pI810Surface->mi1u = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4); - pI810Surface->mi1v = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4); - - pI810Surface->mi2y = (((unsigned int)surface->height - 1)<<16) | - ((unsigned int)surface->width - 1); - pI810Surface->mi2u = (((unsigned int)surface->height - 1)<<15) | - (((unsigned int)surface->width - 1)>>1); - pI810Surface->mi2v = pI810Surface->mi2u; - - pI810Surface->mi3y = ((unsigned int)pI810Surface->offset + - pI810Surface->offsets[0]) & ~0x0000000f; - pI810Surface->mi3u = ((unsigned int)pI810Surface->offset + - pI810Surface->offsets[1]) & ~0x0000000f; - pI810Surface->mi3v = ((unsigned int)pI810Surface->offset + - pI810Surface->offsets[2]) & ~0x0000000f; - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - /* Destination buffer info command */ - pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset + - pI810Surface->offsets[0]) & ~0xfc000fff) | - (pI810Surface->pitch - 9)); - /* Destination buffer variables command */ - if(surface->surface_type_id == FOURCC_YUY2) { - pI810Surface->dbv1 = 0x5<<8; - pI810Surface->mi1y = 0x5<<24 | pI810Surface->pitch | 0x1<<21; - } - else { - pI810Surface->dbv1 = 0x4<<8; - pI810Surface->mi1y = 0x5<<24 | (pI810Surface->pitch - 3); - } - pI810Surface->mi2y = (((unsigned int)surface->width - 1)<<16) | - ((unsigned int)surface->height - 1); - pI810Surface->mi3y = ((unsigned int)pI810Surface->offset + - pI810Surface->offsets[0]) & ~0xfc000fff; - break; - } - pI810XvMC->ref++; - - return Success; -} - - -/*************************************************************************** -// Function: XvMCDestroySurface -***************************************************************************/ -Status XvMCDestroySurface(Display *display, XvMCSurface *surface) { - i810XvMCSurface *pI810Surface; - i810XvMCContext *pI810XvMC; - - if((display == NULL) || (surface == NULL)) { - return BadValue; - } - if(surface->privData == NULL) { - return (error_base + XvMCBadSurface); - } - - pI810Surface = (i810XvMCSurface *)surface->privData; - if(pI810Surface->last_flip) { - XvMCSyncSurface(display,surface); - } - pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; - - _xvmc_destroy_surface(display,surface); - - i810_free_privContext(pI810XvMC); - - free(pI810Surface); - surface->privData = NULL; - return Success; -} - -/*************************************************************************** -// Function: XvMCCreateBlocks -***************************************************************************/ -Status XvMCCreateBlocks(Display *display, XvMCContext *context, - unsigned int num_blocks, - XvMCBlockArray *block) { - - if((display == NULL) || (context == NULL) || (num_blocks == 0)) { - return BadValue; - } - - block->blocks = (short *)malloc(num_blocks<<6 * sizeof(short)); - if(block->blocks == NULL) { - return BadAlloc; - } - - block->num_blocks = num_blocks; - block->context_id = context->context_id; - - block->privData = NULL; - - return Success; -} - -/*************************************************************************** -// Function: XvMCDestroyBlocks -***************************************************************************/ -Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) { - if(display == NULL) { - return BadValue; - } - - free(block->blocks); - block->num_blocks = 0; - block->context_id = 0; - block->privData = NULL; - return Success; -} - -/*************************************************************************** -// Function: XvMCCreateMacroBlocks -***************************************************************************/ -Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, - unsigned int num_blocks, - XvMCMacroBlockArray *blocks) { - - if((display == NULL) || (context == NULL) || (blocks == NULL) || - (num_blocks == 0)) { - return BadValue; - } - memset(blocks,0,sizeof(XvMCMacroBlockArray)); - blocks->context_id = context->context_id; - blocks->privData = NULL; - - blocks->macro_blocks = (XvMCMacroBlock *) - malloc(num_blocks * sizeof(XvMCMacroBlock)); - if(blocks->macro_blocks == NULL) { - return BadAlloc; - } - blocks->num_blocks = num_blocks; - - return Success; -} - -/*************************************************************************** -// Function: XvMCDestroyMacroBlocks -***************************************************************************/ -Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) { - if((display == NULL) || (block == NULL)) { - return BadValue; - } - if(block->macro_blocks) { - free(block->macro_blocks); - } - block->context_id = 0; - block->num_blocks = 0; - block->privData = NULL; - - return Success; -} - - -/*************************************************************************** -// Function: dp (Debug Print) -// Description: This function prints out in hex i * uint32_t at the address -// supplied. This enables you to print out the dma buffers from -// within the debugger even though they are not in your address space. -***************************************************************************/ -void dp(unsigned int *address, unsigned int i) { - int j; - - printf("DebugPrint:\n"); - for(j=0; j<i; j++) { - printf("0x%8.8x ",address[j]); - if(j && !(j & 7)) { printf("\n");} - } -} - -/*************************************************************************** -// Macro: PACK_* -// Description: Packs 16bit signed data from blocks into either 8bit unsigned -// intra data or 16bit signed correction data, both packed into -// 32 bit integers. -***************************************************************************/ -#define PACK_INTRA_DATA(d,b,n) \ - do { \ - char *dp = (char *)d; \ - char *bp = (char *)b; \ - int counter; \ - for(counter = 0; counter < n; counter++) { \ - *dp++ = *bp; \ - bp += 2; \ - } \ - }while(0); - -#define PACK_CORR_DATA(d,b,n) \ - memcpy(d,b,n); \ - d = (uint *)((unsigned long)d + n); - -#define MARK_CORR_DATA(d,n) \ - do { \ - uint* q = (uint*)((unsigned long)d - n); \ - while((unsigned long)q < (unsigned long)d) { \ - *q++ += 0x00330033; \ - } \ - }while(0); - -#define MARK_INTRA_BLOCK(d) \ - do { \ - int q; \ - for(q=0; q<16; q++) { \ - d[q] += 0x33333333; \ - } \ - }while(0); - -/* - Used for DCT 1 when we need DCT 0. Instead - of reading from one block we read from two and - interlace. -*/ -#define PACK_CORR_DATA_1to0(d,top,bottom) \ - do { \ - short *t = top,*b = bottom; \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 16); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 16); \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 16); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 16); \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 16); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 16); \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 16); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 16); \ - }while(0); - -/* Used for DCT 0 when we need DCT 1. */ -#define PACK_CORR_DATA_0to1(d,top,bottom) \ - do{ \ - short *t = top,*b = bottom; \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 32); \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 32); \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 32); \ - PACK_CORR_DATA(d,t,16); \ - t = (short *)((unsigned long)t + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - }while(0); - -#define PACK_CORR_DATA_SHORT(d,block) \ - do { \ - short *b = block; \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - PACK_CORR_DATA(d,b,16); \ - b = (short *)((unsigned long)b + 32); \ - }while(0); - -/* Lookup tables to speed common calculations */ -static unsigned int drps_table[] = {2<<6,3<<6}; - -static unsigned int mvfs_table[] = { - 0x12, - 0x1a, - 0x13, - 0x1b -}; - -static unsigned int type_table[] = { - 0x1<<12, /* This is an error so make it Forward motion */ - 0x1<<12, - 0x1<<12, - 0x1<<12, - 0x2<<12, - 0x2<<12, - 0x3<<12, - 0x3<<12, - 0x1<<12, /* Pattern but no Motion, Make motion Forward */ - 0x1<<12, - 0x1<<12, - 0x1<<12, - 0x2<<12, - 0x2<<12, - 0x3<<12, - 0x3<<12 -}; - -static unsigned int y_frame_bytes[] = { - 0,0,0,0,128,128,128,128, - 128,128,128,128,256,256,256,256, - 128,128,128,128,256,256,256,256, - 256,256,256,256,384,384,384,384, - 128,128,128,128,256,256,256,256, - 256,256,256,256,384,384,384,384, - 256,256,256,256,384,384,384,384, - 384,384,384,384,512,512,512,512 -}; - -static unsigned int u_frame_bytes[] = { - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128, - 0,0,128,128,0,0,128,128 -}; - -static unsigned int v_frame_bytes[] = { - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128, - 0,128,0,128,0,128,0,128 -}; - -static unsigned int y_first_field_bytes[] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 128,128,128,128,128,128,128,128, - 128,128,128,128,128,128,128,128, - 128,128,128,128,128,128,128,128, - 128,128,128,128,128,128,128,128, - 256,256,256,256,256,256,256,256, - 256,256,256,256,256,256,256,256 -}; - -static unsigned int y_second_field_bytes[] = { - 0,0,0,0,128,128,128,128, - 128,128,128,128,256,256,256,256, - 0,0,0,0,128,128,128,128, - 128,128,128,128,256,256,256,256, - 0,0,0,0,128,128,128,128, - 128,128,128,128,256,256,256,256, - 0,0,0,0,128,128,128,128, - 128,128,128,128,256,256,256,256 -}; - -static unsigned int y_dct0_field_bytes[] = { - 0,0,0,0,128,128,128,128, - 128,128,128,128,256,256,256,256, - 128,128,128,128,128,128,128,128, - 256,256,256,256,256,256,256,256, - 128,128,128,128,256,256,256,256, - 128,128,128,128,256,256,256,256, - 256,256,256,256,256,256,256,256, - 256,256,256,256,256,256,256,256 -}; - -static unsigned int y_dct1_frame_bytes[] = { - 0,0,0,0,256,256,256,256, - 256,256,256,256,512,512,512,512, - 256,256,256,256,256,256,256,256, - 512,512,512,512,512,512,512,512, - 256,256,256,256,512,512,512,512, - 256,256,256,256,512,512,512,512, - 512,512,512,512,512,512,512,512, - 512,512,512,512,512,512,512,512 -}; - -static unsigned int u_field_bytes[] = { - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64, - 0,0,64,64,0,0,64,64 -}; - -static unsigned int v_field_bytes[] = { - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64, - 0,64,0,64,0,64,0,64 -}; - -static short empty_block[] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0 -}; - - -/*************************************************************************** -// Function: dispatchYContext -// Description: Allocate a DMA buffer write the Y MC Context info in it, -// and dispatch it to hardware. -***************************************************************************/ - -static __inline__ void dispatchYContext(i810XvMCSurface *privTarget, - i810XvMCSurface *privPast, - i810XvMCSurface *privFuture, - i810XvMCContext *pI810XvMC) { - uint *data; - drmBufPtr pDMA; - drm_i810_mc_t mc; - - pDMA = i810_get_free_buffer(pI810XvMC); - data = pDMA->address; - *data++ = CMD_FLUSH; - *data++ = BOOLEAN_ENA_2; - *data++ = CMD_FLUSH; - *data++ = DEST_BUFFER_INFO; - *data++ = privTarget->dbi1y; - *data++ = DEST_BUFFER_VAR; - *data++ = privTarget->dbv1; - /* Past Surface */ - *data++ = CMD_MAP_INFO; - *data++ = privPast->mi1y; - *data++ = privPast->mi2y; - *data++ = privPast->mi3y; - /* Future Surface */ - *data++ = CMD_MAP_INFO; - *data++ = privFuture->mi1y | 0x1<<28; - *data++ = privFuture->mi2y; - *data++ = privFuture->mi3y; - - mc.idx = pDMA->idx; - mc.used = (unsigned long)data - (unsigned long)pDMA->address; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); -} - -static __inline__ void renderError(void) { - printf("Invalid Macroblock Parameters found.\n"); - return; -} - -/*************************************************************************** -// Function: renderIntrainFrame -// Description: inline function that sets hardware parameters for an Intra -// encoded macroblock in a Frame picture. -***************************************************************************/ -static __inline__ void renderIntrainFrame(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb, - short *block_ptr) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Y Blocks */ - *dy++ = GFXBLOCK + 68; - *dy++ = (1<<30) | (3<<28) | (0xf<<24); - *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<4); - *dy++ = (16<<16) | 16; - *dy++ = 0; - *dy++ = 0; - PACK_INTRA_DATA(dy,block_ptr,256); - dy += 64; - block_ptr += 256; - /* End Y Blocks */ - - /* U Block */ - *du++ = GFXBLOCK + 20; - *du++ = (2<<30) | (1<<28) | (1<<23); - *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); - *du++ = (8<<16) | 8; - *du++ = 0; - *du++ = 0; - PACK_INTRA_DATA(du,block_ptr,64); - du += 16; - block_ptr += 64; - - /* V Block */ - *dv++ = GFXBLOCK + 20; - *dv++ = (3<<30) | (1<<28) | (1<<22); - *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); - *dv++ = (8<<16) | 8; - *dv++ = 0; - *dv++ = 0; - PACK_INTRA_DATA(dv,block_ptr,64); - dv += 16; - block_ptr += 64; - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderIntrainFrameDCT1 -// Description: inline function that sets hardware parameters for an Intra -// encoded macroblock in a Frame picture with DCT type 1. -***************************************************************************/ -static __inline__ void renderIntrainFrameDCT1(uint **datay,uint **datau, - uint **datav,XvMCMacroBlock *mb, - short *block_ptr,uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - - /* Y Blocks */ - *dy++ = GFXBLOCK + 36; - *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x2<<6); - *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3); - *dy++ = (8<<16) | 16; - *dy++ = 0; - *dy++ = 0; - PACK_INTRA_DATA(dy,block_ptr,128); - dy += 32; - block_ptr += 128; - - /* Second Y block */ - *dy++ = GFXBLOCK + 36; - *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x3<<6); - *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3); - *dy++ = (8<<16) | 16; - *dy++ = 0; - *dy++ = 0; - PACK_INTRA_DATA(dy,block_ptr,128); - dy += 32; - block_ptr += 128; - /* End Y Blocks */ - - - /* U Block */ - *du++ = GFXBLOCK + 20; - *du++ = (2<<30) | (1<<28) | (1<<23); - *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); - *du++ = (8<<16) | 8; - *du++ = 0; - *du++ = 0; - PACK_INTRA_DATA(du,block_ptr,64); - du += 16; - block_ptr += 64; - - /* V Block */ - *dv++ = GFXBLOCK + 20; - *dv++ = (3<<30) | (1<<28) | (1<<22); - *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); - *dv++ = (8<<16) | 8; - *dv++ = 0; - *dv++ = 0; - PACK_INTRA_DATA(dv,block_ptr,64); - dv += 16; - block_ptr += 64; - - *datay = dy; - *datau = du; - *datav = dv; -} - - -/*************************************************************************** -// Function: renderIntrainField -// Description: inline function that sets hardware parameters for an Intra -// encoded macroblock in Field pictures. -***************************************************************************/ -static __inline__ void renderIntrainField(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb,short *block_ptr, - uint ps) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); - uint dw1 = drps_table[~ps & 0x1]; - - /* Y Blocks */ - *dy++ = GFXBLOCK + 68; - *dy++ = (1<<30) | (3<<28) | (0xf<<24) | dw1; - *dy++ = xy; - *dy++ = (16<<16) | 16; - *dy++ = 0; - *dy++ = 0; - PACK_INTRA_DATA(dy,block_ptr,256); - dy += 64; - block_ptr += 256; - /* End Y Blocks */ - - xy >>= 1; - - /* U Block */ - *du++ = GFXBLOCK + 20; - *du++ = (2<<30) | (1<<28) | (1<<23) | dw1; - *du++ = xy; - *du++ = (8<<16) | 8; - *du++ = 0; - *du++ = 0; - PACK_INTRA_DATA(du,block_ptr,64); - du += 16; - block_ptr += 64; - - /* V Block */ - *dv++ = GFXBLOCK + 20; - *dv++ = (3<<30) | (1<<28) | (1<<22) | dw1; - *dv++ = xy; - *dv++ = (8<<16) | 8; - *dv++ = 0; - *dv++ = 0; - PACK_INTRA_DATA(dv,block_ptr,64); - dv += 16; - block_ptr += 64; - - *datay = dy; - *datau = du; - *datav = dv; -} - - -/*************************************************************************** -// Function: renderFieldinField -// Description: inline function that sets hardware parameters for a Field -// encoded macroblock in a Field Picture. -***************************************************************************/ -static __inline__ void renderFieldinField(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb,short *block_ptr, - uint ps, uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[2]; - short bmv[2]; - /* gfxblock dword 1 */ - uint dw1; - - uint parity = ~ps & XVMC_TOP_FIELD; - - uint ysize = y_frame_bytes[mb->coded_block_pattern]; - uint usize = u_frame_bytes[mb->coded_block_pattern]; - uint vsize = v_frame_bytes[mb->coded_block_pattern]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); - - /* i810 Specific flag used to identify the second field in a P frame */ - if(flags & 0x80000000) { - /* P Frame */ - if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) == - parity) { - /* Same parity, use reference field (map0) */ - dw1 = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | - (((uint)mb->coded_block_pattern)<<22); - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = 0; - bmv[1] = 0; - } - else { - /* - Opposite parity, set up as if it were backward - motion and use map1. - */ - dw1 = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | - (((uint)mb->coded_block_pattern)<<22); - bmv[0] = mb->PMV[0][0][1]; - bmv[1] = mb->PMV[0][0][0]; - fmv[0] = 0; - fmv[1] = 0; - } - } - else { - dw1 = type_table[mb->macroblock_type & 0xf] | - drps_table[~ps & 0x1] | - mvfs_table[mb->motion_vertical_field_select & 3] | - (((uint)mb->coded_block_pattern)<<22); - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; - } - - /* Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (3<<28) | dw1; - *dy++ = xy; - *dy++ = (16<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; - PACK_CORR_DATA(dy,block_ptr,ysize); - block_ptr = (short *)((unsigned long)block_ptr + ysize); - /* End Y Blocks */ - - fmv[0] /= 2; - fmv[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; - xy >>= 1; - - /* U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1; - *du++ = xy; - *du++ = (8<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - PACK_CORR_DATA(du,block_ptr,usize); - block_ptr = (short *)((unsigned long)block_ptr + usize); - - /* V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1; - *dv++ = xy; - *dv++ = (8<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - PACK_CORR_DATA(dv,block_ptr,vsize); - block_ptr = (short *)((unsigned long)block_ptr + vsize); - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: render16x8inField -// Description: inline function that sets hardware parameters for a 16x8 -// encoded macroblock in a field picture. -***************************************************************************/ -static __inline__ void render16x8inField(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb,short *block_ptr, - uint ps, uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[4]; - short bmv[4]; - /* gfxblock dword 1 */ - uint dw1[2]; - - uint y1size = y_first_field_bytes[mb->coded_block_pattern]; - uint y2size = y_second_field_bytes[mb->coded_block_pattern]; - uint usize = u_field_bytes[mb->coded_block_pattern]; - uint vsize = v_field_bytes[mb->coded_block_pattern]; - - uint parity = ~ps & XVMC_TOP_FIELD; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); - - /* i810 Specific flag used to identify the second field in a P frame */ - if(flags & 0x80000000) { - /* P Frame */ - if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) == - parity) { - /* Same parity, use reference field (map0) */ - dw1[0] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | - (((uint)mb->coded_block_pattern)<<22); - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = 0; - bmv[1] = 0; - } - else { - /* - Opposite parity, set up as if it were backward - motion and use map1. - */ - dw1[0] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | - (((uint)mb->coded_block_pattern)<<22); - - bmv[0] = mb->PMV[0][0][1]; - bmv[1] = mb->PMV[0][0][0]; - fmv[0] = 0; - fmv[1] = 0; - } - if((mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD) == - (parity<<2)) { - /* Same parity, use reference field (map0) */ - dw1[1] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | - ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | - (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); - - fmv[2] = mb->PMV[1][0][1]; - fmv[3] = mb->PMV[1][0][0]; - bmv[2] = 0; - bmv[3] = 0; - } - else { - /* - Opposite parity, set up as if it were backward - motion and use map1. - */ - dw1[1] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | - ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | - (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); - - bmv[2] = mb->PMV[1][0][1]; - bmv[3] = mb->PMV[1][0][0]; - fmv[2] = 0; - fmv[3] = 0; - } - } - else { - dw1[0] = type_table[mb->macroblock_type & 0xf] | - drps_table[~ps & 0x1] | - mvfs_table[mb->motion_vertical_field_select & 3] | - (((uint)mb->coded_block_pattern)<<22); - - dw1[1] = type_table[mb->macroblock_type & 0xf] | - drps_table[~ps & 0x1] | - mvfs_table[(mb->motion_vertical_field_select>>2) & 0x3] | - ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | - (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - fmv[2] = mb->PMV[1][0][1]; - fmv[3] = mb->PMV[1][0][0]; - - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; - bmv[2] = mb->PMV[1][1][1]; - bmv[3] = mb->PMV[1][1][0]; - } - - /* First Y Block */ - *dy++ = GFXBLOCK + 4 + (y1size>>2); - *dy++ = (1<<30) | (2<<28) | dw1[0]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; - PACK_CORR_DATA(dy,block_ptr,y1size); - block_ptr = (short *)((unsigned long)block_ptr + y1size); - - /* Second Y Block */ - *dy++ = GFXBLOCK + 4 + (y2size>>2); - *dy++ = (1<<30) | (2<<28) | dw1[1]; - *dy++ = (xy + 8); - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; - PACK_CORR_DATA(dy,block_ptr,y2size); - block_ptr = (short *)((unsigned long)block_ptr + y2size); - /* End Y Blocks */ - - fmv[0] /= 2; - fmv[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; - - bmv[0] /= 2; - bmv[1] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; - - xy >>= 1; - - /* U Blocks */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[0]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - PACK_CORR_DATA(du,block_ptr,usize); - block_ptr = (short *)((unsigned long)block_ptr + usize); - - /* Second U block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[1]; - *du++ = (xy + 4); - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; - PACK_CORR_DATA(du,block_ptr,usize); - block_ptr = (short *)((unsigned long)block_ptr + usize); - /* End U Blocks */ - - /* V Blocks */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[0]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - PACK_CORR_DATA(dv,block_ptr,vsize); - block_ptr = (short *)((unsigned long)block_ptr + vsize); - - /* Second V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[1]; - *dv++ = (xy + 4); - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; - PACK_CORR_DATA(dv,block_ptr,vsize); - block_ptr = (short *)((unsigned long)block_ptr + vsize); - /* End V Blocks */ - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderDualPrimeinField -// Description: inline function that sets hardware parameters for a Dual -// prime encoded macroblock in a field picture. -***************************************************************************/ -static __inline__ void renderDualPrimeinField(uint **datay,uint **datau, - uint **datav,XvMCMacroBlock *mb, - short *block_ptr,uint ps, - uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[2]; - short bmv[2]; - /* gfxblock dword 1 */ - uint dw1; - - - uint ysize = y_frame_bytes[mb->coded_block_pattern]; - uint usize = u_frame_bytes[mb->coded_block_pattern]; - uint vsize = v_frame_bytes[mb->coded_block_pattern]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); - - - if(ps & XVMC_TOP_FIELD) { - dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 2<<6 | 2<<3 | 3; - } - else { - dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 3<<6 | 3<<3 | 2; - } - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; - - /* Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (3<<28) | dw1; - *dy++ = xy; - *dy++ = (16<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; - PACK_CORR_DATA(dy,block_ptr,ysize); - block_ptr = (short *)((unsigned long)block_ptr + ysize); - /* End Y Blocks */ - - fmv[0] /= 2; - fmv[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; - xy >>= 1; - - /* U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1; - *du++ = xy; - *du++ = (8<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - PACK_CORR_DATA(du,block_ptr,usize); - block_ptr = (short *)((unsigned long)block_ptr + usize); - - /* V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1; - *dv++ = xy; - *dv++ = (8<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - PACK_CORR_DATA(dv,block_ptr,vsize); - block_ptr = (short *)((unsigned long)block_ptr + vsize); - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderFieldinFrame -// Description: inline function that sets hardware parameters for a Field -// encoded macroblock in a frame picture. -***************************************************************************/ -static __inline__ void renderFieldinFrame(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb,short *block_ptr, - uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[4]; - short bmv[4]; - /* gfxblock dword 1 */ - uint dw1[2]; - - uint y1size = y_first_field_bytes[mb->coded_block_pattern]; - uint y2size = y_second_field_bytes[mb->coded_block_pattern]; - uint usize = u_field_bytes[mb->coded_block_pattern]; - uint vsize = v_field_bytes[mb->coded_block_pattern]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); - - dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) | - mvfs_table[mb->motion_vertical_field_select & 3] | - (((uint)mb->coded_block_pattern)<<22); - - dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) | - mvfs_table[mb->motion_vertical_field_select>>2] | - (((mb->coded_block_pattern & 0x3) | - ((mb->coded_block_pattern & 0xc)<<2))<<22); - - fmv[0] = mb->PMV[0][0][1]/2; - fmv[1] = mb->PMV[0][0][0]; - fmv[2] = mb->PMV[1][0][1]/2; - fmv[3] = mb->PMV[1][0][0]; - - bmv[0] = mb->PMV[0][1][1]/2; - bmv[1] = mb->PMV[0][1][0]; - bmv[2] = mb->PMV[1][1][1]/2; - bmv[3] = mb->PMV[1][1][0]; - - /* First Y Block */ - *dy++ = GFXBLOCK + 4 + (y1size>>2); - *dy++ = (1<<30) | (2<<28) | dw1[0]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[0]; - *dy++ = *(uint *)&bmv[0]; - PACK_CORR_DATA(dy,block_ptr,y1size); - block_ptr = (short *)((unsigned long)block_ptr + y1size); - - /* Second Y Block */ - *dy++ = GFXBLOCK + 4 + (y2size>>2); - *dy++ = (1<<30) | (2<<28) | dw1[1]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; - PACK_CORR_DATA(dy,block_ptr,y2size); - block_ptr = (short *)((unsigned long)block_ptr + y2size); - /* End Y Blocks */ - - fmv[0] /= 2; - fmv[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; - - bmv[0] /= 2; - bmv[1] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; - - xy >>= 1; - - /* U Blocks */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[0]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[0]; - *du++ = *(uint *)&bmv[0]; - if(usize) { - PACK_CORR_DATA_SHORT(du,block_ptr); - } - - /* Second U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[1]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; - if(usize) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(du,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End U Blocks */ - - /* V Blocks */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[0]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[0]; - *dv++ = *(uint *)&bmv[0]; - if(vsize) { - PACK_CORR_DATA_SHORT(dv,block_ptr); - } - - /* Second V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[1]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; - if(vsize) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(dv,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End V Blocks */ - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderFieldinFrameDCT0 -// Description: inline function that sets hardware parameters for a Field -// encoded macroblock in a frame picture with DCT0. -***************************************************************************/ -static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, - uint **datav,XvMCMacroBlock *mb, - short *block_ptr,uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[4]; - short bmv[4]; - /* CBP */ - uint cbp = (uint)mb->coded_block_pattern; - /* gfxblock dword 1 */ - uint dw1[2]; - - short * top_left_b = NULL; - short * top_right_b = NULL; - short * bottom_left_b = NULL; - short * bottom_right_b = NULL; - - unsigned int ysize = y_dct0_field_bytes[cbp]; - unsigned int usize = u_field_bytes[cbp]; - unsigned int vsize = v_field_bytes[cbp]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); - - dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) | - mvfs_table[mb->motion_vertical_field_select & 3] | - ((cbp | ((cbp<<2) & 0x30))<<22); - - dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) | - mvfs_table[mb->motion_vertical_field_select>>2] | - ((cbp | ((cbp<<2) & 0x30))<<22); - - - fmv[0] = mb->PMV[0][0][1]/2; - fmv[1] = mb->PMV[0][0][0]; - fmv[2] = mb->PMV[1][0][1]/2; - fmv[3] = mb->PMV[1][0][0]; - - bmv[0] = mb->PMV[0][1][1]/2; - bmv[1] = mb->PMV[0][1][0]; - bmv[2] = mb->PMV[1][1][1]/2; - bmv[3] = mb->PMV[1][1][0]; - - /* - The i810 cannot use DCT0 directly with field motion, we have to - interlace the data for it. We use a zero block when the CBP has - one half of the to-be-interlaced data but not the other half. - */ - top_left_b = &empty_block[0]; - if(cbp & 0x20) { - top_left_b = block_ptr; - block_ptr += 64; - } - - top_right_b = &empty_block[0]; - if(cbp & 0x10) { - top_right_b = block_ptr; - block_ptr += 64; - } - - bottom_left_b = &empty_block[0]; - if(cbp & 0x8) { - bottom_left_b = block_ptr; - block_ptr += 64; - } - - bottom_right_b = &empty_block[0]; - if(cbp & 0x4) { - bottom_right_b = block_ptr; - block_ptr += 64; - } - - /* First Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (2<<28) | dw1[0]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[0]; - *dy++ = *(uint *)&bmv[0]; - if(dw1[0] & (1<<27)) { - PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); - } - if(dw1[0] & (1<<26)) { - PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); - } - - /* Second Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (2<<28) | dw1[1]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; - if(dw1[1] & (1<<27)) { - top_left_b = (short *)((unsigned long)top_left_b + 16); - bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); - PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); - } - if(dw1[1] & (1<<26)) { - top_right_b = (short *)((unsigned long)top_right_b + 16); - bottom_right_b = (short *)((unsigned long)bottom_right_b + 16); - PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); - } - /* End Y Blocks */ - - fmv[0] /= 2; - fmv[1] /= 2; - fmv[2] /= 2; - fmv[3] /= 2; - - bmv[0] /= 2; - bmv[1] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; - - xy >>= 1; - - /* U Blocks */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[0]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[0]; - *du++ = *(uint *)&bmv[0]; - if(usize) { - PACK_CORR_DATA_SHORT(du,block_ptr); - } - - /* Second U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[1]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; - if(usize) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(du,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End U Blocks */ - - /* V Blocks */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[0]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[0]; - *dv++ = *(uint *)&bmv[0]; - if(vsize) { - PACK_CORR_DATA_SHORT(dv,block_ptr); - } - - /* Second V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[1]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; - if(vsize) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(dv,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End V Blocks */ - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderFrameinFrame -// Description: inline function that sets hardware parameters for a Frame -// encoded macroblock in a frame picture. -***************************************************************************/ -static __inline__ void renderFrameinFrame(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb,short *block_ptr, - uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[2]; - short bmv[2]; - /* gfxblock dword 1 */ - uint dw1; - - unsigned int ysize = y_frame_bytes[mb->coded_block_pattern]; - unsigned int usize = u_frame_bytes[mb->coded_block_pattern]; - unsigned int vsize = v_frame_bytes[mb->coded_block_pattern]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); - - dw1 = type_table[mb->macroblock_type & 0xf] | - (((uint)mb->coded_block_pattern)<<22); - - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; - - /* Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (3<<28) | dw1; - *dy++ = xy; - *dy++ = (16<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; - PACK_CORR_DATA(dy,block_ptr,ysize); - block_ptr = (short *)((unsigned long)block_ptr + ysize); - /* End Y Blocks */ - - fmv[0] /= 2; - fmv[1] /= 2; - - bmv[0] /= 2; - bmv[1] /= 2; - - xy >>= 1; - - /* U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1; - *du++ = xy; - *du++ = (8<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - PACK_CORR_DATA(du,block_ptr,usize); - block_ptr = (short *)((unsigned long)block_ptr + usize); - /* End U Block */ - - /* V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1; - *dv++ = xy; - *dv++ = (8<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - PACK_CORR_DATA(dv,block_ptr,vsize); - block_ptr = (short *)((unsigned long)block_ptr + vsize); - /* End V Block */ - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderFrameinFrameDCT1 -// Description: inline function that sets hardware parameters for a Frame -// encoded macroblock in a frame picture with DCT type 1. -***************************************************************************/ -static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, - uint **datav,XvMCMacroBlock *mb, - short *block_ptr,uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[4]; - short bmv[4]; - - short * top_left_b = NULL; - short * top_right_b = NULL; - short * bottom_left_b = NULL; - short * bottom_right_b = NULL; - - uint temp_bp = 0; - - uint ysize = y_dct1_frame_bytes[mb->coded_block_pattern]; - uint usize = u_frame_bytes[mb->coded_block_pattern]; - uint vsize = v_frame_bytes[mb->coded_block_pattern]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); - - uint dw1 = type_table[mb->macroblock_type & 0xf] | - (((uint)mb->coded_block_pattern)<<22); - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - - bmv[0] = mb->PMV[0][1][1]; - bmv[1] = mb->PMV[0][1][0]; - - /* - It is easiest to find out what blocks are in need of reading first - rather than as we go. - */ - top_left_b = &empty_block[0]; - if(dw1 & (1<<27)) { - temp_bp |= (1<<25); - top_left_b = block_ptr; - block_ptr += 64; - } - - top_right_b = &empty_block[0]; - if(dw1 & (1<<26)) { - temp_bp |= (1<<24); - top_right_b = block_ptr; - block_ptr += 64; - } - - bottom_left_b = &empty_block[0]; - if(dw1 & (1<<25)) { - temp_bp |= (1<<27); - bottom_left_b = block_ptr; - block_ptr += 64; - } - - bottom_right_b = &empty_block[0]; - if(dw1 & (1<<24)) { - temp_bp |= (1<<26); - bottom_right_b = block_ptr; - block_ptr += 64; - } - dw1 |= temp_bp; - - /* Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (3<<28) | dw1; - *dy++ = xy; - *dy++ = (16<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; - if(dw1 & (1<<27)) { - PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); - top_left_b = (short *)((unsigned long)top_left_b + 64); - bottom_left_b = (short *)((unsigned long)bottom_left_b + 64); - } - if(dw1 & (1<<26)) { - PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b); - top_right_b = (short *)((unsigned long)top_right_b + 64); - bottom_right_b = (short *)((unsigned long)bottom_right_b + 64); - } - if(dw1 & (1<<27)) { - PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); - } - if(dw1 & (1<<26)) { - PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b); - } - /* End Y Block */ - - fmv[0] /= 2; - fmv[1] /= 2; - - bmv[0] /= 2; - bmv[1] /= 2; - - xy >>= 1; - - /* U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1; - *du++ = xy; - *du++ = (8<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - PACK_CORR_DATA(du,block_ptr,usize); - block_ptr = (short *)((unsigned long)block_ptr + usize); - - /* V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1; - *dv++ = xy; - *dv++ = (8<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - PACK_CORR_DATA(dv,block_ptr,vsize); - block_ptr = (short *)((unsigned long)block_ptr + vsize); - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderDualPrimeinFrame -// Description: inline function that sets hardware parameters for a Dual -// Prime encoded macroblock in a frame picture with dct 1. -***************************************************************************/ -static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, - uint **datav,XvMCMacroBlock *mb, - short *block_ptr,uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[4]; - short bmv[4]; - /* gfxblock dword 1 */ - uint dw1[2]; - - uint y1size = y_first_field_bytes[mb->coded_block_pattern]; - uint y2size = y_second_field_bytes[mb->coded_block_pattern]; - uint usize = u_field_bytes[mb->coded_block_pattern]; - uint vsize = v_field_bytes[mb->coded_block_pattern]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); - - /* - Past Surface (map 0) is used for same parity prediction, - Future surface (map 1) is used for opposite. - */ - dw1[0] = (((uint)mb->coded_block_pattern)<<22) | - 3<<12 | 2<<6 | 2<<3 | 3; - dw1[1] = (((mb->coded_block_pattern & 0x3) | - ((mb->coded_block_pattern & 0xc)<<2))<<22) | - 3<<12 | 3<<6 | 3<<3 | 2; - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[1][0][1]; - bmv[1] = mb->PMV[1][0][0]; - - fmv[2] = mb->PMV[0][0][1]; - fmv[3] = mb->PMV[0][0][0]; - bmv[2] = mb->PMV[1][1][1]; - bmv[3] = mb->PMV[1][1][0]; - - /* First Y Block */ - *dy++ = GFXBLOCK + 4 + (y1size>>2); - *dy++ = (1<<30) | (2<<28) | dw1[0]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv;; - PACK_CORR_DATA(dy,block_ptr,y1size); - block_ptr = (short *)((unsigned long)block_ptr + y1size); - - /* Second Y Block */ - *dy++ = GFXBLOCK + 4 + (y2size>>2); - *dy++ = (1<<30) | (2<<28) | dw1[1]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; - PACK_CORR_DATA(dy,block_ptr,y2size); - block_ptr = (short *)((unsigned long)block_ptr + y2size); - - fmv[0] /= 2; - fmv[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; - - fmv[2] /= 2; - fmv[3] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; - - xy >>= 1; - - /* U Blocks */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[0]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - if(dw1[0] & (1<<23)) { - PACK_CORR_DATA_SHORT(du,block_ptr); - } - - /* Second U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[1]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; - if(dw1[1] & (1<<23)) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(du,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End U Blocks */ - - /* V Blocks */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[0]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - if(dw1[0] & (1<<22)) { - PACK_CORR_DATA_SHORT(dv,block_ptr); - } - - /* Second V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[1]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; - if(dw1[1] & (1<<22)) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(dv,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End V Blocks */ - - *datay = dy; - *datau = du; - *datav = dv; -} - -/*************************************************************************** -// Function: renderDualPrimeinFrameDCT0 -// Description: inline function that sets hardware parameters for a Dual -// Prime encoded macroblock in a frame picture with dct 0. -***************************************************************************/ -static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, - uint **datav, - XvMCMacroBlock *mb, - short *block_ptr, - uint flags) { - - register uint *dy = *datay; - register uint *du = *datau; - register uint *dv = *datav; - - /* Motion Vectors */ - short fmv[4]; - short bmv[4]; - /* gfxblock dword 1 */ - uint dw1[2]; - - short * top_left_b = NULL; - short * top_right_b = NULL; - short * bottom_left_b = NULL; - short * bottom_right_b = NULL; - - uint cbp = (uint)mb->coded_block_pattern; - - uint ysize = y_dct0_field_bytes[cbp]; - uint usize = u_field_bytes[cbp]; - uint vsize = v_field_bytes[cbp]; - - uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); - - /* - Past Surface (map 0) is used for same parity prediction, - Future surface (map 1) is used for opposite. - */ - dw1[0] = ((cbp | ((cbp<<2) & 0x30))<<22) | - 3<<12 | 2<<6 | 2<<3 | 3; - dw1[1] = ((cbp | ((cbp<<2) & 0x30))<<22) | - 3<<12 | 3<<6 | 3<<3 | 2; - - fmv[0] = mb->PMV[0][0][1]; - fmv[1] = mb->PMV[0][0][0]; - bmv[0] = mb->PMV[1][0][1]; - bmv[1] = mb->PMV[1][0][0]; - - fmv[2] = mb->PMV[0][0][1]; - fmv[3] = mb->PMV[0][0][0]; - bmv[2] = mb->PMV[1][1][1]; - bmv[3] = mb->PMV[1][1][0]; - - /* - The i810 cannot use DCT0 directly with field motion, we have to - interlace the data for it. We use a zero block when the CBP has - one half of the to-be-interlaced data but not the other half. - */ - top_left_b = &empty_block[0]; - if(cbp & 0x20) { - top_left_b = block_ptr; - block_ptr += 64; - } - - top_right_b = &empty_block[0]; - if(cbp & 0x10) { - top_right_b = block_ptr; - block_ptr += 64; - } - - bottom_left_b = &empty_block[0]; - if(cbp & 0x8) { - bottom_left_b = block_ptr; - block_ptr += 64; - } - - bottom_right_b = &empty_block[0]; - if(cbp & 0x4) { - bottom_right_b = block_ptr; - block_ptr += 64; - } - - /* First Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (2<<28) | dw1[0]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)fmv; - *dy++ = *(uint *)bmv; - if(cbp & 0x20) { - PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); - } - if(cbp & 0x10) { - PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); - } - - /* Second Y Block */ - *dy++ = GFXBLOCK + 4 + (ysize>>2); - *dy++ = (1<<30) | (2<<28) | dw1[1]; - *dy++ = xy; - *dy++ = (8<<16) | 16; - *dy++ = *(uint *)&fmv[2]; - *dy++ = *(uint *)&bmv[2]; - if(cbp & 0x20) { - top_left_b = (short *)((unsigned long)top_left_b + 16); - bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); - PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); - } - if(cbp & 0x10) { - top_right_b = (short *)((unsigned long)top_right_b + 16); - bottom_right_b = (short *)((unsigned long)bottom_right_b + 16); - PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); - } - /* End Y Blocks */ - - - fmv[0] /= 2; - fmv[1] /= 2; - bmv[0] /= 2; - bmv[1] /= 2; - - fmv[2] /= 2; - fmv[3] /= 2; - bmv[2] /= 2; - bmv[3] /= 2; - - xy >>= 1; - - /* U Blocks */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[0]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)fmv; - *du++ = *(uint *)bmv; - if(cbp & (1<<23)) { - PACK_CORR_DATA_SHORT(du,block_ptr); - } - - /* Second U Block */ - *du++ = GFXBLOCK + 4 + (usize>>2); - *du++ = (2<<30) | (1<<28) | dw1[1]; - *du++ = xy; - *du++ = (4<<16) | 8; - *du++ = *(uint *)&fmv[2]; - *du++ = *(uint *)&bmv[2]; - if(cbp & (1<<23)) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(du,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End U Blocks */ - - /* V Blocks */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[0]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)fmv; - *dv++ = *(uint *)bmv; - if(cbp & (1<<22)) { - PACK_CORR_DATA_SHORT(dv,block_ptr); - } - - /* Second V Block */ - *dv++ = GFXBLOCK + 4 + (vsize>>2); - *dv++ = (3<<30) | (1<<28) | dw1[1]; - *dv++ = xy; - *dv++ = (4<<16) | 8; - *dv++ = *(uint *)&fmv[2]; - *dv++ = *(uint *)&bmv[2]; - if(cbp & (1<<22)) { - block_ptr = (short *)((unsigned long)block_ptr + 16); - PACK_CORR_DATA_SHORT(dv,block_ptr); - block_ptr = (short *)((unsigned long)block_ptr + 112); - } - /* End V Blocks */ - - *datay = dy; - *datau = du; - *datav = dv; -} - - -/*************************************************************************** -// Function: XvMCRenderSurface -// Description: This function does the actual HWMC. Given a list of -// macroblock structures it dispatched the hardware commands to execute -// them. DMA buffer containing Y data are dispatched as they fill up -// U and V DMA buffers are queued until all Y's are done. This minimizes -// the context flipping and flushing required when switching between Y -// U and V surfaces. -***************************************************************************/ -#define UV_QUEUE 14 -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) { - /* Dma Data Structures */ - drmBufPtr pDMAy = NULL,pDMAu[UV_QUEUE],pDMAv[UV_QUEUE]; - int u_index = 0,v_index = 0; - int dirty_context = 1; - - /* Block Pointer */ - short *block_ptr; - /* Current Macroblock Pointer */ - XvMCMacroBlock *mb; - - drm_i810_mc_t mc; - int i,j; - i810XvMCSurface *privTarget; - i810XvMCSurface *privFuture = NULL; - i810XvMCSurface *privPast = NULL; - i810XvMCContext *pI810XvMC; - - /* DMA Pointers set to NULL */ - uint *datay = NULL; - uint *datau = NULL; - uint *datav = NULL; - - - /* Check Parameters for validity */ - if((target_surface == NULL) || (context == NULL) || (display == NULL)) { - printf("Error, Invalid Target,Context, or DIsplay!\n"); - return BadValue; - } - - if(num_macroblocks == 0) {return Success;} - if((macroblock_array == NULL) || (blocks == NULL)) {return BadValue;} - if(context->privData == NULL) {return BadValue;} - pI810XvMC = (i810XvMCContext *)context->privData; - - - if(target_surface->privData == NULL) { - printf("Error, Invalid Target Surface!\n"); - return BadValue; - } - privTarget = (i810XvMCSurface *)target_surface->privData; - - if(macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) { - printf("Error, Too many macroblocks requested for MB array size.\n"); - return BadValue; - } - - /* Test For YV12 Surface */ - if(context->surface_type_id != FOURCC_YV12) { - printf("Error, HWMC only possible on YV12 Surfaces\n"); - return BadValue; - } - - /* P Frame Test */ - if(past_surface == NULL) { - /* Just to avoid some ifs later. */ - privPast = privTarget; - } - else { - if(past_surface->privData == NULL) { - printf("Error, Invalid Past Surface!\n"); - return BadValue; - } - privPast = (i810XvMCSurface *)past_surface->privData; - } - - - /* B Frame Test */ - if(future_surface == NULL) { - privFuture = privTarget; - if(pI810XvMC->dual_prime) { - privFuture = privPast; - /* I810 Specific flag for marking when dual prime is in use. */ - flags |= 0x40000000; - } - - /* - References are different for the Second Field Picture. The - i810 needs to know if it is the second field picture in a - P picture. We use a Private flag to mark this. - */ - if(flags & XVMC_SECOND_FIELD) { - /* I810 Specific flag for marking second fields. */ - flags |= 0x80000000; - } - } - else { - if((future_surface->privData == NULL) || (past_surface == NULL)) { - printf("Error, Invalid Future Surface or No Past Surface!\n"); - return BadValue; - } - privFuture = (i810XvMCSurface *)future_surface->privData; - - /* - Undo Second Field flag since the second field in B frames is just like - the first. - */ - flags &= ~0x80000000; - } - - /* Lock For DMA */ - I810_LOCK(pI810XvMC,0); - - for(i=first_macroblock; i<(num_macroblocks + first_macroblock); i++) { - /* Set up values needed for each macroblock */ - mb = ¯oblock_array->macro_blocks[i]; - block_ptr = &(blocks->blocks[mb->index<<6]); - - /* Lockup can happen if the coordinates are too far out of range */ - if(mb->x > target_surface->width>>4) { - mb->x = 0; - } - if(mb->y > target_surface->height>>4) { - mb->y = 0; - } - - /* If buffers are almost full dispatch them */ - if(datay) { - pDMAy->used = (unsigned long)datay - (unsigned long)pDMAy->address; - if(pDMAy->used > 3520) { - if(dirty_context) { - dispatchYContext(privTarget,privPast,privFuture,pI810XvMC); - } - dirty_context = 0; - mc.idx = pDMAy->idx; - mc.used = pDMAy->used; - datay = NULL; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - } /* datay near full */ - } /* if(datay) */ - if(datau) { - pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address; - if(pDMAu[u_index]->used > 3904) { - u_index++; - datau = NULL; - if(u_index == UV_QUEUE) { - for(j=0; j<UV_QUEUE; j++) { - mc.idx = pDMAu[j]->idx; - mc.used = pDMAu[j]->used; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - } - u_index = 0; - dirty_context = 1; - } /* if(u_index == UV_QUEUE) */ - } /* datau near full */ - } /* if(datau) */ - if(datav) { - pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address; - if(pDMAv[v_index]->used > 3904) { - v_index++; - datav = NULL; - if(v_index == UV_QUEUE) { - for(j=0; j<UV_QUEUE; j++) { - mc.idx = pDMAv[j]->idx; - mc.used = pDMAv[j]->used; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - } - v_index = 0; - dirty_context = 1; - } /* if(v_index == UV_QUEUE) */ - } /* datav near full */ - } /* if(datav) */ - - /* Allocate buffers if this is the first loop,or if we just dispatched */ - if(datay == NULL) { - pDMAy = i810_get_free_buffer(pI810XvMC); - datay = pDMAy->address; - }/* if(datay == NULL) */ - if(datau == NULL) { - pDMAu[u_index] = i810_get_free_buffer(pI810XvMC); - datau = pDMAu[u_index]->address; - if(u_index == 0) { - *datau++ = CMD_FLUSH; - *datau++ = BOOLEAN_ENA_2; - *datau++ = CMD_FLUSH; - *datau++ = DEST_BUFFER_INFO; - *datau++ = privTarget->dbi1u; - *datau++ = DEST_BUFFER_VAR; - *datau++ = privTarget->dbv1; - /* Past Surface */ - *datau++ = CMD_MAP_INFO; - *datau++ = privPast->mi1u; - *datau++ = privPast->mi2u; - *datau++ = privPast->mi3u; - /* Future Surface */ - *datau++ = CMD_MAP_INFO; - *datau++ = privFuture->mi1u | 0x1<<28; - *datau++ = privFuture->mi2u; - *datau++ = privFuture->mi3u; - } - } /* if(datau == NULL) */ - if(datav == NULL) { - pDMAv[v_index] = i810_get_free_buffer(pI810XvMC); - datav = pDMAv[v_index]->address; - if(v_index == 0) { - *datav++ = CMD_FLUSH; - *datav++ = BOOLEAN_ENA_2; - *datav++ = CMD_FLUSH; - *datav++ = DEST_BUFFER_INFO; - *datav++ = privTarget->dbi1v; - *datav++ = DEST_BUFFER_VAR; - *datav++ = privTarget->dbv1; - /* Past Surface */ - *datav++ = CMD_MAP_INFO; - *datav++ = privPast->mi1v; - *datav++ = privPast->mi2v; - *datav++ = privPast->mi3v; - /* Future Surface */ - *datav++ = CMD_MAP_INFO; - *datav++ = privFuture->mi1v | 0x1<<28; - *datav++ = privFuture->mi2v; - *datav++ = privFuture->mi3v; - } - }/* if(datav == NULL) */ - - /* Catch no pattern case */ - if(!(mb->macroblock_type & 0x8)) { - mb->coded_block_pattern = 0; - } - - - if(mb->motion_type == XVMC_PREDICTION_DUAL_PRIME) { - /* - By default the maps will not be set up for dual - prime. We have to change them. - */ - if(!pI810XvMC->dual_prime) { - pI810XvMC->dual_prime = 1; - privFuture = privPast; - /* Y */ - *datay++ = CMD_MAP_INFO; - *datay++ = privFuture->mi1y | 0x1<<28; - *datay++ = privFuture->mi2y; - *datay++ = privFuture->mi3y; - /* U */ - *datau++ = CMD_MAP_INFO; - *datau++ = privFuture->mi1u | 0x1<<28; - *datau++ = privFuture->mi2u; - *datau++ = privFuture->mi3u; - /* V */ - *datav++ = CMD_MAP_INFO; - *datav++ = privFuture->mi1v | 0x1<<28; - *datav++ = privFuture->mi2v; - *datav++ = privFuture->mi3v; - } - } - if((pI810XvMC->dual_prime) && - (mb->motion_type != XVMC_PREDICTION_DUAL_PRIME)) { - pI810XvMC->dual_prime = 0; - privFuture = privTarget; - /* Y */ - *datay++ = CMD_MAP_INFO; - *datay++ = privFuture->mi1y | 0x1<<28; - *datay++ = privFuture->mi2y; - *datay++ = privFuture->mi3y; - /* U */ - *datau++ = CMD_MAP_INFO; - *datau++ = privFuture->mi1u | 0x1<<28; - *datau++ = privFuture->mi2u; - *datau++ = privFuture->mi3u; - /* V */ - *datav++ = CMD_MAP_INFO; - *datav++ = privFuture->mi1v | 0x1<<28; - *datav++ = privFuture->mi2v; - *datav++ = privFuture->mi3v; - } - - - /* Frame Picture */ - if((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { - /* Intra Blocks */ - if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) { - if(mb->dct_type) { - renderIntrainFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - } - renderIntrainFrame(&datay,&datau,&datav,mb,block_ptr); - continue; - } - switch((mb->motion_type & 0x3) | (mb->dct_type<<2)) { - case 0x2: /* Frame DCT0 */ - renderFrameinFrame(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - case 0x5: /* Field DCT1 */ - renderFieldinFrame(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - case 0x6: /* Frame DCT1 */ - renderFrameinFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - case 0x1: /* Field DCT0 */ - renderFieldinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - case 0x3: /* Dual Prime DCT0 */ - renderDualPrimeinFrame(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - case 0x7: /* Dual Prime DCT1 */ - renderDualPrimeinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags); - continue; - default: /* No Motion Type */ - renderError(); - continue; - } /* Switch */ - } /* Frame Picture */ - - /* Field Pictures */ - if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) { - renderIntrainField(&datay,&datau,&datav,mb,block_ptr,picture_structure); - continue; - } - switch(mb->motion_type & 0x3) { - case 0x1: /* Field Motion */ - renderFieldinField(&datay,&datau,&datav,mb,block_ptr,picture_structure, - flags); - continue; - case 0x2: /* 16x8 Motion */ - render16x8inField(&datay,&datau,&datav,mb,block_ptr,picture_structure, - flags); - continue; - case 0x3: /* Dual Prime */ - renderDualPrimeinField(&datay,&datau,&datav,mb,block_ptr, - picture_structure,flags); - continue; - default: /* No Motion Type */ - renderError(); - continue; - } - continue; - - } /* for each Macroblock */ - - /* Dispatch remaining DMA buffers */ - if(dirty_context) { - dispatchYContext(privTarget,privPast,privFuture,pI810XvMC); - } - mc.idx = pDMAy->idx; - mc.used = (unsigned long)datay - (unsigned long)pDMAy->address; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - - pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address; - for(j=0; j<=u_index; j++) { - mc.idx = pDMAu[j]->idx; - mc.used = pDMAu[j]->used; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - } - pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address; - for(j=0; j<=v_index; j++) { - mc.idx = pDMAv[j]->idx; - mc.used = pDMAv[j]->used; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - } - - I810_UNLOCK(pI810XvMC); - - return Success; -} - -/*************************************************************************** -// Function: XvMCPutSurface -// Description: -// Arguments: -// display: Connection to X server -// surface: Surface to be displayed -// draw: X Drawable on which to display the surface -// srcx: X coordinate of the top left corner of the region to be -// displayed within the surface. -// srcy: Y coordinate of the top left corner of the region to be -// displayed within the surface. -// srcw: Width of the region to be displayed. -// srch: Height of the region to be displayed. -// destx: X cordinate of the top left corner of the destination region -// in the drawable coordinates. -// desty: Y cordinate of the top left corner of the destination region -// in the drawable coordinates. -// destw: Width of the destination region. -// desth: Height of the destination region. -// flags: One or more of the following. -// XVMC_TOP_FIELD - Display only the Top field of the surface. -// XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface. -// XVMC_FRAME_PICTURE - Display both fields or frame. -// -// Info: Portions of this function derived from i810_video.c (XFree86) -// -// This function is organized so that we wait as long as possible before -// touching the overlay registers. Since we don't know that the last -// flip has happened yet we want to give the overlay as long as -// possible to catch up before we have to check on its progress. This -// makes it unlikely that we have to wait on the last flip. -***************************************************************************/ -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) { - i810XvMCContext *pI810XvMC; - i810XvMCSurface *pI810Surface; - i810OverlayRecPtr pORegs; - unsigned int ysrc_offset,uvsrc_offset; - Box extents; - uint window_width,window_height; - unsigned int xscaleInt = 0,xscaleFract = 0,yscaleInt = 0,yscaleFract = 0; - unsigned int xscaleFractUV = 0,xscaleIntUV = 0,yscaleFractUV = 0; - unsigned int yscaleIntUV = 0,yPitch = 0,uvPitch = 0; - unsigned int ovcmd = 0; - uint d; - double xscale,yscale; - int diff; - int clipped_srcx, clipped_srcy, clipped_destx, clipped_desty; - int clipped_srcw, clipped_srch, clipped_destw, clipped_desth; - uint x1,y1,root_width,root_height; - int x2 = 0, y2 = 0,unused; - uint nChilds; - int stat; - Window win,root,parent,*pChilds; - - - if((display == NULL) || (surface == NULL)) { - return BadValue; - } - - if(surface->privData == NULL) { - return (error_base + XvMCBadSurface); - } - pI810Surface = (i810XvMCSurface *)surface->privData; - pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; - pORegs = (i810OverlayRecPtr)pI810XvMC->oregs; - - - switch(surface->surface_type_id) { - case FOURCC_YV12: - case FOURCC_I420: - yPitch = (srcw + 7) & ~7; - uvPitch = ((srcw>>1) + 7) & ~7; - if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) { - srch = srch>>1; - } - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - /* FIXME: Non Planar not fully implemented. */ - return BadValue; - yPitch = ((srcw + 7) & ~7) << 1; - break; - }/* switch(surface->surface_type_id) */ - - /* - FIXME: This should be using the DRI's clip rect but that isn't - all hooked up yet. This has some latency but we get by. - */ - win = draw; - XQueryTree(display,win,&root,&parent,&pChilds,&nChilds); - if(nChilds) XFree(pChilds); - XGetGeometry(display,win, &root, &x2, &y2, &window_width, - &window_height, &d, &d); - x1 = x2; - y1 = y2; - win = parent; - do { - XQueryTree(display,win,&root,&parent,&pChilds,&nChilds); - if(nChilds) XFree(pChilds); - XGetGeometry(display,win, &root, &x2, &y2, &d, &d, &d, &d); - x1 += x2; - y1 += y2; - win = parent; - }while(win != root); - XGetGeometry(display,root, &root, &unused, &unused, - &root_width, &root_height, &d, &d); - - /* Left edge of Video window clipped to screen */ - extents.x1 = 0; - if(x1 > extents.x1) { - extents.x1 = x1; - } - /* Right edge of Video window clipped to screen */ - extents.x2 = root_width; - if(extents.x2 > (x1 + window_width)) { - extents.x2 = x1 + window_width; - } - /* Top edge of Video window clipped to screen */ - extents.y1 = 0; - if(y1 > extents.y1) { - extents.y1 = y1; - } - /* Bottom edge of Video window clipped to screen */ - extents.y2 = root_height; - if(extents.y2 > (y1 + window_height)) { - extents.y2 = y1 + window_height; - } - - /* - Clipping is more difficult than is seems. We need to keep the - scaling factors even if the destination window needs to be clipped. - We clip the destination window first then apply a scaled version - to the source window. - */ - - /* Put destination coords in screen coords */ - destx += x1; - desty += y1; - - /* Scale factors requested */ - xscale = (double)srcw / (double)destw; - yscale = (double)srch / (double)desth; - - /* - If destination window needs to be clipped we actually adjust both - the src and dest window so as to keep the scaling that was requested - */ - clipped_srcx = srcx; - clipped_srcy = srcy; - clipped_destx = destx; - clipped_desty = desty; - clipped_srcw = srcw; - clipped_srch = srch; - clipped_destw = destw; - clipped_desth = desth; - - /* Clip to the source surface boundaries */ - if(clipped_srcx < 0) { - clipped_destx += (0 - clipped_srcx) / xscale; - clipped_srcw -= clipped_srcx; - clipped_destw -= clipped_srcx / xscale; - clipped_srcx = 0; - } - if((clipped_srcw + clipped_srcx) > surface->width) { - clipped_srcw = surface->width - clipped_srcx; - clipped_destw -= (clipped_srcw - srcw) / xscale; - } - if(clipped_srcy < 0) { - clipped_desty += (0 - clipped_srcy) / yscale; - clipped_srch -= clipped_srcy; - clipped_desth -= clipped_srcy / yscale; - clipped_srcy = 0; - } - if((clipped_srch + clipped_srcy) > surface->height) { - clipped_srch = surface->height - clipped_srcy; - clipped_desth -= (clipped_srch - srch) / yscale; - } - - /* Clip to the extents */ - if(clipped_destx < extents.x1) { - diff = extents.x1 - clipped_destx; - clipped_srcx += diff * xscale; - clipped_srcw -= diff * xscale; - clipped_destw -= diff; - clipped_destx = extents.x1; - } - - diff = (clipped_destx + clipped_destw) - extents.x2; - if(diff > 0) { - clipped_destw -= diff; - clipped_srcw -= diff * xscale; - } - - if(clipped_desty < extents.y1) { - diff = extents.y1 - clipped_desty; - clipped_srcy += diff * yscale; - clipped_srch -= diff * yscale; - clipped_desth -= diff; - clipped_desty = 0; - } - - diff = (clipped_desty + clipped_desth) - extents.y2; - if(diff > 0) { - clipped_desth -= diff; - clipped_srch -= diff * yscale; - } - - /* If the whole window is clipped turn off the overlay */ - if((clipped_destx + clipped_destw < extents.x1) || - (clipped_desty + clipped_desth < extents.y1) || - (clipped_destx > extents.x2) || - (clipped_desty > extents.y2)) { - return XvMCHideSurface(display, surface); - } - - /* - Adjust the source offset width and height according to the clipped - destination window. - */ - ysrc_offset = ((clipped_srcx + 1) & ~1) + - ((clipped_srcy + 1) & ~1) * (1<<pI810Surface->pitch); - uvsrc_offset = (clipped_srcx>>1) + - (clipped_srcy>>1) * (1<<(pI810Surface->pitch - 1)); - - /* - Initially, YCbCr and Overlay Enable and - vertical chrominance up interpolation and horozontal chrominance - up interpolation - */ - ovcmd = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | - Y_ADJUST | OVERLAY_ENABLE; - - if ((clipped_destw != clipped_srcw) || - (clipped_desth != clipped_srch)) { - xscaleInt = (clipped_srcw / clipped_destw) & 0x3; - xscaleFract = (clipped_srcw << 12) / clipped_destw; - yscaleInt = (clipped_srch / clipped_desth) & 0x3; - yscaleFract = (clipped_srch << 12) / clipped_desth; - - if (clipped_destw > clipped_srcw) { - /* horizontal up-scaling */ - ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER; - ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER; - ovcmd |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION); - } - - if (clipped_desth > clipped_srch) { - /* vertical up-scaling */ - ovcmd &= ~VERTICAL_CHROMINANCE_FILTER; - ovcmd &= ~VERTICAL_LUMINANCE_FILTER; - ovcmd |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION); - } - - if (clipped_destw < clipped_srcw) { - /* horizontal down-scaling */ - ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER; - ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER; - ovcmd |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION); - } - - if (clipped_desth < clipped_srch) { - /* vertical down-scaling */ - ovcmd &= ~VERTICAL_CHROMINANCE_FILTER; - ovcmd &= ~VERTICAL_LUMINANCE_FILTER; - ovcmd |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION); - } - - /* now calculate the UV scaling factor */ - if (xscaleFract) { - xscaleFractUV = xscaleFract >> MINUV_SCALE; - ovcmd &= ~HC_DOWN_INTERPOLATION; - ovcmd |= HC_UP_INTERPOLATION; - } - - if (xscaleInt) { - xscaleIntUV = xscaleInt >> MINUV_SCALE; - if (xscaleIntUV) { - ovcmd &= ~HC_UP_INTERPOLATION; - } - } - - if (yscaleFract) { - yscaleFractUV = yscaleFract >> MINUV_SCALE; - ovcmd &= ~VC_DOWN_INTERPOLATION; - ovcmd |= VC_UP_INTERPOLATION; - } - - if (yscaleInt) { - yscaleIntUV = yscaleInt >> MINUV_SCALE; - if (yscaleIntUV) { - ovcmd &= ~VC_UP_INTERPOLATION; - ovcmd |= VC_DOWN_INTERPOLATION; - } - } - - }/* if((destw != srcw) || (desth != srch)) */ - - /* Lock the DRM */ - I810_LOCK(pI810XvMC,0); - - /* Block until rendering on this surface is finished */ - stat = XVMC_RENDERING; - while(stat & XVMC_RENDERING) { - XvMCGetSurfaceStatus(display,surface,&stat); - } - /* Block until the last flip is finished */ - if(pI810XvMC->last_flip) { - BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); - } - - pI810XvMC->current = !pI810XvMC->current; - pORegs->OV0CMD = ovcmd; - - if ((clipped_destw != clipped_srcw) || - (clipped_desth != clipped_srch)) { - pORegs->YRGBSCALE = (xscaleInt << 15) | - ((xscaleFract & 0xFFF) << 3) | (yscaleInt) | - ((yscaleFract & 0xFFF) << 20); - - pORegs->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) | - ((yscaleFractUV & 0xFFF) << 20); - } - else { - /* Normal 1:1 scaling */ - pORegs->YRGBSCALE = 0x80004000; - pORegs->UVSCALE = 0x80004000; - } - - pORegs->SHEIGHT = clipped_srch | (clipped_srch << 15); - pORegs->DWINPOS = (clipped_desty << 16) | clipped_destx; - pORegs->DWINSZ = ((clipped_desth<< 16) | (clipped_destw)); - - /* Attributes */ - pORegs->OV0CLRC0 = ((pI810XvMC->contrast & 0x1ff)<<8) | - (pI810XvMC->brightness & 0xff); - pORegs->OV0CLRC1 = (pI810XvMC->saturation & 0x3ff); - - /* Destination Colorkey Setup */ - pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey); - - /* buffer locations, add the offset from the clipping */ - if(pI810XvMC->current) { - pORegs->OBUF_1Y = (unsigned long)pI810Surface->offset + - (unsigned long)pI810Surface->offsets[0] + ysrc_offset; - pORegs->OBUF_1V = (unsigned long)pI810Surface->offset + - (unsigned long)pI810Surface->offsets[2] + uvsrc_offset; - pORegs->OBUF_1U = (unsigned long)pI810Surface->offset + - (unsigned long)pI810Surface->offsets[1] + uvsrc_offset; - } - else { - pORegs->OBUF_0Y = (unsigned long)pI810Surface->offset + - (unsigned long)pI810Surface->offsets[0] + ysrc_offset; - pORegs->OBUF_0V = (unsigned long)pI810Surface->offset + - (unsigned long)pI810Surface->offsets[2] + uvsrc_offset; - pORegs->OBUF_0U = (unsigned long)pI810Surface->offset + - (unsigned long)pI810Surface->offsets[1] + uvsrc_offset; - } - - switch(surface->surface_type_id) { - case FOURCC_YV12: - case FOURCC_I420: - pORegs->SWID = (uvPitch << 16) | yPitch; - pORegs->SWIDQW = (uvPitch << 13) | (yPitch >> 3); - pORegs->OV0STRIDE = (1<<pI810Surface->pitch) | - ((1<<pI810Surface->pitch) << 15); - pORegs->OV0CMD &= ~SOURCE_FORMAT; - pORegs->OV0CMD |= YUV_420; - if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) { - /* Top Field Only */ - if(flags & XVMC_TOP_FIELD) { - if(pI810XvMC->current == 1) { - pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | - BUFFER1_FIELD0); - } - else { - pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | - BUFFER0_FIELD0); - } - pORegs->YRGB_VPH = 1<<15 | 1<<31; - pORegs->UV_VPH = 3<<14 | 3<<30; - pORegs->INIT_PH = 0x06 | 0x18; - } - /* Bottom Field Only */ - else { - if(pI810XvMC->current == 1) { - pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | - BUFFER1_FIELD1); - } - else { - pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | - BUFFER0_FIELD1); - } - pORegs->YRGB_VPH = 0; - pORegs->UV_VPH = 7<<29 | 7<<13; - pORegs->INIT_PH = 0x06; - } - } - /* Frame Picture */ - else { - if(pI810XvMC->current == 1) { - pORegs->OV0CMD |= BUFFER1_FIELD0; - } - else { - pORegs->OV0CMD |= BUFFER0_FIELD0; - } - pORegs->YRGB_VPH = 0; - pORegs->UV_VPH = 0; - pORegs->INIT_PH = 0; - } - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - pORegs->SWID = srcw; - pORegs->SWIDQW = srcw >> 3; - pORegs->OV0STRIDE = pI810Surface->pitch; - pORegs->OV0CMD &= ~SOURCE_FORMAT; - pORegs->OV0CMD |= YUV_422; - pORegs->OV0CMD &= ~OV_BYTE_ORDER; - if (surface->surface_type_id == FOURCC_UYVY) { - pORegs->OV0CMD |= Y_SWAP; - } - - pORegs->OV0CMD &= ~BUFFER_AND_FIELD; - if(pI810XvMC->current == 1) { - pORegs->OV0CMD |= BUFFER1_FIELD0; - } - else { - pORegs->OV0CMD |= BUFFER0_FIELD0; - } - - break; - } /* switch(surface->surface_type_id) */ - - - - OVERLAY_FLIP(pI810XvMC); - - /* - The Overlay only flips when it knows you changed - something. So the first time change stuff while it - is watching to be sure. - */ - if(!pI810XvMC->last_flip) { - pORegs->OV0CMD &= ~0x4; - if(pI810XvMC->current == 1) { - pORegs->OV0CMD |= BUFFER1_FIELD0; - } - else { - pORegs->OV0CMD |= BUFFER0_FIELD0; - } - } - pI810Surface->last_flip = ++pI810XvMC->last_flip; - I810_UNLOCK(pI810XvMC); - - return Success; -} - -/*************************************************************************** -// Function: XvMCSyncSurface -// Arguments: -// display - Connection to the X server -// surface - The surface to synchronize -// Info: -// Returns: Status -***************************************************************************/ -Status XvMCSyncSurface(Display *display,XvMCSurface *surface) { - Status ret; - int stat=0; - /* - FIXME: Perhaps a timer here to prevent lockup? - FIXME: Perhaps a usleep to not be busy waiting? - */ - do { - ret = XvMCGetSurfaceStatus(display,surface,&stat); - }while(!ret && (stat & XVMC_RENDERING)); - return ret; -} - -/*************************************************************************** -// Function: XvMCFlushSurface -// Description: -// This function commits pending rendering requests to ensure that they -// wll be completed in a finite amount of time. -// Arguments: -// display - Connection to X server -// surface - Surface to flush -// Info: -// This command is a noop for i810 becuase we always dispatch buffers in -// render. There is little gain to be had with 4k buffers. -// Returns: Status -***************************************************************************/ -Status XvMCFlushSurface(Display * display, XvMCSurface *surface) { - return Success; -} - -/*************************************************************************** -// Function: XvMCGetSurfaceStatus -// Description: -// Arguments: -// display: connection to X server -// surface: The surface to query -// stat: One of the Following -// XVMC_RENDERING - The last XvMCRenderSurface command has not -// completed. -// XVMC_DISPLAYING - The surface is currently being displayed or a -// display is pending. -***************************************************************************/ -Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, - int *stat) { - i810XvMCSurface *privSurface; - i810XvMCContext *pI810XvMC; - int temp; - - if((display == NULL) || (surface == NULL) || (stat == NULL)) { - return BadValue; - } - if(surface->privData == NULL) { - return BadValue; - } - *stat = 0; - privSurface = surface->privData; - - pI810XvMC = privSurface->privContext; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadSurface); - } - - I810_LOCK(pI810XvMC,0); - if(privSurface->last_flip) { - /* This can not happen */ - if(pI810XvMC->last_flip < privSurface->last_flip) { - printf("Error: Context last flip is less than surface last flip.\n"); - return BadValue; - } - /* - If the context has 2 or more flips after this surface it - cannot be displaying. Don't bother to check. - */ - if(!(pI810XvMC->last_flip > (privSurface->last_flip + 1))) { - /* - If this surface was the last flipped it is either displaying - or about to be so don't bother checking. - */ - if(pI810XvMC->last_flip == privSurface->last_flip) { - *stat |= XVMC_DISPLAYING; - } - else { - /* - In this case there has been one more flip since our surface's - but we need to check if it is finished or not. - */ - temp = GET_FSTATUS(pI810XvMC); - if(((temp & (1<<20))>>20) != pI810XvMC->current) { - *stat |= XVMC_DISPLAYING; - } - } - } - } - - if(privSurface->last_render && - (privSurface->last_render > GET_RSTATUS(pI810XvMC))) { - *stat |= XVMC_RENDERING; - } - I810_UNLOCK(pI810XvMC); - - return Success; -} - -/*************************************************************************** -// -// Surface manipulation functions -// -***************************************************************************/ - -/*************************************************************************** -// Function: XvMCHideSurface -// Description: Stops the display of a surface. -// Arguments: -// display - Connection to the X server. -// surface - surface to be hidden. -// -// Returns: Status -***************************************************************************/ -Status XvMCHideSurface(Display *display, XvMCSurface *surface) { - i810XvMCSurface *pI810Surface; - i810XvMCContext *pI810XvMC; - int ss, xx; - - /* Did we get a good display and surface passed into us? */ - if(display == NULL) { - return BadValue; - } - - if(surface == NULL) { - return (error_base + XvMCBadSurface); - } - - XvMCSyncSurface(display, surface); - - /* Get surface private data pointer */ - if(surface->privData == NULL) { - return (error_base + XvMCBadSurface); - } - pI810Surface = (i810XvMCSurface *)surface->privData; - - /* - Get the status of the surface, if it is not currently displayed - we don't need to worry about it. - */ - if((xx = XvMCGetSurfaceStatus(display, surface, &ss)) != Success) { - return xx; - } - if(! (ss & XVMC_DISPLAYING)) { - return Success; - } - - /* Get the associated context pointer */ - pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadSurface); - } - - if(pI810XvMC->last_flip) { - I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); - - /* Make sure last flip is done */ - BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); - - /* Set the registers to turn the overlay off */ - pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | - Y_ADJUST; - pI810XvMC->current = !pI810XvMC->current; - if(pI810XvMC->current == 1) { - pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0; - } - else { - pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0; - } - OVERLAY_FLIP(pI810XvMC); - /* - Increment the context flip but not the surface. This way no - surface has the last flip #. - */ - pI810XvMC->last_flip++; - - - /* Now wait until the hardware reads the registers and makes the change. */ - BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current) - - I810_UNLOCK(pI810XvMC); - } - - return Success; -} - - - - -/*************************************************************************** -// -// Functions that deal with subpictures -// -***************************************************************************/ - - - -/*************************************************************************** -// Function: XvMCCreateSubpicture -// Description: This creates a subpicture by filling out the XvMCSubpicture -// structure passed to it and returning Success. -// Arguments: -// display - Connection to the X server. -// context - The context to create the subpicture for. -// subpicture - Pre-allocated XvMCSubpicture structure to be filled in. -// width - of subpicture -// height - of subpicture -// xvimage_id - The id describing the XvImage format. -// -// Returns: Status -***************************************************************************/ -Status XvMCCreateSubpicture(Display *display, XvMCContext *context, - XvMCSubpicture *subpicture, - unsigned short width, unsigned short height, - int xvimage_id) { - i810XvMCContext *pI810XvMC; - i810XvMCSubpicture *pI810Subpicture; - int priv_count; - uint *priv_data; - Status ret; - - if((subpicture == NULL) || (context == NULL) || (display == NULL)){ - return BadValue; - } - - pI810XvMC = (i810XvMCContext *)context->privData; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadContext); - } - - - subpicture->context_id = context->context_id; - subpicture->xvimage_id = xvimage_id; - - /* These need to be checked to make sure they are not too big! */ - subpicture->width = width; - subpicture->height = height; - - subpicture->privData = - (i810XvMCSubpicture *)malloc(sizeof(i810XvMCSubpicture)); - - if(!subpicture->privData) { - return BadAlloc; - } - pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; - - - if((ret = _xvmc_create_subpicture(display, context, subpicture, - &priv_count, &priv_data))) { - printf("Unable to create XvMCSubpicture.\n"); - return ret; - } - - if(priv_count != 1) { - printf("_xvmc_create_subpicture() returned incorrect data size.\n"); - printf("Expected 1 got %d\n",priv_count); - free(priv_data); - return BadAlloc; - } - /* Data == Client Address, offset == Physical address offset */ - pI810Subpicture->data = pI810XvMC->surfaces.address; - pI810Subpicture->offset = pI810XvMC->surfaces.offset; - - /* Initialize private values */ - pI810Subpicture->privContext = pI810XvMC; - - pI810Subpicture->last_render = 0; - pI810Subpicture->last_flip = 0; - - /* Based on the xvimage_id we will need to set the other values */ - subpicture->num_palette_entries = 16; - subpicture->entry_bytes = 3; - strcpy(subpicture->component_order,"YUV"); - - /* - i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch - and the Tiler need 512k aligned surfaces, basically we are - stuck with fixed memory with pitch 1024. - */ - pI810Subpicture->pitch = 10; - - /* - offsets[0] == offset into the map described by either - address (Client memeory address) or offset (physical offset from fb base) - */ - pI810Subpicture->offsets[0] = priv_data[0]; - if(((unsigned long)pI810Subpicture->data + pI810Subpicture->offsets[0]) & 4095) { - printf("XvMCCreateSubpicture: Subpicture offset 0 is not 4096 aligned\n"); - } - - /* Free data returned from xvmc_create_surface */ - free(priv_data); - - /* Clear the surface to 0 */ - memset((void *)((unsigned long)pI810Subpicture->data + (unsigned long)pI810Subpicture->offsets[0]), - 0, ((1<<pI810Subpicture->pitch) * subpicture->height)); - - switch(subpicture->xvimage_id) { - case FOURCC_IA44: - case FOURCC_AI44: - /* Destination buffer info command */ - pI810Subpicture->dbi1 = ((((unsigned int)pI810Subpicture->offset + - pI810Subpicture->offsets[0]) & ~0xfc000fff) | - (pI810Subpicture->pitch - 9)); - - /* Destination buffer variables command */ - pI810Subpicture->dbv1 = (0x8<<20) | (0x8<<16); - - /* Map info command */ - pI810Subpicture->mi1 = (0x0<<24) | (3<<21) | (1<<9) | - (pI810Subpicture->pitch - 3); - - pI810Subpicture->mi2 = (((unsigned int)subpicture->height - 1)<<16) | - ((unsigned int)subpicture->width - 1); - - pI810Subpicture->mi3 = ((unsigned int)pI810Subpicture->offset + - pI810Subpicture->offsets[0]) & ~0xfc00000f; - break; - default: - free(subpicture->privData); - return BadMatch; - } - - pI810XvMC->ref++; - return Success; -} - - - -/*************************************************************************** -// Function: XvMCClearSubpicture -// Description: Clear the area of the given subpicture to "color". -// structure passed to it and returning Success. -// Arguments: -// display - Connection to the X server. -// subpicture - Subpicture to clear. -// x, y, width, height - rectangle in the subpicture to clear. -// color - The data to file the rectangle with. -// -// Returns: Status -***************************************************************************/ -Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture, - short x, short y, - unsigned short width, unsigned short height, - unsigned int color) { - - i810XvMCContext *pI810XvMC; - i810XvMCSubpicture *pI810Subpicture; - int i; - - if((subpicture == NULL) || (display == NULL)){ - return BadValue; - } - - if(!subpicture->privData) { - return (error_base + XvMCBadSubpicture); - } - pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; - - pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadSubpicture); - } - - if((x < 0) || (x + width > subpicture->width)) { - return BadValue; - } - - if((y < 0) || (y + height > subpicture->height)) { - return BadValue; - } - - for(i=y; i<y + height; i++) { - memset((void *)((unsigned long)pI810Subpicture->data + - (unsigned long)pI810Subpicture->offsets[0] + x + - (1<<pI810Subpicture->pitch) * i),(char)color,width); - } - - return Success; -} - -/*************************************************************************** -// Function: XvMCCompositeSubpicture -// Description: Composite the XvImae on the subpicture. This composit uses -// non-premultiplied alpha. Destination alpha is utilized -// except for with indexed subpictures. Indexed subpictures -// use a simple "replace". -// Arguments: -// display - Connection to the X server. -// subpicture - Subpicture to clear. -// image - the XvImage to be used as the source of the composite. -// srcx, srcy, width, height - The rectangle from the image to be used. -// dstx, dsty - location in the subpicture to composite the source. -// -// Returns: Status -***************************************************************************/ -Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture, - XvImage *image, - short srcx, short srcy, - unsigned short width, unsigned short height, - short dstx, short dsty) { - - i810XvMCContext *pI810XvMC; - i810XvMCSubpicture *pI810Subpicture; - int i; - - if((subpicture == NULL) || (display == NULL)){ - return BadValue; - } - - if(!subpicture->privData) { - return (error_base + XvMCBadSubpicture); - } - pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; - - pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadSubpicture); - } - - if((srcx < 0) || (srcx + width > image->width)) { - return BadValue; - } - - if((dstx < 0) || (dstx + width > subpicture->width)) { - return BadValue; - } - - if((srcy < 0) || (srcy + height > image->height)) { - return BadValue; - } - - if((dsty < 0) || (dsty + height > subpicture->height)) { - return BadValue; - } - - for(i=0; i<height; i++) { - memcpy((void *)((unsigned long)pI810Subpicture->data + - (unsigned long)pI810Subpicture->offsets[0] + dstx + - (1<<pI810Subpicture->pitch) * (i + dsty)), - (void *)((unsigned long)image->data + - (unsigned long)image->offsets[0] + srcx + - image->pitches[0] * (i + srcy)) - ,width); - } - - return Success; - -} - - -/*************************************************************************** -// Function: XvMCDestroySubpicture -// Description: Destroys the specified subpicture. -// Arguments: -// display - Connection to the X server. -// subpicture - Subpicture to be destroyed. -// -// Returns: Status -***************************************************************************/ -Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) { - - i810XvMCSubpicture *pI810Subpicture; - i810XvMCContext *pI810XvMC; - - if((display == NULL) || (subpicture == NULL)) { - return BadValue; - } - if(!subpicture->privData) { - return (error_base + XvMCBadSubpicture); - } - pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; - - pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; - if(!pI810XvMC) { - return (error_base + XvMCBadSubpicture); - } - - - if(pI810Subpicture->last_render) { - XvMCSyncSubpicture(display,subpicture); - } - - _xvmc_destroy_subpicture(display,subpicture); - - i810_free_privContext(pI810XvMC); - - free(pI810Subpicture); - subpicture->privData = NULL; - return Success; -} - - -/*************************************************************************** -// Function: XvMCSetSubpicturePalette -// Description: Set the subpictures palette -// Arguments: -// display - Connection to the X server. -// subpicture - Subpiture to set palette for. -// palette - A pointer to an array holding the palette data. The array -// is num_palette_entries * entry_bytes in size. -// Returns: Status -***************************************************************************/ - -Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, - unsigned char *palette) { - i810XvMCSubpicture *privSubpicture; - int i,j; - - if((display == NULL) || (subpicture == NULL)) { - return BadValue; - } - if(subpicture->privData == NULL) { - return (error_base + XvMCBadSubpicture); - } - privSubpicture = (i810XvMCSubpicture *)subpicture->privData; - - j=0; - for(i=0; i<16; i++) { - privSubpicture->palette[0][i] = palette[j++]; - privSubpicture->palette[1][i] = palette[j++]; - privSubpicture->palette[2][i] = palette[j++]; - } - return Success; -} - -/*************************************************************************** -// Function: XvMCBlendSubpicture -// Description: -// The behavior of this function is different depending on whether -// or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. -// i810 only support frontend behavior. -// -// XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): -// -// XvMCBlendSubpicture is a no-op in this case. -// -// Arguments: -// display - Connection to the X server. -// subpicture - The subpicture to be blended into the video. -// target_surface - The surface to be displayed with the blended subpic. -// source_surface - Source surface prior to blending. -// subx, suby, subw, subh - The rectangle from the subpicture to use. -// surfx, surfy, surfw, surfh - The rectangle in the surface to blend -// blend the subpicture rectangle into. Scaling can ocure if -// XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. -// -// Returns: Status -***************************************************************************/ -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) { - - return BadMatch; -} - - - -/*************************************************************************** -// Function: XvMCBlendSubpicture2 -// Description: -// The behavior of this function is different depending on whether -// or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. -// i810 only supports frontend blending. -// -// XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): -// -// XvMCBlendSubpicture2 blends the source_surface and subpicture and -// puts it in the target_surface. This does not effect the status of -// the source surface but will cause the target_surface to query -// XVMC_RENDERING until the blend is completed. -// -// Arguments: -// display - Connection to the X server. -// subpicture - The subpicture to be blended into the video. -// target_surface - The surface to be displayed with the blended subpic. -// source_surface - Source surface prior to blending. -// subx, suby, subw, subh - The rectangle from the subpicture to use. -// surfx, surfy, surfw, surfh - The rectangle in the surface to blend -// blend the subpicture rectangle into. Scaling can ocure if -// XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. -// -// Returns: Status -***************************************************************************/ -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) { - drmBufPtr pDMA; - unsigned int *data; - i810XvMCContext *pI810XvMC; - i810XvMCSubpicture *privSubpicture; - i810XvMCSurface *privTarget; - i810XvMCSurface *privSource; - drm_i810_mc_t mc; - int i,j; - - if(display == NULL) { - return BadValue; - } - - if(subpicture == NULL) { - return (error_base + XvMCBadSubpicture); - } - - if((target_surface == NULL) || (source_surface == NULL)) { - return (error_base + XvMCBadSurface); - } - - if((subpicture->xvimage_id != FOURCC_AI44) && - (subpicture->xvimage_id != FOURCC_IA44)) { - return (error_base + XvMCBadSubpicture); - } - - if(!subpicture->privData) { - return (error_base + XvMCBadSubpicture); - } - privSubpicture = (i810XvMCSubpicture *)subpicture->privData; - - pI810XvMC = (i810XvMCContext *)privSubpicture->privContext; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadSubpicture); - } - - if(!target_surface->privData) { - return (error_base + XvMCBadSurface); - } - privTarget = (i810XvMCSurface *)target_surface->privData; - - if(!source_surface->privData) { - return (error_base + XvMCBadSurface); - } - privSource = (i810XvMCSurface *)source_surface->privData; - - - /* Check that size isn't bigger than subpicture */ - if((subx + subw) > subpicture->width) { - return BadValue; - } - if((suby + subh) > subpicture->height) { - return BadValue; - } - /* Check that dest isn't bigger than surface */ - if((surfx + surfw) > target_surface->width) { - return BadValue; - } - if((surfy + surfh) > target_surface->height) { - return BadValue; - } - /* Make sure surfaces match */ - if(target_surface->width != source_surface->width) { - return BadValue; - } - if(target_surface->height != source_surface->height) { - return BadValue; - } - - /* Lock For DMA */ - I810_LOCK(pI810XvMC,0); - - /* Allocate DMA buffer */ - pDMA = i810_get_free_buffer(pI810XvMC); - data = pDMA->address; - - /* Copy Y data first */ - /* SOURCE_COPY_BLT */ - *data++ = (2<<29) | (0x43<<22) | 0x4; - *data++ = (0xcc<<16) | (1<<26) | (1<<privTarget->pitch); - *data++ = (target_surface->height<<16) | target_surface->width; - *data++ = privTarget->offset + privTarget->offsets[0]; - *data++ = (1<<privSource->pitch); - *data++ = privSource->offset + privSource->offsets[0]; - - /* Select Context 1 for loading */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<17) | (1<<8); - *data++ = CMD_FLUSH; - - /* Load Palette */ - *data++ = MAP_PALETTE_LOAD; - /* 16 levels of alpha for each Y */ - switch(subpicture->xvimage_id) { - case FOURCC_IA44: - for(i=0; i<16; i++) { - for(j=0; j<16; j++) { - *data++ = (j<<12) | (j<<8) | privSubpicture->palette[0][i]; - } - } - break; - case FOURCC_AI44: - for(i=0; i<16; i++) { - for(j=0; j<16; j++) { - *data++ = (i<<12) | (i<<8) | privSubpicture->palette[0][j]; - } - } - break; - } - /* TARGET */ - /* *data++ = CMD_FLUSH; */ - /* *data++ = BOOLEAN_ENA_2; */ - *data++ = CMD_FLUSH; - *data++ = DEST_BUFFER_INFO; - *data++ = privTarget->dbi1y; - *data++ = DEST_BUFFER_VAR; - *data++ = privTarget->dbv1; - - /* ALPHA */ - *data++ = CMD_MAP_INFO; - *data++ = privSubpicture->mi1; - *data++ = privSubpicture->mi2; - *data++ = privSubpicture->mi3; - - *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); - *data++ = BOOLEAN_ENA_1; - *data++ = SRC_DEST_BLEND_MONO | (0x940); - /* Map Filter */ - *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (0x224); - - /* Use context 1 */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<16) | 1; - *data++ = CMD_FLUSH; - - /* Drawing Rect Info */ - *data++ = DRAWING_RECT_INFO; - *data++ = 0x0; - *data++ = 0x0; - *data++ = 0x0; - *data++ = 0x0; - *data++ = 0x0; - - /* GFXPRIMITIVE RECTANGLE */ - *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; - /* Bottom Right Vertex */ - *(float *)data++ = (float) (surfx + surfw); - *(float *)data++ = (float) (surfy + surfh); - *(float *)data++ = (float) (subx + subw); - *(float *)data++ = (float) (suby + subh); - /* Bottom Left Vertex */ - *(float *)data++ = (float) surfx; - *(float *)data++ = (float) (surfy + surfh); - *(float *)data++ = (float) subx; - *(float *)data++ = (float) (suby + subh); - /* Top Left Vertex */ - *(float *)data++ = (float) surfx; - *(float *)data++ = (float) surfy; - *(float *)data++ = (float) subx; - *(float *)data++ = (float) suby; - - /* Load and Use Context 0 */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<17) | (1<<16); - *data++ = CMD_FLUSH; - - /* U data */ - /* SOURCE_COPY_BLT */ - *data++ = (2<<29) | (0x43<<22) | 0x4; - *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1)); - *data++ = (target_surface->height<<15) | (target_surface->width>>1); - *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[1]; - *data++ = (1<<(privSource->pitch - 1)); - *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[1]; - - /* Context 1 select */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<17) | (1<<8); - *data++ = CMD_FLUSH; - /* ALPHA PALETTE */ - *data++ = MAP_PALETTE_LOAD; - /* 16 levels of alpha for each Y */ - switch(subpicture->xvimage_id) { - case FOURCC_IA44: - for(i=0; i<16; i++) { - for(j=0; j<16; j++) { - *data++ = (j<<12) | (j<<8) | privSubpicture->palette[2][i]; - } - } - break; - case FOURCC_AI44: - for(i=0; i<16; i++) { - for(j=0; j<16; j++) { - *data++ = (i<<12) | (i<<8) | privSubpicture->palette[2][j]; - } - } - break; - } - /* TARGET */ - *data++ = CMD_FLUSH; - *data++ = BOOLEAN_ENA_2; - *data++ = CMD_FLUSH; - *data++ = DEST_BUFFER_INFO; - *data++ = privTarget->dbi1u; - *data++ = DEST_BUFFER_VAR; - *data++ = privTarget->dbv1; - - /* ALPHA */ - *data++ = CMD_MAP_INFO; - *data++ = privSubpicture->mi1; - *data++ = privSubpicture->mi2; - *data++ = privSubpicture->mi3; - - *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); - *data++ = BOOLEAN_ENA_1; - *data++ = SRC_DEST_BLEND_MONO | (0x940); - /* Map Filter */ - *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224); - - /* Use context 1 */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<16) | 1; - *data++ = CMD_FLUSH; - - /* Drawing Rect Info */ - *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3; - *data++ = 0; - *data++ = 0; - *data++ = 0; - *data++ = 0; - *data++ = 0; - - /* Rectangle */ - *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; - /* Bottom Right */ - *(float *)data++ = (float) ((surfx + surfw)>>1); - *(float *)data++ = (float) ((surfy + surfh)>>1); - *(float *)data++ = (float) subx + subw; - *(float *)data++ = (float) suby + subh; - /* Bottom Left */ - *(float *)data++ = (float) (surfx>>1); - *(float *)data++ = (float) ((surfy + surfh)>>1); - *(float *)data++ = (float) subx; - *(float *)data++ = (float) suby + subh; - /* Top Left */ - *(float *)data++ = (float) (surfx>>1); - *(float *)data++ = (float) (surfy>>1); - *(float *)data++ = (float) subx; - *(float *)data++ = (float) suby; - - /* Load and Use Context 0 */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<17) | (1<<16); - *data++ = CMD_FLUSH; - - /* V data */ - /* SOURCE_COPY_BLT */ - *data++ = (2<<29) | (0x43<<22) | 0x4; - *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1)); - *data++ = (target_surface->height<<15) | (target_surface->width>>1); - *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[2]; - *data++ = (1<<(privSource->pitch - 1)); - *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[2]; - - /* Context 1 select */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<17) | (1<<8); - *data++ = CMD_FLUSH; - - /* ALPHA PALETTE */ - *data++ = MAP_PALETTE_LOAD; - /* 16 levels of alpha for each Y */ - switch(subpicture->xvimage_id) { - case FOURCC_IA44: - for(i=0; i<16; i++) { - for(j=0; j<16; j++) { - *data++ = (j<<12) | (j<<8) | privSubpicture->palette[1][i]; - } - } - break; - case FOURCC_AI44: - for(i=0; i<16; i++) { - for(j=0; j<16; j++) { - *data++ = (i<<12) | (i<<8) | privSubpicture->palette[1][j]; - } - } - break; - } - /* TARGET */ - *data++ = CMD_FLUSH; - *data++ = BOOLEAN_ENA_2; - *data++ = CMD_FLUSH; - *data++ = DEST_BUFFER_INFO; - *data++ = privTarget->dbi1v; - *data++ = DEST_BUFFER_VAR; - *data++ = privTarget->dbv1; - - /* ALPHA */ - *data++ = CMD_MAP_INFO; - *data++ = privSubpicture->mi1; - *data++ = privSubpicture->mi2; - *data++ = privSubpicture->mi3; - - *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); - *data++ = BOOLEAN_ENA_1; - *data++ = SRC_DEST_BLEND_MONO | (0x940); - /* Map Filter */ - *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224); - - /* Use context 1 */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<16) | 1; - *data++ = CMD_FLUSH; - - /* Drawing Rect Info */ - *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3; - *data++ = 0; - *data++ = 0; - *data++ = 0; - *data++ = 0; - *data++ = 0; - - /* Rectangle */ - *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; - /* Bottom Right */ - *(float *)data++ = (float) ((surfx + surfw)>>1); - *(float *)data++ = (float) ((surfy + surfh)>>1); - *(float *)data++ = (float) subx + subw; - *(float *)data++ = (float) suby + subh; - /* Bottom Left */ - *(float *)data++ = (float) (surfx>>1); - *(float *)data++ = (float) ((surfy + surfh)>>1); - *(float *)data++ = (float) subx; - *(float *)data++ = (float) suby + subh; - /* Top Left */ - *(float *)data++ = (float) (surfx>>1); - *(float *)data++ = (float) (surfy>>1); - *(float *)data++ = (float) subx; - *(float *)data++ = (float) suby; - - /* Load and Use Context 0 */ - *data++ = CMD_FLUSH; - *data++ = (5<<23) | (1<<17) | (1<<16); - *data++ = CMD_FLUSH; - - - /* Dispatch */ - pDMA->used = (unsigned long)data - (unsigned long)pDMA->address; - mc.idx = pDMA->idx; - mc.used = pDMA->used; - mc.last_render = ++pI810XvMC->last_render; - privTarget->last_render = pI810XvMC->last_render; - I810_MC(pI810XvMC,mc); - - I810_UNLOCK(pI810XvMC); - return Success; -} - - - -/*************************************************************************** -// Function: XvMCSyncSubpicture -// Description: This function blocks until all composite/clear requests on -// the subpicture have been complete. -// Arguments: -// display - Connection to the X server. -// subpicture - The subpicture to synchronize -// -// Returns: Status -***************************************************************************/ -Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) { - Status ret; - int stat=0; - do { - ret = XvMCGetSubpictureStatus(display,subpicture,&stat); - }while(!ret && (stat & XVMC_RENDERING)); - return ret; -} - - - -/*************************************************************************** -// Function: XvMCFlushSubpicture -// Description: This function commits pending composite/clear requests to -// ensure that they will be completed in a finite amount of -// time. -// Arguments: -// display - Connection to the X server. -// subpicture - The subpicture whos compsiting should be flushed -// -// Returns: Status -// NOTES: i810 always dispatches commands so flush is a no-op -***************************************************************************/ -Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) { - if(display == NULL) { - return BadValue; - } - if(subpicture == NULL) { - return (error_base + XvMCBadSubpicture); - } - - return Success; -} - - - -/*************************************************************************** -// Function: XvMCGetSubpictureStatus -// Description: This function gets the current status of a subpicture -// -// Arguments: -// display - Connection to the X server. -// subpicture - The subpicture whos status is being queried -// stat - The status of the subpicture. It can be any of the following -// OR'd together: -// XVMC_RENDERING - Last composite or clear request not completed -// XVMC_DISPLAYING - Suppicture currently being displayed. -// -// Returns: Status -// Notes: i810 always blends into a third surface so the subpicture is -// never actually displaying, only a copy of it is displaying. We only -// have to worry about the rendering case. -***************************************************************************/ -Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, - int *stat) { - - i810XvMCSubpicture *privSubpicture; - i810XvMCContext *pI810XvMC; - - if((display == NULL) || (stat == NULL)) { - return BadValue; - } - if((subpicture == NULL) || (subpicture->privData == NULL)) { - return (error_base + XvMCBadSubpicture); - } - *stat = 0; - privSubpicture = (i810XvMCSubpicture *)subpicture->privData; - - pI810XvMC = (i810XvMCContext *)privSubpicture->privContext; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadSubpicture); - } - - I810_LOCK(pI810XvMC,0); - - if(privSubpicture->last_render && - (privSubpicture->last_render > GET_RSTATUS(pI810XvMC))) { - *stat |= XVMC_RENDERING; - } - I810_UNLOCK(pI810XvMC); - - return Success; -} - -#define NUM_XVMC_ATTRIBUTES 4 -static XvAttribute I810_XVMC_ATTRIBUTES[] = { - {XvGettable | XvSettable, 0, 0xffffff, "XV_COLORKEY"}, - {XvGettable | XvSettable, -127, +127, "XV_BRIGHTNESS"}, - {XvGettable | XvSettable, 0, 0x1ff, "XV_CONTRAST"}, - {XvGettable | XvSettable, 0, 0x3ff, "XV_SATURATION"} -}; - - -/*************************************************************************** -// Function: XvMCQueryAttributes -// Description: An array of XvAttributes of size "number" is returned by -// this function. If there are no attributes, NULL is returned and number -// is set to 0. The array may be freed with xfree(). -// -// Arguments: -// display - Connection to the X server. -// context - The context whos attributes we are querying. -// number - The number of returned atoms. -// -// Returns: -// An array of XvAttributes. -// Notes: -// For i810 we support these Attributes: -// XV_COLORKEY: The colorkey value, initialized from the Xv value at -// context creation time. -// XV_BRIGHTNESS -// XV_CONTRAST -// XV_SATURATION -***************************************************************************/ -XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context, - int *number) { - i810XvMCContext *pI810XvMC; - XvAttribute *attributes; - - if(number == NULL) { - return NULL; - } - if(display == NULL) { - *number = 0; - return NULL; - } - if(context == NULL) { - *number = 0; - return NULL; - } - pI810XvMC = context->privData; - if(pI810XvMC == NULL) { - *number = 0; - return NULL; - } - - attributes = (XvAttribute *)malloc(NUM_XVMC_ATTRIBUTES * - sizeof(XvAttribute)); - if(attributes == NULL) { - *number = 0; - return NULL; - } - - memcpy(attributes,I810_XVMC_ATTRIBUTES,(NUM_XVMC_ATTRIBUTES * - sizeof(XvAttribute))); - - *number = NUM_XVMC_ATTRIBUTES; - return attributes; -} - -/*************************************************************************** -// Function: XvMCSetAttribute -// Description: This function sets a context-specific attribute. -// -// Arguments: -// display - Connection to the X server. -// context - The context whos attributes we are querying. -// attribute - The X atom of the attribute to be changed. -// value - The new value for the attribute. -// -// Returns: -// Status -// Notes: -// For i810 we support these Attributes: -// XV_COLORKEY: The colorkey value, initialized from the Xv value at -// context creation time. -// XV_BRIGHTNESS -// XV_CONTRAST -// XV_SATURATION -***************************************************************************/ -Status XvMCSetAttribute(Display *display, XvMCContext *context, - Atom attribute, int value) { - i810XvMCContext *pI810XvMC; - - if(display == NULL) { - return BadValue; - } - if(context == NULL) { - return (error_base + XvMCBadContext); - } - pI810XvMC = context->privData; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadContext); - } - - if(attribute == pI810XvMC->xv_colorkey) { - if((value < I810_XVMC_ATTRIBUTES[0].min_value) || - (value > I810_XVMC_ATTRIBUTES[0].max_value)) { - return BadValue; - } - pI810XvMC->colorkey = value; - return Success; - } - if(attribute == pI810XvMC->xv_brightness) { - if((value < I810_XVMC_ATTRIBUTES[1].min_value) || - (value > I810_XVMC_ATTRIBUTES[1].max_value)) { - return BadValue; - } - pI810XvMC->brightness = value; - return Success; - } - if(attribute == pI810XvMC->xv_saturation) { - if((value < I810_XVMC_ATTRIBUTES[2].min_value) || - (value > I810_XVMC_ATTRIBUTES[2].max_value)) { - return BadValue; - } - pI810XvMC->saturation = value; - return Success; - } - if(attribute == pI810XvMC->xv_contrast) { - if((value < I810_XVMC_ATTRIBUTES[3].min_value) || - (value > I810_XVMC_ATTRIBUTES[3].max_value)) { - return BadValue; - } - pI810XvMC->contrast = value; - return Success; - } - return BadValue; -} - -/*************************************************************************** -// Function: XvMCGetAttribute -// Description: This function queries a context-specific attribute and -// returns the value. -// -// Arguments: -// display - Connection to the X server. -// context - The context whos attributes we are querying. -// attribute - The X atom of the attribute to be queried -// value - The returned attribute value -// -// Returns: -// Status -// Notes: -// For i810 we support these Attributes: -// XV_COLORKEY: The colorkey value, initialized from the Xv value at -// context creation time. -// XV_BRIGHTNESS -// XV_CONTRAST -// XV_SATURATION -***************************************************************************/ -Status XvMCGetAttribute(Display *display, XvMCContext *context, - Atom attribute, int *value) { - i810XvMCContext *pI810XvMC; - - if(display == NULL) { - return BadValue; - } - if(context == NULL) { - return (error_base + XvMCBadContext); - } - pI810XvMC = context->privData; - if(pI810XvMC == NULL) { - return (error_base + XvMCBadContext); - } - if(value == NULL) { - return BadValue; - } - - if(attribute == pI810XvMC->xv_colorkey) { - *value = pI810XvMC->colorkey; - return Success; - } - if(attribute == pI810XvMC->xv_brightness) { - *value = pI810XvMC->brightness; - return Success; - } - if(attribute == pI810XvMC->xv_saturation) { - *value = pI810XvMC->saturation; - return Success; - } - if(attribute == pI810XvMC->xv_contrast) { - *value = pI810XvMC->contrast; - return Success; - } - return BadValue; -} - - - - |