i810_video.c

来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 1,420 行 · 第 1/3 页

C
1,420
字号
    if(diff > 0) {	dst->x2 = extents->x2;	*x2 -= diff * hscale;         }    diff = extents->y1 - dst->y1;    if(diff > 0) {	dst->y1 = extents->y1;	*y1 += diff * vscale;         }    diff = dst->y2 - extents->y2;    if(diff > 0) {	dst->y2 = extents->y2;	*y2 -= diff * vscale;         }    if(*x1 < 0) {	diff =  (- *x1 + hscale - 1)/ hscale;	dst->x1 += diff;	*x1 += diff * hscale;    }    delta = *x2 - (width << 16);    if(delta > 0) {	diff = (delta + hscale - 1)/ hscale;	dst->x2 -= diff;	*x2 -= diff * hscale;    }    if(*y1 < 0) {	diff =  (- *y1 + vscale - 1)/ vscale;	dst->y1 += diff;	*y1 += diff * vscale;    }    delta = *y2 - (height << 16);    if(delta > 0) {	diff = (delta + vscale - 1)/ vscale;	dst->y2 -= diff;	*y2 -= diff * vscale;    }} static void I810StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown){  I810PortPrivPtr pPriv = (I810PortPrivPtr)data;  I810Ptr pI810 = I810PTR(pScrn);  I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart);   REGION_EMPTY(pScrn->pScreen, &pPriv->clip);     if(shutdown) {     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {	overlay->OV0CMD &= 0xFFFFFFFE;	OVERLAY_UPDATE(pI810->OverlayPhysical);     }     if(pPriv->linear) {	xf86FreeOffscreenLinear(pPriv->linear);	pPriv->linear = NULL;     }     pPriv->videoStatus = 0;  } else {     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {	pPriv->videoStatus |= OFF_TIMER;	pPriv->offTime = currentTime.milliseconds + OFF_DELAY;      }  }}static int I810SetPortAttribute(  ScrnInfoPtr pScrn,   Atom attribute,  INT32 value,   pointer data){  I810PortPrivPtr pPriv = (I810PortPrivPtr)data;  I810Ptr pI810 = I810PTR(pScrn);  I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart);   if(attribute == xvBrightness) {	if((value < -128) || (value > 127))	   return BadValue;	pPriv->brightness = value;	overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff);	OVERLAY_UPDATE(pI810->OverlayPhysical);  } else  if(attribute == xvContrast) {	if((value < 0) || (value > 255))	   return BadValue;	pPriv->contrast = value;	overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff);	OVERLAY_UPDATE(pI810->OverlayPhysical);  } else  if(attribute == xvColorKey) {	pPriv->colorKey = value;	switch(pScrn->depth) {	case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);	         break;	case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);                 break;	default: overlay->DCLRKV = pPriv->colorKey;                 break;	}	OVERLAY_UPDATE(pI810->OverlayPhysical);	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);     } else return BadMatch;  return Success;}static int I810GetPortAttribute(  ScrnInfoPtr pScrn,   Atom attribute,  INT32 *value,   pointer data){  I810PortPrivPtr pPriv = (I810PortPrivPtr)data;  if(attribute == xvBrightness) {	*value = pPriv->brightness;  } else  if(attribute == xvContrast) {	*value = pPriv->contrast;  } else  if(attribute == xvColorKey) {	*value = pPriv->colorKey;  } else return BadMatch;  return Success;}static void I810QueryBestSize(  ScrnInfoPtr pScrn,   Bool motion,  short vid_w, short vid_h,   short drw_w, short drw_h,   unsigned int *p_w, unsigned int *p_h,   pointer data){   if(vid_w > (drw_w << 1)) drw_w = vid_w >> 1;   if(vid_h > (drw_h << 1)) drw_h = vid_h >> 1;  *p_w = drw_w;  *p_h = drw_h; }static voidI810CopyPackedData(   ScrnInfoPtr pScrn,    unsigned char *buf,   int srcPitch,   int dstPitch,   int top,   int left,   int h,   int w   ){    I810Ptr pI810 = I810PTR(pScrn);    I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr;    unsigned char *src, *dst;        src = buf + (top*srcPitch) + (left<<1);    if (pPriv->currentBuf == 0)	dst = pI810->FbBase + pPriv->YBuf0offset;    else	dst = pI810->FbBase + pPriv->YBuf1offset;    w <<= 1;    while(h--) {	memcpy(dst, src, w);	src += srcPitch;	dst += dstPitch;    }}static voidI810CopyPlanarData(   ScrnInfoPtr pScrn,    unsigned char *buf,   int srcPitch,   int dstPitch,  /* of chroma */   int srcH,   int top,   int left,   int h,   int w,   int id   ){    I810Ptr pI810 = I810PTR(pScrn);    I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr;    int i;    unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;    /* Copy Y data */    src1 = buf + (top*srcPitch) + left;    if (pPriv->currentBuf == 0)	dst1 = pI810->FbBase + pPriv->YBuf0offset;    else	dst1 = pI810->FbBase + pPriv->YBuf1offset;    for (i = 0; i < h; i++) {	memcpy(dst1, src1, w);	src1 += srcPitch;	dst1 += dstPitch << 1;    }    /* Copy V data for YV12, or U data for I420 */    src2 = buf + (srcH*srcPitch) + ((top*srcPitch)>>2) + (left>>1);    if (pPriv->currentBuf == 0) {	if (id == FOURCC_I420)	    dst2 = pI810->FbBase + pPriv->UBuf0offset;	else	    dst2 = pI810->FbBase + pPriv->VBuf0offset;    } else {	if (id == FOURCC_I420)	    dst2 = pI810->FbBase + pPriv->UBuf1offset;	else	    dst2 = pI810->FbBase + pPriv->VBuf1offset;    }    for (i = 0; i < h/2; i++) {	memcpy(dst2, src2, w/2);	src2 += srcPitch>>1;	dst2 += dstPitch;    }    /* Copy U data for YV12, or V data for I420 */    src3 = buf + (srcH*srcPitch) + ((srcH*srcPitch)>>2) + ((top*srcPitch)>>2) + (left>>1);    if (pPriv->currentBuf == 0) {	if (id == FOURCC_I420) 	    dst3 = pI810->FbBase + pPriv->VBuf0offset;	else	    dst3 = pI810->FbBase + pPriv->UBuf0offset;    } else {	if (id == FOURCC_I420) 	    dst3 = pI810->FbBase + pPriv->VBuf1offset;	else	    dst3 = pI810->FbBase + pPriv->UBuf1offset;    }        for (i = 0; i < h/2; i++) {	memcpy(dst3, src3, w/2);	src3 += srcPitch>>1;	dst3 += dstPitch;    }}static voidI810DisplayVideo(    ScrnInfoPtr pScrn,    int id,    short width, short height,    int dstPitch,  /* of chroma for 4:2:0 */    int x1, int y1, int x2, int y2,    BoxPtr dstBox,    short src_w, short src_h,    short drw_w, short drw_h){    I810Ptr pI810 = I810PTR(pScrn);    I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr;    I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart);     int xscaleInt, xscaleFract, yscaleInt, yscaleFract;    int xscaleIntUV = 0, xscaleFractUV = 0, yscaleIntUV = 0, yscaleFractUV = 0;    unsigned int swidth;    switch(id) {    case FOURCC_YV12:    case FOURCC_I420:	swidth = (width + 7) & ~7;	overlay->SWID = (swidth << 15) | swidth;	overlay->SWIDQW = (swidth << 12) | (swidth >> 3);	break;    case FOURCC_UYVY:    case FOURCC_YUY2:    default:	swidth = ((width + 3) & ~3) << 1;	overlay->SWID = swidth;	overlay->SWIDQW = swidth >> 3;	break;    }    /* wide video formats (>720 pixels) are special */    if( swidth > IMAGE_FAST_WIDTH ) {	overlay->OV0CONF = 1; /* one 1440 pixel line buffer */     } else {	overlay->OV0CONF = 0; /* two 720 pixel line buffers */    }	        overlay->SHEIGHT = height | (height << 15);    overlay->DWINPOS = (dstBox->y1 << 16) | (dstBox->x1);    overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) | 	              (dstBox->x2 - dstBox->x1);    /* buffer locations */    overlay->OBUF_0Y = pPriv->YBuf0offset;    overlay->OBUF_1Y = pPriv->YBuf1offset;    overlay->OBUF_0U = pPriv->UBuf0offset;     overlay->OBUF_0V = pPriv->VBuf0offset;    overlay->OBUF_1U = pPriv->UBuf1offset;    overlay->OBUF_1V = pPriv->VBuf1offset;    /*      * Calculate horizontal and vertical scaling factors, default to 1:1     */    overlay->YRGBSCALE = 0x80004000;    overlay->UVSCALE = 0x80004000;    /*      * Initially, YCbCr and Overlay Enable and     * vertical chrominance up interpolation and horozontal chrominance     * up interpolation     */    overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | 	              OVERLAY_ENABLE;     if ((drw_w != src_w) || (drw_h != src_h))     {	xscaleInt = (src_w / drw_w) & 0x3;	xscaleFract = (src_w << 12) / drw_w;	yscaleInt = (src_h / drw_h) & 0x3;	yscaleFract = (src_h << 12) / drw_h;	overlay->YRGBSCALE = (xscaleInt << 15) | 	                     ((xscaleFract & 0xFFF) << 3) |	                     (yscaleInt) |			     ((yscaleFract & 0xFFF) << 20);	if (drw_w > src_w) 	{	    /* horizontal up-scaling */	    overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER;	    overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER;	    overlay->OV0CMD |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION);	}	if (drw_h > src_h) 	{ 	    /* vertical up-scaling */	    overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER;	    overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER;	    overlay->OV0CMD |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION);	}	if (drw_w < src_w) 	{ 	    /* horizontal down-scaling */	    overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER;	    overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER;	    overlay->OV0CMD |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION);	}	if (drw_h < src_h) 	{ 	    /* vertical down-scaling */	    overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER;	    overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER;	    overlay->OV0CMD |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION);	}	/* now calculate the UV scaling factor */	if (xscaleFract)	{	    xscaleFractUV = xscaleFract >> MINUV_SCALE;	    overlay->OV0CMD &= ~HC_DOWN_INTERPOLATION;	    overlay->OV0CMD |= HC_UP_INTERPOLATION;	}	if (xscaleInt)	{	    xscaleIntUV = xscaleInt >> MINUV_SCALE;	    if (xscaleIntUV)	    {		overlay->OV0CMD &= ~HC_UP_INTERPOLATION;	    }	}	if (yscaleFract)	{	    yscaleFractUV = yscaleFract >> MINUV_SCALE;	    overlay->OV0CMD &= ~VC_DOWN_INTERPOLATION;	    overlay->OV0CMD |= VC_UP_INTERPOLATION;	}	if (yscaleInt)	{	    yscaleIntUV = yscaleInt >> MINUV_SCALE;	    if (yscaleIntUV)	    {		overlay->OV0CMD &= ~VC_UP_INTERPOLATION;		overlay->OV0CMD |= VC_DOWN_INTERPOLATION;	    }	}	overlay->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) |	                   ((yscaleFractUV & 0xFFF) << 20);    }    switch(id) {    case FOURCC_YV12:    case FOURCC_I420:	/* set UV vertical phase to -0.25 */	overlay->UV_VPH = 0x30003000;	overlay->INIT_PH = UV_VERT_BUF0 | UV_VERT_BUF1;	overlay->OV0STRIDE = (dstPitch << 1) | (dstPitch << 16);	overlay->OV0CMD &= ~SOURCE_FORMAT;	overlay->OV0CMD |= YUV_420;	break;    case I810_RV15:    case I810_RV16:	overlay->UV_VPH = 0;	overlay->INIT_PH = 0;	overlay->OV0STRIDE = dstPitch;	overlay->OV0CMD &= ~SOURCE_FORMAT;	overlay->OV0CMD |= (id==I810_RV15 ? RGB_555 : RGB_565);	overlay->OV0CMD &= ~OV_BYTE_ORDER;	break;    case FOURCC_UYVY:    case FOURCC_YUY2:    default:	overlay->UV_VPH = 0;	overlay->INIT_PH = 0;	overlay->OV0STRIDE = dstPitch;	overlay->OV0CMD &= ~SOURCE_FORMAT;	overlay->OV0CMD |= YUV_422;	overlay->OV0CMD &= ~OV_BYTE_ORDER;	if (id == FOURCC_UYVY)	    overlay->OV0CMD |= Y_SWAP;	break;    }    overlay->OV0CMD &= ~BUFFER_AND_FIELD;    if (pPriv->currentBuf == 0)	overlay->OV0CMD |= BUFFER0_FIELD0;    else	overlay->OV0CMD |= BUFFER1_FIELD0;    OVERLAY_UPDATE(pI810->OverlayPhysical);}static FBLinearPtrI810AllocateMemory(  ScrnInfoPtr pScrn,  FBLinearPtr linear,  int size){   ScreenPtr pScreen;   FBLinearPtr new_linear;   if(linear) {	if(linear->size >= size)	   return linear;	if(xf86ResizeOffscreenLinear(linear, size))	   return linear;	xf86FreeOffscreenLinear(linear);   }   pScreen = screenInfo.screens[pScrn->scrnIndex];   new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4,                                            NULL, NULL, NULL);   if(!new_linear) {        int max_size;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?