summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2008-11-25 21:12:01 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2008-11-25 21:12:01 +0200
commit835511ac394d5283c9c449e6154ccb0db1365321 (patch)
treec223ee6b82481a0030273cfae9e831dada249fd8 /libvo
parent6c712271ce9e8d4eb9cd615e920139ebcb1d1d49 (diff)
parentcc5e0406412a5f8b4e6e7094f6ffa18a65decd74 (diff)
downloadmpv-835511ac394d5283c9c449e6154ccb0db1365321.tar.bz2
mpv-835511ac394d5283c9c449e6154ccb0db1365321.tar.xz
Merge svn changes up to r28038
Diffstat (limited to 'libvo')
-rw-r--r--libvo/video_out.h4
-rw-r--r--libvo/vo_direct3d.c162
-rw-r--r--libvo/vo_fbdev.c1813
-rw-r--r--libvo/vo_gl.c42
-rw-r--r--libvo/vo_macosx.m12
-rw-r--r--libvo/vo_quartz.c2512
-rw-r--r--libvo/vo_wii.c275
-rw-r--r--libvo/vo_x11.c37
-rw-r--r--libvo/vo_xvmc.c9
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;
+