From 4d87844508943aa18b58bd00971291f4eb65fee7 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 6 Mar 2015 12:14:49 +0100 Subject: 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) --- video/out/vo_vaapi.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file 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 #include +#include #include #include @@ -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; -- cgit v1.2.3