vo_dxr2.c

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

C
956
字号
      sub_w = (sub_h*aspect + (1<<15))>>16;    else      sub_h = ((sub_w<<16) + (aspect>>1)) /aspect;    sub_w += olw_cor;    sub_h += olh_cor;    sub_x_off = (vo_dwidth-sub_w) / 2;    sub_y_off = (vo_dheight-sub_h) / 2;    sub_x = -vo_dx; // Be sure to also replace the overlay    win.arg1 = sub_w;    win.arg2 = sub_h;    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] set win size w=%d h=%d and offset x=%d y=%d \n",win.arg1,win.arg2,sub_x_off,sub_y_off);    ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION, &win);  }    if(vo_dx != sub_x || vo_dy != sub_y) {    sub_x = vo_dx + olx_cor + sub_x_off;    sub_y = vo_dy + oly_cor + sub_y_off;    win.arg1 = (sub_x > 0 ? sub_x : 0);    win.arg2 = (sub_y > 0 ? sub_y : 0);    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] set pos x=%d y=%d \n",win.arg1,win.arg2);    ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);  }}static int config(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t height, uint32_t flags, char *title, uint32_t format){  int arg;  dxr2_threeArg_t arg3;  if(dxr2_fd < 0) {    mp_msg(MSGT_VO,MSGL_ERR,"DXR2 fd is not valid\n");    return VO_ERROR;  }  if(playing) {    dxr2_send_eof();    flush_dxr2();    ioctl(dxr2_fd, DXR2_IOC_STOP, NULL);    playing = 0;  }  // Video stream setup  arg3.arg1 = DXR2_STREAM_VIDEO;  arg3.arg2 = 0;  ioctl(dxr2_fd, DXR2_IOC_SELECT_STREAM, &arg3);	  if (vo_fps > 28)    arg3.arg1 = DXR2_SRC_VIDEO_FREQ_30;  else arg3.arg1 = DXR2_SRC_VIDEO_FREQ_25;  arg3.arg2 = s_width;  arg3.arg3 = s_height;  ioctl(dxr2_fd, DXR2_IOC_SET_SOURCE_VIDEO_FORMAT, &arg3);  arg = DXR2_BITSTREAM_TYPE_MPEG_VOB;  ioctl(dxr2_fd, DXR2_IOC_SET_BITSTREAM_TYPE, &arg);  // Aspect ratio  if (1.76 <= movie_aspect && movie_aspect <= 1.80) {    arg = DXR2_ASPECTRATIO_16_9;    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] source aspect ratio 16:9\n");  } else {    arg = DXR2_ASPECTRATIO_4_3;    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] source aspect ratio 4:3\n");  }  ioctl(dxr2_fd, DXR2_IOC_SET_SOURCE_ASPECT_RATIO, &arg);  if (1.76 <= monitor_aspect && monitor_aspect <=1.80) {    arg = DXR2_ASPECTRATIO_16_9;    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] monitor aspect ratio 16:9\n");  } else {    arg = DXR2_ASPECTRATIO_4_3;    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] monitor aspect ratio 4:3\n");  }  ioctl(dxr2_fd, DXR2_IOC_SET_OUTPUT_ASPECT_RATIO, &arg);  arg = ar_mode;  ioctl(dxr2_fd, DXR2_IOC_SET_ASPECT_RATIO_MODE, &arg);  // TV setup  arg = mv_mode;  ioctl(dxr2_fd, DXR2_IOC_SET_TV_MACROVISION_MODE, &arg);  arg = _75ire_mode;  ioctl(dxr2_fd, DXR2_IOC_SET_TV_75IRE_MODE, &arg);  arg = bw_mode;  ioctl(dxr2_fd, DXR2_IOC_SET_TV_BLACKWHITE_MODE, &arg);  arg = interlaced_mode;  ioctl(dxr2_fd, DXR2_IOC_SET_TV_INTERLACED_MODE, &arg);  arg = pixel_mode;  ioctl(dxr2_fd, DXR2_IOC_SET_TV_PIXEL_MODE, &arg);    if (norm) {    if (strcmp(norm, "ntsc")==0)      arg = DXR2_OUTPUTFORMAT_NTSC;    else if (strcmp(norm, "pal")==0) {      if (vo_fps > 28) {	mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] you want pal, but we play at 30 fps, selecting pal60 instead\n");	arg = DXR2_OUTPUTFORMAT_PAL_60;	norm="pal60";      } else arg = DXR2_OUTPUTFORMAT_PAL_BDGHI;    } else if (strcmp(norm, "pal60")==0) {      if (vo_fps > 28)	arg = DXR2_OUTPUTFORMAT_PAL_60;      else {	mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] you want pal60, but we play at 25 fps, selecting pal instead\n");	arg = DXR2_OUTPUTFORMAT_PAL_BDGHI;	norm="pal";      }    } else if (strcmp(norm, "palm")==0)      arg = DXR2_OUTPUTFORMAT_PAL_M;    else if (strcmp(norm, "paln")==0)      arg = DXR2_OUTPUTFORMAT_PAL_N;    else if (strcmp(norm, "palnc")==0)      arg = DXR2_OUTPUTFORMAT_PAL_Nc;    else {      mp_msg(MSGT_VO,MSGL_WARN,"[dxr2] invalid norm %s\n", norm);      mp_msg(MSGT_VO,MSGL_WARN,"Valid values are ntsc,pal,pal60,palm,paln,palnc\n");      mp_msg(MSGT_VO,MSGL_WARN,"Using ntsc\n");      norm="ntsc";    }  } else {    if (vo_fps > 28) {      arg = DXR2_OUTPUTFORMAT_NTSC;      norm="ntsc";    } else {      arg = DXR2_OUTPUTFORMAT_PAL_BDGHI;      norm="pal";    }  }  mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] output norm set to %s\n", norm);  ioctl(dxr2_fd, DXR2_IOC_SET_TV_OUTPUT_FORMAT, &arg);  // Subtitles  arg = DXR2_SUBPICTURE_ON;  ioctl(dxr2_fd,DXR2_IOC_ENABLE_SUBPICTURE,&arg);  arg3.arg1 = DXR2_STREAM_SUBPICTURE;  arg3.arg2 = 0;  ioctl(dxr2_fd, DXR2_IOC_SELECT_STREAM, &arg3);  // Audio  arg = iec958_mode;  ioctl(dxr2_fd, DXR2_IOC_IEC958_OUTPUT_MODE, &arg);  arg = DXR2_AUDIO_WIDTH_16;  ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_DATA_WIDTH, &arg);  arg = DXR2_AUDIO_FREQ_48;  ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_SAMPLE_FREQUENCY, &arg);  arg3.arg1 = DXR2_STREAM_AUDIO_LPCM;  arg3.arg2 = 0;  ioctl(dxr2_fd, DXR2_IOC_SELECT_STREAM, &arg3);  arg = 19;  ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_VOLUME, &arg);  arg = mute_mode;  ioctl(dxr2_fd, DXR2_IOC_AUDIO_MUTE, &arg);  movie_w = width;  movie_h = height;  //vo_fs = flags & VOFLAG_FULLSCREEN ? 1 : 0;  // Overlay  while(use_ol) {    dxr2_twoArg_t win;    dxr2_oneArg_t om;    int cc = vo_config_count;    vo_config_count = sub_config_count;    // Load or detect the overlay stuff    if(!dxr2_setup_vga_params()) {      sub_vo->uninit();      sub_vo = NULL;      vo_config_count = cc;      break;    }    // Does the sub vo support the x11 stuff    // Fix me : test the other x11 vo's and enable them    if(strcmp(sub_vo->info->short_name,"x11") == 0)      sub_vo_win = 1;    else      sub_vo_win = 0;    // No window and no osd => we don't need any subdriver    if(!sub_vo_win && !ol_osd) {      sub_vo->uninit();      sub_vo = NULL;    }      while(sub_vo) {      dxr2_sixArg_t oc;      int i,sub_flags = VOFLAG_SWSCALE | (flags & VOFLAG_FULLSCREEN);      if(sub_vo->config(width,height,width,height,sub_flags,			"MPlayer DXR2 render",IMGFMT_BGR24) != 0) {	mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] sub vo config failed => No X11 window\n");	sub_vo->uninit();	sub_vo = NULL;	break;      }      sub_config_count++;      // Feel free to try some other other color and report your results      oc.arg1 = ck_rmin;      oc.arg2 = ck_rmax;      oc.arg3 = ck_gmin;      oc.arg4 = ck_gmax;      oc.arg5 = ck_bmin;      oc.arg6 = ck_bmax;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_COLOUR, &oc);            om.arg = DXR2_OVERLAY_WINDOW_COLOUR_KEY;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_MODE,&om);      sub_img = malloc(width*height*3);      for(i = 0 ; i < width*height*3 ; i += 3) {	sub_img[i] = ck_b;	sub_img[i+1] = ck_g;	sub_img[i+2] = ck_r;      }      aspect = ((1<<16)*width + height/2)/height;      sub_w = sub_h = 0;      dxr2_set_overlay_window();      break;    }    vo_config_count = cc;    if(!sub_vo) { // Fallback on non windowed overlay      vo_fs = flags & VOFLAG_FULLSCREEN ? 1 : 0;      om.arg = DXR2_OVERLAY_WINDOW_KEY;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_MODE,&om);      win.arg1 = flags & VOFLAG_FULLSCREEN ? vo_screenwidth : width;      win.arg2 = flags & VOFLAG_FULLSCREEN ? vo_screenheight : height;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION, &win);      win.arg1 = (vo_screenwidth - win.arg1) / 2;      win.arg2 = (vo_screenheight - win.arg2) / 2;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);    }    break;  }  if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop);    // start playing  if(ioctl(dxr2_fd, DXR2_IOC_PLAY, NULL) == 0) {    playing = 1;    return 0;  } else    return VO_ERROR;}static void clear_alpha(int x0,int y0, int w,int h) {  uint8_t* src[] = { sub_img , NULL, NULL };  int stride[] = { movie_w * 3, 0, 0 };  sub_vo->draw_slice(src,stride,w,h,x0,y0);}static void draw_osd(void){  if(sub_vo && ol_osd) {    vo_remove_text(movie_w,movie_h,clear_alpha);    sub_vo->draw_osd();  }}static int draw_frame(uint8_t * src[]){  vo_mpegpes_t *p=(vo_mpegpes_t *)src[0];  if(p->id == 0x1E0) {// Video    send_mpeg_ps_packet (p->data, p->size, p->id,                         p->timestamp ? p->timestamp : vo_pts, 2, write_dxr2);  } else if(p->id == 0x20) // Subtitles    dxr2_send_sub_packet(p->data, p->size, p->id, p->timestamp);  return 0;}static void flip_page (void){  if(sub_vo && ol_osd && vo_osd_changed_flag)    sub_vo->flip_page();}static int draw_slice( uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0 ){  return 0;}static int query_format(uint32_t format){  if (format==IMGFMT_MPEGPES)    return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_TIMER|VFCAP_SPU;  return 0;}static void uninit(void){  mp_msg(MSGT_VO,MSGL_DBG2, "VO: [dxr2] Uninitializing\n" );  if (dxr2_fd > 0) {    if(playing) {      dxr2_send_eof();      flush_dxr2();      playing = 0;    }    close(dxr2_fd);    dxr2_fd = -1;  }  if(sub_img) {    free(sub_img);    sub_img = NULL;  }  if(sub_vo) {    int cc = vo_config_count;    vo_config_count = sub_config_count;    sub_vo->uninit();    sub_vo = NULL;    vo_config_count = cc;  }}static void check_events(void){  // I'd like to have this done in an x11 independent way  // It's because of this that we are limited to vo_x11 for windowed overlay :-(#ifdef X11_FULLSCREEN  if(sub_vo && sub_vo_win) {    int e=vo_x11_check_events(mDisplay);    if ( !(e&VO_EVENT_RESIZE) && !(e&VO_EVENT_EXPOSE) ) return;    XSetBackground(mDisplay, vo_gc, 0);    XClearWindow(mDisplay, vo_window);    dxr2_set_overlay_window();  }#endif}static int preinit(const char *arg) {  int uCodeFD = -1;  int uCodeSize;  dxr2_uCode_t* uCode;  dxr2_fourArg_t crop;  int n=0;  sub_vo = NULL;  sub_config_count = 0;  if(use_ol) {    if (arg) {      for(n = 0 ; video_out_drivers[n] != NULL ; n++) {	const vo_info_t* vi = video_out_drivers[n]->info;	if(!vi)	  continue;	if(strcasecmp(arg,vi->short_name) == 0)	  break;      }      sub_vo = video_out_drivers[n];    } else {      mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] We need a sub driver to initialize the overlay\n");      use_ol = 0;    }  }    if(!sub_vo) {    if(use_ol)      mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] Sub driver '%s' not found => no overlay\n",arg);    use_ol = 0;  } else {    if(sub_vo->preinit(NULL) != 0) {      mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] Sub vo %s preinit failed => no overlay\n",arg);      sub_vo = NULL;      use_ol = 0;    } else {      uint32_t fmt = IMGFMT_BGR24;      mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] Sub vo %s inited\n",arg);      if(sub_vo->control(VOCTRL_QUERY_FORMAT,&fmt) <= 0) {	mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] Sub vo %s doesn't support BGR24 => no overlay\n",arg);	sub_vo->uninit();	sub_vo = NULL;	use_ol = 0;      }    }  }  dxr2_fd = open( "/dev/dxr2", O_WRONLY);  if( dxr2_fd < 0 ) {      mp_msg(MSGT_VO,MSGL_V, "VO: [dxr2] Error opening /dev/dxr2 for writing!\n" );      return VO_ERROR;  }  if(ucode)    uCodeFD = open(ucode, O_RDONLY);  else for (n=0; ucodesearchpath[n] != NULL; n++) {    mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] Looking for microcode in %s... ",	   ucodesearchpath[n]);    if ((uCodeFD = open(ucodesearchpath[n], O_RDONLY))>0) {      mp_msg(MSGT_VO,MSGL_V,"ok\n");      break;    } else {      mp_msg(MSGT_VO,MSGL_V,"failed (%s)\n", strerror(errno));    }  }  if (uCodeFD < 0) {    mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Could not open microcode\n");    return VO_ERROR;  }  uCodeSize = lseek(uCodeFD, 0, SEEK_END);  if ((uCode = malloc(uCodeSize + 4)) == NULL) {    mp_msg(MSGT_VO,MSGL_FATAL,"VO: [dxr2] Could not allocate memory for uCode: %s\n", strerror(errno));    return VO_ERROR;  }  lseek(uCodeFD, 0, SEEK_SET);  if (read(uCodeFD, uCode+4, uCodeSize) != uCodeSize) {    mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Could not read uCode uCode: %s\n", strerror(errno));    return VO_ERROR;  }  close(uCodeFD);  uCode->uCodeLength = uCodeSize;  // upload ucode  ioctl(dxr2_fd, DXR2_IOC_INIT_ZIVADS, uCode);  // reset card  ioctl(dxr2_fd, DXR2_IOC_RESET, NULL);  playing = 0;  if(!use_ol) {    crop.arg1=0;    crop.arg2=0;    crop.arg3=0;    crop.arg4=0;    ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_CROPPING, &crop);  }  return 0;}static int control(uint32_t request, void *data, ...){  switch (request) {  case VOCTRL_QUERY_FORMAT:    return query_format(*((uint32_t*)data));  case VOCTRL_PAUSE:    ioctl(dxr2_fd,DXR2_IOC_PAUSE, NULL);    return VO_TRUE;  case VOCTRL_RESUME:    ioctl(dxr2_fd, DXR2_IOC_PLAY, NULL);    return VO_TRUE;  case VOCTRL_RESET:    flush_dxr2();    ioctl(dxr2_fd, DXR2_IOC_PLAY, NULL);    return VO_TRUE;  case VOCTRL_ONTOP:    vo_x11_ontop();    return VO_TRUE;  case VOCTRL_FULLSCREEN:    if(!use_ol)      return VO_NOTIMPL;    else if(sub_vo) {      int r = sub_vo->control(VOCTRL_FULLSCREEN,0);      if(r == VO_TRUE && !sub_vo_win)	dxr2_set_overlay_window();      return r;    } else {      dxr2_twoArg_t win;      vo_fs = !vo_fs;      win.arg1 = vo_fs ? vo_screenwidth : movie_w;      win.arg2 = vo_fs ? vo_screenheight : movie_h;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION, &win);      win.arg1 = (vo_screenwidth - win.arg1) / 2;      win.arg2 = (vo_screenheight - win.arg2) / 2;      ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);      return VO_TRUE;    }  case VOCTRL_SET_SPU_PALETTE: {     if(ioctl(dxr2_fd,DXR2_IOC_SET_SUBPICTURE_PALETTE,data) < 0) {      mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] SPU palette loading failed\n");      return VO_ERROR;    }    return VO_TRUE;   }   }  return VO_NOTIMPL;}

⌨️ 快捷键说明

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