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