vo_svga.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 755 行 · 第 1/2 页
C
755 行
/* Video driver for SVGAlib by Zoltan Mark Vician <se7en@sch.bme.hu> Code started: Mon Apr 1 23:25:47 2001 Some changes by Matan Ziv-Av <matan@svgalib.org> Compleat rewrite by Ivan Kalvachev 19 Mar 2003:Wrangings: - 1bpp doesn't work right for me with '-double' and svgalib 1.4.3, but works OK with svgalib 1.9.17 - The HW acceleration is not tested - svgalibs supports few chipsets, and i don't have any of them. If it works for you then let me know. I will remove this warning after confirm its status. - retrace sync works only in doublebuffer mode. - the retrace sync may slow down decoding a lot - mplayer is blocked while waiting for retrace - denoise3d fails to find common colorspace, use -vf denoise3d,scale TODO: - let choose_best_mode take aspect into account - set palette from mpi->palette or mpi->plane[1] - make faster OSD black bars clear - need some OSD changes - Make nicer CONFIG parsing - change video mode logical width to match img->stride[0] - for HW only */#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <vga.h>#include "config.h"#include "video_out.h"#include "video_out_internal.h"#include "fastmemcpy.h"#include "osdep/getch2.h"#ifdef CONFIG_VIDIX#include "vosub_vidix.h"#endif#include "sub.h"#include "mp_msg.h"#include "help_mp.h"//#include "mp_image.h"#include <assert.h>//silence warnings, probably it have to go in some global header#define UNUSED(x) ((void)(x)) static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride);static uint32_t get_image(mp_image_t *mpi);#define MAXPAGES 16#define PAGE_EMPTY 0#define PAGE_BUSY 1#define CAP_ACCEL_CLEAR 8#define CAP_ACCEL_PUTIMAGE 4#define CAP_ACCEL_BACKGR 2#define CAP_LINEAR 1static uint8_t zerobuf[8192];//used when clear screen with vga_drawstatic int squarepix;static int force_vm=0;static int force_native=0;static int sync_flip=0;static int blackbar_osd=0;static int cpage,max_pages,old_page;static vga_modeinfo * modeinfo;static int mode_stride; //keep it in case of vga_setlogicalwidthstatic int stride_granularity; //not yet usedstatic int mode_bpp;static int mode_capabilities;static int image_width,image_height; // used by OSDstatic int x_pos, y_pos;static struct { int yoffset;//y position of the page int doffset;//display start of the page void * vbase;//memory start address of the page int locks;}PageStore[MAXPAGES];static vo_info_t info = { "SVGAlib", "svga", "Ivan Kalvachev <iive@users.sf.net>", ""};#ifdef CONFIG_VIDIXstatic char vidix_name[32] = "";static vidix_grkey_t gr_key;#endifLIBVO_EXTERN(svga)//return number of 1'st free page or -1 if no free onestatic inline int page_find_free(void){int i; for(i=0;i<max_pages;i++) if(PageStore[i].locks == PAGE_EMPTY) return i; return -1;}static int preinit(const char *arg){int i;char s[64]; getch2_disable(); memset(zerobuf,0,sizeof(zerobuf)); force_vm=force_native=squarepix=0; sync_flip=vo_vsync; blackbar_osd=0; if(arg)while(*arg) {#ifdef CONFIG_VIDIX if(memcmp(arg,"vidix",5)==0) { i=6; while(arg[i] && arg[i]!=':') i++; strncpy(vidix_name, arg+6, i-6); vidix_name[i-5]=0; if(arg[i]==':')i++; arg+=i; vidix_preinit(vidix_name, &video_out_svga); }#endif if(!strncmp(arg,"sq",2)) { squarepix=1; arg+=2; if( *arg == ':' ) arg++; } if(!strncmp(arg,"native",6)) { force_native=1; arg+=6; if( *arg == ':' ) arg++; } if(!strncmp(arg,"bbosd",5)) { blackbar_osd=1; arg+=5; if( *arg == ':' ) arg++; } if(!strncmp(arg,"retrace",7)) { sync_flip=1; arg+=7; if( *arg == ':' ) arg++; } if(*arg) { i=0; while(arg[i] && arg[i]!=':')i++; if(i<64){ strncpy(s, arg, i); s[i]=0; force_vm=vga_getmodenumber(s); if(force_vm>0) { if( mp_msg_test(MSGT_VO,MSGL_V) ) mp_msg(MSGT_VO,MSGL_V, "vo_svga: Forcing mode %i\n",force_vm); }else{ force_vm = 0; } } arg+=i; if(*arg==':')arg++; } } vga_init(); return 0;}static void svga_clear_box(int x,int y,int w,int h){uint8_t * rgbplane;int i; if (mode_capabilities&CAP_ACCEL_CLEAR){ if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: clearing box %d,%d - %d,%d with HW acceleration\n", x,y,w,h); if(mode_capabilities&CAP_ACCEL_BACKGR) vga_accel(ACCEL_SYNC); vga_accel(ACCEL_SETFGCOLOR,0);//black vga_accel(ACCEL_FILLBOX,x,y,w,h); return; } if (mode_capabilities & CAP_LINEAR){ if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: clearing box %d,%d - %d,%d with memset\n",x,y,w,h); rgbplane=PageStore[0].vbase + (y*mode_stride) + (x*modeinfo->bytesperpixel); for(i=0;i<h;i++){//i'm afraid that memcpy is better optimized than memset;) fast_memcpy(rgbplane,zerobuf,w*modeinfo->bytesperpixel);// memset(rgbplane,0,w*modeinfo->bytesperpixel); rgbplane+=mode_stride; } return; } //native if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: clearing box %d,%d - %d,%d with native draw \n",x,y,w,h); if(modeinfo->bytesperpixel!=0) w*=modeinfo->bytesperpixel; for(i=0;i<h;i++){ vga_drawscansegment(zerobuf,x,y+i,w); }};static uint32_t svga_draw_image(mp_image_t *mpi){int i,x,y,w,h;int stride;uint8_t *rgbplane, *base;int bytesperline;int page; if(mpi->flags & MP_IMGFLAG_DIRECT){ if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: drawing direct rendered surface\n"); cpage=(uint32_t)mpi->priv; assert((cpage>=0)&&(cpage<max_pages)); return VO_TRUE; //it's already done }// if (mpi->flags&MP_IMGFLAGS_DRAWBACK) // return VO_TRUE;//direct render method 2//find a free page to draw into//if there is no one then use the current one page = page_find_free(); if(page>=0) cpage=page; PageStore[cpage].locks=PAGE_BUSY;// these variables are used in loops x = mpi->x; y = mpi->y; w = mpi->w; h = mpi->h; stride = mpi->stride[0]; rgbplane = mpi->planes[0] + y*stride + (x*mpi->bpp)/8; x+=x_pos;//center y+=y_pos; if(mpi->bpp >= 8){//for modes<8 use only native if( (mode_capabilities&CAP_ACCEL_PUTIMAGE) && (x==0) && (w==mpi->width) && (stride == mode_stride) ){ //only monolite image can be accelerated w=(stride*8)/mpi->bpp;//we transfer pixels in the stride so the source//ACCELERATE if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: using HW PutImage (x=%d,y=%d,w=%d,h=%d)\n",x,y,w,h); if(mode_capabilities & CAP_ACCEL_BACKGR) vga_accel(ACCEL_SYNC); vga_accel(ACCEL_PUTIMAGE,x,y+PageStore[cpage].yoffset,w,h,rgbplane); return VO_TRUE; } if( mode_capabilities&CAP_LINEAR){//DIRECT if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: using Direct memcpy (x=%d,y=%d,w=%d,h=%d)\n",x,y,w,h); bytesperline=(w*mpi->bpp)/8; base=PageStore[cpage].vbase + (y*mode_stride) + (x*mpi->bpp)/8; for(i=0;i<h;i++){ mem2agpcpy(base,rgbplane,bytesperline); base+=mode_stride; rgbplane+=stride; } return VO_TRUE; } }//(modebpp>=8 //NATIVE { int length; length=(w*mpi->bpp)/8; //one byte per pixel! svgalib innovation if(mpi->imgfmt==IMGFMT_RG4B || mpi->imgfmt==IMGFMT_BG4B) length=w; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: using Native vga_draw(x=%d,y=%d,w=%d,h=%d)\n",x,y,w,h); y+=PageStore[cpage].yoffset;//y position of the page beggining for(i=0;i<h;i++){ vga_drawscansegment(rgbplane,x,y+i,length); rgbplane+=stride; } } return VO_TRUE;}static int bpp_from_vminfo(vga_modeinfo *vminfo){ switch(vminfo->colors){ case 2: return 1; case 16: return 4; case 256: return 8; case 32768: return 15; case 65536: return 16; case 1<<24: return 8*vminfo->bytesperpixel; } return 0;}static int find_best_svga_mode(int req_w,int req_h, int req_bpp){ int badness,prev_badness; int bestmode,lastmode; int i; vga_modeinfo *vminfo;//int best aspect mode // best linear mode // best normal mode (no modeX) prev_badness = 0;//take care of special case below bestmode = 0; //0 is the TEXT mode lastmode = vga_lastmodenumber(); for(i=1;i<=lastmode;i++){ vminfo = vga_getmodeinfo(i); if( vminfo == NULL ) continue; if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) mp_msg(MSGT_VO,MSGL_DBG4, "vo_svga: testing mode %d (%s)\n",i,vga_getmodename(i)); if( vga_hasmode(i) == 0 ) continue; if( req_bpp != bpp_from_vminfo(vminfo) )continue; if( (vminfo->width < req_w) || (vminfo->height < req_h) ) continue; badness=(vminfo->width * vminfo->height) - (req_h * req_w); //put here aspect calculations if(squarepix) if( vminfo->width*3 != vminfo->height*4 ) continue; if( bestmode==0 || prev_badness >= badness ){//modeX etc... prev_badness=badness; bestmode=i; if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) mp_msg(MSGT_VO,MSGL_DBG4, "vo_svga: found good mode %d with badness %d\n",i,badness); } } return bestmode;}static int control(uint32_t request, void *data, ...){ switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_DRAW_IMAGE: return svga_draw_image( (mp_image_t *)data); case VOCTRL_GET_IMAGE: return get_image(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, value); } case VOCTRL_GET_EQUALIZER: { va_list ap; int *value;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?