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