sis_vid.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,514 行 · 第 1/3 页
C
1,514 行
setsrregmask(0x06, 0x80, 0xc0); setsrregmask(0x32, 0x80, 0xc0); } else { setsrregmask(0x06, 0x40, 0xc0); setsrregmask(0x32, 0x40, 0xc0); } break; case DISPMODE_MIRROR: /* TW: CRT1 + CRT2 */ default: if (sis_verbose > 2) { printf("[SiS] Setting up overlay on CRT1 AND CRT2!\n"); } setsrregmask(0x06, 0x80, 0xc0); setsrregmask(0x32, 0x80, 0xc0); break; }}static void init_overlay(void){ /* Initialize first overlay (CRT1) */ /* Write-enable video registers */ setvideoregmask(Index_VI_Control_Misc2, 0x80, 0x81); /* Disable overlay */ setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); /* Disable bobEnable */ setvideoregmask(Index_VI_Control_Misc1, 0x02, 0x02); /* Reset scale control and contrast */ setvideoregmask(Index_VI_Scale_Control, 0x60, 0x60); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); setvideoreg(Index_VI_Play_Threshold_Low, 0x00); setvideoreg(Index_VI_Play_Threshold_High, 0x00); /* may not want to init these here, could already be set to other values by app? */ setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); setvideoreg(Index_VI_Brightness, 0x20); if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Hue, 0x00); setvideoreg(Index_VI_Saturation, 0x00); } /* Initialize second overlay (CRT2) */ if (sis_has_two_overlays) { /* Write-enable video registers */ setvideoregmask(Index_VI_Control_Misc2, 0x81, 0x81); /* Disable overlay */ setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); /* Disable bobEnable */ setvideoregmask(Index_VI_Control_Misc1, 0x02, 0x02); /* Reset scale control and contrast */ setvideoregmask(Index_VI_Scale_Control, 0x60, 0x60); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); setvideoreg(Index_VI_Play_Threshold_Low, 0x00); setvideoreg(Index_VI_Play_Threshold_High, 0x00); setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x01); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); setvideoreg(Index_VI_Brightness, 0x20); if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Hue, 0x00); setvideoreg(Index_VI_Saturation, 0x00); } }}static int sis_set_eq(const vidix_video_eq_t * eq);static int sis_config_playback(vidix_playback_t * info){ SISOverlayRec overlay; int srcOffsetX = 0, srcOffsetY = 0; int sx, sy; int index = 0, iscrt2 = 0; int total_size; short src_w, drw_w; short src_h, drw_h; short src_x, drw_x; short src_y, drw_y; long dga_offset; int pitch; unsigned int i; if (!is_supported_fourcc(info->fourcc)) return -1; /* set chipset/engine.dependent config info */ /* which CRT to use, etc.? */ switch (sis_vga_engine) { case SIS_315_VGA: sis_shift_value = 1; sis_equal.cap |= VEQ_CAP_SATURATION | VEQ_CAP_HUE; break; case SIS_300_VGA: default: sis_shift_value = 2; break; } sis_displaymode = DISPMODE_SINGLE1; /* xV driver code in set_dispmode() */ set_dispmode(); set_disptype_regs(); init_overlay(); /* get basic dimension info */ src_x = info->src.x; src_y = info->src.y; src_w = info->src.w; src_h = info->src.h; drw_x = info->dest.x; drw_y = info->dest.y; drw_w = info->dest.w; drw_h = info->dest.h; switch (info->fourcc) { case IMGFMT_YV12: case IMGFMT_I420: pitch = (src_w + 7) & ~7; total_size = (pitch * src_h * 3) >> 1; break; case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_RGB15: case IMGFMT_RGB16: pitch = ((src_w << 1) + 3) & ~3; total_size = pitch * src_h; break; default: return -1; } /* "allocate" memory for overlay! */ /* start at 8MB = sisfb's "dri reserved space" - really shouldn't hardcode though */ /* XXX: JCP - this can use the sisfb FBIO_ALLOC ioctl to safely allocate "video heap" memory... */ dga_offset = 0x800000; /* use 7MB for now. need to calc/get real info from sisfb? */ /* this can result in a LOT of frames - probably not necessary */ info->num_frames = 0x700000 / (total_size * 2); if (info->num_frames > VID_PLAY_MAXFRAMES) info->num_frames = VID_PLAY_MAXFRAMES; info->dga_addr = sis_mem_base + dga_offset; info->dest.pitch.y = 16; info->dest.pitch.u = 16; info->dest.pitch.v = 16; info->offset.y = 0; info->offset.u = 0; info->offset.v = 0; info->frame_size = (total_size * 2); /* why times 2 ? */ for (i = 0; i < info->num_frames; i++) { info->offsets[i] = info->frame_size * i; /* save ptrs to mem buffers */ sis_frames[i] = (dga_offset + info->offsets[i]); } memset(&overlay, 0, sizeof(overlay)); overlay.pixelFormat = sis_format = info->fourcc; overlay.pitch = overlay.origPitch = pitch; overlay.keyOP = (sis_grkey.ckey.op == CKEY_TRUE ? VI_ROP_DestKey : VI_ROP_Always); overlay.bobEnable = 0x00; overlay.SCREENheight = sis_screen_height; /* probably will not support X virtual screen > phys very well? */ overlay.dstBox.x1 = drw_x; /* - pScrn->frameX0; */ overlay.dstBox.x2 = drw_x + drw_w; /* - pScrn->frameX0; ??? */ overlay.dstBox.y1 = drw_y; /* - pScrn->frameY0; */ overlay.dstBox.y2 = drw_y + drw_h; /* - pScrn->frameY0; ??? */ if ((overlay.dstBox.x1 > overlay.dstBox.x2) || (overlay.dstBox.y1 > overlay.dstBox.y2)) return -1; if ((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) return -1; if (overlay.dstBox.x1 < 0) { srcOffsetX = src_w * (-overlay.dstBox.x1) / drw_w; overlay.dstBox.x1 = 0; } if (overlay.dstBox.y1 < 0) { srcOffsetY = src_h * (-overlay.dstBox.y1) / drw_h; overlay.dstBox.y1 = 0; } switch (info->fourcc) { case IMGFMT_YV12: info->dest.pitch.y = 16; sx = (src_x + srcOffsetX) & ~7; sy = (src_y + srcOffsetY) & ~1; info->offset.y = sis_Yoff = sx + sy * pitch; /* JCP: NOTE reversed u & v here! Not sure why this is needed. maybe mplayer & sis define U & V differently?? */ info->offset.u = sis_Voff = src_h * pitch + ((sx + sy * pitch / 2) >> 1); info->offset.v = sis_Uoff = src_h * pitch * 5 / 4 + ((sx + sy * pitch / 2) >> 1); overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; overlay.PSV = (sis_frames[0] + sis_Voff) >> sis_shift_value; overlay.PSU = (sis_frames[0] + sis_Uoff) >> sis_shift_value; break; case IMGFMT_I420: sx = (src_x + srcOffsetX) & ~7; sy = (src_y + srcOffsetY) & ~1; info->offset.y = sis_Yoff = sx + sy * pitch; /* JCP: see above... */ info->offset.u = sis_Voff = src_h * pitch * 5 / 4 + ((sx + sy * pitch / 2) >> 1); info->offset.v = sis_Uoff = src_h * pitch + ((sx + sy * pitch / 2) >> 1); overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; overlay.PSV = (sis_frames[0] + sis_Voff) >> sis_shift_value; overlay.PSU = (sis_frames[0] + sis_Uoff) >> sis_shift_value; break; case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_RGB16: case IMGFMT_RGB15: default: sx = (src_x + srcOffsetX) & ~1; sy = (src_y + srcOffsetY); info->offset.y = sis_Yoff = sx * 2 + sy * pitch; overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; break; } /* FIXME: is it possible that srcW < 0? */ overlay.srcW = src_w - (sx - src_x); overlay.srcH = src_h - (sy - src_y); /* set merge line buffer */ merge_line_buf(overlay.srcW > 384); /* calculate line buffer length */ set_line_buf_size(&overlay); if (sis_displaymode == DISPMODE_SINGLE2) { if (sis_has_two_overlays) { /* TW: On chips with two overlays we use * overlay 2 for CRT2 */ index = 1; iscrt2 = 1; } else { /* TW: On chips with only one overlay we * use that only overlay for CRT2 */ index = 0; iscrt2 = 1; } overlay.VBlankActiveFunc = vblank_active_CRT2; /* overlay.GetScanLineFunc = get_scanline_CRT2; */ } else { index = 0; iscrt2 = 0; overlay.VBlankActiveFunc = vblank_active_CRT1; /* overlay.GetScanLineFunc = get_scanline_CRT1; */ } /* calc scale factor (to use below) */ calc_scale_factor(&overlay, index, iscrt2); /* Select video1 (used for CRT1) or video2 (used for CRT2) */ setvideoregmask(Index_VI_Control_Misc2, index, 0x01); set_format(&overlay); set_colorkey(); sis_set_eq(&sis_equal); /* set up video overlay registers */ set_overlay(&overlay, index); /* prevent badness if bits are not at default setting */ setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x01); setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x04); /* JCP: Xv driver implementation loops back over above code to setup mirror CRT2 */ return 0;}static int sis_playback_on(void){ setvideoregmask(Index_VI_Control_Misc0, 0x02, 0x02); return 0;}static int sis_playback_off(void){ unsigned char sridx, cridx; sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); close_overlay(); outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); return 0;}static int sis_frame_select(unsigned int frame){ uint8_t data; int index = 0; uint32_t PSY; if (sis_displaymode == DISPMODE_SINGLE2 && sis_has_two_overlays) { index = 1; } PSY = (sis_frames[frame] + sis_Yoff) >> sis_shift_value; /* 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 start address */ setvideoreg(Index_VI_Disp_Y_Buf_Start_Low, (uint8_t) (PSY)); setvideoreg(Index_VI_Disp_Y_Buf_Start_Middle, (uint8_t) ((PSY) >> 8)); setvideoreg(Index_VI_Disp_Y_Buf_Start_High, (uint8_t) ((PSY) >> 16)); /* set 310/325 series overflow bits for Y plane */ if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Y_Buf_Start_Over, ((uint8_t) ((PSY) >> 24) & 0x01)); } /* Set U/V data if using plane formats */ if ((sis_format == IMGFMT_YV12) || (sis_format == IMGFMT_I420)) { uint32_t PSU, PSV; PSU = (sis_frames[frame] + sis_Uoff) >> sis_shift_value; PSV = (sis_frames[frame] + sis_Voff) >> sis_shift_value; /* 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_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); } /* Lock the address registers */ setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x20); return 0;}static int sis_get_gkeys(vidix_grkey_t * grkey){ memcpy(grkey, &sis_grkey, sizeof(vidix_grkey_t)); return 0;}static int sis_set_gkeys(const vidix_grkey_t * grkey){ memcpy(&sis_grkey, grkey, sizeof(vidix_grkey_t)); set_colorkey(); return 0;}static int sis_get_eq(vidix_video_eq_t * eq){ memcpy(eq, &sis_equal, sizeof(vidix_video_eq_t)); return 0;}static int sis_set_eq(const vidix_video_eq_t * eq){ int br, sat, cr, hue; if (eq->cap & VEQ_CAP_BRIGHTNESS) sis_equal.brightness = eq->brightness; if (eq->cap & VEQ_CAP_CONTRAST) sis_equal.contrast = eq->contrast; if (eq->cap & VEQ_CAP_SATURATION) sis_equal.saturation = eq->saturation; if (eq->cap & VEQ_CAP_HUE) sis_equal.hue = eq->hue; if (eq->cap & VEQ_CAP_RGB_INTENSITY) { sis_equal.red_intensity = eq->red_intensity; sis_equal.green_intensity = eq->green_intensity; sis_equal.blue_intensity = eq->blue_intensity; } sis_equal.flags = eq->flags; cr = (sis_equal.contrast + 1000) * 7 / 2000; if (cr < 0) cr = 0; if (cr > 7) cr = 7; br = sis_equal.brightness * 127 / 1000; if (br < -128) br = -128; if (br > 127) br = 127; sat = (sis_equal.saturation * 7) / 1000; if (sat < -7) sat = -7; if (sat > 7) sat = 7; hue = sis_equal.hue * 7 / 1000; if (hue < -8) hue = -8; if (hue > 7) hue = 7; set_brightness(br); set_contrast(cr); if (sis_vga_engine == SIS_315_VGA) { set_saturation(sat); set_hue(hue); } return 0;}static void set_overlay(SISOverlayPtr pOverlay, int index){ uint16_t pitch = 0; uint8_t h_over = 0, v_over = 0; uint16_t top, bottom, left, right; uint16_t screenX = sis_screen_width; uint16_t screenY = sis_screen_height; uint8_t data; uint32_t watchdog; top = pOverlay->dstBox.y1; bottom = pOverlay->dstBox.y2; if (bottom > screenY) { bottom = screenY; } left = pOverlay->dstBox.x1; right = pOverlay->dstBox.x2; if (right > screenX) { right = screenX; } /* JCP: these aren't really tested... */ /* TW: DoubleScan modes require Y coordinates * 2 */ if (sis_vmode & VMODE_DOUBLESCAN) { top <<= 1; bottom <<= 1; } /* TW: Interlace modes require Y coordinates / 2 */ if (sis_vmode & VMODE_INTERLACED) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?