diff options
author | wm4 <wm4@nowhere> | 2015-03-06 12:14:49 +0100 |
---|---|---|
committer | Diogo Franco (Kovensky) <diogomfranco@gmail.com> | 2015-03-11 12:30:50 +0900 |
commit | 4d87844508943aa18b58bd00971291f4eb65fee7 (patch) | |
tree | 8bba9eab14aa2e12df3efe19d3885446927023f0 /video | |
parent | cced4bf4d61cfb726186b275bb1c8674f418dd21 (diff) | |
download | mpv-4d87844508943aa18b58bd00971291f4eb65fee7.tar.bz2 mpv-4d87844508943aa18b58bd00971291f4eb65fee7.tar.xz |
vo_vaapi: fix video equalizer (second try)
The vaapi equalizer have a custom range, and can have a smaller range
than mpv's normalized video equalizer values. The result is that a vaapi
equalizer value can map to multiple mpv values, so changing a mpv value
by 1 can get "stuck". Fix by remember the mpv value, and returning it if
it still corresponds to the vaapi value.
Really fixes #1647.
(Why am I even bothering with this irredeemable crap?)
(cherry picked from commit fc571e0adb2498cc9278ee51f9aa6b00ee165644)
Diffstat (limited to 'video')
-rw-r--r-- | video/out/vo_vaapi.c | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index 51f1f4ec03..8d0102be77 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -23,6 +23,7 @@ #include <assert.h> #include <stdarg.h> +#include <limits.h> #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -100,6 +101,7 @@ struct priv { unsigned int *va_subpic_flags; int va_num_subpic_formats; VADisplayAttribute *va_display_attrs; + int *mp_display_attr; int va_num_display_attrs; }; @@ -446,46 +448,67 @@ static int get_displayattribtype(const char *name) return -1; } -static VADisplayAttribute *get_display_attribute(struct priv *p, - const char *name) +static int get_display_attribute(struct priv *p, const char *name) { int type = get_displayattribtype(name); for (int n = 0; n < p->va_num_display_attrs; n++) { VADisplayAttribute *attr = &p->va_display_attrs[n]; if (attr->type == type) - return attr; + return n; } - return NULL; + return -1; +} + +static int mp_eq_to_va(VADisplayAttribute * const attr, int mpvalue) +{ + /* normalize to attribute value range */ + int r = attr->max_value - attr->min_value; + if (r == 0) + return INT_MIN; // assume INT_MIN is outside allowed min/max range + return ((mpvalue + 100) * r + 100) / 200 + attr->min_value; } static int get_equalizer(struct priv *p, const char *name, int *value) { - VADisplayAttribute * const attr = get_display_attribute(p, name); + int index = get_display_attribute(p, name); + if (index < 0) + return VO_NOTIMPL; + + VADisplayAttribute *attr = &p->va_display_attrs[index]; - if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_GETTABLE)) + if (!(attr->flags & VA_DISPLAY_ATTRIB_GETTABLE)) return VO_NOTIMPL; /* normalize to -100 .. 100 range */ int r = attr->max_value - attr->min_value; if (r == 0) return VO_NOTIMPL; + *value = ((attr->value - attr->min_value) * 200 + r / 2) / r - 100; + if (mp_eq_to_va(attr, p->mp_display_attr[index]) == attr->value) + *value = p->mp_display_attr[index]; + return VO_TRUE; } static int set_equalizer(struct priv *p, const char *name, int value) { - VADisplayAttribute * const attr = get_display_attribute(p, name); VAStatus status; + int index = get_display_attribute(p, name); + if (index < 0) + return VO_NOTIMPL; + + VADisplayAttribute *attr = &p->va_display_attrs[index]; - if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE)) + if (!(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE)) return VO_NOTIMPL; - /* normalize to attribute value range */ - int r = attr->max_value - attr->min_value; - if (r == 0) + int r = mp_eq_to_va(attr, value); + if (r == INT_MIN) return VO_NOTIMPL; - attr->value = ((value + 100) * r + 100) / 200 + attr->min_value; + + attr->value = r; + p->mp_display_attr[index] = value; MP_VERBOSE(p, "Changing '%s' (range [%d, %d]) to %d\n", name, attr->max_value, attr->min_value, attr->value); @@ -645,6 +668,7 @@ static int preinit(struct vo *vo) &p->va_num_display_attrs); if (!CHECK_VA_STATUS(p, "vaQueryDisplayAttributes()")) p->va_num_display_attrs = 0; + p->mp_display_attr = talloc_zero_array(vo, int, p->va_num_display_attrs); } return 0; |