vo_vesa.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,140 行 · 第 1/3 页
C
1,140 行
} if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vo_vesa: Mode (%03u): mode=%04X %ux%u@%u attr=%04X\n" "vo_vesa: #planes=%u model=%u(%s) #pages=%u\n" "vo_vesa: winA=%X(attr=%u) winB=%X(attr=%u) winSize=%u winGran=%u\n" "vo_vesa: direct_color=%u DGA_phys_addr=%08lX\n" ,i,mode_ptr[i],vmib.XResolution,vmib.YResolution,vmib.BitsPerPixel,vmib.ModeAttributes ,vmib.NumberOfPlanes,vmib.MemoryModel,model2str(vmib.MemoryModel),vmib.NumberOfImagePages ,vmib.WinASegment,vmib.WinAAttributes,vmib.WinBSegment,vmib.WinBAttributes,vmib.WinSize,vmib.WinGranularity ,vmib.DirectColorModeInfo,vmib.PhysBasePtr); if(vmib.MemoryModel == 6 || vmib.MemoryModel == 7) mp_msg(MSGT_VO,MSGL_V, "vo_vesa: direct_color_info = %u:%u:%u:%u\n" ,vmib.RedMaskSize,vmib.GreenMaskSize,vmib.BlueMaskSize,vmib.RsvdMaskSize); fflush(stdout); } } if(best_mode_idx != UINT_MAX) { video_mode = vib.VideoModePtr[best_mode_idx]; fflush(stdout); if((err=vbeGetMode(&init_mode)) != VBE_OK) { PRINT_VBE_ERR("vbeGetMode",err); return -1; } if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vo_vesa: Initial video mode: %x\n",init_mode); } if((err=vbeGetModeInfo(video_mode,&video_mode_info)) != VBE_OK) { PRINT_VBE_ERR("vbeGetModeInfo",err); return -1; } dstBpp = video_mode_info.BitsPerPixel; mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingVesaMode ,best_mode_idx,video_mode,video_mode_info.XResolution ,video_mode_info.YResolution,dstBpp); if(subdev_flags & SUBDEV_NODGA) video_mode_info.PhysBasePtr = 0; if(use_scaler || fs_mode) { /* software scale */ if(use_scaler > 1#ifdef CONFIG_VIDIX || vidix_name#endif ) { aspect_save_orig(width,height); aspect_save_prescale(d_width,d_height); aspect_save_screenres(video_mode_info.XResolution,video_mode_info.YResolution); aspect(&dstW,&dstH,A_ZOOM); } else if(fs_mode) { dstW = video_mode_info.XResolution; dstH = video_mode_info.YResolution; } use_scaler = 1; } if(!lvo_name#ifdef CONFIG_VIDIX && !vidix_name#endif ) { sws = sws_getContextFromCmdLine(srcW,srcH,srcFourcc,dstW,dstH,dstFourcc); if(!sws) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CantInitializeSwscaler); return -1; } else if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vo_vesa: Using SW BES emulator\n"); } } if((video_mode_info.WinAAttributes & FRAME_MODE) == FRAME_MODE) win.idx = 0; /* frame A */ else if((video_mode_info.WinBAttributes & FRAME_MODE) == FRAME_MODE) win.idx = 1; /* frame B */ else win.idx = -2; /* Try use DGA instead */ if(video_mode_info.PhysBasePtr && vib.TotalMemory && (video_mode_info.ModeAttributes & MODE_ATTR_LINEAR)) { void *lfb; unsigned long vsize; vsize = vib.TotalMemory*64*1024; lfb = vbeMapVideoBuffer(video_mode_info.PhysBasePtr,vsize); if(lfb == NULL) mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CantUseDga); else { video_base = win.ptr = lfb; win.low = 0UL; win.high = vsize; win.idx = -1; /* HAS_DGA() is on */ video_mode |= VESA_MODE_USE_LINEAR; mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingDga ,video_mode_info.PhysBasePtr ,vsize); if( mp_msg_test(MSGT_VO,MSGL_V) ) { printf(" at %08lXh",(unsigned long)lfb); } printf("\n"); if(!(multi_size = fillMultiBuffer(vsize,2))) return -1; if(vo_doublebuffering && multi_size < 2) mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CantUseDoubleBuffering); } } if(win.idx == -2) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantFindNeitherDga); return -1; } if(!HAS_DGA()) { if(subdev_flags & SUBDEV_FORCEDGA) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_YouveForcedDga); return -1; } if(!(win_seg = win.idx == 0 ? video_mode_info.WinASegment:video_mode_info.WinBSegment)) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantFindValidWindowAddress); return -1; } win.ptr = PhysToVirtSO(win_seg,0); win.low = 0L; win.high= video_mode_info.WinSize*1024; mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingBankSwitchingMode ,(unsigned long)win.ptr,(unsigned long)win.high); } if(video_mode_info.XResolution > dstW) x_offset = (video_mode_info.XResolution - dstW) / 2; else x_offset = 0; if(video_mode_info.YResolution > dstH) y_offset = (video_mode_info.YResolution - dstH) / 2; else y_offset = 0; if( mp_msg_test(MSGT_VO,MSGL_V) ) mp_msg(MSGT_VO,MSGL_V, "vo_vesa: image: %ux%u screen = %ux%u x_offset = %u y_offset = %u\n" ,dstW,dstH ,video_mode_info.XResolution,video_mode_info.YResolution ,x_offset,y_offset); if(HAS_DGA()) { dga_buffer = win.ptr; /* Trickly ;) */ cpy_blk_fnc = __vbeCopyBlockFast; } else { cpy_blk_fnc = __vbeCopyBlock; if(!lvo_name#ifdef CONFIG_VIDIX && !vidix_name#endif ) { if(!(dga_buffer = memalign(32,video_mode_info.XResolution*video_mode_info.YResolution*dstBpp))) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantAllocateTemporaryBuffer); return -1; } if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vo_vesa: dga emulator was allocated = %p\n",dga_buffer); } } } if((err=vbeSaveState(&init_state)) != VBE_OK) { PRINT_VBE_ERR("vbeSaveState",err); } /* TODO: user might pass refresh value, GTF constants might be read from monitor for best results, I don't have a spec (RM) */ if (((int)(vib.VESAVersion >> 8) & 0xff) > 2) { if (set_refresh(video_mode_info.XResolution,video_mode_info.YResolution,video_mode,&crtc_pass)) video_mode = video_mode | 0x800; } ; if ((err=vbeSetMode(video_mode,&crtc_pass)) != VBE_OK) { PRINT_VBE_ERR("vbeSetMode",err); return -1; } if (neomagic_tvout) { err = vbeSetTV(video_mode,neomagic_tvnorm); if (err!=0x4f) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_SorryUnsupportedMode); } else { mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_OhYouReallyHavePictureOnTv); } } /* Now we are in video mode!!!*/ /* Below 'return -1' is impossible */ if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vo_vesa: Graphics mode was activated\n"); fflush(stdout); } if(lvo_name) { if(vlvo_init(width,height,x_offset,y_offset,dstW,dstH,format,dstBpp) != 0) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantInitialozeLinuxVideoOverlay); vesa_term(); return -1; } else mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingVideoOverlay,lvo_name); lvo_opened = 1; }#ifdef CONFIG_VIDIX else if(vidix_name) { if(vidix_init(width,height,x_offset,y_offset,dstW, dstH,format,dstBpp, video_mode_info.XResolution,video_mode_info.YResolution) != 0) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantInitializeVidixDriver); vesa_term(); return -1; } else mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_UsingVidix); vidix_start(); /* set colorkey */ if (vidix_grkey_support()) { vidix_grkey_get(&gr_key); gr_key.key_op = KEYS_PUT;#if 0 if (!(vo_colorkey & 0xFF000000)) { gr_key.ckey.op = CKEY_TRUE; gr_key.ckey.red = (vo_colorkey & 0x00FF0000) >> 16; gr_key.ckey.green = (vo_colorkey & 0x0000FF00) >> 8; gr_key.ckey.blue = vo_colorkey & 0x000000FF; } else#endif gr_key.ckey.op = CKEY_FALSE; vidix_grkey_set(&gr_key); } vidix_opened = 1; }#endif } else { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_VESA_CantFindModeFor,width,height,bpp); return -1; } if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_VESA_InitializationComplete); fflush(stdout); } if(HAS_DGA() && vo_doublebuffering) { if (VBE_OK != vbeSetDisplayStart(0, vo_vsync)) { mp_msg(MSGT_VO,MSGL_WARN, "[VO_VESA] Can't use double buffering: changing displays failed.\n"); multi_size = 1; } for(i=0;i<multi_size;i++) { win.ptr = dga_buffer = video_base + multi_buff[i]; clear_screen(); /* Clear screen for stupid BIOSes */ if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) paintBkGnd(); } } else { clear_screen(); /* Clear screen for stupid BIOSes */ if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { int x; x = (video_mode_info.XResolution/video_mode_info.XCharSize)/2-strlen(title)/2; if(x < 0) x = 0; paintBkGnd(); vbeWriteString(x,0,7,title); } } return 0;}static voiduninit(void){ // not inited vesa_term(); if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_vesa: uninit was called\n");}static void check_events(void){ if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_vesa: check_events was called\n");/* Nothing to do */}static int preinit(const char *arg){ int pre_init_err = 0; int fd; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) mp_msg(MSGT_VO,MSGL_DBG2, "vo_vesa: preinit(%s) was called\n",arg); if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_vesa: subdevice %s is being initialized\n",arg); subdev_flags = 0; lvo_name = NULL;#ifdef CONFIG_VIDIX vidix_name = NULL;#endif if(arg) subdev_flags = parseSubDevice(arg); if(lvo_name) pre_init_err = vlvo_preinit(lvo_name);#ifdef CONFIG_VIDIX else if(vidix_name) pre_init_err = vidix_preinit(vidix_name,&video_out_vesa);#endif // check if we can open /dev/mem (it will be opened later in config(), but if we // detect now that we can't we can exit cleanly) fd = open("/dev/mem", O_RDWR); if (fd < 0) return -1; else close(fd); if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_subdevice: initialization returns: %i\n",pre_init_err); return pre_init_err;}static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); }#ifdef CONFIG_VIDIX if (vidix_name) { switch (request) { case VOCTRL_SET_EQUALIZER: { va_list ap; int value; va_start(ap, data); value = va_arg(ap, int); va_end(ap); return vidix_control(request, data, (int *)value); } case VOCTRL_GET_EQUALIZER: { va_list ap; int *value; va_start(ap, data); value = va_arg(ap, int*); va_end(ap); return vidix_control(request, data, value); } } return vidix_control(request, data); }#endif return VO_NOTIMPL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?