summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-07-27 03:40:38 +0300
committerUoti Urpala <uau@mplayer2.org>2012-07-27 03:40:38 +0300
commit31458a51b5c6a7c8a6449b0b3baa4f3fef6c4938 (patch)
treea7504628cd47ac9f4df4190a3a95f235c4e8178d
parentadfa7bdfb2c61b136b2d15dcae516c0394b2e86b (diff)
downloadmpv-31458a51b5c6a7c8a6449b0b3baa4f3fef6c4938.tar.bz2
mpv-31458a51b5c6a7c8a6449b0b3baa4f3fef6c4938.tar.xz
vo_vdpau: disable refresh-aware frame timing when composited
Under a compositing window manager the current VDPAU implementation behaves differently than without it. Frame flip timing info becomes incorrect (I guess it only reflects when the frame was sent to the compositor, not when it was actually shown), and there is no limitation to at most one frame switch per refresh like without compositing. Detect whether a compositing window manager is active and disable refresh-aware frame timing and dropping in this case, similarly to what fps=-1 would do. This behavior can be controlled with the new suboption "composite-detect". Disabling the refresh-aware logic makes timing somewhat less accurate. Because the video switch rate limit isn't there, the lack of frame dropping on player side does not impose a hard limit on video FPS, but does reduce performance somewhat as redundant frames are drawn in memory. The existence of a compositing window manager does not guarantee that the current window is actually composited, so the current check is not foolproof. In particular, some WMs have support for a "unredirect fullscreen windows" option. Support for such things could be improved.
-rw-r--r--libvo/vo_vdpau.c9
-rw-r--r--libvo/x11_common.c9
-rw-r--r--libvo/x11_common.h2
3 files changed, 18 insertions, 2 deletions
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index 36ca7ab84b..684776dabc 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -154,6 +154,7 @@ struct vdpctx {
int query_surface_num;
VdpTime recent_vsync_time;
float user_fps;
+ int composite_detect;
unsigned int vsync_interval;
uint64_t last_queue_time;
uint64_t queue_time[MAX_OUTPUT_SURFACES];
@@ -545,7 +546,10 @@ static int win_x11_init_vdpau_flip_queue(struct vo *vo)
vc->last_sync_update = GetTimer();
vc->vsync_interval = 1;
- if (vc->user_fps > 0) {
+ if (vc->composite_detect && vo_x11_screen_is_composited(vo)) {
+ mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Compositing window manager "
+ "detected. Assuming timing info is inaccurate.\n");
+ } else if (vc->user_fps > 0) {
vc->vsync_interval = 1e9 / vc->user_fps;
mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Assuming user-specified display "
"refresh rate of %.3f Hz.\n", vc->user_fps);
@@ -1315,7 +1319,7 @@ static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration)
else
duration *= 1000;
- if (vc->user_fps < 0)
+ if (vc->vsync_interval == 1)
duration = -1; // Make sure drop logic is disabled
uint64_t now = sync_vdptime(vo);
@@ -1858,6 +1862,7 @@ const struct vo_driver video_out_vdpau = {
"instead.\n"),
OPT_INTRANGE("hqscaling", hqscaling, 0, 0, 9),
OPT_FLOAT("fps", user_fps, 0),
+ OPT_FLAG_ON("composite-detect", composite_detect, 0, OPTDEF_INT(1)),
OPT_INT("queuetime_windowed", flip_offset_window, 0, OPTDEF_INT(50)),
OPT_INT("queuetime_fs", flip_offset_fs, 0, OPTDEF_INT(50)),
OPT_INTRANGE("output_surfaces", num_output_surfaces, 0,
diff --git a/libvo/x11_common.c b/libvo/x11_common.c
index ee50ba5575..cf8bb2dc4f 100644
--- a/libvo/x11_common.c
+++ b/libvo/x11_common.c
@@ -337,6 +337,9 @@ static void init_atoms(struct vo_x11_state *x11)
XA_INIT(WM_PROTOCOLS);
XA_INIT(WM_DELETE_WINDOW);
XA_INIT(UTF8_STRING);
+ char buf[50];
+ sprintf(buf, "_NET_WM_CM_S%d", x11->screen);
+ x11->XA_NET_WM_CM = XInternAtom(x11->display, buf, False);
}
void update_xinerama_info(struct vo *vo) {
@@ -1941,6 +1944,12 @@ uint32_t vo_x11_get_equalizer(const char *name, int *value)
return VO_TRUE;
}
+bool vo_x11_screen_is_composited(struct vo *vo)
+{
+ struct vo_x11_state *x11 = vo->x11;
+ return XGetSelectionOwner(x11->display, x11->XA_NET_WM_CM) != None;
+}
+
#ifdef CONFIG_XV
int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, const char *name, int value)
{
diff --git a/libvo/x11_common.h b/libvo/x11_common.h
index 14c7e44549..bd340c822d 100644
--- a/libvo/x11_common.h
+++ b/libvo/x11_common.h
@@ -95,6 +95,7 @@ struct vo_x11_state {
Atom XAWM_PROTOCOLS;
Atom XAWM_DELETE_WINDOW;
Atom XAUTF8_STRING;
+ Atom XA_NET_WM_CM;
};
#if defined(CONFIG_GL) || defined(CONFIG_X11) || defined(CONFIG_XV)
@@ -137,6 +138,7 @@ void vo_x11_uninit(struct vo *vo);
Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo);
uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value);
uint32_t vo_x11_get_equalizer(const char *name, int *value);
+bool vo_x11_screen_is_composited(struct vo *vo);
void fstype_help(void);
void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis,
int x, int y, unsigned int width, unsigned int height, int flags,