vo_fbdev.c

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

C
1,205
字号
	if(pre_init_err == -2)	{	    mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n");	    return -1;	}	if (pre_init_err) return 1;	if (fb_mode_name && !vm) {		mp_msg(MSGT_VO, MSGL_ERR, "-fbmode can only be used with -vm\n");		return 1;	}	if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0))			return 1;	if (d_width && (fs || vm)) {		out_width = d_width;		out_height = d_height;	} else {		out_width = width;		out_height = height;	}	in_width = width;	in_height = height;	pixel_format = format;	if (fb_mode_name) {		if (!(fb_mode = find_mode_by_name(fb_mode_name))) {			mp_msg(MSGT_VO, MSGL_ERR, "can't find requested video mode\n");			return 1;		}		fb_mode2fb_vinfo(fb_mode, &fb_vinfo);	} else if (vm) {		monitor_hfreq = str2range(monitor_hfreq_str);		monitor_vfreq = str2range(monitor_vfreq_str);		monitor_dotclock = str2range(monitor_dotclock_str);		if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) {			mp_msg(MSGT_VO, MSGL_ERR, "you have to specify the capabilities of"					" the monitor.\n");			return 1;		}		if (!(fb_mode = find_best_mode(out_width, out_height,					monitor_hfreq, monitor_vfreq,					monitor_dotclock))) {			mp_msg(MSGT_VO, MSGL_ERR, "can't find best video mode\n");			return 1;		}		mp_msg(MSGT_VO, MSGL_V, "using mode %dx%d @ %.1fHz\n", fb_mode->xres,				fb_mode->yres, vsf(fb_mode));		fb_mode2fb_vinfo(fb_mode, &fb_vinfo);	}	fb_bpp_we_want = fb_bpp;	set_bpp(&fb_vinfo, fb_bpp);	fb_vinfo.xres_virtual = fb_vinfo.xres;	fb_vinfo.yres_virtual = fb_vinfo.yres;        if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) {                mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno));                close(fb_tty_fd);                fb_tty_fd = -1;        }	if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {		mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno));                if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) {                        mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno));                }		return 1;	}	fb_pixel_size = fb_vinfo.bits_per_pixel / 8;	fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +		fb_vinfo.blue.length + fb_vinfo.transp.length;	if (fb_bpp_we_want != fb_bpp)		mp_msg(MSGT_VO, MSGL_WARN, "requested %d bpp, got %d bpp!!!\n",				fb_bpp_we_want, fb_bpp);	switch (fb_bpp) {		case 32: draw_alpha_p = vo_draw_alpha_rgb32; break;		case 24: draw_alpha_p = vo_draw_alpha_rgb24; break;		case 16: draw_alpha_p = vo_draw_alpha_rgb16; break;		case 15: draw_alpha_p = vo_draw_alpha_rgb15; break;		default: return 1;	}	fb_xres = fb_vinfo.xres;	fb_yres = fb_vinfo.yres;	if (vm || fs) {		out_width = fb_xres;		out_height = fb_yres;	}	if (out_width < in_width || out_height < in_height) {		mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n");		return 1;	}	first_row = (out_height - in_height) / 2;	last_row = (out_height + in_height) / 2;	if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {		mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno));		return 1;	}	lots_of_printf();	if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) {		mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type);		return 1;	}	switch (fb_finfo.visual) {		case FB_VISUAL_TRUECOLOR:			break;		case FB_VISUAL_DIRECTCOLOR:			mp_msg(MSGT_VO, MSGL_V, "creating cmap for directcolor\n");			if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) {				mp_msg(MSGT_VO, MSGL_ERR, "can't get cmap: %s\n",						strerror(errno));				return 1;			}			if (!(cmap = make_directcolor_cmap(&fb_vinfo)))				return 1;			if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) {				mp_msg(MSGT_VO, MSGL_ERR, "can't put cmap: %s\n",						strerror(errno));				return 1;			}			fb_cmap_changed = 1;			free(cmap->red);			free(cmap->green);			free(cmap->blue);			free(cmap);			break;		default:			mp_msg(MSGT_VO, MSGL_ERR, "visual: %d not yet supported\n",					fb_finfo.visual);			return 1;	}	fb_line_len = fb_finfo.line_length;	fb_size = fb_finfo.smem_len;	frame_buffer = NULL;#ifdef CONFIG_VIDIX	if(vidix_name)	{	    unsigned image_width,image_height,x_offset,y_offset;	    if(zoom || fs){		aspect_save_orig(width,height);		aspect_save_prescale(d_width,d_height);		aspect_save_screenres(fb_xres,fb_yres);		aspect(&image_width,&image_height,fs ? A_ZOOM : A_NOZOOM);	    } else {		image_width=width;		image_height=height;	    }		if(fb_xres > image_width)		    x_offset = (fb_xres - image_width) / 2;		else x_offset = 0;		if(fb_yres > image_height)		    y_offset = (fb_yres - image_height) / 2;		else y_offset = 0;		if(vidix_init(width,height,x_offset,y_offset,image_width,			    image_height,format,fb_bpp,			    fb_xres,fb_yres) != 0)		{		    mp_msg(MSGT_VO, MSGL_ERR, "Can't initialize VIDIX driver\n");		    vidix_name = NULL;		    vidix_term();		    return -1;		}		else mp_msg(MSGT_VO, MSGL_V, "Using VIDIX\n");		vidix_start();		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);		}	}	else#endif	{	    int x_offset=0,y_offset=0;	    if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE,				    MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) {		mp_msg(MSGT_VO, MSGL_ERR, "Can't mmap %s: %s\n", fb_dev_name, strerror(errno));		return 1;	    }	    center = frame_buffer +		    ( (out_width - in_width) / 2 ) * fb_pixel_size +		    ( (out_height - in_height) / 2 ) * fb_line_len +		    x_offset * fb_pixel_size + y_offset * fb_line_len;	    mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer);	    mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center);	    mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size);	    if (fs || vm)		memset(frame_buffer, '\0', fb_line_len * fb_yres);	}	if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) {		mp_msg(MSGT_VO, MSGL_ERR, "can't open /dev/tty: %s\n", strerror(errno));		vt_doit = 0;	}	if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) {		mp_msg(MSGT_VO, MSGL_ERR, "can't fdopen /dev/tty: %s\n", strerror(errno));		vt_doit = 0;	}	if (vt_doit)		vt_set_textarea(last_row, fb_yres);	return 0;}static int query_format(uint32_t format){	if (!fb_preinit(0))		return 0;#ifdef CONFIG_VIDIX	if(vidix_name)		return (vidix_query_fourcc(format));#endif	if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {		int bpp = format & 0xff;		if (bpp == fb_bpp)			return VFCAP_ACCEPT_STRIDE | VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;	}	return 0;}static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,		unsigned char *srca, int stride){	unsigned char *dst;	dst = center + fb_line_len * y0 + fb_pixel_size * x0;	(*draw_alpha_p)(w, h, src, srca, stride, dst, fb_line_len);}static int draw_frame(uint8_t *src[]) { return 1; }static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x,		int y){	uint8_t *d;	uint8_t *s;	d = center + fb_line_len * y + fb_pixel_size * x;	s = src[0];	while (h) {		fast_memcpy(d, s, w * fb_pixel_size);		d += fb_line_len;		s += stride[0];		h--;	}	return 0;}static void check_events(void){}static void flip_page(void){}static void draw_osd(void){	vo_draw_text(in_width, in_height, draw_alpha);}static void uninit(void){	if (fb_cmap_changed) {		if (ioctl(fb_dev_fd, FBIOPUTCMAP, &fb_oldcmap))			mp_msg(MSGT_VO, MSGL_WARN, "Can't restore original cmap\n");		fb_cmap_changed = 0;	}	if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo))		mp_msg(MSGT_VO, MSGL_WARN, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));	fb_orig_vinfo.xoffset = fb_vinfo.xoffset;	fb_orig_vinfo.yoffset = fb_vinfo.yoffset;	if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo))		mp_msg(MSGT_VO, MSGL_WARN, "Can't reset original fb_var_screeninfo: %s\n", strerror(errno));        if (fb_tty_fd >= 0) {                if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0)                        mp_msg(MSGT_VO, MSGL_WARN, "Can't restore text mode: %s\n", strerror(errno));        }	if (vt_doit)		vt_set_textarea(0, fb_orig_vinfo.yres);        close(fb_tty_fd);	close(fb_dev_fd);	if(frame_buffer) munmap(frame_buffer, fb_size);	frame_buffer = NULL;#ifdef CONFIG_VIDIX	if(vidix_name) vidix_term();#endif	fb_preinit(1);}static int preinit(const char *vo_subdevice){    pre_init_err = 0;    if(vo_subdevice)    {#ifdef CONFIG_VIDIX	if (memcmp(vo_subdevice, "vidix", 5) == 0)	    vidix_name = &vo_subdevice[5];	if(vidix_name)	    pre_init_err = vidix_preinit(vidix_name,&video_out_fbdev);	else#endif	{	    if (fb_dev_name) free(fb_dev_name);	    fb_dev_name = strdup(vo_subdevice);	}    }    if(!pre_init_err) return (pre_init_err=(fb_preinit(0)?0:-1));    return(-1);}static uint32_t get_image(mp_image_t *mpi){    if (	!IMGFMT_IS_BGR(mpi->imgfmt) ||	(IMGFMT_BGR_DEPTH(mpi->imgfmt) != fb_bpp) ||	((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) ||	(mpi->flags & MP_IMGFLAG_PLANAR) ||	(mpi->flags & MP_IMGFLAG_YUV) ||	(mpi->width != in_width) ||	(mpi->height != in_height)       )    return(VO_FALSE);    mpi->planes[0] = center;    mpi->stride[0] = fb_line_len;    mpi->flags |= MP_IMGFLAG_DIRECT;    return(VO_TRUE);}static int control(uint32_t request, void *data, ...){  switch (request) {  case VOCTRL_GET_IMAGE:    return get_image(data);  case VOCTRL_QUERY_FORMAT:    return query_format(*((uint32_t*)data));  }#ifdef CONFIG_VIDIX  if (vidix_name) {      switch (request) {      case VOCTRL_SET_EQUALIZER:	  {	      va_list ap;	      int value;	      	      va_start(ap, data);	      value = va_arg(ap, int);	      va_end(ap);	      	      return vidix_control(request, data, value);         }      case VOCTRL_GET_EQUALIZER:	  {	      va_list ap;	      int *value;	      	      va_start(ap, data);	      value = va_arg(ap, int*);	      va_end(ap);	      	      return vidix_control(request, data, value);	  }      }  }#endif  return VO_NOTIMPL;}

⌨️ 快捷键说明

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