diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2008-11-25 21:12:01 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2008-11-25 21:12:01 +0200 |
commit | 835511ac394d5283c9c449e6154ccb0db1365321 (patch) | |
tree | c223ee6b82481a0030273cfae9e831dada249fd8 /libvo | |
parent | 6c712271ce9e8d4eb9cd615e920139ebcb1d1d49 (diff) | |
parent | cc5e0406412a5f8b4e6e7094f6ffa18a65decd74 (diff) | |
download | mpv-835511ac394d5283c9c449e6154ccb0db1365321.tar.bz2 mpv-835511ac394d5283c9c449e6154ccb0db1365321.tar.xz |
Merge svn changes up to r28038
Diffstat (limited to 'libvo')
-rw-r--r-- | libvo/video_out.h | 4 | ||||
-rw-r--r-- | libvo/vo_direct3d.c | 162 | ||||
-rw-r--r-- | libvo/vo_fbdev.c | 1813 | ||||
-rw-r--r-- | libvo/vo_gl.c | 42 | ||||
-rw-r--r-- | libvo/vo_macosx.m | 12 | ||||
-rw-r--r-- | libvo/vo_quartz.c | 2512 | ||||
-rw-r--r-- | libvo/vo_wii.c | 275 | ||||
-rw-r--r-- | libvo/vo_x11.c | 37 | ||||
-rw-r--r-- | libvo/vo_xvmc.c | 9 |
9 files changed, 2392 insertions, 2474 deletions
diff --git a/libvo/video_out.h b/libvo/video_out.h index e392b55f2b..7ad09a74a8 100644 --- a/libvo/video_out.h +++ b/libvo/video_out.h @@ -286,8 +286,6 @@ extern int vo_colorkey; extern int WinID; -#if defined(CONFIG_FBDEV) || defined(CONFIG_VESA) - typedef struct { float min; float max; @@ -300,6 +298,4 @@ extern char *monitor_hfreq_str; extern char *monitor_vfreq_str; extern char *monitor_dotclock_str; -#endif /* defined(CONFIG_FBDEV) || defined(CONFIG_VESA) */ - #endif /* MPLAYER_VIDEO_OUT_H */ diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index 43f594777c..78b8dbc159 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -52,9 +52,9 @@ const LIBVO_EXTERN(direct3d) static struct global_priv { int is_paused; /**< 1 = Movie is paused, 0 = Movie is not paused */ - int is_cfg_finished; /**< Synchronization "semaphore". 1 when - instance of reconfigure_d3d is finished */ - + int is_clear_needed; /**< 1 = Clear the backbuffer before StretchRect + 0 = (default) Don't clear it */ + D3DLOCKED_RECT locked_rect; /**< The locked Offscreen surface */ RECT fs_movie_rect; /**< Rect (upscaled) of the movie when displayed in fullscreen */ RECT fs_panscan_rect; /**< PanScan source surface cropping in @@ -155,6 +155,12 @@ static void calc_fs_rect(void) "<vo_direct3d>Fullscreen Movie Rect: t: %ld, l: %ld, r: %ld, b:%ld\r\n", priv->fs_movie_rect.top, priv->fs_movie_rect.left, priv->fs_movie_rect.right, priv->fs_movie_rect.bottom); + + /* The backbuffer should be cleared before next StretchRect. This is + * necessary because our new draw area could be smaller than the + * previous one used by StretchRect and without it, leftovers from the + * previous frame will be left. */ + priv->is_clear_needed = 1; } /** @brief Destroy D3D Context related to the current window. @@ -164,6 +170,11 @@ static void destroy_d3d_context(void) mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>destroy_d3d_context called\r\n"); /* Let's destroy the old (if any) D3D Content */ + if (priv->locked_rect.pBits) { + IDirect3DSurface9_UnlockRect(priv->d3d_surface); + priv->locked_rect.pBits = NULL; + } + if (priv->d3d_surface != NULL) { IDirect3DSurface9_Release (priv->d3d_surface); priv->d3d_surface = NULL; @@ -254,10 +265,6 @@ static int reconfigure_d3d(void) return 0; } - /* Fill the Surface with black color. */ - IDirect3DDevice9_ColorFill(priv->d3d_device, priv->d3d_surface, NULL, - D3DCOLOR_ARGB(0xFF, 0, 0, 0) ); - calc_fs_rect(); return 1; @@ -269,9 +276,6 @@ static void uninit_d3d(void) { mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>uninit_d3d called\r\n"); - /* Block further calls to reconfigure_d3d(). */ - priv->is_cfg_finished = 0; - /* Destroy D3D Context inside the window. */ destroy_d3d_context(); @@ -288,40 +292,48 @@ static void uninit_d3d(void) */ static uint32_t render_d3d_frame(mp_image_t *mpi) { - D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order - to copy MPlayer's frame inside it.*/ - /* Uncomment when direct rendering is implemented. * if (mpi->flags & MP_IMGFLAG_DIRECT) ... */ if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) - return VO_TRUE; + goto skip_upload; if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Copy a planar frame. */ draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0); - return VO_TRUE; + goto skip_upload; } - /* If the previous if failed, we should draw a packed frame */ - if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, - &locked_rect, NULL, 0))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>Surface lock failure\n"); - return VO_ERROR; + /* If we're here, then we should lock the rect and copy a packed frame */ + if (!priv->locked_rect.pBits) { + if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, + &priv->locked_rect, NULL, 0))) { + mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>Surface lock failure\n"); + return VO_ERROR; + } } - memcpy_pic(locked_rect.pBits, mpi->planes[0], mpi->stride[0], - mpi->height, locked_rect.Pitch, mpi->stride[0]); + memcpy_pic(priv->locked_rect.pBits, mpi->planes[0], mpi->stride[0], + mpi->height, priv->locked_rect.Pitch, mpi->stride[0]); +skip_upload: + /* This unlock is used for both slice_draw path and render_d3d_frame path. */ if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) { mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface unlock failure\n"); return VO_ERROR; } + priv->locked_rect.pBits = NULL; + + if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { + mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed\n"); + return VO_ERROR; + } + + if (priv->is_clear_needed) { + IDirect3DDevice9_Clear (priv->d3d_device, 0, NULL, + D3DCLEAR_TARGET, 0, 0, 0); + priv->is_clear_needed = 0; + } if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device, priv->d3d_surface, @@ -441,9 +453,6 @@ static int preinit(const char *arg) return -1; } - /* Allow the first call to reconfigure_d3d. */ - priv->is_cfg_finished = 1; - return 0; } @@ -527,14 +536,9 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, return VO_ERROR; } - if (priv->is_cfg_finished) { - priv->is_cfg_finished = 0; - if (!reconfigure_d3d()) { - priv->is_cfg_finished = 1; - return VO_ERROR; - } - priv->is_cfg_finished = 1; - } + if (!reconfigure_d3d()) + return VO_ERROR; + return 0; /* Success */ } @@ -560,7 +564,6 @@ static void flip_page(void) mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Video adapter reinitialized.\n"); } - /*IDirect3DDevice9_Clear (priv->d3d_device, 0, NULL, D3DCLEAR_TARGET, 0, 0, 0);*/ } /** @brief libvo Callback: Draw OSD/Subtitles, @@ -607,75 +610,50 @@ static void check_events(void) */ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) { - D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order - to copy MPlayer's frame inside it.*/ - char *Src; /**< Pointer to the source image */ - char *Dst; /**< Pointer to the destination image */ - int UVstride; /**< Stride of the U/V planes */ - - if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, - &locked_rect, NULL, 0))) { - mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface lock failure\n"); - return VO_FALSE; + char *my_src; /**< Pointer to the source image */ + char *dst; /**< Pointer to the destination image */ + int uv_stride; /**< Stride of the U/V planes */ + + /* Lock the offscreen surface if it's not already locked. */ + if (!priv->locked_rect.pBits) { + if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, + &priv->locked_rect, NULL, 0))) { + mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface lock failure\n"); + return VO_FALSE; + } } - UVstride = locked_rect.Pitch / 2; + uv_stride = priv->locked_rect.Pitch / 2; /* Copy Y */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * y + x; - Src=src[0]; - memcpy_pic(Dst, Src, w, h, locked_rect.Pitch, stride[0]); + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * y + x; + my_src=src[0]; + memcpy_pic(dst, my_src, w, h, priv->locked_rect.Pitch, stride[0]); w/=2;h/=2;x/=2;y/=2; /* Copy U */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * priv->src_height - + UVstride * y + x; + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * priv->src_height + + uv_stride * y + x; if (priv->movie_src_fmt == MAKEFOURCC('Y','V','1','2')) - Src=src[2]; + my_src=src[2]; else - Src=src[1]; + my_src=src[1]; - memcpy_pic(Dst, Src, w, h, UVstride, stride[1]); + memcpy_pic(dst, my_src, w, h, uv_stride, stride[1]); /* Copy V */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * priv->src_height - + UVstride * (priv->src_height / 2) + UVstride * y + x; + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * priv->src_height + + uv_stride * (priv->src_height / 2) + uv_stride * y + x; if (priv->movie_src_fmt == MAKEFOURCC('Y','V','1','2')) - Src=src[1]; + my_src=src[1]; else - Src=src[2]; - - memcpy_pic(Dst, Src, w, h, UVstride, stride[2]); + my_src=src[2]; - if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) { - mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface unlock failure\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device, - priv->d3d_surface, - &priv->fs_panscan_rect, - priv->d3d_backbuf, - &priv->fs_movie_rect, - D3DTEXF_LINEAR))) { - mp_msg(MSGT_VO,MSGL_V, - "<vo_direct3d>Unable to copy the frame to the back buffer\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DDevice9_EndScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>EndScene failed\n"); - return VO_ERROR; - } + memcpy_pic(dst, my_src, w, h, uv_stride, stride[2]); return 0; /* Success */ } diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c index e8f5e86ba7..310e3e0400 100644 --- a/libvo/vo_fbdev.c +++ b/libvo/vo_fbdev.c @@ -2,7 +2,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 * Some fixes and small improvements by Joey Parrish <joey@nicewarrior.org> */ @@ -33,10 +33,10 @@ #include "mp_msg.h" static const vo_info_t info = { - "Framebuffer Device", - "fbdev", - "Szabolcs Berecz <szabi@inf.elte.hu>", - "" + "Framebuffer Device", + "fbdev", + "Szabolcs Berecz <szabi@inf.elte.hu>", + "" }; LIBVO_EXTERN(fbdev) @@ -48,39 +48,39 @@ static vidix_grkey_t gr_key; #endif static signed int pre_init_err = -2; /****************************** -* fb.modes support * -******************************/ + * fb.modes support * + ******************************/ static range_t *monitor_hfreq = NULL; static range_t *monitor_vfreq = NULL; static range_t *monitor_dotclock = NULL; 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; + 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 MAX_NR_TOKEN 16 +#define MAX_NR_TOKEN 16 -#define MAX_LINE_LEN 1000 +#define MAX_LINE_LEN 1000 -#define RET_EOF -1 -#define RET_EOL -2 +#define RET_EOF -1 +#define RET_EOL -2 static int validate_mode(fb_mode_t *m) { - if (!m->xres) { - mp_msg(MSGT_VO, MSGL_V, "needs geometry "); - return 0; - } - if (!m->pixclock) { - mp_msg(MSGT_VO, MSGL_V, "needs timings "); - return 0; - } - return 1; + if (!m->xres) { + mp_msg(MSGT_VO, MSGL_V, "needs geometry "); + return 0; + } + if (!m->pixclock) { + mp_msg(MSGT_VO, MSGL_V, "needs timings "); + return 0; + } + return 1; } static FILE *fp; @@ -90,58 +90,58 @@ 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) { - mp_msg(MSGT_VO, MSGL_V, "get_token(): max >= MAX_NR_TOKEN!\n"); - 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; - 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 */; - if (!line[line_pos]) - goto out_eol; - line[line_pos] = ' '; - } 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'; - } + static int read_nextline = 1; + static int line_pos; + int i; + char c; + + if (num >= MAX_NR_TOKEN) { + mp_msg(MSGT_VO, MSGL_V, "get_token(): max >= MAX_NR_TOKEN!\n"); + 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; + 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 */; + if (!line[line_pos]) + goto out_eol; + line[line_pos] = ' '; + } 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'; + } out_ok: - return i; + return i; out_eof: - return RET_EOF; + return RET_EOF; out_eol: - return RET_EOL; + return RET_EOL; } static fb_mode_t *fb_modes = NULL; @@ -150,388 +150,389 @@ static int nr_modes = 0; static int parse_fbmode_cfg(char *cfgfile) { #define CHECK_IN_MODE_DEF\ - if (!in_mode_def) {\ - mp_msg(MSGT_VO, MSGL_V, "'needs 'mode' first");\ - goto err_out_print_linenum;\ - } - fb_mode_t *mode = NULL; - char *endptr; // strtoul()... - int in_mode_def = 0; - int tmp, i; - - /* If called more than once, reuse parsed data */ - if (nr_modes) - return nr_modes; - - mp_msg(MSGT_VO, MSGL_V, "Reading %s: ", cfgfile); - - if ((fp = fopen(cfgfile, "r")) == NULL) { - mp_msg(MSGT_VO, MSGL_V, "can't open '%s': %s\n", cfgfile, strerror(errno)); - return -1; - } - - if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { - mp_msg(MSGT_VO, MSGL_V, "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 (in_mode_def) { - mp_msg(MSGT_VO, MSGL_V, "'endmode' required"); - goto err_out_print_linenum; - } - 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)))) { - mp_msg(MSGT_VO, MSGL_V, "can't realloc 'fb_modes' (nr_modes = %d):" - " %s\n", nr_modes, 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)) { - mp_msg(MSGT_VO, MSGL_V, "mode name '%s' isn't unique", token[0]); - goto err_out_print_linenum; - } - } - if (!(mode->name = strdup(token[0]))) { - mp_msg(MSGT_VO, MSGL_V, "can't strdup -> 'name': %s\n", strerror(errno)); - goto err_out; - } - in_mode_def = 1; - } else if (!strcmp(token[0], "geometry")) { - CHECK_IN_MODE_DEF; - 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")) { - CHECK_IN_MODE_DEF; - 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")) { - CHECK_IN_MODE_DEF; - in_mode_def = 0; - } else if (!strcmp(token[0], "accel")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - /* - * it's only used for text acceleration - * so we just ignore it. - */ - } else if (!strcmp(token[0], "hsync")) { - CHECK_IN_MODE_DEF; - 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")) { - CHECK_IN_MODE_DEF; - 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")) { - CHECK_IN_MODE_DEF; - 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")) { - CHECK_IN_MODE_DEF; - 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")) { - CHECK_IN_MODE_DEF; - 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], "double")) { - CHECK_IN_MODE_DEF; - 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; + if (!in_mode_def) {\ + mp_msg(MSGT_VO, MSGL_V, "'needs 'mode' first");\ + goto err_out_print_linenum;\ + } + fb_mode_t *mode = NULL; + char *endptr; // strtoul()... + int in_mode_def = 0; + int tmp, i; + + /* If called more than once, reuse parsed data */ + if (nr_modes) + return nr_modes; + + mp_msg(MSGT_VO, MSGL_V, "Reading %s: ", cfgfile); + + if ((fp = fopen(cfgfile, "r")) == NULL) { + mp_msg(MSGT_VO, MSGL_V, "can't open '%s': %s\n", cfgfile, strerror(errno)); + return -1; + } + + if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { + mp_msg(MSGT_VO, MSGL_V, "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 (in_mode_def) { + mp_msg(MSGT_VO, MSGL_V, "'endmode' required"); + goto err_out_print_linenum; + } + 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)))) { + mp_msg(MSGT_VO, MSGL_V, "can't realloc 'fb_modes' (nr_modes = %d):" + " %s\n", nr_modes, 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)) { + mp_msg(MSGT_VO, MSGL_V, "mode name '%s' isn't unique", token[0]); + goto err_out_print_linenum; + } + } + if (!(mode->name = strdup(token[0]))) { + mp_msg(MSGT_VO, MSGL_V, "can't strdup -> 'name': %s\n", strerror(errno)); + goto err_out; + } + in_mode_def = 1; + } else if (!strcmp(token[0], "geometry")) { + CHECK_IN_MODE_DEF; + 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")) { + CHECK_IN_MODE_DEF; + 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")) { + CHECK_IN_MODE_DEF; + in_mode_def = 0; + } else if (!strcmp(token[0], "accel")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + /* + * it's only used for text acceleration + * so we just ignore it. + */ + } else if (!strcmp(token[0], "hsync")) { + CHECK_IN_MODE_DEF; + 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")) { + CHECK_IN_MODE_DEF; + 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")) { + CHECK_IN_MODE_DEF; + 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")) { + CHECK_IN_MODE_DEF; + 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")) { + CHECK_IN_MODE_DEF; + 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], "double")) { + CHECK_IN_MODE_DEF; + 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: - mp_msg(MSGT_VO, MSGL_V, "%d modes\n", nr_modes); - free(line); - fclose(fp); - return nr_modes; + mp_msg(MSGT_VO, MSGL_V, "%d modes\n", nr_modes); + free(line); + fclose(fp); + return nr_modes; err_out_parse_error: - mp_msg(MSGT_VO, MSGL_V, "parse error"); + mp_msg(MSGT_VO, MSGL_V, "parse error"); err_out_print_linenum: - mp_msg(MSGT_VO, MSGL_V, " at line %d\n", line_num); + mp_msg(MSGT_VO, MSGL_V, " at line %d\n", line_num); err_out: - if (fb_modes) { - free(fb_modes); - fb_modes = NULL; - } - nr_modes = 0; - free(line); - free(fp); - return -2; + if (fb_modes) { + free(fb_modes); + fb_modes = NULL; + } + nr_modes = 0; + free(line); + free(fp); + return -2; err_out_not_valid: - mp_msg(MSGT_VO, MSGL_V, "previous mode is not correct"); - goto err_out_print_linenum; + mp_msg(MSGT_VO, MSGL_V, "previous mode is not correct"); + goto err_out_print_linenum; } static fb_mode_t *find_mode_by_name(char *name) { - int i; + int i; - for (i = 0; i < nr_modes; i++) - if (!strcmp(name, fb_modes[i].name)) - return fb_modes + i; - return NULL; + for (i = 0; i < nr_modes; i++) + if (!strcmp(name, fb_modes[i].name)) + return fb_modes + i; + return NULL; } -static float dcf(fb_mode_t *m) //driving clock frequency +static float dcf(fb_mode_t *m) //driving clock frequency { - return 1e12f / m->pixclock; + return 1e12f / m->pixclock; } -static float hsf(fb_mode_t *m) //horizontal scan frequency +static float hsf(fb_mode_t *m) //horizontal scan frequency { - int htotal = m->left + m->xres + m->right + m->hslen; - return dcf(m) / htotal; + int htotal = m->left + m->xres + m->right + m->hslen; + return dcf(m) / htotal; } -static float vsf(fb_mode_t *m) //vertical scan frequency +static float vsf(fb_mode_t *m) //vertical scan frequency { - int vtotal = m->upper + m->yres + m->lower + m->vslen; - return hsf(m) / vtotal; + int vtotal = m->upper + m->yres + m->lower + m->vslen; + return hsf(m) / vtotal; } static int mode_works(fb_mode_t *m, range_t *hfreq, range_t *vfreq, - range_t *dotclock) + range_t *dotclock) { - float h = hsf(m); - float v = vsf(m); - float d = dcf(m); - int ret = 1; - - mp_msg(MSGT_VO, MSGL_DBG2, "mode %dx%d:", m->xres, m->yres); - if (!in_range(hfreq, h)) { - ret = 0; - 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; + |