summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-09-30 00:37:44 +0200
committerwm4 <wm4@nowhere>2013-09-30 00:47:24 +0200
commitc000a08de2d967aff85d0c19b3e8dd3e762a76c2 (patch)
treedeceb1b2e06ea9144ee470a18276201d208e4be8 /video
parent00d41cc5b065cc809ab64901aca3dcaae8035869 (diff)
downloadmpv-c000a08de2d967aff85d0c19b3e8dd3e762a76c2.tar.bz2
mpv-c000a08de2d967aff85d0c19b3e8dd3e762a76c2.tar.xz
x11: remove colormap code, always request TrueColor visuals
vo_x11 had a clever trick to implement a video equalizer: it requested a DirectColor visual. This is a X11 mechanism which allows you to specify a lookup table for each color channel. Effectively, this is a safe override for the graphic card's gamma ramp. If X thinks the window deserves priority over other windows in the system, X would temporarily switch the gamma ramp so that DirectColor visuals can be displayed as the application intends. (I'm not sure what the exact policy is, but in practice, this meant the equalizer worked when the mouse button was inside the window.) But all in all, this is just lots of useless code for a feature that is rarely ever useful. Remove it and use the libswscale equalizer instead. (This comes without a cost, since vo_x11 already uses libswscale.) One worry was that using DirectColor could have made it work better in 8-bit paletted mode. But this is not the case: there's no difference, and in both cases, the video looks equally bad.
Diffstat (limited to 'video')
-rw-r--r--video/out/vo_x11.c21
-rw-r--r--video/out/x11_common.c150
-rw-r--r--video/out/x11_common.h10
3 files changed, 17 insertions, 164 deletions
diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c
index 95f4ba299c..98d7a23534 100644
--- a/video/out/vo_x11.c
+++ b/video/out/vo_x11.c
@@ -29,6 +29,7 @@
#include "video/csputils.h"
#include "video/mp_image.h"
#include "video/vfcap.h"
+#include "video/filter/vf.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -302,13 +303,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt, int flags)
p->depth = find_depth_from_visuals(vo, &visual);
}
if (!XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth,
- DirectColor, &p->vinfo)
- || (vo->opts->WinID > 0
- && p->vinfo.visualid != XVisualIDFromVisual(p->attribs.visual)))
- {
- XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth, TrueColor,
- &p->vinfo);
- }
+ TrueColor, &p->vinfo))
+ return -1;
vo_x11_config_vo_window(vo, &p->vinfo, vo->dx, vo->dy, vo->dwidth,
vo->dheight, flags, "x11");
@@ -612,12 +608,19 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_SET_EQUALIZER:
{
struct voctrl_set_equalizer_args *args = data;
- return vo_x11_set_equalizer(vo, args->name, args->value);
+ struct vf_seteq eq = {args->name, args->value};
+ if (mp_sws_set_vf_equalizer(p->sws, &eq) == 0)
+ break;
+ return true;
}
case VOCTRL_GET_EQUALIZER:
{
struct voctrl_get_equalizer_args *args = data;
- return vo_x11_get_equalizer(vo, args->name, args->valueptr);
+ struct vf_seteq eq = {args->name};
+ if (mp_sws_get_vf_equalizer(p->sws, &eq) == 0)
+ break;
+ *(int *)args->valueptr = eq.value;
+ return true;
}
case VOCTRL_GET_PANSCAN:
return VO_TRUE;
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index b5964ff531..9029de6a03 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -145,8 +145,6 @@ static void saver_off(struct vo_x11_state *x11);
static void vo_x11_selectinput_witherr(struct vo *vo, Display *display,
Window w, long event_mask);
static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer);
-static void vo_x11_create_colormap(struct vo_x11_state *x11,
- XVisualInfo *vinfo);
/*
* Sends the EWMH fullscreen state event.
@@ -1073,7 +1071,11 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y,
find_default_visual(x11, vis);
}
- vo_x11_create_colormap(x11, vis);
+ if (x11->colormap == None) {
+ x11->colormap = XCreateColormap(x11->display, x11->rootwin,
+ vis->visual, AllocNone);
+ }
+
unsigned long xswamask = CWBorderPixel | CWColormap;
XSetWindowAttributes xswa = {
.border_pixel = 0,
@@ -1680,148 +1682,6 @@ double vo_x11_vm_get_fps(struct vo *vo)
}
#endif
-
-static void vo_x11_create_colormap(struct vo_x11_state *x11,
- XVisualInfo *vinfo)
-{
- unsigned k, r, g, b, ru, gu, bu, m, rv, gv, bv, rvu, gvu, bvu;
-
- if (x11->colormap != None)
- return;
-
- if (vinfo->class != DirectColor) {
- x11->colormap = XCreateColormap(x11->display, x11->rootwin,
- vinfo->visual, AllocNone);
- return;
- }
-
- // DirectColor is requested by vo_x11 by default, for the equalizer
-
- x11->cm_size = vinfo->colormap_size;
- x11->red_mask = vinfo->red_mask;
- x11->green_mask = vinfo->green_mask;
- x11->blue_mask = vinfo->blue_mask;
- ru = (x11->red_mask & (x11->red_mask - 1)) ^ x11->red_mask;
- gu = (x11->green_mask & (x11->green_mask - 1)) ^ x11->green_mask;
- bu = (x11->blue_mask & (x11->blue_mask - 1)) ^ x11->blue_mask;
- rvu = 65536ull * ru / (x11->red_mask + ru);
- gvu = 65536ull * gu / (x11->green_mask + gu);
- bvu = 65536ull * bu / (x11->blue_mask + bu);
- r = g = b = 0;
- rv = gv = bv = 0;
- m = DoRed | DoGreen | DoBlue;
- for (k = 0; k < x11->cm_size; k++) {
- int t;
-
- x11->cols[k].pixel = r | g | b;
- x11->cols[k].red = rv;
- x11->cols[k].green = gv;
- x11->cols[k].blue = bv;
- x11->cols[k].flags = m;
- t = (r + ru) & x11->red_mask;
- if (t < r)
- m &= ~DoRed;
- r = t;
- t = (g + gu) & x11->green_mask;
- if (t < g)
- m &= ~DoGreen;
- g = t;
- t = (b + bu) & x11->blue_mask;
- if (t < b)
- m &= ~DoBlue;
- b = t;
- rv += rvu;
- gv += gvu;
- bv += bvu;
- }
- x11->colormap = XCreateColormap(x11->display, x11->rootwin, vinfo->visual,
- AllocAll);
- XStoreColors(x11->display, x11->colormap, x11->cols, x11->cm_size);
-}
-
-static int transform_color(float val,
- float brightness, float contrast, float gamma)
-{
- float s = pow(val, gamma);
- s = (s - 0.5) * contrast + 0.5;
- s += brightness;
- if (s < 0)
- s = 0;
- if (s > 1)
- s = 1;
- return (unsigned short) (s * 65535);
-}
-
-uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value)
-{
- struct vo_x11_state *x11 = vo->x11;
- float gamma, brightness, contrast;
- float rf, gf, bf;
- int k;
- int red_mask = x11->red_mask;
- int green_mask = x11->green_mask;
- int blue_mask = x11->blue_mask;
-
- /*
- * IMPLEMENTME: consider using XF86VidModeSetGammaRamp in the case
- * of TrueColor-ed window but be careful:
- * Unlike the colormaps, which are private for the X client
- * who created them and thus automatically destroyed on client
- * disconnect, this gamma ramp is a system-wide (X-server-wide)
- * setting and _must_ be restored before the process exits.
- * Unforunately when the process crashes (or gets killed
- * for some reason) it is impossible to restore the setting,
- * and such behaviour could be rather annoying for the users.
- */
- if (x11->colormap == None)
- return VO_NOTAVAIL;
-
- if (!strcasecmp(name, "brightness"))
- x11->vo_brightness = value;
- else if (!strcasecmp(name, "contrast"))
- x11->vo_contrast = value;
- else if (!strcasecmp(name, "gamma"))
- x11->vo_gamma = value;
- else
- return VO_NOTIMPL;
-
- brightness = 0.01 * x11->vo_brightness;
- contrast = tan(0.0095 * (x11->vo_contrast + 100) * M_PI / 4);
- gamma = pow(2, -0.02 * x11->vo_gamma);
-
- rf = (float) ((red_mask & (red_mask - 1)) ^ red_mask) / red_mask;
- gf = (float) ((green_mask & (green_mask - 1)) ^ green_mask) /
- green_mask;
- bf = (float) ((blue_mask & (blue_mask - 1)) ^ blue_mask) / blue_mask;
-
- /* now recalculate the colormap using the newly set value */
- for (k = 0; k < x11->cm_size; k++) {
- x11->cols[k].red = transform_color(rf * k, brightness, contrast, gamma);
- x11->cols[k].green = transform_color(gf * k, brightness, contrast, gamma);
- x11->cols[k].blue = transform_color(bf * k, brightness, contrast, gamma);
- }
-
- XStoreColors(vo->x11->display, x11->colormap, x11->cols, x11->cm_size);
- XFlush(vo->x11->display);
- return VO_TRUE;
-}
-
-uint32_t vo_x11_get_equalizer(struct vo *vo, const char *name, int *value)
-{
- struct vo_x11_state *x11 = vo->x11;
- if (x11->colormap == None)
- return VO_NOTAVAIL;
- if (!strcasecmp(name, "brightness"))
- *value = x11->vo_brightness;
- else if (!strcasecmp(name, "contrast"))
- *value = x11->vo_contrast;
- else if (!strcasecmp(name, "gamma"))
- *value = x11->vo_gamma;
- else
- return VO_NOTIMPL;
- return VO_TRUE;
-}
-
bool vo_x11_screen_is_composited(struct vo *vo)
{
struct vo_x11_state *x11 = vo->x11;
diff --git a/video/out/x11_common.h b/video/out/x11_common.h
index c085a7af41..7cd848245d 100644
--- a/video/out/x11_common.h
+++ b/video/out/x11_common.h
@@ -94,14 +94,6 @@ struct vo_x11_state {
unsigned int oldfuncs;
XComposeStatus compose_status;
- int vo_gamma;
- int vo_brightness;
- int vo_contrast;
-
- Colormap cmap;
- XColor cols[256];
- int cm_size, red_mask, green_mask, blue_mask;
-
/* XShm stuff */
int ShmCompletionEvent;
/* Number of outstanding XShmPutImage requests */
@@ -131,8 +123,6 @@ struct vo_x11_state {
int vo_x11_init(struct vo *vo);
void vo_x11_uninit(struct vo *vo);
int vo_x11_check_events(struct vo *vo);
-uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value);
-uint32_t vo_x11_get_equalizer(struct vo *vo, const char *name, int *value);
bool vo_x11_screen_is_composited(struct vo *vo);
void fstype_help(void);
void vo_x11_config_vo_window(struct vo *vo, XVisualInfo *vis,