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?)
This commit is contained in:
wm4 2015-03-06 12:14:49 +01:00
parent 720d4a5a1a
commit fc571e0adb
1 changed files with 37 additions and 13 deletions

View File

@ -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;
if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_GETTABLE))
VADisplayAttribute *attr = &p->va_display_attrs[index];
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;
if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE))
int index = get_display_attribute(p, name);
if (index < 0)
return VO_NOTIMPL;
/* normalize to attribute value range */
int r = attr->max_value - attr->min_value;
if (r == 0)
VADisplayAttribute *attr = &p->va_display_attrs[index];
if (!(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE))
return VO_NOTIMPL;
attr->value = ((value + 100) * r + 100) / 200 + attr->min_value;
int r = mp_eq_to_va(attr, value);
if (r == INT_MIN)
return VO_NOTIMPL;
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;