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