sis_vid.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,514 行 · 第 1/3 页

C
1,514
字号
	top >>= 1;	bottom >>= 1;    }    h_over = (((left >> 8) & 0x0f) | ((right >> 4) & 0xf0));    v_over = (((top >> 8) & 0x0f) | ((bottom >> 4) & 0xf0));    pitch = pOverlay->pitch >> sis_shift_value;    /* set line buffer size */    setvideoreg(Index_VI_Line_Buffer_Size, pOverlay->lineBufSize);    /* set color key mode */    setvideoregmask(Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0F);    /* TW: We don't have to wait for vertical retrace in all cases */    /* JCP: be safe for now. */    if (1 /*pPriv->mustwait */ ) {	watchdog = WATCHDOG_DELAY;	while (pOverlay->VBlankActiveFunc() && --watchdog);	watchdog = WATCHDOG_DELAY;	while ((!pOverlay->VBlankActiveFunc()) && --watchdog);	if (!watchdog && sis_verbose > 0) {	    printf("[SiS]: timed out waiting for vertical retrace\n");	}    }    /* Unlock address registers */    data = getvideoreg(Index_VI_Control_Misc1);    setvideoreg(Index_VI_Control_Misc1, data | 0x20);    /* TEST: Is this required? */    setvideoreg(Index_VI_Control_Misc1, data | 0x20);    /* TEST end */    /* TEST: Is this required? */    if (sis_vga_engine == SIS_315_VGA)	setvideoreg(Index_VI_Control_Misc3, 0x00);    /* TEST end */    /* Set Y buf pitch */    setvideoreg(Index_VI_Disp_Y_Buf_Pitch_Low, (uint8_t) (pitch));    setvideoregmask(Index_VI_Disp_Y_UV_Buf_Pitch_Middle,		    (uint8_t) (pitch >> 8), 0x0f);    /* Set Y start address */    setvideoreg(Index_VI_Disp_Y_Buf_Start_Low, (uint8_t) (pOverlay->PSY));    setvideoreg(Index_VI_Disp_Y_Buf_Start_Middle,		(uint8_t) ((pOverlay->PSY) >> 8));    setvideoreg(Index_VI_Disp_Y_Buf_Start_High,		(uint8_t) ((pOverlay->PSY) >> 16));    /* set 310/325 series overflow bits for Y plane */    if (sis_vga_engine == SIS_315_VGA) {	setvideoreg(Index_VI_Disp_Y_Buf_Pitch_High,		    (uint8_t) (pitch >> 12));	setvideoreg(Index_VI_Y_Buf_Start_Over,		    ((uint8_t) ((pOverlay->PSY) >> 24) & 0x01));    }    /* Set U/V data if using plane formats */    if ((pOverlay->pixelFormat == IMGFMT_YV12) ||	(pOverlay->pixelFormat == IMGFMT_I420)) {	uint32_t PSU, PSV;	PSU = pOverlay->PSU;	PSV = pOverlay->PSV;	/* Set U/V pitch */	setvideoreg(Index_VI_Disp_UV_Buf_Pitch_Low,		    (uint8_t) (pitch >> 1));	setvideoregmask(Index_VI_Disp_Y_UV_Buf_Pitch_Middle,			(uint8_t) (pitch >> 5), 0xf0);	/* set U/V start address */	setvideoreg(Index_VI_U_Buf_Start_Low, (uint8_t) PSU);	setvideoreg(Index_VI_U_Buf_Start_Middle, (uint8_t) (PSU >> 8));	setvideoreg(Index_VI_U_Buf_Start_High, (uint8_t) (PSU >> 16));	setvideoreg(Index_VI_V_Buf_Start_Low, (uint8_t) PSV);	setvideoreg(Index_VI_V_Buf_Start_Middle, (uint8_t) (PSV >> 8));	setvideoreg(Index_VI_V_Buf_Start_High, (uint8_t) (PSV >> 16));	/* 310/325 series overflow bits */	if (sis_vga_engine == SIS_315_VGA) {	    setvideoreg(Index_VI_Disp_UV_Buf_Pitch_High,			(uint8_t) (pitch >> 13));	    setvideoreg(Index_VI_U_Buf_Start_Over,			((uint8_t) (PSU >> 24) & 0x01));	    setvideoreg(Index_VI_V_Buf_Start_Over,			((uint8_t) (PSV >> 24) & 0x01));	}    }    if (sis_vga_engine == SIS_315_VGA) {	/* Trigger register copy for 310 series */	setvideoreg(Index_VI_Control_Misc3, 1 << index);    }    /* set scale factor */    setvideoreg(Index_VI_Hor_Post_Up_Scale_Low,		(uint8_t) (pOverlay->HUSF));    setvideoreg(Index_VI_Hor_Post_Up_Scale_High,		(uint8_t) ((pOverlay->HUSF) >> 8));    setvideoreg(Index_VI_Ver_Up_Scale_Low, (uint8_t) (pOverlay->VUSF));    setvideoreg(Index_VI_Ver_Up_Scale_High,		(uint8_t) ((pOverlay->VUSF) >> 8));    setvideoregmask(Index_VI_Scale_Control, (pOverlay->IntBit << 3)		    | (pOverlay->wHPre), 0x7f);    /* set destination window position */    setvideoreg(Index_VI_Win_Hor_Disp_Start_Low, (uint8_t) left);    setvideoreg(Index_VI_Win_Hor_Disp_End_Low, (uint8_t) right);    setvideoreg(Index_VI_Win_Hor_Over, (uint8_t) h_over);    setvideoreg(Index_VI_Win_Ver_Disp_Start_Low, (uint8_t) top);    setvideoreg(Index_VI_Win_Ver_Disp_End_Low, (uint8_t) bottom);    setvideoreg(Index_VI_Win_Ver_Over, (uint8_t) v_over);    setvideoregmask(Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a);    /* Lock the address registers */    setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x20);}/* TW: Overlay MUST NOT be switched off while beam is over it */static void close_overlay(void){    uint32_t watchdog;    if ((sis_displaymode == DISPMODE_SINGLE2) ||	(sis_displaymode == DISPMODE_MIRROR)) {	if (sis_has_two_overlays) {	    setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x01);	    watchdog = WATCHDOG_DELAY;	    while (vblank_active_CRT2() && --watchdog);	    watchdog = WATCHDOG_DELAY;	    while ((!vblank_active_CRT2()) && --watchdog);	    setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02);	    watchdog = WATCHDOG_DELAY;	    while (vblank_active_CRT2() && --watchdog);	    watchdog = WATCHDOG_DELAY;	    while ((!vblank_active_CRT2()) && --watchdog);	} else if (sis_displaymode == DISPMODE_SINGLE2) {	    setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01);	    watchdog = WATCHDOG_DELAY;	    while (vblank_active_CRT1() && --watchdog);	    watchdog = WATCHDOG_DELAY;	    while ((!vblank_active_CRT1()) && --watchdog);	    setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02);	    watchdog = WATCHDOG_DELAY;	    while (vblank_active_CRT1() && --watchdog);	    watchdog = WATCHDOG_DELAY;	    while ((!vblank_active_CRT1()) && --watchdog);	}    }    if ((sis_displaymode == DISPMODE_SINGLE1) ||	(sis_displaymode == DISPMODE_MIRROR)) {	setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01);	watchdog = WATCHDOG_DELAY;	while (vblank_active_CRT1() && --watchdog);	watchdog = WATCHDOG_DELAY;	while ((!vblank_active_CRT1()) && --watchdog);	setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02);	watchdog = WATCHDOG_DELAY;	while (vblank_active_CRT1() && --watchdog);	watchdog = WATCHDOG_DELAY;	while ((!vblank_active_CRT1()) && --watchdog);    }}static voidcalc_scale_factor(SISOverlayPtr pOverlay, int index, int iscrt2){    uint32_t i = 0, mult = 0;    int flag = 0;    int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1;    int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1;    int srcW = pOverlay->srcW;    int srcH = pOverlay->srcH;    /*    uint16_t LCDheight = pSiS->LCDheight; */    int srcPitch = pOverlay->origPitch;    int origdstH = dstH;    /* get rid of warnings for now */    index = index;    iscrt2 = iscrt2;    /* TW: For double scan modes, we need to double the height     *     (Perhaps we also need to scale LVDS, but I'm not sure.)     *     On 310/325 series, we need to double the width as well.     *     Interlace mode vice versa.     */    if (sis_vmode & VMODE_DOUBLESCAN) {	dstH = origdstH << 1;	flag = 0;	if (sis_vga_engine == SIS_315_VGA) {	    dstW <<= 1;	}    }    if (sis_vmode & VMODE_INTERLACED) {	dstH = origdstH >> 1;	flag = 0;    }    if (dstW < OVERLAY_MIN_WIDTH)	dstW = OVERLAY_MIN_WIDTH;    if (dstW == srcW) {	pOverlay->HUSF = 0x00;	pOverlay->IntBit = 0x05;	pOverlay->wHPre = 0;    } else if (dstW > srcW) {	dstW += 2;	pOverlay->HUSF = (srcW << 16) / dstW;	pOverlay->IntBit = 0x04;	pOverlay->wHPre = 0;    } else {	int tmpW = dstW;	/* TW: It seems, the hardware can't scale below factor .125 (=1/8) if the	   pitch isn't a multiple of 256.	   TODO: Test this on the 310/325 series!	 */	if ((srcPitch % 256) || (srcPitch < 256)) {	    if (((dstW * 1000) / srcW) < 125)		dstW = tmpW = ((srcW * 125) / 1000) + 1;	}	i = 0;	pOverlay->IntBit = 0x01;	while (srcW >= tmpW) {	    tmpW <<= 1;	    i++;	}	pOverlay->wHPre = (uint8_t) (i - 1);	dstW <<= (i - 1);	if ((srcW % dstW))	    pOverlay->HUSF = ((srcW - dstW) << 16) / dstW;	else	    pOverlay->HUSF = 0x00;    }    if (dstH < OVERLAY_MIN_HEIGHT)	dstH = OVERLAY_MIN_HEIGHT;    if (dstH == srcH) {	pOverlay->VUSF = 0x00;	pOverlay->IntBit |= 0x0A;    } else if (dstH > srcH) {	dstH += 0x02;	pOverlay->VUSF = (srcH << 16) / dstH;	pOverlay->IntBit |= 0x08;    } else {	uint32_t realI;	i = realI = srcH / dstH;	pOverlay->IntBit |= 0x02;	if (i < 2) {	    pOverlay->VUSF = ((srcH - dstH) << 16) / dstH;	    /* TW: Needed for LCD-scaling modes */	    if ((flag) && (mult = (srcH / origdstH)) >= 2)		pOverlay->pitch /= mult;	} else {	    if (((srcPitch * i) >> 2) > 0xFFF) {		i = (0xFFF * 2 / srcPitch);		pOverlay->VUSF = 0xFFFF;	    } else {		dstH = i * dstH;		if (srcH % dstH)		    pOverlay->VUSF = ((srcH - dstH) << 16) / dstH;		else		    pOverlay->VUSF = 0x00;	    }	    /* set video frame buffer offset */	    pOverlay->pitch = (uint16_t) (srcPitch * i);	}    }}static void set_line_buf_size(SISOverlayPtr pOverlay){    uint8_t preHIDF;    uint32_t i;    uint32_t line = pOverlay->srcW;    if ((pOverlay->pixelFormat == IMGFMT_YV12) ||	(pOverlay->pixelFormat == IMGFMT_I420)) {	preHIDF = pOverlay->wHPre & 0x07;	switch (preHIDF) {	case 3:	    if ((line & 0xffffff00) == line)		i = (line >> 8);	    else		i = (line >> 8) + 1;	    pOverlay->lineBufSize = (uint8_t) (i * 32 - 1);	    break;	case 4:	    if ((line & 0xfffffe00) == line)		i = (line >> 9);	    else		i = (line >> 9) + 1;	    pOverlay->lineBufSize = (uint8_t) (i * 64 - 1);	    break;	case 5:	    if ((line & 0xfffffc00) == line)		i = (line >> 10);	    else		i = (line >> 10) + 1;	    pOverlay->lineBufSize = (uint8_t) (i * 128 - 1);	    break;	case 6:	    if ((line & 0xfffff800) == line)		i = (line >> 11);	    else		i = (line >> 11) + 1;	    pOverlay->lineBufSize = (uint8_t) (i * 256 - 1);	    break;	default:	    if ((line & 0xffffff80) == line)		i = (line >> 7);	    else		i = (line >> 7) + 1;	    pOverlay->lineBufSize = (uint8_t) (i * 16 - 1);	    break;	}    } else {			/* YUV2, UYVY */	if ((line & 0xffffff8) == line)	    i = (line >> 3);	else	    i = (line >> 3) + 1;	pOverlay->lineBufSize = (uint8_t) (i - 1);    }}static void merge_line_buf(int enable){    if (enable) {	switch (sis_displaymode) {	case DISPMODE_SINGLE1:	    if (sis_has_two_overlays) {		/* dual line merge */		setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    } else {		setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    }	    break;	case DISPMODE_SINGLE2:	    if (sis_has_two_overlays) {		/* line merge */		setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04);	    } else {		setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    }	    break;	case DISPMODE_MIRROR:	default:	    /* line merge */	    setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11);	    setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04);	    if (sis_has_two_overlays) {		/* line merge */		setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04);	    }	    break;	}    } else {	switch (sis_displaymode) {	case DISPMODE_SINGLE1:	    setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11);	    setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    break;	case DISPMODE_SINGLE2:	    if (sis_has_two_overlays) {		setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    } else {		setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    }	    break;	case DISPMODE_MIRROR:	default:	    setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11);	    setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    if (sis_has_two_overlays) {		setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11);		setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04);	    }	    break;	}    }}static void set_format(SISOverlayPtr pOverlay){    uint8_t fmt;    switch (pOverlay->pixelFormat) {    case IMGFMT_YV12:    case IMGFMT_I420:	fmt = 0x0c;	break;    case IMGFMT_YUY2:	fmt = 0x28;	break;    case IMGFMT_UYVY:	fmt = 0x08;	break;    case IMGFMT_RGB15:		/* D[5:4] : 00 RGB555, 01 RGB 565 */	fmt = 0x00;	break;    case IMGFMT_RGB16:	fmt = 0x10;	break;    default:	fmt = 0x00;	break;    }    setvideoregmask(Index_VI_Control_Misc0, fmt, 0x7c);}static void set_colorkey(void){    uint8_t r, g, b;    b = (uint8_t) sis_grkey.ckey.blue;    g = (uint8_t) sis_grkey.ckey.green;    r = (uint8_t) sis_grkey.ckey.red;    /* set color key mode */    setvideoregmask(Index_VI_Key_Overlay_OP,		    sis_grkey.ckey.op == CKEY_TRUE ?		    VI_ROP_DestKey : VI_ROP_Always, 0x0F);    /* set colorkey values */    setvideoreg(Index_VI_Overlay_ColorKey_Blue_Min, (uint8_t) b);    setvideoreg(Index_VI_Overlay_ColorKey_Green_Min, (uint8_t) g);    setvideoreg(Index_VI_Overlay_ColorKey_Red_Min, (uint8_t) r);    setvideoreg(Index_VI_Overlay_ColorKey_Blue_Max, (uint8_t) b);    setvideoreg(Index_VI_Overlay_ColorKey_Green_Max, (uint8_t) g);    setvideoreg(Index_VI_Overlay_ColorKey_Red_Max, (uint8_t) r);}static void set_brightness(uint8_t brightness){    setvideoreg(Index_VI_Brightness, brightness);}static void set_contrast(uint8_t contrast){    setvideoregmask(Index_VI_Contrast_Enh_Ctrl, contrast, 0x07);}/* Next 3 functions are 310/325 series only */static void set_saturation(char saturation){    uint8_t temp = 0;    if (saturation < 0) {	temp |= 0x88;	saturation = -saturation;    }    temp |= (saturation & 0x07);    temp |= ((saturation & 0x07) << 4);    setvideoreg(Index_VI_Saturation, temp);}static void set_hue(uint8_t hue){    setvideoreg(Index_VI_Hue, (hue & 0x08) ? (hue ^ 0x07) : hue);}VDXDriver sis_drv = {  "sis",  NULL,      .probe = sis_probe,  .get_caps = sis_get_caps,  .query_fourcc = sis_query_fourcc,  .init = sis_init,  .destroy = sis_destroy,  .config_playback = sis_config_playback,  .playback_on = sis_playback_on,  .playback_off = sis_playback_off,  .frame_sel = sis_frame_select,  .get_eq = sis_get_eq,  .set_eq = sis_set_eq,  .get_gkey = sis_get_gkeys,  .set_gkey = sis_set_gkeys,};

⌨️ 快捷键说明

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