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 + -
显示快捷键?