summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-03-06 12:14:49 +0100
committerwm4 <wm4@nowhere>2015-03-06 12:15:03 +0100
commitfc571e0adb2498cc9278ee51f9aa6b00ee165644 (patch)
tree1991fb47192b444890e349b09d2b359301c78c88
parent720d4a5a1a82b2fa2da78dc2a3b1ca6ab87f973c (diff)
downloadmpv-fc571e0adb2498cc9278ee51f9aa6b00ee165644.tar.bz2
mpv-fc571e0adb2498cc9278ee51f9aa6b00ee165644.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?)
-rw-r--r--video/out/vo_vaapi.c48
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;