vo_tdfx_vid.c

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

C
670
字号
/*  *  vo_tdfx_vid.c * *	Copyright (C) Alban Bedel - 03/2003 * *  This file is part of MPlayer, a free movie player. *	 *  MPlayer is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  MPlayer is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *    *  You should have received a copy of the GNU General Public License along *  with MPlayer; if not, write to the Free Software Foundation, Inc., *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <mplaylib.h>#include <sys/ioctl.h>#include <sys/mman.h>#include "config.h"#include "video_out.h"#include "video_out_internal.h"#include "aspect.h"#include "mp_msg.h"#include "help_mp.h"#include "fastmemcpy.h"#include "drivers/tdfx_vid.h"static vo_info_t info = {	"tdfx vid",	"tdfx_vid",	"Albeu",	""};//#define VERBOSELIBVO_EXTERN(tdfx_vid)static tdfx_vid_config_t tdfx_cfg;static unsigned char* agp_mem = NULL;static int tdfx_fd = -1;static uint32_t img_fmt; // The real input formatstatic uint32_t src_width, src_height, src_fmt, src_bpp, src_stride;static uint32_t dst_width, dst_height, dst_fmt, dst_bpp, dst_stride;static uint32_t tdfx_page;static uint32_t front_buffer;static uint32_t back_buffer;static uint8_t num_buffer = 3;static uint32_t buffer_size; // Max sizestatic uint8_t current_buffer = 0;static uint8_t current_ip_buf = 0;static uint32_t buffer_stride[3];static int use_overlay = 1;static tdfx_vid_overlay_t tdfx_ov;// FIXMEstatic void clear_screen(void) {  tdfx_vid_agp_move_t mov;  memset(agp_mem,0,tdfx_cfg.screen_width*dst_bpp*tdfx_cfg.screen_height);    mov.move2 = TDFX_VID_MOVE_2_PACKED;  mov.width = tdfx_cfg.screen_width*dst_bpp;  mov.height = tdfx_cfg.screen_height;  mov.src = 0;  mov.src_stride = tdfx_cfg.screen_width*dst_bpp;  mov.dst = front_buffer;  mov.dst_stride = tdfx_cfg.screen_stride;  mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_Move, mov.width,mov.src_stride,mov.height,mov.dst_stride);  if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov))    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AGPMoveFailedToClearTheScreen);  }static int draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y){  uint8_t* ptr[3];#ifdef VERBOSE  printf("Draw slices %d\n",current_buffer);#endif  switch(img_fmt) {  case IMGFMT_YUY2:  case IMGFMT_UYVY:  case IMGFMT_BGR8:  case IMGFMT_BGR16:  case IMGFMT_BGR24:  case IMGFMT_BGR32:    // copy :( to agp_mem    // still faster than tdfxfb wich directly copy to the video mem :)    mem2agpcpy_pic(agp_mem + current_buffer * buffer_size + 	       y*buffer_stride[0] + x * src_bpp,	       image[0],	       src_bpp*w,h,buffer_stride[0],stride[0]);    return 0;  case IMGFMT_YV12:  case IMGFMT_I420:    // Copy to agp mem    ptr[0] = agp_mem + current_buffer * buffer_size;    mem2agpcpy_pic(ptr[0] + y * buffer_stride[0] + x,image[0],w,h,		   buffer_stride[0],stride[0]);    ptr[1] = ptr[0] + (src_height*src_width);    mem2agpcpy_pic(ptr[1] + y/2 * buffer_stride[1] + x/2,image[1],w/2,h/2,		   buffer_stride[1],stride[1]);    ptr[2] = ptr[1] + (src_height*src_width/4);    mem2agpcpy_pic(ptr[2] + y/2 * buffer_stride[2] + x/2,image[2],w/2,h/2,		   buffer_stride[2],stride[2]);    return 0;  }      return 1;}static void draw_osd(void){}static voidflip_page(void){  tdfx_vid_blit_t blit;  //return;  // Scale convert#ifdef VERBOSE  printf("Flip\n");#endif  if(use_overlay) {    // TDFX_VID_OVERLAY_ON does nothing if the overlay is already on    if(!ioctl(tdfx_fd,TDFX_VID_OVERLAY_ON)) { // X11 killed the overlay :(      if(ioctl(tdfx_fd,TDFX_VID_SET_OVERLAY,&tdfx_ov))	mp_msg(MSGT_VO, MSGL_ERR, "tdfx_vid: set_overlay failed\n");    }    // These formats need conversion    switch(src_fmt) {    case IMGFMT_BGR8:    case IMGFMT_BGR24:    case IMGFMT_BGR32:      memset(&blit,0,sizeof(tdfx_vid_blit_t));      blit.src = back_buffer;      blit.src_stride = src_stride;      blit.src_x = 0;      blit.src_y = 0;      blit.src_w = src_width;      blit.src_h = src_height;      blit.src_format = src_fmt;            blit.dst = front_buffer;      blit.dst_stride = dst_stride;      blit.dst_x = 0;      blit.dst_y = 0;      blit.dst_w = src_width;      blit.dst_h = src_height;      blit.dst_format = IMGFMT_BGR16;      if(ioctl(tdfx_fd,TDFX_VID_BLIT,&blit))	mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_BlitFailed);    }    return;  }  memset(&blit,0,sizeof(tdfx_vid_blit_t));  blit.src = back_buffer;  blit.src_stride = src_stride;  blit.src_x = 0;  blit.src_y = 0;  blit.src_w = src_width;  blit.src_h = src_height;  blit.src_format = src_fmt;  blit.dst = front_buffer;  blit.dst_stride = dst_stride;  blit.dst_x = 0;  blit.dst_y = 0;  blit.dst_w = dst_width;  blit.dst_h = dst_height;  blit.dst_format = dst_fmt;  if(ioctl(tdfx_fd,TDFX_VID_BLIT,&blit))    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_BlitFailed);}static intdraw_frame(uint8_t *src[]){  int stride[] = { src_stride, 0, 0};  return draw_slice(src,stride,src_width, src_height,0,0);}static intquery_format(uint32_t format){  switch(format) {  case IMGFMT_BGR8:    if(tdfx_cfg.screen_format == TDFX_VID_FORMAT_BGR8)      return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;    return 0;  case IMGFMT_YUY2:  case IMGFMT_UYVY:  case IMGFMT_BGR15:  case IMGFMT_BGR16:  case IMGFMT_BGR24:  case IMGFMT_BGR32:  case IMGFMT_YV12:  case IMGFMT_I420:    if(tdfx_cfg.screen_format == TDFX_VID_FORMAT_BGR8)      return 0;    return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;  }  return 0;}static intconfig(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format){  if(tdfx_fd < 0)    return 1;  // When we are run as sub vo we must follow the size gaven to us  if(!(flags & VOFLAG_XOVERLAY_SUB_VO)) {    if(!vo_screenwidth)      vo_screenwidth = tdfx_cfg.screen_width;    if(!vo_screenheight)      vo_screenheight = tdfx_cfg.screen_height;        aspect_save_orig(width,height);    aspect_save_prescale(d_width,d_height);    aspect_save_screenres(vo_screenwidth,vo_screenheight);        if(flags&VOFLAG_FULLSCREEN) { /* -fs */      aspect(&d_width,&d_height,A_ZOOM);      vo_fs = VO_TRUE;    } else {      aspect(&d_width,&d_height,A_NOZOOM);      vo_fs = VO_FALSE;    }  }  src_width = width;  src_height = height;  buffer_size = 0;  buffer_stride[0] = 0;  src_fmt = 0;  switch(format) {  case IMGFMT_BGR8:  case IMGFMT_BGR24:  case IMGFMT_BGR32:    if(use_overlay)      mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_TDFXVID_NonNativeOverlayFormatNeedConversion);  case IMGFMT_BGR15:  case IMGFMT_BGR16:    src_bpp = ((format & 0x3F)+7)/8;     break;  case IMGFMT_YV12:  case IMGFMT_I420:    buffer_size = src_width * src_height * 3 / 2;    buffer_stride[0] = ((src_width+1)/2)*2;    buffer_stride[1] = buffer_stride[2] = buffer_stride[0]/2;    src_fmt = TDFX_VID_FORMAT_YUY2;  case IMGFMT_YUY2:  case IMGFMT_UYVY:     src_bpp = 2;    break;  default:    mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_UnsupportedInputFormat,format);    return 1;  }  img_fmt = format;  src_stride = src_width*src_bpp;  // The overlay need a 4 bytes aligned stride  if(use_overlay)    src_stride = ((src_stride+3)/4)*4;  if(!src_fmt)    src_fmt = format;  if(!buffer_size)    buffer_size = src_stride*src_height;  if(!buffer_stride[0])    buffer_stride[0] = src_stride;  dst_fmt = tdfx_cfg.screen_format;  dst_bpp = ((dst_fmt & 0x3F)+7)/8;  dst_width = d_width;  dst_height = d_height;  dst_stride = tdfx_cfg.screen_stride;  tdfx_page =  tdfx_cfg.screen_stride*tdfx_cfg.screen_height;  front_buffer = tdfx_cfg.screen_start;  back_buffer = front_buffer + tdfx_page;  while(use_overlay) {    tdfx_vid_overlay_t ov;    uint32_t ov_fmt = src_fmt, ov_stride = src_stride;    // Align the buffer    back_buffer = (((back_buffer+3)/4)*4);    // With the overlay the front buffer is not on the screen    // so we take the back buffer    front_buffer = back_buffer;    switch(src_fmt) {    case IMGFMT_BGR8:    case IMGFMT_BGR24:    case IMGFMT_BGR32:      back_buffer = front_buffer + 2*(src_stride*src_height);      ov_stride = dst_stride = src_width<<1;      ov_fmt = IMGFMT_BGR16;      break;    }    ov.src[0] = front_buffer;    ov.src[1] = front_buffer + (src_stride*src_height);    ov.src_width = src_width;    ov.src_height = src_height;    ov.src_stride = ov_stride;    ov.format = ov_fmt;    ov.dst_width = dst_width;    ov.dst_height = dst_height;

⌨️ 快捷键说明

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