vo_tdfx_vid.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 670 行 · 第 1/2 页

C
670
字号
    ov.dst_x = vo_dx;    ov.dst_y = vo_dy;    ov.use_colorkey = 0;    if(ioctl(tdfx_fd,TDFX_VID_SET_OVERLAY,&ov)) {      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlaySetupFailed);      use_overlay = 0;      break;    }    tdfx_ov = ov;    if(use_overlay == 1) {      if(ioctl(tdfx_fd,TDFX_VID_OVERLAY_ON)) {	mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlayOnFailed);	use_overlay = 0;	break;      }      use_overlay++;    }        mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_OverlayReady,	   src_width,src_stride,src_height,src_bpp,	   dst_width,dst_stride,dst_height,dst_bpp);    break;  }  if(!use_overlay)    mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_TextureBlitReady,	   src_width,src_stride,src_height,src_bpp,	   dst_width,dst_stride,dst_height,dst_bpp);    return 0;}static voiduninit(void){  if(use_overlay == 2) {    if(ioctl(tdfx_fd,TDFX_VID_OVERLAY_OFF))      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_OverlayOffFailed);    use_overlay--;  }  close(tdfx_fd);  tdfx_fd = -1;}static void check_events(void){}static int preinit(const char *arg){   tdfx_fd = open(arg ? arg : "/dev/tdfx_vid", O_RDWR);  if(tdfx_fd < 0) {    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_CantOpen,arg ? arg : "/dev/tdfx_vid",	   strerror(errno));    return 1;  }  if(ioctl(tdfx_fd,TDFX_VID_GET_CONFIG,&tdfx_cfg)) {    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_CantGetCurrentCfg,strerror(errno));    return 1;  }  mp_msg(MSGT_VO,MSGL_INFO, "tdfx_vid version %d\n"	 "  Ram: %d\n"	 "  Screen: %d x %d\n"	 "  Format: %c%c%c%d\n",	 tdfx_cfg.version,	 tdfx_cfg.ram_size,	 tdfx_cfg.screen_width, tdfx_cfg.screen_height,	 tdfx_cfg.screen_format>>24,(tdfx_cfg.screen_format>>16)&0xFF,	 (tdfx_cfg.screen_format>>8)&0xFF,tdfx_cfg.screen_format&0xFF);  // For now just allocate more than i ever need  agp_mem = mmap( NULL, 1024*768*4, PROT_READ | PROT_WRITE, MAP_SHARED,		  tdfx_fd, 0);  if(agp_mem == MAP_FAILED) {    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_MemmapFailed);    return 1;  }    memset(agp_mem,0,1024*768*4);  return 0;}static uint32_t get_image(mp_image_t *mpi) {  int buf = 0;#ifdef VERBOSE  printf("Get image %d\n",buf);#endif  // Currently read are too slow bcs we read from the  // agp aperture and not the memory directly  //if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE;  if(mpi->flags&MP_IMGFLAG_READABLE &&     (mpi->type==MP_IMGTYPE_IPB || mpi->type==MP_IMGTYPE_IP)){    // reference (I/P) frame of IP or IPB:    if(num_buffer<2) return VO_FALSE; // not enough    current_ip_buf^=1;    // for IPB with 2 buffers we can DR only one of the 2 P frames:    if(mpi->type==MP_IMGTYPE_IPB && num_buffer<3 && current_ip_buf) return VO_FALSE;    buf=current_ip_buf;    if(mpi->type==MP_IMGTYPE_IPB) ++buf; // preserve space for B  }  switch(mpi->imgfmt) {  case IMGFMT_YUY2:  case IMGFMT_UYVY:  case IMGFMT_BGR8:  case IMGFMT_BGR15:  case IMGFMT_BGR16:  case IMGFMT_BGR24:  case IMGFMT_BGR32:    mpi->planes[0] = agp_mem + buf * buffer_size;    mpi->stride[0] = src_stride;    break;  case IMGFMT_YV12:  case IMGFMT_I420:    mpi->planes[0] = agp_mem + buf * buffer_size;    mpi->stride[0] = mpi->width;    mpi->planes[1] = mpi->planes[0] + mpi->stride[0]*mpi->height;    mpi->stride[1] = mpi->chroma_width;    mpi->planes[2] = mpi->planes[1] + mpi->stride[1]*mpi->chroma_height;    mpi->stride[2] = mpi->chroma_width;    break;  default:    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_GetImageTodo);    return VO_FALSE;  }  mpi->flags |= MP_IMGFLAG_DIRECT;  mpi->priv = (void*)buf;    return VO_TRUE;}static uint32_t start_slice(mp_image_t *mpi){  int buf = 0;#ifdef VERBOSE  printf("Start slices %d\n",buf);#endif  if(mpi->flags & MP_IMGFLAG_DIRECT)    buf = (int)mpi->priv;  current_buffer = buf;  return VO_TRUE;}static uint32_t draw_image(mp_image_t *mpi){  int buf = 0;  tdfx_vid_agp_move_t mov;  tdfx_vid_yuv_t yuv;  int p;  uint8_t* planes[3];#ifdef VERBOSE  printf("Draw image %d\n",buf);#endif  if(mpi->flags & MP_IMGFLAG_DIRECT)    buf = (int)mpi->priv;  switch(mpi->imgfmt) {  case IMGFMT_YUY2:  case IMGFMT_UYVY:  case IMGFMT_BGR8:  case IMGFMT_BGR15:  case IMGFMT_BGR16:  case IMGFMT_BGR24:  case IMGFMT_BGR32:    if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))) {      // copy to agp_mem#ifdef VERBOSE      printf("Memcpy\n");#endif      planes[0] = agp_mem + buf * buffer_size;      mem2agpcpy_pic(planes[0],mpi->planes[0],src_bpp*mpi->width,mpi->height,		     buffer_stride[0],mpi->stride[0]);    } else      planes[0] = agp_mem + buf * buffer_size;    mov.move2 = TDFX_VID_MOVE_2_PACKED;    mov.width = mpi->width*((mpi->bpp+7)/8);    mov.height = mpi->height;    mov.src = planes[0] - agp_mem;    mov.src_stride = buffer_stride[0];      mov.dst = back_buffer;    mov.dst_stride = src_stride;	     if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov))      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailed);    break;  case IMGFMT_YV12:  case IMGFMT_I420:    if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))) {      // Copy to agp mem#ifdef VERBOSE      printf("Memcpy\n");#endif      planes[0] = agp_mem + buf * buffer_size;      memcpy_pic(planes[0],mpi->planes[0],mpi->width,mpi->height,		 buffer_stride[0],mpi->stride[0]);      planes[1] = planes[0] + (mpi->height*mpi->stride[0]);      memcpy_pic(planes[1],mpi->planes[1],mpi->chroma_width,mpi->chroma_height,		 buffer_stride[1],mpi->stride[1]);      planes[2] = planes[1] + (mpi->chroma_height*mpi->stride[1]);      memcpy_pic(planes[2],mpi->planes[2],mpi->chroma_width,mpi->chroma_height,		 buffer_stride[2],mpi->stride[2]);    } else {      planes[0] = agp_mem + buf * buffer_size;      planes[1] = planes[0] + buffer_stride[0] * src_height;      planes[2] = planes[1] + buffer_stride[1] * src_height/2;    }    // Setup the yuv thing    yuv.base = back_buffer;    yuv.stride = src_stride;    if(ioctl(tdfx_fd,TDFX_VID_SET_YUV,&yuv)) {      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_SetYuvFailed);      break;    }        // Now agp move that    // Y    mov.move2 = TDFX_VID_MOVE_2_YUV;    mov.width = mpi->width;    mov.height = mpi->height;    mov.src = planes[0] - agp_mem;    mov.src_stride =  buffer_stride[0];    mov.dst = 0x0;    mov.dst_stride = TDFX_VID_YUV_STRIDE;    if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) {      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnYPlane);      break;    }    //return 0;    // U    p = mpi->imgfmt == IMGFMT_YV12 ? 1 : 2;    mov.width = mpi->chroma_width;    mov.height = mpi->chroma_height;    mov.src = planes[p] - agp_mem;    mov.src_stride = buffer_stride[p];    mov.dst += TDFX_VID_YUV_PLANE_SIZE;    if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) {      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnUPlane);      break;    }    // V    p = mpi->imgfmt == IMGFMT_YV12 ? 2 : 1;    mov.src = planes[p] - agp_mem;    mov.src_stride = buffer_stride[p];    mov.dst += TDFX_VID_YUV_PLANE_SIZE;    if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) {      mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnVPlane);      break;    }    break;  default:    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_UnknownFormat,mpi->imgfmt);    return VO_TRUE;  }  return VO_TRUE;}static uint32_t fullscreen(void) {  vo_fs ^= 1;  aspect(&dst_width,&dst_height,vo_fs ? A_ZOOM : A_NOZOOM);  // This does not work :((  //clear_screen();  return VO_TRUE;}static uint32_t set_window(mp_win_t* w) {  if(!use_overlay) return VO_FALSE;  tdfx_ov.dst_x = w->x;  tdfx_ov.dst_y = w->y;  tdfx_ov.dst_width = w->w;  tdfx_ov.dst_height = w->h;  if(ioctl(tdfx_fd,TDFX_VID_SET_OVERLAY,&tdfx_ov))    mp_msg(MSGT_VO, MSGL_V, "tdfx_vid: set window failed\n");  return VO_TRUE;}static uint32_t set_colorkey(mp_colorkey_t* colork) {  if(!use_overlay) return VO_FALSE;  tdfx_ov.colorkey[0] = tdfx_ov.colorkey[1] = colork->x11;  tdfx_ov.use_colorkey = 1;  tdfx_ov.invert_colorkey = 0;  if(ioctl(tdfx_fd,TDFX_VID_SET_OVERLAY,&tdfx_ov))    mp_msg(MSGT_VO, MSGL_V, "tdfx_vid: set colorkey failed\n");  return VO_TRUE;}static int control(uint32_t request, void *data, ...){  switch (request) {  case VOCTRL_QUERY_FORMAT:    return query_format(*((uint32_t*)data));  case VOCTRL_GET_IMAGE:    return get_image(data);  case VOCTRL_DRAW_IMAGE:    return draw_image(data);  case VOCTRL_START_SLICE:    return start_slice(data);  case VOCTRL_FULLSCREEN:    return fullscreen();  case VOCTRL_XOVERLAY_SUPPORT:    return VO_TRUE;  case VOCTRL_XOVERLAY_SET_COLORKEY:    return set_colorkey(data);  case VOCTRL_XOVERLAY_SET_WIN:    return set_window(data);  }  return VO_NOTIMPL;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?