vo_fbdev.c

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

C
1,205
字号
		mp_msg(MSGT_VO, MSGL_DBG2, " hsync out of range.");	}	if (!in_range(vfreq, v)) {		ret = 0;		mp_msg(MSGT_VO, MSGL_DBG2, " vsync out of range.");	}	if (!in_range(dotclock, d)) {		ret = 0;		mp_msg(MSGT_VO, MSGL_DBG2, " dotclock out of range.");	}	if (ret)		mp_msg(MSGT_VO, MSGL_DBG2, " hsync, vsync, dotclock ok.\n");	else		mp_msg(MSGT_VO, MSGL_DBG2, "\n");	return ret;}static fb_mode_t *find_best_mode(int xres, int yres, range_t *hfreq,		range_t *vfreq, range_t *dotclock){	int i;	fb_mode_t *best = fb_modes;	fb_mode_t *curr;	mp_msg(MSGT_VO, MSGL_DBG2, "Searching for first working mode\n");	for (i = 0; i < nr_modes; i++, best++)		if (mode_works(best, hfreq, vfreq, dotclock))			break;	if (i == nr_modes)		return NULL;	if (i == nr_modes - 1)		return best;	mp_msg(MSGT_VO, MSGL_DBG2, "First working mode: %dx%d\n", best->xres, best->yres);	mp_msg(MSGT_VO, MSGL_DBG2, "Searching for better modes\n");	for (curr = best + 1; i < nr_modes - 1; i++, curr++) {		if (!mode_works(curr, hfreq, vfreq, dotclock))			continue;		if (best->xres < xres || best->yres < yres) {			if (curr->xres > best->xres || curr->yres > best->yres) {				mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too small.\n",							best->xres, best->yres);				best = curr;			} else				mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n");		} else if (curr->xres == best->xres && curr->yres == best->yres &&				vsf(curr) > vsf(best)) {			mp_msg(MSGT_VO, MSGL_DBG2, "faster screen refresh.\n");			best = curr;		} else if ((curr->xres <= best->xres && curr->yres <= best->yres) &&				(curr->xres >= xres && curr->yres >= yres)) {			mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too large.\n",						best->xres, best->yres);			best = curr;		} else {			if (curr->xres < xres || curr->yres < yres)				mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n");			else if (curr->xres > best->xres || curr->yres > best->yres)				mp_msg(MSGT_VO, MSGL_DBG2, "too large.\n");			else mp_msg(MSGT_VO, MSGL_DBG2, "it's worse, don't know why.\n");		}	}	return best;}static void set_bpp(struct fb_var_screeninfo *p, int bpp){	p->bits_per_pixel = (bpp + 1) & ~1;	p->red.msb_right = p->green.msb_right = p->blue.msb_right = p->transp.msb_right = 0;	p->transp.offset = p->transp.length = 0;	p->blue.offset = 0;	switch (bpp) {		case 32:			p->transp.offset = 24;			p->transp.length = 8;		case 24:			p->red.offset = 16;			p->red.length = 8;			p->green.offset = 8;			p->green.length = 8;			p->blue.length = 8;			break;		case 16:			p->red.offset = 11;			p->green.length = 6;			p->red.length = 5;			p->green.offset = 5;			p->blue.length = 5;			break;		case 15:			p->red.offset = 10;			p->green.length = 5;			p->red.length = 5;			p->green.offset = 5;			p->blue.length = 5;			break;	}}static void fb_mode2fb_vinfo(fb_mode_t *m, struct fb_var_screeninfo *v){	v->xres = m->xres;	v->yres = m->yres;	v->xres_virtual = m->vxres;	v->yres_virtual = m->vyres;	set_bpp(v, m->depth);	v->pixclock = m->pixclock;	v->left_margin = m->left;	v->right_margin = m->right;	v->upper_margin = m->upper;	v->lower_margin = m->lower;	v->hsync_len = m->hslen;	v->vsync_len = m->vslen;	v->sync = m->sync;	v->vmode = m->vmode;}/*******************************	    vo_fbdev	      *******************************//* command line/config file options */char *fb_dev_name = NULL;char *fb_mode_cfgfile = NULL;char *fb_mode_name = NULL;static fb_mode_t *fb_mode = NULL;/* vt related variables */static FILE *vt_fp = NULL;static int vt_doit = 1;/* vo_fbdev related variables */static int fb_dev_fd;static int fb_tty_fd = -1;static size_t fb_size;static uint8_t *frame_buffer;static uint8_t *center;	/* thx .so :) */static struct fb_fix_screeninfo fb_finfo;static struct fb_var_screeninfo fb_orig_vinfo;static struct fb_var_screeninfo fb_vinfo;static unsigned short fb_ored[256], fb_ogreen[256], fb_oblue[256];static struct fb_cmap fb_oldcmap = { 0, 256, fb_ored, fb_ogreen, fb_oblue };static int fb_cmap_changed = 0;static int fb_pixel_size;	// 32:  4  24:  3  16:  2  15:  2static int fb_bpp;		// 32: 32  24: 24  16: 16  15: 15static int fb_bpp_we_want;	// 32: 32  24: 24  16: 16  15: 15static int fb_line_len;static int fb_xres;static int fb_yres;static void (*draw_alpha_p)(int w, int h, unsigned char *src,		unsigned char *srca, int stride, unsigned char *dst,		int dstride);static int in_width;static int in_height;static int out_width;static int out_height;static int first_row;static int last_row;static uint32_t pixel_format;static int fs;/* * Note: this function is completely cut'n'pasted from * Chris Lawrence's code. * (modified a bit to fit in my code...) */static struct fb_cmap *make_directcolor_cmap(struct fb_var_screeninfo *var){  /* Hopefully any DIRECTCOLOR device will have a big enough palette   * to handle mapping the full color depth.   * e.g. 8 bpp -> 256 entry palette   *   * We could handle some sort of gamma here   */  int i, cols, rcols, gcols, bcols;  uint16_t *red, *green, *blue;  struct fb_cmap *cmap;          rcols = 1 << var->red.length;  gcols = 1 << var->green.length;  bcols = 1 << var->blue.length;    /* Make our palette the length of the deepest color */  cols = (rcols > gcols ? rcols : gcols);  cols = (cols > bcols ? cols : bcols);    red = malloc(cols * sizeof(red[0]));  if(!red) {	  mp_msg(MSGT_VO, MSGL_V, "Can't allocate red palette with %d entries.\n", cols);	  return NULL;  }  for(i=0; i< rcols; i++)    red[i] = (65535/(rcols-1)) * i;    green = malloc(cols * sizeof(green[0]));  if(!green) {	  mp_msg(MSGT_VO, MSGL_V, "Can't allocate green palette with %d entries.\n", cols);	  free(red);	  return NULL;  }  for(i=0; i< gcols; i++)    green[i] = (65535/(gcols-1)) * i;    blue = malloc(cols * sizeof(blue[0]));  if(!blue) {	  mp_msg(MSGT_VO, MSGL_V, "Can't allocate blue palette with %d entries.\n", cols);	  free(red);	  free(green);	  return NULL;  }  for(i=0; i< bcols; i++)    blue[i] = (65535/(bcols-1)) * i;    cmap = malloc(sizeof(struct fb_cmap));  if(!cmap) {	  mp_msg(MSGT_VO, MSGL_V, "Can't allocate color map\n");	  free(red);	  free(green);	  free(blue);	  return NULL;  }  cmap->start = 0;  cmap->transp = 0;  cmap->len = cols;  cmap->red = red;  cmap->blue = blue;  cmap->green = green;  cmap->transp = NULL;    return cmap;}static int fb_preinit(int reset){	static int fb_preinit_done = 0;	static int fb_works = 0;	if (reset)	{	    fb_preinit_done = 0;	    return 0;	}	if (fb_preinit_done)		return fb_works;	if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))		fb_dev_name = strdup("/dev/fb0");	mp_msg(MSGT_VO, MSGL_V, "using %s\n", fb_dev_name);	if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) {		mp_msg(MSGT_VO, MSGL_ERR, "Can't open %s: %s\n", fb_dev_name, strerror(errno));		goto err_out;	}	if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {		mp_msg(MSGT_VO, MSGL_ERR, "Can't get VSCREENINFO: %s\n", strerror(errno));		goto err_out_fd;	}	fb_orig_vinfo = fb_vinfo;        if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) {                mp_msg(MSGT_VO, MSGL_ERR, "notice: Can't open /dev/tty: %s\n", strerror(errno));        }	fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +		fb_vinfo.blue.length + fb_vinfo.transp.length;	if (fb_bpp == 8 && !vo_dbpp) {		mp_msg(MSGT_VO, MSGL_ERR, "8 bpp output is not supported.\n");		goto err_out_tty_fd;	}	if (vo_dbpp) {		if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 &&				vo_dbpp != 32) {			mp_msg(MSGT_VO, MSGL_ERR, "can't switch to %d bpp\n", vo_dbpp);			goto err_out_fd;		}		fb_bpp = vo_dbpp;			}		if (!fb_mode_cfgfile)	    fb_mode_cfgfile = strdup("/etc/fb.modes");	fb_preinit_done = 1;	fb_works = 1;	return 1;err_out_tty_fd:        close(fb_tty_fd);        fb_tty_fd = -1;err_out_fd:	close(fb_dev_fd);	fb_dev_fd = -1;err_out:	fb_preinit_done = 1;	fb_works = 0;	return 0;}static void lots_of_printf(void){	mp_msg(MSGT_VO, MSGL_V, "var info:\n");	mp_msg(MSGT_VO, MSGL_V, "xres: %u\n", fb_vinfo.xres);	mp_msg(MSGT_VO, MSGL_V, "yres: %u\n", fb_vinfo.yres);	mp_msg(MSGT_VO, MSGL_V, "xres_virtual: %u\n", fb_vinfo.xres_virtual);	mp_msg(MSGT_VO, MSGL_V, "yres_virtual: %u\n", fb_vinfo.yres_virtual);	mp_msg(MSGT_VO, MSGL_V, "xoffset: %u\n", fb_vinfo.xoffset);	mp_msg(MSGT_VO, MSGL_V, "yoffset: %u\n", fb_vinfo.yoffset);	mp_msg(MSGT_VO, MSGL_V, "bits_per_pixel: %u\n", fb_vinfo.bits_per_pixel);	mp_msg(MSGT_VO, MSGL_V, "grayscale: %u\n", fb_vinfo.grayscale);	mp_msg(MSGT_VO, MSGL_V, "red: %lu %lu %lu\n",			(unsigned long) fb_vinfo.red.offset,			(unsigned long) fb_vinfo.red.length,			(unsigned long) fb_vinfo.red.msb_right);	mp_msg(MSGT_VO, MSGL_V, "green: %lu %lu %lu\n",			(unsigned long) fb_vinfo.green.offset,			(unsigned long) fb_vinfo.green.length,			(unsigned long) fb_vinfo.green.msb_right);	mp_msg(MSGT_VO, MSGL_V, "blue: %lu %lu %lu\n",			(unsigned long) fb_vinfo.blue.offset,			(unsigned long) fb_vinfo.blue.length,			(unsigned long) fb_vinfo.blue.msb_right);	mp_msg(MSGT_VO, MSGL_V, "transp: %lu %lu %lu\n",			(unsigned long) fb_vinfo.transp.offset,			(unsigned long) fb_vinfo.transp.length,			(unsigned long) fb_vinfo.transp.msb_right);	mp_msg(MSGT_VO, MSGL_V, "nonstd: %u\n", fb_vinfo.nonstd);	mp_msg(MSGT_VO, MSGL_DBG2, "activate: %u\n", fb_vinfo.activate);	mp_msg(MSGT_VO, MSGL_DBG2, "height: %u\n", fb_vinfo.height);	mp_msg(MSGT_VO, MSGL_DBG2, "width: %u\n", fb_vinfo.width);	mp_msg(MSGT_VO, MSGL_DBG2, "accel_flags: %u\n", fb_vinfo.accel_flags);	mp_msg(MSGT_VO, MSGL_DBG2, "timing:\n");	mp_msg(MSGT_VO, MSGL_DBG2, "pixclock: %u\n", fb_vinfo.pixclock);	mp_msg(MSGT_VO, MSGL_DBG2, "left_margin: %u\n", fb_vinfo.left_margin);	mp_msg(MSGT_VO, MSGL_DBG2, "right_margin: %u\n", fb_vinfo.right_margin);	mp_msg(MSGT_VO, MSGL_DBG2, "upper_margin: %u\n", fb_vinfo.upper_margin);	mp_msg(MSGT_VO, MSGL_DBG2, "lower_margin: %u\n", fb_vinfo.lower_margin);	mp_msg(MSGT_VO, MSGL_DBG2, "hsync_len: %u\n", fb_vinfo.hsync_len);	mp_msg(MSGT_VO, MSGL_DBG2, "vsync_len: %u\n", fb_vinfo.vsync_len);	mp_msg(MSGT_VO, MSGL_DBG2, "sync: %u\n", fb_vinfo.sync);	mp_msg(MSGT_VO, MSGL_DBG2, "vmode: %u\n", fb_vinfo.vmode);	mp_msg(MSGT_VO, MSGL_V, "fix info:\n");	mp_msg(MSGT_VO, MSGL_V, "framebuffer size: %d bytes\n", fb_finfo.smem_len);	mp_msg(MSGT_VO, MSGL_V, "type: %lu\n", (unsigned long) fb_finfo.type);	mp_msg(MSGT_VO, MSGL_V, "type_aux: %lu\n", (unsigned long) fb_finfo.type_aux);	mp_msg(MSGT_VO, MSGL_V, "visual: %lu\n", (unsigned long) fb_finfo.visual);	mp_msg(MSGT_VO, MSGL_V, "line_length: %lu bytes\n", (unsigned long) fb_finfo.line_length);	mp_msg(MSGT_VO, MSGL_DBG2, "id: %.16s\n", fb_finfo.id);	mp_msg(MSGT_VO, MSGL_DBG2, "smem_start: %p\n", (void *) fb_finfo.smem_start);	mp_msg(MSGT_VO, MSGL_DBG2, "xpanstep: %u\n", fb_finfo.xpanstep);	mp_msg(MSGT_VO, MSGL_DBG2, "ypanstep: %u\n", fb_finfo.ypanstep);	mp_msg(MSGT_VO, MSGL_DBG2, "ywrapstep: %u\n", fb_finfo.ywrapstep);	mp_msg(MSGT_VO, MSGL_DBG2, "mmio_start: %p\n", (void *) fb_finfo.mmio_start);	mp_msg(MSGT_VO, MSGL_DBG2, "mmio_len: %u bytes\n", fb_finfo.mmio_len);	mp_msg(MSGT_VO, MSGL_DBG2, "accel: %u\n", fb_finfo.accel);	mp_msg(MSGT_VO, MSGL_V, "fb_bpp: %d\n", fb_bpp);	mp_msg(MSGT_VO, MSGL_V, "fb_pixel_size: %d bytes\n", fb_pixel_size);	mp_msg(MSGT_VO, MSGL_V, "other:\n");	mp_msg(MSGT_VO, MSGL_V, "in_width: %d\n", in_width);	mp_msg(MSGT_VO, MSGL_V, "in_height: %d\n", in_height);	mp_msg(MSGT_VO, MSGL_V, "out_width: %d\n", out_width);	mp_msg(MSGT_VO, MSGL_V, "out_height: %d\n", out_height);	mp_msg(MSGT_VO, MSGL_V, "first_row: %d\n", first_row);	mp_msg(MSGT_VO, MSGL_V, "last_row: %d\n", last_row);	mp_msg(MSGT_VO, MSGL_DBG2, "draw_alpha_p:%dbpp = %p\n", fb_bpp, draw_alpha_p);}static void vt_set_textarea(int u, int l){	/* how can I determine the font height?	 * just use 16 for now	 */	int urow = ((u + 15) / 16) + 1;	int lrow = l / 16;	mp_msg(MSGT_VO, MSGL_DBG2, "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow);	if(vt_fp) {	  fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0);	  fflush(vt_fp);	}}static int config(uint32_t width, uint32_t height, uint32_t d_width,		uint32_t d_height, uint32_t flags, char *title,		uint32_t format){	struct fb_cmap *cmap;	int vm = flags & VOFLAG_MODESWITCHING;	int zoom = flags & VOFLAG_SWSCALE;	int vt_fd;	fs = flags & VOFLAG_FULLSCREEN;

⌨️ 快捷键说明

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