vo_svga.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 755 行 · 第 1/2 页
C
755 行
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;}//// This function is called to init the video driver for specific mode//static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { int32_t req_w = width;// (d_width > 0 ? d_width : width); int32_t req_h = height;// (d_height > 0 ? d_height : height); uint16_t vid_mode = 0; int32_t req_bpp; uint32_t accflags; if( mp_msg_test(MSGT_VO,MSGL_V) ) mp_msg(MSGT_VO,MSGL_V, "vo_svga: config(%i, %i, %i, %i, %08x, %s, %08x)\n", width, height, d_width, d_height, flags, title, format);//Only RGB modes supported if (!IMGFMT_IS_RGB(format) && !IMGFMT_IS_BGR(format)) {assert(0);return -1;} req_bpp = IMGFMT_BGR_DEPTH(format); if( vo_dbpp!=0 && vo_dbpp!=req_bpp) {assert(0);return-1;} if(!force_vm) { if ( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "vo_svga: Looking for the best resolution...\n"); mp_msg(MSGT_VO,MSGL_V, "vo_svga: req_w: %d, req_h: %d, bpp: %d\n",req_w,req_h,req_bpp); } vid_mode=find_best_svga_mode(req_w,req_h,req_bpp); if(vid_mode==0) return 1; modeinfo=vga_getmodeinfo(vid_mode); }else{//force_vm vid_mode=force_vm; if(vga_hasmode(vid_mode) == 0){ mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_ForcedVidmodeNotAvailable, vid_mode,vga_getmodename(vid_mode)); return 1; //error; } modeinfo=vga_getmodeinfo(vid_mode); if( (modeinfo->width < req_w) || (modeinfo->height < req_h) ){ mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_ForcedVidmodeTooSmall, vid_mode,vga_getmodename(vid_mode)); return 1; } } mode_bpp=bpp_from_vminfo(modeinfo); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_Vidmode, vid_mode,modeinfo->width,modeinfo->height,mode_bpp); if (vga_setmode(vid_mode) == -1) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SVGA_VgasetmodeFailed,vid_mode); uninit(); return 1; // error } /* set 332 palette for 8 bpp */ if(mode_bpp==8){ int i; for(i=0; i<256; i++) vga_setpalette(i, ((i>>5)&7)*9, ((i>>2)&7)*9, (i&3)*21); } /* set 121 palette for 4 bpp */ else if(mode_bpp==4){ int i; for(i=0; i<16; i++) vga_setpalette(i, ((i>>3)&1)*63, ((i>>1)&3)*21, (i&1)*63); } //if we change the logical width, we should know the granularity stride_granularity=8;//according to man vga_logicalwidth if(modeinfo->flags & EXT_INFO_AVAILABLE){ stride_granularity=modeinfo->linewidth_unit; } //look for hardware acceleration mode_capabilities=0;//NATIVE; if(!force_native){//if we want to use only native drawers if(modeinfo->flags & HAVE_EXT_SET){//support for hwaccel interface accflags=vga_ext_set(VGA_EXT_AVAILABLE,VGA_AVAIL_ACCEL); if(accflags & ACCELFLAG_FILLBOX) // clear screen mode_capabilities|=CAP_ACCEL_CLEAR; if(accflags & ACCELFLAG_PUTIMAGE)//support for mem->vid transfer mode_capabilities|=CAP_ACCEL_PUTIMAGE; if((accflags & ACCELFLAG_SETMODE) && (accflags & ACCELFLAG_SYNC)){ vga_accel(ACCEL_SETMODE,BLITS_IN_BACKGROUND); mode_capabilities|=CAP_ACCEL_BACKGR;//can draw in backgraund } } if(modeinfo->flags & IS_LINEAR){ mode_capabilities|=CAP_LINEAR; //don't use bank & vga_draw } else{ if(modeinfo->flags & CAPABLE_LINEAR){ int vid_mem_size; vid_mem_size = vga_setlinearaddressing(); if(vid_mem_size != -1){ modeinfo=vga_getmodeinfo(vid_mode);//sometimes they change parameters mode_capabilities|=CAP_LINEAR; } } } }//fi force native if(mode_capabilities&CAP_LINEAR){ mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_VideoModeIsLinearAndMemcpyCouldBeUsed); } if(mode_capabilities&CAP_ACCEL_PUTIMAGE){ mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_VideoModeHasHardwareAcceleration); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_IfItWorksForYouIWouldLikeToKnow); } //here is the place to handle strides for accel_ modes; mode_stride=modeinfo->linewidth;//we may try to set a bigger stride for video mode that will match the mpi->stride, //this way we will transfer more data, but HW put_image can do it in backgraund!//now let's see how many pages we can use max_pages = modeinfo->maxpixels/(modeinfo->height * modeinfo->width); if(max_pages > MAXPAGES) max_pages = MAXPAGES; if(!vo_doublebuffering) max_pages=1;//fill PageStore structs { int i; uint8_t * GRAPH_MEM; int dof; GRAPH_MEM=vga_getgraphmem(); for(i=0;i<max_pages;i++){ //calculate display offset dof = i * modeinfo->height * modeinfo->width; if(modeinfo->bytesperpixel != 0) dof*=modeinfo->bytesperpixel; //check video chip limitations if( dof != (dof & modeinfo->startaddressrange) ){ max_pages=i;//page 0 will never come here break; } PageStore[i].yoffset = i * modeinfo->height;//starting y offset PageStore[i].vbase = GRAPH_MEM + i*modeinfo->height*mode_stride; //memory base address PageStore[i].doffset = dof; //display offset PageStore[i].locks = PAGE_EMPTY; } } assert(max_pages>0); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_VideoModeHas,max_pages); //15bpp if(modeinfo->bytesperpixel!=0) vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * modeinfo->bytesperpixel); else vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * mode_bpp / 8); cpage=old_page=0; svga_clear_box(0,0,modeinfo->width,modeinfo->height * max_pages); image_height=req_h; image_width=req_w; x_pos = (modeinfo->width - req_w) / 2; y_pos = (modeinfo->height - req_h) / 2; x_pos &= ~(15); //align x offset position to 16 pixels mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_CenteringImageStartAt,x_pos,y_pos);#ifdef CONFIG_VIDIX if(vidix_name[0]){ vidix_init(width, height, x_pos, y_pos, modeinfo->width, modeinfo->height, format, mode_bpp, modeinfo->width,modeinfo->height); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SVGA_UsingVidix,width,height, modeinfo->width,modeinfo->height); vidix_start(); /*set colorkey*/ if(vidix_grkey_support()){ vidix_grkey_get(&gr_key); gr_key.key_op = KEYS_PUT; 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 gr_key.ckey.op = CKEY_FALSE; vidix_grkey_set(&gr_key); } }#endif vga_setdisplaystart(0); return (0);}static int draw_slice(uint8_t *image[],int stride[], int w, int h, int x, int y) {assert(0);UNUSED(image);UNUSED(stride);UNUSED(w);UNUSED(h);UNUSED(x);UNUSED(y); return VO_ERROR;//this is yv12 only -> vf_scale should do all transforms}static int draw_frame(uint8_t *src[]) {assert(0);UNUSED(src); return VO_ERROR;//this one should not be called}static void draw_osd(void){ if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) mp_msg(MSGT_VO,MSGL_DBG4, "vo_svga: draw_osd()\n"); //only modes with bytesperpixel>0 can draw OSD if(modeinfo->bytesperpixel==0) return; if(!(mode_capabilities&CAP_LINEAR)) return;//force_native will remove OSD if(blackbar_osd){//111//3 4//222 svga_clear_box(0,0 + PageStore[cpage].yoffset, modeinfo->width, y_pos); svga_clear_box(0, image_height + y_pos + PageStore[cpage].yoffset, modeinfo->width, modeinfo->height-(image_height+ y_pos)); svga_clear_box(0, y_pos + PageStore[cpage].yoffset, x_pos, image_height); svga_clear_box(image_width + x_pos, y_pos + PageStore[cpage].yoffset, modeinfo->width-(x_pos+image_width), image_height);// vo_remove_text(modeinfo->width, modeinfo->height, clear_alpha); vo_draw_text(modeinfo->width, modeinfo->height, draw_alpha); }else{ vo_draw_text(image_width, image_height, draw_alpha); }}static void flip_page(void) { PageStore[old_page].locks=PAGE_EMPTY; PageStore[cpage].locks=PAGE_BUSY; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: viewing page %d\n",cpage); if(sync_flip && old_page!=cpage){ if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga:vga_waitretrace\n"); vga_waitretrace(); } vga_setdisplaystart(PageStore[cpage].doffset); old_page=cpage;//cpage will be overwriten on next draw_image}static void check_events(void) {}static void uninit(void) {#ifdef CONFIG_VIDIX if(vidix_name[0])vidix_term();#endif vga_setmode(TEXT);}/* --------------------------------------------------------------------- */static int query_format(uint32_t format) {int32_t req_bpp,flags;int i,lastmode;vga_modeinfo * vminfo; if ( mp_msg_test(MSGT_VO,MSGL_DBG4) ) mp_msg(MSGT_VO,MSGL_DBG4, "vo_svga: query_format=%X \n",format);//only RGB modes supported if( (!IMGFMT_IS_RGB(format)) && (!IMGFMT_IS_BGR(format)) ) return 0; // Reject different endian#ifdef WORDS_BIGENDIAN if (IMGFMT_IS_BGR(format)) return 0;#else if (IMGFMT_IS_RGB(format)) return 0;#endif //svgalib supports only BG4B! if we want BGR4 we have to emulate it (sw) if( format==IMGFMT_BGR4 || format==IMGFMT_RGB4) return 0; req_bpp = IMGFMT_RGB_DEPTH(format); if( vo_dbpp>0 && vo_dbpp!=req_bpp ) return 0; //support -bpp options//scan all modes lastmode = vga_lastmodenumber(); for(i=1;i<=lastmode;i++){ vminfo = vga_getmodeinfo(i); if( vminfo == NULL ) continue; if( vga_hasmode(i) == 0 ) continue; if( req_bpp != bpp_from_vminfo(vminfo) ) continue; if( (force_vm > 0) && (force_vm != i) ) continue;//quick hack flags = VFCAP_CSP_SUPPORTED| VFCAP_CSP_SUPPORTED_BY_HW| VFCAP_ACCEPT_STRIDE| 0; if(req_bpp>8) flags|=VFCAP_OSD; return flags; } return 0;}static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { char* base; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: draw_alpha(x0=%d,y0=%d,w=%d,h=%d,src=%p,srca=%p,stride=%d\n", x0,y0,w,h,src,srca,stride); if(!blackbar_osd) { //drawing in the image, so place the stuff there x0+=x_pos; y0+=y_pos; } if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) mp_msg(MSGT_VO,MSGL_DBG4, "vo_svga: OSD draw in page %d\n",cpage); base=PageStore[cpage].vbase + y0*mode_stride + x0*modeinfo->bytesperpixel; switch (mode_bpp) { case 32: vo_draw_alpha_rgb32(w, h, src, srca, stride, base, mode_stride); break; case 24: vo_draw_alpha_rgb24(w, h, src, srca, stride, base, mode_stride); break; case 16: vo_draw_alpha_rgb16(w, h, src, srca, stride, base, mode_stride); break; case 15: vo_draw_alpha_rgb15(w, h, src, srca, stride, base, mode_stride); break; }}static uint32_t get_image(mp_image_t *mpi){int page; if(!IMGFMT_IS_BGR(mpi->imgfmt) && !IMGFMT_IS_RGB(mpi->imgfmt) ){ assert(0);//should never happen return(VO_FALSE); } if ( ( (mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) || (mpi->flags & MP_IMGFLAG_PLANAR) || (mpi->flags & MP_IMGFLAG_YUV) ) return(VO_FALSE);//reading from video memory is horribly slow if( !(mpi->flags & MP_IMGFLAG_READABLE) && vo_directrendering && (mode_capabilities & CAP_LINEAR) ){//find free page and reserve it page=page_find_free(); if(page >= 0){ PageStore[page].locks=PAGE_BUSY; mpi->flags |= MP_IMGFLAG_DIRECT; mpi->stride[0] = mode_stride; mpi->planes[0] = PageStore[page].vbase + y_pos*mode_stride + (x_pos*mpi->bpp)/8; mpi->priv=(void *)page; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) mp_msg(MSGT_VO,MSGL_DBG3, "vo_svga: direct render allocated! page=%d\n",page); return(VO_TRUE); } } return(VO_FALSE);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?