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