mirror of
https://github.com/mpv-player/mpv
synced 2024-12-23 23:32:26 +00:00
video mode change supported
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@360 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
feb552b3de
commit
e4c07a314f
566
libvo/vo_fbdev.c
566
libvo/vo_fbdev.c
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Video driver for Framebuffer device
|
||||
* by Szabolcs Berecz <szabi@inf.elte.hu>
|
||||
* (C) 2001
|
||||
*
|
||||
* Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27
|
||||
*/
|
||||
@ -11,6 +12,8 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -35,33 +38,334 @@ static vo_info_t vo_info = {
|
||||
""
|
||||
};
|
||||
|
||||
static int vt_active = -1;
|
||||
static int vt_fd;
|
||||
/******************************
|
||||
* fb.modes parser *
|
||||
******************************/
|
||||
|
||||
/*
|
||||
* read the fb.modes manual page!
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint32_t xres, yres, vxres, vyres, depth;
|
||||
uint32_t pixclock, left, right, upper, lower, hslen, vslen;
|
||||
uint32_t sync;
|
||||
uint32_t vmode;
|
||||
} fb_mode_t;
|
||||
|
||||
#define PRINT_LINENUM printf(" at line %d\n", line_num)
|
||||
|
||||
#define MAX_NR_TOKEN 16
|
||||
|
||||
#define MAX_LINE_LEN 1000
|
||||
|
||||
#define RET_EOF -1
|
||||
#define RET_EOL -2
|
||||
|
||||
static int validate_mode(fb_mode_t *m)
|
||||
{
|
||||
if (!m->xres) {
|
||||
printf("needs geometry ");
|
||||
return 0;
|
||||
}
|
||||
if (!m->pixclock) {
|
||||
printf("needs timings ");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static FILE *fp;
|
||||
static int line_num = 0;
|
||||
static char *line;
|
||||
static char *token[MAX_NR_TOKEN];
|
||||
|
||||
static int get_token(int num)
|
||||
{
|
||||
static int read_nextline = 1;
|
||||
static int line_pos;
|
||||
int i;
|
||||
char c;
|
||||
|
||||
if (num >= MAX_NR_TOKEN) {
|
||||
printf("get_token(): max >= MAX_NR_TOKEN!");
|
||||
goto out_eof;
|
||||
}
|
||||
|
||||
if (read_nextline) {
|
||||
if (!fgets(line, MAX_LINE_LEN, fp))
|
||||
goto out_eof;
|
||||
line_pos = 0;
|
||||
++line_num;
|
||||
read_nextline = 0;
|
||||
}
|
||||
for (i = 0; i < num; i++) {
|
||||
while (isspace(line[line_pos]))
|
||||
++line_pos;
|
||||
if (line[line_pos] == '\0' || line[line_pos] == '#') {
|
||||
read_nextline = 1;
|
||||
if (i == num)
|
||||
goto out_ok;
|
||||
goto out_eol;
|
||||
}
|
||||
token[i] = line + line_pos;
|
||||
c = line[line_pos];
|
||||
if (c == '"' || c == '\'') {
|
||||
token[i]++;
|
||||
while (line[++line_pos] != c && line[line_pos])
|
||||
/* NOTHING */;
|
||||
} else {
|
||||
for (/* NOTHING */; !isspace(line[line_pos]) &&
|
||||
line[line_pos]; line_pos++)
|
||||
/* NOTHING */;
|
||||
}
|
||||
if (!line[line_pos]) {
|
||||
read_nextline = 1;
|
||||
if (i == num - 1)
|
||||
goto out_ok;
|
||||
goto out_eol;
|
||||
}
|
||||
line[line_pos] = '\0';
|
||||
line_pos++;
|
||||
}
|
||||
out_ok:
|
||||
return i;
|
||||
out_eof:
|
||||
return RET_EOF;
|
||||
out_eol:
|
||||
return RET_EOL;
|
||||
}
|
||||
|
||||
static fb_mode_t *fb_modes = NULL;
|
||||
static int nr_modes = 0;
|
||||
|
||||
static int parse_fbmode_cfg(char *cfgfile)
|
||||
{
|
||||
fb_mode_t *mode = NULL;
|
||||
char *endptr; // strtoul()...
|
||||
int tmp, i;
|
||||
|
||||
#ifdef DEBUG
|
||||
assert(cfgfile != NULL);
|
||||
#endif
|
||||
|
||||
printf("Reading %s: ", cfgfile);
|
||||
|
||||
if ((fp = fopen(cfgfile, "r")) == NULL) {
|
||||
printf("can't open '%s': %s\n", cfgfile, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) {
|
||||
printf("can't get memory for 'line': %s\n", strerror(errno));
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if the cfgfile starts with 'mode'
|
||||
*/
|
||||
while ((tmp = get_token(1)) == RET_EOL)
|
||||
/* NOTHING */;
|
||||
if (tmp == RET_EOF)
|
||||
goto out;
|
||||
if (!strcmp(token[0], "mode"))
|
||||
goto loop_enter;
|
||||
goto err_out_parse_error;
|
||||
|
||||
while ((tmp = get_token(1)) != RET_EOF) {
|
||||
if (tmp == RET_EOL)
|
||||
continue;
|
||||
if (!strcmp(token[0], "mode")) {
|
||||
if (!validate_mode(mode))
|
||||
goto err_out_not_valid;
|
||||
loop_enter:
|
||||
if (!(fb_modes = (fb_mode_t *) realloc(fb_modes,
|
||||
sizeof(fb_mode_t) * (nr_modes + 1)))) {
|
||||
printf("can't realloc 'fb_modes': %s\n", strerror(errno));
|
||||
goto err_out;
|
||||
}
|
||||
mode=fb_modes + nr_modes;
|
||||
++nr_modes;
|
||||
memset(mode,0,sizeof(fb_mode_t));
|
||||
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
for (i = 0; i < nr_modes - 1; i++) {
|
||||
if (!strcmp(token[0], fb_modes[i].name)) {
|
||||
printf("mode name '%s' isn't unique", token[0]);
|
||||
goto err_out_print_linenum;
|
||||
}
|
||||
}
|
||||
if (!(mode->name = strdup(token[0]))) {
|
||||
printf("can't strdup -> 'name': %s\n", strerror(errno));
|
||||
goto err_out;
|
||||
}
|
||||
} else if (!strcmp(token[0], "geometry")) {
|
||||
if (get_token(5) < 0)
|
||||
goto err_out_parse_error;
|
||||
mode->xres = strtoul(token[0], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->yres = strtoul(token[1], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->vxres = strtoul(token[2], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->vyres = strtoul(token[3], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->depth = strtoul(token[4], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "timings")) {
|
||||
if (get_token(7) < 0)
|
||||
goto err_out_parse_error;
|
||||
mode->pixclock = strtoul(token[0], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->left = strtoul(token[1], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->right = strtoul(token[2], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->upper = strtoul(token[3], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->lower = strtoul(token[4], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->hslen = strtoul(token[5], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
mode->vslen = strtoul(token[6], &endptr, 0);
|
||||
if (*endptr)
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "endmode")) {
|
||||
/* NOTHING for now*/
|
||||
} else if (!strcmp(token[0], "hsync")) {
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
if (!strcmp(token[0], "low"))
|
||||
mode->sync &= ~FB_SYNC_HOR_HIGH_ACT;
|
||||
else if(!strcmp(token[0], "high"))
|
||||
mode->sync |= FB_SYNC_HOR_HIGH_ACT;
|
||||
else
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "vsync")) {
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
if (!strcmp(token[0], "low"))
|
||||
mode->sync &= ~FB_SYNC_VERT_HIGH_ACT;
|
||||
else if(!strcmp(token[0], "high"))
|
||||
mode->sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
else
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "csync")) {
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
if (!strcmp(token[0], "low"))
|
||||
mode->sync &= ~FB_SYNC_COMP_HIGH_ACT;
|
||||
else if(!strcmp(token[0], "high"))
|
||||
mode->sync |= FB_SYNC_COMP_HIGH_ACT;
|
||||
else
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "extsync")) {
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
if (!strcmp(token[0], "false"))
|
||||
mode->sync &= ~FB_SYNC_EXT;
|
||||
else if(!strcmp(token[0], "true"))
|
||||
mode->sync |= FB_SYNC_EXT;
|
||||
else
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "laced")) {
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
if (!strcmp(token[0], "false"))
|
||||
mode->vmode = FB_VMODE_NONINTERLACED;
|
||||
else if (!strcmp(token[0], "true"))
|
||||
mode->vmode = FB_VMODE_INTERLACED;
|
||||
else
|
||||
goto err_out_parse_error;
|
||||
} else if (!strcmp(token[0], "dblscan")) {
|
||||
if (get_token(1) < 0)
|
||||
goto err_out_parse_error;
|
||||
if (!strcmp(token[0], "false"))
|
||||
;
|
||||
else if (!strcmp(token[0], "true"))
|
||||
mode->vmode = FB_VMODE_DOUBLE;
|
||||
else
|
||||
goto err_out_parse_error;
|
||||
} else
|
||||
goto err_out_parse_error;
|
||||
}
|
||||
if (!validate_mode(mode))
|
||||
goto err_out_not_valid;
|
||||
out:
|
||||
printf("%d modes\n", nr_modes);
|
||||
free(line);
|
||||
fclose(fp);
|
||||
return nr_modes;
|
||||
err_out_parse_error:
|
||||
printf("parse error");
|
||||
err_out_print_linenum:
|
||||
PRINT_LINENUM;
|
||||
err_out:
|
||||
if (fb_modes)
|
||||
free(fb_modes);
|
||||
free(line);
|
||||
free(fp);
|
||||
return -2;
|
||||
err_out_not_valid:
|
||||
printf("mode is not definied correctly");
|
||||
goto err_out_print_linenum;
|
||||
}
|
||||
|
||||
static fb_mode_t *find_mode_by_name(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_modes; i++) {
|
||||
if (!strcmp(name, fb_modes[i].name))
|
||||
return fb_modes + i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* vo_fbdev *
|
||||
******************************/
|
||||
|
||||
static int fb_init_done = 0;
|
||||
static int fb_works = 0;
|
||||
char *fb_dev_name = NULL;
|
||||
static int fb_dev_fd;
|
||||
static size_t fb_size;
|
||||
static uint8_t *frame_buffer;
|
||||
static int fb_pixel_size;
|
||||
static int fb_bpp;
|
||||
static int fb_bpp_on_screen;
|
||||
struct fb_fix_screeninfo fb_fix_info;
|
||||
struct fb_var_screeninfo fb_var_info;
|
||||
static uint32_t fb_xres_virtual;
|
||||
static uint32_t fb_yres_virtual;
|
||||
static struct fb_cmap *oldcmap = NULL;
|
||||
static struct fb_fix_screeninfo fb_finfo;
|
||||
static struct fb_var_screeninfo fb_orig_vinfo;
|
||||
static struct fb_var_screeninfo fb_vinfo;
|
||||
static struct fb_cmap *fb_oldcmap = NULL;
|
||||
static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
|
||||
static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15
|
||||
static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15
|
||||
static int fb_screen_width;
|
||||
|
||||
char *fb_mode_cfgfile = "/etc/fb.modes";
|
||||
char *fb_mode_name = NULL;
|
||||
static fb_mode_t *fb_mode = NULL;
|
||||
static int fb_switch_mode = 0;
|
||||
|
||||
static uint8_t *next_frame;
|
||||
static int in_width;
|
||||
static int in_height;
|
||||
static int out_width;
|
||||
static int out_height;
|
||||
static uint8_t *next_frame;
|
||||
static int screen_width;
|
||||
static uint32_t pixel_format;
|
||||
|
||||
static int fb_init_done = 0;
|
||||
static int fb_works = 0;
|
||||
|
||||
/*
|
||||
* Note: this function is completely cut'n'pasted from
|
||||
* Chris Lawrence's code.
|
||||
@ -138,6 +442,16 @@ static int fb_init(void)
|
||||
int fd;
|
||||
struct fb_cmap *cmap;
|
||||
|
||||
if (fb_mode_name) {
|
||||
if (parse_fbmode_cfg(fb_mode_cfgfile) < 0)
|
||||
return 1;
|
||||
if (!(fb_mode = find_mode_by_name(fb_mode_name))) {
|
||||
printf("fb_init: can't find requested video mode\n");
|
||||
return 1;
|
||||
}
|
||||
fb_switch_mode = 1;
|
||||
}
|
||||
|
||||
if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
|
||||
fb_dev_name = "/dev/fb0";
|
||||
printf("fb_init: using %s\n", fb_dev_name);
|
||||
@ -147,28 +461,75 @@ static int fb_init(void)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_var_info)) {
|
||||
if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
|
||||
printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno));
|
||||
goto err_out_fd;
|
||||
}
|
||||
|
||||
/* disable scrolling */
|
||||
fb_xres_virtual = fb_var_info.xres_virtual;
|
||||
fb_yres_virtual = fb_var_info.yres_virtual;
|
||||
fb_var_info.xres_virtual = fb_var_info.xres;
|
||||
fb_var_info.yres_virtual = fb_var_info.yres;
|
||||
fb_orig_vinfo = fb_vinfo;
|
||||
if (fb_switch_mode) {
|
||||
fb_vinfo.xres = fb_mode->xres;
|
||||
fb_vinfo.yres = fb_mode->yres;
|
||||
fb_vinfo.xres_virtual = fb_mode->vxres;
|
||||
fb_vinfo.yres_virtual = fb_mode->vyres;
|
||||
fb_vinfo.bits_per_pixel = fb_mode->depth;
|
||||
switch (fb_mode->depth) {
|
||||
case 32:
|
||||
case 24:
|
||||
fb_vinfo.red.offset = 16;
|
||||
fb_vinfo.red.length = 8;
|
||||
fb_vinfo.red.msb_right = 0;
|
||||
fb_vinfo.green.offset = 8;
|
||||
fb_vinfo.green.length = 8;
|
||||
fb_vinfo.green.msb_right = 0;
|
||||
fb_vinfo.blue.offset = 0;
|
||||
fb_vinfo.blue.length = 8;
|
||||
fb_vinfo.blue.msb_right = 0;
|
||||
case 16:
|
||||
fb_vinfo.red.offset = 11;
|
||||
fb_vinfo.red.length = 5;
|
||||
fb_vinfo.red.msb_right = 0;
|
||||
fb_vinfo.green.offset = 5;
|
||||
fb_vinfo.green.length = 6;
|
||||
fb_vinfo.green.msb_right = 0;
|
||||
fb_vinfo.blue.offset = 0;
|
||||
fb_vinfo.blue.length = 5;
|
||||
fb_vinfo.blue.msb_right = 0;
|
||||
case 15:
|
||||
fb_vinfo.red.offset = 10;
|
||||
fb_vinfo.red.length = 5;
|
||||
fb_vinfo.red.msb_right = 0;
|
||||
fb_vinfo.green.offset = 5;
|
||||
fb_vinfo.green.length = 5;
|
||||
fb_vinfo.green.msb_right = 0;
|
||||
fb_vinfo.blue.offset = 0;
|
||||
fb_vinfo.blue.length = 5;
|
||||
fb_vinfo.blue.msb_right = 0;
|
||||
}
|
||||
fb_vinfo.pixclock = fb_mode->pixclock;
|
||||
fb_vinfo.left_margin = fb_mode->left;
|
||||
fb_vinfo.right_margin = fb_mode->right;
|
||||
fb_vinfo.upper_margin = fb_mode->upper;
|
||||
fb_vinfo.lower_margin = fb_mode->lower;
|
||||
fb_vinfo.hsync_len = fb_mode->hslen;
|
||||
fb_vinfo.vsync_len = fb_mode->vslen;
|
||||
fb_vinfo.sync = fb_mode->sync;
|
||||
fb_vinfo.vmode = fb_mode->vmode;
|
||||
}
|
||||
fb_vinfo.xres_virtual = fb_vinfo.xres;
|
||||
fb_vinfo.yres_virtual = fb_vinfo.yres;
|
||||
|
||||
if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) {
|
||||
if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
|
||||
printf("fb_init: Can't put VSCREENINFO: %s\n", strerror(errno));
|
||||
goto err_out_fd;
|
||||
}
|
||||
|
||||
if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_fix_info)) {
|
||||
if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
|
||||
printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno));
|
||||
goto err_out_fd;
|
||||
return 1;
|
||||
}
|
||||
switch (fb_fix_info.type) {
|
||||
switch (fb_finfo.type) {
|
||||
case FB_TYPE_VGA_PLANES:
|
||||
printf("fb_init: FB_TYPE_VGA_PLANES not supported.\n");
|
||||
goto err_out_fd;
|
||||
@ -192,17 +553,17 @@ static int fb_init(void)
|
||||
printf("fb_init: FB_TYPE_PACKED_PIXELS: OK\n");
|
||||
break;
|
||||
default:
|
||||
printf("fb_init: unknown FB_TYPE: %d\n", fb_fix_info.type);
|
||||
printf("fb_init: unknown FB_TYPE: %d\n", fb_finfo.type);
|
||||
goto err_out_fd;
|
||||
}
|
||||
if (fb_fix_info.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
if (fb_finfo.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
printf("fb_init: creating cmap for directcolor\n");
|
||||
if (ioctl(fb_dev_fd, FBIOGETCMAP, oldcmap)) {
|
||||
if (ioctl(fb_dev_fd, FBIOGETCMAP, fb_oldcmap)) {
|
||||
printf("fb_init: can't get cmap: %s\n",
|
||||
strerror(errno));
|
||||
goto err_out_fd;
|
||||
}
|
||||
if (!(cmap = make_directcolor_cmap(&fb_var_info)))
|
||||
if (!(cmap = make_directcolor_cmap(&fb_vinfo)))
|
||||
goto err_out_fd;
|
||||
if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) {
|
||||
printf("fb_init: can't put cmap: %s\n",
|
||||
@ -213,18 +574,18 @@ static int fb_init(void)
|
||||
free(cmap->green);
|
||||
free(cmap->blue);
|
||||
free(cmap);
|
||||
} else if (fb_fix_info.visual != FB_VISUAL_TRUECOLOR) {
|
||||
} else if (fb_finfo.visual != FB_VISUAL_TRUECOLOR) {
|
||||
printf("fb_init: visual: %d not yet supported\n",
|
||||
fb_fix_info.visual);
|
||||
fb_finfo.visual);
|
||||
goto err_out_fd;
|
||||
}
|
||||
|
||||
fb_pixel_size = fb_var_info.bits_per_pixel / 8;
|
||||
fb_bpp = fb_var_info.red.length + fb_var_info.green.length +
|
||||
fb_var_info.blue.length;
|
||||
fb_bpp_on_screen = (fb_pixel_size == 4) ? 32 : fb_bpp;
|
||||
screen_width = fb_fix_info.line_length;
|
||||
fb_size = fb_fix_info.smem_len;
|
||||
fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
|
||||
fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
|
||||
fb_vinfo.blue.length;
|
||||
fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp;
|
||||
fb_screen_width = fb_finfo.line_length;
|
||||
fb_size = fb_finfo.smem_len;
|
||||
if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) {
|
||||
printf("fb_init: Can't mmap %s: %s\n", fb_dev_name, strerror(errno));
|
||||
@ -234,16 +595,16 @@ static int fb_init(void)
|
||||
printf("fb_init: framebuffer @ %p\n", frame_buffer);
|
||||
printf("fb_init: framebuffer size: %d bytes\n", fb_size);
|
||||
printf("fb_init: bpp: %d\n", fb_bpp);
|
||||
printf("fb_init: bpp on screen: %d\n", fb_bpp_on_screen);
|
||||
printf("fb_init: pixel size: %d\n", fb_pixel_size);
|
||||
printf("fb_init: pixel per line: %d\n", screen_width / fb_pixel_size);
|
||||
printf("fb_init: visual: %d\n", fb_fix_info.visual);
|
||||
printf("fb_init: red: %d %d %d\n", fb_var_info.red.offset,
|
||||
fb_var_info.red.length, fb_var_info.red.msb_right);
|
||||
printf("fb_init: green: %d %d %d\n", fb_var_info.green.offset,
|
||||
fb_var_info.green.length, fb_var_info.green.msb_right);
|
||||
printf("fb_init: blue: %d %d %d\n", fb_var_info.blue.offset,
|
||||
fb_var_info.blue.length, fb_var_info.blue.msb_right);
|
||||
printf("fb_init: real bpp: %d\n", fb_real_bpp);
|
||||
printf("fb_init: pixel size: %d bytes\n", fb_pixel_size);
|
||||
printf("fb_init: pixel per line: %d\n", fb_screen_width / fb_pixel_size);
|
||||
printf("fb_init: visual: %d\n", fb_finfo.visual);
|
||||
printf("fb_init: red: %d %d %d\n", fb_vinfo.red.offset,
|
||||
fb_vinfo.red.length, fb_vinfo.red.msb_right);
|
||||
printf("fb_init: green: %d %d %d\n", fb_vinfo.green.offset,
|
||||
fb_vinfo.green.length, fb_vinfo.green.msb_right);
|
||||
printf("fb_init: blue: %d %d %d\n", fb_vinfo.blue.offset,
|
||||
fb_vinfo.blue.length, fb_vinfo.blue.msb_right);
|
||||
|
||||
fb_init_done = 1;
|
||||
fb_works = 1;
|
||||
@ -277,8 +638,7 @@ static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width,
|
||||
}
|
||||
|
||||
if (format == IMGFMT_YV12)
|
||||
// yuv2rgb_init(fb_pixel_size * 8, MODE_RGB);
|
||||
yuv2rgb_init(fb_bpp_on_screen, MODE_RGB);
|
||||
yuv2rgb_init(fb_bpp, MODE_RGB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -292,65 +652,16 @@ static uint32_t query_format(uint32_t format)
|
||||
|
||||
if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
|
||||
int bpp = format & 0xff;
|
||||
if (bpp == fb_bpp_on_screen)
|
||||
if (bpp == fb_bpp)
|
||||
return 1;
|
||||
else if (bpp == 15 && fb_bpp_on_screen == 16)
|
||||
else if (bpp == 15 && fb_bpp == 16)
|
||||
return 1;
|
||||
else if (bpp == 24 && fb_bpp_on_screen == 32)
|
||||
else if (bpp == 24 && fb_bpp == 32)
|
||||
return 1;
|
||||
}
|
||||
if (format == IMGFMT_YV12)
|
||||
return 1;
|
||||
return 0;
|
||||
/*
|
||||
printf("vo_fbdev: query_format(%#x(%.4s)): ", format, &format);
|
||||
if (format & IMGFMT_BGR_MASK == IMGFMT_BGR)
|
||||
goto not_supported;
|
||||
switch (format) {
|
||||
case IMGFMT_YV12:
|
||||
goto supported;
|
||||
|
||||
case IMGFMT_RGB32:
|
||||
if (fb_bpp == 32)
|
||||
goto supported;
|
||||
break;
|
||||
case IMGFMT_RGB24:
|
||||
if (fb_bpp == 24)
|
||||
goto supported;
|
||||
break;
|
||||
case IMGFMT_RGB16:
|
||||
if (fb_bpp == 16)
|
||||
goto supported;
|
||||
break;
|
||||
case IMGFMT_RGB15:
|
||||
if (fb_bpp == 15)
|
||||
goto supported;
|
||||
break;
|
||||
|
||||
case IMGFMT_BGR|32:
|
||||
if (fb_bpp == 24 && fb_pixel_size == 4)
|
||||
goto supported;
|
||||
break;
|
||||
case IMGFMT_BGR|24:
|
||||
if (fb_bpp == 24 && fb_pixel_size == 3)
|
||||
goto supported;
|
||||
break;
|
||||
case IMGFMT_BGR|16:
|
||||
if (fb_bpp == 16)
|
||||
goto supported;
|
||||
break;
|
||||
case IMGFMT_BGR|15:
|
||||
if (fb_bpp == 15)
|
||||
goto supported;
|
||||
break;
|
||||
}
|
||||
not_supported:
|
||||
printf("not_supported\n");
|
||||
return 0;
|
||||
supported:
|
||||
printf("supported\n");
|
||||
return 1;
|
||||
*/
|
||||
}
|
||||
|
||||
static const vo_info_t *get_info(void)
|
||||
@ -361,6 +672,24 @@ static const vo_info_t *get_info(void)
|
||||
static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
|
||||
unsigned char *srca, int stride)
|
||||
{
|
||||
uint8_t *dst = next_frame + (in_width * y0 + x0) * fb_pixel_size;
|
||||
int dstride = in_width * fb_pixel_size;
|
||||
|
||||
switch (fb_real_bpp) {
|
||||
case 24:
|
||||
vo_draw_alpha_rgb24(w, h, src, srca, stride, dst, dstride);
|
||||
break;
|
||||
case 32:
|
||||
vo_draw_alpha_rgb32(w, h, src, srca, stride, dst, dstride);
|
||||
break;
|
||||
case 15:
|
||||
vo_draw_alpha_rgb15(w, h, src, srca, stride, dst, dstride);
|
||||
break;
|
||||
case 16:
|
||||
vo_draw_alpha_rgb16(w, h, src, srca, stride, dst, dstride);
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
int x, y;
|
||||
uint8_t *dst;
|
||||
|
||||
@ -379,6 +708,7 @@ static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
|
||||
srca += stride;
|
||||
}
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t draw_frame(uint8_t *src[])
|
||||
@ -392,7 +722,7 @@ static uint32_t draw_frame(uint8_t *src[])
|
||||
char *d = next_frame;
|
||||
char *s = src[0];
|
||||
if (sbpp == fb_pixel_size) {
|
||||
if (fb_bpp == 16 && pixel_format == (IMGFMT_BGR|15)) {
|
||||
if (fb_real_bpp == 16 && pixel_format == (IMGFMT_BGR|15)) {
|
||||
#ifdef HAVE_MMX
|
||||
rgb15to16_mmx(s, d, 2 * in_width * in_height);
|
||||
#else
|
||||
@ -408,16 +738,6 @@ static uint32_t draw_frame(uint8_t *src[])
|
||||
memcpy(d, s, sbpp * in_width * in_height);
|
||||
}
|
||||
}
|
||||
/*
|
||||
} else if ((pixel_format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
|
||||
if (pixel_format == fb_bpp_on_screen)
|
||||
memcpy(next_frame, src[0],
|
||||
in_width * in_height * fb_pixel_size);
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -443,7 +763,7 @@ static void put_frame(void)
|
||||
for (i = 0; i < in_height; i++) {
|
||||
memcpy(frame_buffer + out_offset, next_frame + in_offset,
|
||||
in_width * fb_pixel_size);
|
||||
out_offset += screen_width;
|
||||
out_offset += fb_screen_width;
|
||||
in_offset += in_width * fb_pixel_size;
|
||||
}
|
||||
}
|
||||
@ -458,22 +778,22 @@ static void flip_page(void)
|
||||
static void uninit(void)
|
||||
{
|
||||
printf("vo_fbdev: uninit\n");
|
||||
if (oldcmap) {
|
||||
if (ioctl(fb_dev_fd, FBIOPUTCMAP, oldcmap))
|
||||
if (fb_oldcmap) {
|
||||
if (ioctl(fb_dev_fd, FBIOPUTCMAP, fb_oldcmap))
|
||||
printf("vo_fbdev: Can't restore original cmap\n");
|
||||
oldcmap = NULL;
|
||||
fb_oldcmap = NULL;
|
||||
}
|
||||
fb_var_info.xres_virtual = fb_xres_virtual;
|
||||
fb_var_info.yres_virtual = fb_yres_virtual;
|
||||
if (fb_dev_fd != -1) {
|
||||
if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info))
|
||||
printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno));
|
||||
close(fb_dev_fd);
|
||||
if (fb_switch_mode)
|
||||
fb_vinfo = fb_orig_vinfo;
|
||||
else {
|
||||
fb_vinfo.xres_virtual = fb_orig_vinfo.xres_virtual;
|
||||
fb_vinfo.yres_virtual = fb_orig_vinfo.yres_virtual;
|
||||
}
|
||||
if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo))
|
||||
printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno));
|
||||
close(fb_dev_fd);
|
||||
memset(next_frame, '\0', in_height * in_width * fb_pixel_size);
|
||||
put_frame();
|
||||
if (vt_active >= 0)
|
||||
ioctl(vt_fd, VT_ACTIVATE, vt_active);
|
||||
free(next_frame);
|
||||
munmap(frame_buffer, fb_size);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user