mirror of
https://github.com/mpv-player/mpv
synced 2025-04-19 21:56:40 +00:00
video: redo video equalizer option handling
I really wouldn't care much about this, but some parts of the core code
are under HAVE_GPL, so there's some need to get rid of it. Simply turn
the video equalizer from its current fine-grained handling with vf/vo
fallbacks into global options. This makes updating them much simpler.
This removes any possibility of applying video equalizers in filters,
which affects vf_scale, and the previously removed vf_eq. Not a big
loss, since the preferred VOs have this builtin.
Remove video equalizer handling from vo_direct3d, vo_sdl, vo_vaapi, and
vo_xv. I'm not going to waste my time on these legacy VOs.
vo.eq_opts_cache exists _only_ to send a VOCTRL_SET_EQUALIZER, which
exists _only_ to trigger a redraw. This seems silly, but for now I feel
like this is less of a pain. The rest of the equalizer using code is
self-updating.
See commit 96b906a51d
for how some video equalizer code was GPL only.
Some command line option names and ranges can probably be traced back to
a GPL only committer, but we don't consider these copyrightable.
This commit is contained in:
parent
d67aa6da6b
commit
03cf150ff3
@ -572,15 +572,7 @@ const m_option_t mp_opts[] = {
|
||||
.deprecation_message = "use Lua scripting instead"),
|
||||
OPT_FLOAT("heartbeat-interval", heartbeat_interval, CONF_MIN, 0),
|
||||
|
||||
#if HAVE_GPL
|
||||
OPT_INTRANGE("brightness", gamma_brightness, 0, -100, 100),
|
||||
OPT_INTRANGE("saturation", gamma_saturation, 0, -100, 100),
|
||||
OPT_INTRANGE("contrast", gamma_contrast, 0, -100, 100),
|
||||
OPT_INTRANGE("hue", gamma_hue, 0, -100, 100),
|
||||
OPT_INTRANGE("gamma", gamma_gamma, 0, -100, 100),
|
||||
OPT_CHOICE_C("video-output-levels", video_output_levels, 0,
|
||||
mp_csp_levels_names),
|
||||
#endif
|
||||
OPT_SUBSTRUCT("", video_equalizer, mp_csp_equalizer_conf, 0),
|
||||
|
||||
OPT_FLAG("use-filedir-conf", use_filedir_conf, 0),
|
||||
OPT_CHOICE("osd-level", osd_level, 0,
|
||||
@ -856,11 +848,6 @@ const struct MPOpts mp_default_opts = {
|
||||
.heartbeat_interval = 30.0,
|
||||
.stop_screensaver = 1,
|
||||
.cursor_autohide_delay = 1000,
|
||||
.gamma_gamma = 0,
|
||||
.gamma_brightness = 0,
|
||||
.gamma_contrast = 0,
|
||||
.gamma_saturation = 0,
|
||||
.gamma_hue = 0,
|
||||
.video_osd = 1,
|
||||
.osd_level = 1,
|
||||
.osd_duration = 1000,
|
||||
|
@ -119,13 +119,7 @@ typedef struct MPOpts {
|
||||
char *media_title;
|
||||
int force_rgba_osd;
|
||||
|
||||
// ranges -100 - 100, 1000 if the vo default should be used
|
||||
int gamma_gamma;
|
||||
int gamma_brightness;
|
||||
int gamma_contrast;
|
||||
int gamma_saturation;
|
||||
int gamma_hue;
|
||||
int video_output_levels;
|
||||
struct mp_csp_equalizer_opts *video_equalizer;
|
||||
|
||||
int stop_screensaver;
|
||||
int cursor_autohide_delay;
|
||||
|
@ -2613,35 +2613,6 @@ static int mp_property_frame_count(void *ctx, struct m_property *prop,
|
||||
return m_property_int_ro(action, arg, frames);
|
||||
}
|
||||
|
||||
#if HAVE_GPL
|
||||
static int mp_property_video_color(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
{
|
||||
const char *name = prop->priv ? prop->priv : prop->name;
|
||||
MPContext *mpctx = ctx;
|
||||
if (!mpctx->vo_chain)
|
||||
return mp_property_generic_option(mpctx, prop, action, arg);
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET: {
|
||||
if (video_set_colors(mpctx->vo_chain, name, *(int *) arg) <= 0)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
break;
|
||||
}
|
||||
case M_PROPERTY_GET:
|
||||
if (video_get_colors(mpctx->vo_chain, name, (int *)arg) <= 0)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
// Write new value to option variable
|
||||
mp_property_generic_option(mpctx, prop, M_PROPERTY_SET, arg);
|
||||
return M_PROPERTY_OK;
|
||||
case M_PROPERTY_GET_NEUTRAL:
|
||||
*(int *)arg = 0;
|
||||
return M_PROPERTY_OK;
|
||||
}
|
||||
return mp_property_generic_option(mpctx, prop, action, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Video codec tag (RO)
|
||||
static int mp_property_video_format(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
@ -4041,15 +4012,6 @@ static const struct m_property mp_properties_base[] = {
|
||||
{"ontop", mp_property_ontop},
|
||||
{"border", mp_property_border},
|
||||
{"on-all-workspaces", mp_property_all_workspaces},
|
||||
#if HAVE_GPL
|
||||
{"gamma", mp_property_video_color},
|
||||
{"brightness", mp_property_video_color},
|
||||
{"contrast", mp_property_video_color},
|
||||
{"saturation", mp_property_video_color},
|
||||
{"hue", mp_property_video_color},
|
||||
{"video-output-levels", mp_property_video_color,
|
||||
.priv = (void *)"output-levels"},
|
||||
#endif
|
||||
{"video-out-params", mp_property_vo_imgparams},
|
||||
{"video-dec-params", mp_property_dec_imgparams},
|
||||
{"video-params", mp_property_vd_imgparams},
|
||||
|
@ -70,37 +70,6 @@ static const char av_desync_help_text[] =
|
||||
"position will not match to the video (see A-V status field).\n"
|
||||
"\n";
|
||||
|
||||
#if HAVE_GPL
|
||||
int video_set_colors(struct vo_chain *vo_c, const char *item, int value)
|
||||
{
|
||||
vf_equalizer_t data;
|
||||
|
||||
data.item = item;
|
||||
data.value = value;
|
||||
|
||||
MP_VERBOSE(vo_c, "set video colors %s=%d \n", item, value);
|
||||
if (video_vf_vo_control(vo_c, VFCTRL_SET_EQUALIZER, &data) == CONTROL_TRUE)
|
||||
return 1;
|
||||
MP_VERBOSE(vo_c, "Video attribute '%s' is not supported by selected vo.\n",
|
||||
item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_get_colors(struct vo_chain *vo_c, const char *item, int *value)
|
||||
{
|
||||
vf_equalizer_t data;
|
||||
|
||||
data.item = item;
|
||||
|
||||
MP_VERBOSE(vo_c, "get video colors %s \n", item);
|
||||
if (video_vf_vo_control(vo_c, VFCTRL_GET_EQUALIZER, &data) == CONTROL_TRUE) {
|
||||
*value = data.value;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send a VCTRL, or if it doesn't work, translate it to a VOCTRL and try the VO.
|
||||
int video_vf_vo_control(struct vo_chain *vo_c, int vf_cmd, void *data)
|
||||
{
|
||||
@ -110,26 +79,6 @@ int video_vf_vo_control(struct vo_chain *vo_c, int vf_cmd, void *data)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (vf_cmd) {
|
||||
case VFCTRL_SET_EQUALIZER: {
|
||||
vf_equalizer_t *eq = data;
|
||||
if (!vo_c->vo->config_ok)
|
||||
return CONTROL_FALSE; // vo not configured?
|
||||
struct voctrl_set_equalizer_args param = {
|
||||
eq->item, eq->value
|
||||
};
|
||||
return vo_control(vo_c->vo, VOCTRL_SET_EQUALIZER, ¶m) == VO_TRUE;
|
||||
}
|
||||
case VFCTRL_GET_EQUALIZER: {
|
||||
vf_equalizer_t *eq = data;
|
||||
if (!vo_c->vo->config_ok)
|
||||
return CONTROL_FALSE; // vo not configured?
|
||||
struct voctrl_get_equalizer_args param = {
|
||||
eq->item, &eq->value
|
||||
};
|
||||
return vo_control(vo_c->vo, VOCTRL_GET_EQUALIZER, ¶m) == VO_TRUE;
|
||||
}
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -980,28 +929,6 @@ static void update_av_diff(struct MPContext *mpctx, double offset)
|
||||
}
|
||||
}
|
||||
|
||||
static void init_vo(struct MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
struct vo_chain *vo_c = mpctx->vo_chain;
|
||||
|
||||
#if HAVE_GPL
|
||||
if (opts->gamma_gamma != 0)
|
||||
video_set_colors(vo_c, "gamma", opts->gamma_gamma);
|
||||
if (opts->gamma_brightness != 0)
|
||||
video_set_colors(vo_c, "brightness", opts->gamma_brightness);
|
||||
if (opts->gamma_contrast != 0)
|
||||
video_set_colors(vo_c, "contrast", opts->gamma_contrast);
|
||||
if (opts->gamma_saturation != 0)
|
||||
video_set_colors(vo_c, "saturation", opts->gamma_saturation);
|
||||
if (opts->gamma_hue != 0)
|
||||
video_set_colors(vo_c, "hue", opts->gamma_hue);
|
||||
video_set_colors(vo_c, "output-levels", opts->video_output_levels);
|
||||
#endif
|
||||
|
||||
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
|
||||
}
|
||||
|
||||
double calc_average_frame_duration(struct MPContext *mpctx)
|
||||
{
|
||||
double total = 0;
|
||||
@ -1445,7 +1372,7 @@ void write_video(struct MPContext *mpctx)
|
||||
mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
|
||||
goto error;
|
||||
}
|
||||
init_vo(mpctx);
|
||||
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
|
||||
}
|
||||
|
||||
mpctx->time_frame -= get_relative_time(mpctx);
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "mp_image.h"
|
||||
#include "csputils.h"
|
||||
#include "options/m_config.h"
|
||||
#include "options/m_option.h"
|
||||
|
||||
const struct m_opt_choice_alternatives mp_csp_names[] = {
|
||||
@ -96,15 +97,6 @@ const struct m_opt_choice_alternatives mp_csp_light_names[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
const char *const mp_csp_equalizer_names[MP_CSP_EQ_COUNT] = {
|
||||
"brightness",
|
||||
"contrast",
|
||||
"hue",
|
||||
"saturation",
|
||||
"gamma",
|
||||
"output-levels",
|
||||
};
|
||||
|
||||
const struct m_opt_choice_alternatives mp_chroma_names[] = {
|
||||
{"unknown", MP_CHROMA_AUTO},
|
||||
{"mpeg2/4/h264",MP_CHROMA_LEFT},
|
||||
@ -817,9 +809,25 @@ bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2)
|
||||
c1.sig_peak == c2.sig_peak;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct mp_csp_equalizer_opts
|
||||
|
||||
const struct m_sub_options mp_csp_equalizer_conf = {
|
||||
.opts = (const m_option_t[]) {
|
||||
OPT_INTRANGE("brightness", values[MP_CSP_EQ_BRIGHTNESS], 0, -100, 100),
|
||||
OPT_INTRANGE("saturation", values[MP_CSP_EQ_SATURATION], 0, -100, 100),
|
||||
OPT_INTRANGE("contrast", values[MP_CSP_EQ_CONTRAST], 0, -100, 100),
|
||||
OPT_INTRANGE("hue", values[MP_CSP_EQ_HUE], 0, -100, 100),
|
||||
OPT_INTRANGE("gamma", values[MP_CSP_EQ_GAMMA], 0, -100, 100),
|
||||
OPT_CHOICE_C("video-output-levels", values[MP_CSP_EQ_OUTPUT_LEVELS], 0,
|
||||
mp_csp_levels_names),
|
||||
{0}
|
||||
},
|
||||
.size = sizeof(struct mp_csp_equalizer_opts),
|
||||
};
|
||||
|
||||
// Copy settings from eq into params.
|
||||
void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
|
||||
const struct mp_csp_equalizer *eq)
|
||||
const struct mp_csp_equalizer_opts *eq)
|
||||
{
|
||||
params->brightness = eq->values[MP_CSP_EQ_BRIGHTNESS] / 100.0;
|
||||
params->contrast = (eq->values[MP_CSP_EQ_CONTRAST] + 100) / 100.0;
|
||||
@ -829,37 +837,28 @@ void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
|
||||
params->levels_out = eq->values[MP_CSP_EQ_OUTPUT_LEVELS];
|
||||
}
|
||||
|
||||
static int find_eq(int capabilities, const char *name)
|
||||
struct mp_csp_equalizer_state *mp_csp_equalizer_create(void *ta_parent,
|
||||
struct mpv_global *global)
|
||||
{
|
||||
for (int i = 0; i < MP_CSP_EQ_COUNT; i++) {
|
||||
if (strcmp(name, mp_csp_equalizer_names[i]) == 0)
|
||||
return ((1 << i) & capabilities) ? i : -1;
|
||||
}
|
||||
return -1;
|
||||
struct m_config_cache *c = m_config_cache_alloc(ta_parent, global,
|
||||
&mp_csp_equalizer_conf);
|
||||
// The terrible, terrible truth.
|
||||
return (struct mp_csp_equalizer_state *)c;
|
||||
}
|
||||
|
||||
int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property,
|
||||
int *out_value)
|
||||
bool mp_csp_equalizer_state_changed(struct mp_csp_equalizer_state *state)
|
||||
{
|
||||
int index = find_eq(eq->capabilities, property);
|
||||
if (index < 0)
|
||||
return -1;
|
||||
|
||||
*out_value = eq->values[index];
|
||||
|
||||
return 0;
|
||||
struct m_config_cache *c = (struct m_config_cache *)state;
|
||||
return m_config_cache_update(c);
|
||||
}
|
||||
|
||||
int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property,
|
||||
int value)
|
||||
void mp_csp_equalizer_state_get(struct mp_csp_equalizer_state *state,
|
||||
struct mp_csp_params *params)
|
||||
{
|
||||
int index = find_eq(eq->capabilities, property);
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
eq->values[index] = value;
|
||||
|
||||
return 1;
|
||||
struct m_config_cache *c = (struct m_config_cache *)state;
|
||||
m_config_cache_update(c);
|
||||
struct mp_csp_equalizer_opts *opts = c->opts;
|
||||
mp_csp_copy_equalizer_values(params, opts);
|
||||
}
|
||||
|
||||
void mp_invert_cmat(struct mp_cmat *out, struct mp_cmat *in)
|
||||
|
@ -185,6 +185,8 @@ enum mp_chroma_location {
|
||||
|
||||
extern const struct m_opt_choice_alternatives mp_chroma_names[];
|
||||
|
||||
extern const struct m_sub_options mp_csp_equalizer_conf;
|
||||
|
||||
enum mp_csp_equalizer_param {
|
||||
MP_CSP_EQ_BRIGHTNESS,
|
||||
MP_CSP_EQ_CONTRAST,
|
||||
@ -195,28 +197,23 @@ enum mp_csp_equalizer_param {
|
||||
MP_CSP_EQ_COUNT,
|
||||
};
|
||||
|
||||
#define MP_CSP_EQ_CAPS_COLORMATRIX \
|
||||
( (1 << MP_CSP_EQ_BRIGHTNESS) \
|
||||
| (1 << MP_CSP_EQ_CONTRAST) \
|
||||
| (1 << MP_CSP_EQ_HUE) \
|
||||
| (1 << MP_CSP_EQ_SATURATION) \
|
||||
| (1 << MP_CSP_EQ_OUTPUT_LEVELS) )
|
||||
|
||||
#define MP_CSP_EQ_CAPS_GAMMA (1 << MP_CSP_EQ_GAMMA)
|
||||
#define MP_CSP_EQ_CAPS_BRIGHTNESS (1 << MP_CSP_EQ_BRIGHTNESS)
|
||||
|
||||
extern const char *const mp_csp_equalizer_names[MP_CSP_EQ_COUNT];
|
||||
|
||||
// Default initialization with 0 is enough, except for the capabilities field
|
||||
struct mp_csp_equalizer {
|
||||
// Bit field of capabilities. For example (1 << MP_CSP_EQ_HUE) means hue
|
||||
// support is available.
|
||||
int capabilities;
|
||||
struct mp_csp_equalizer_opts {
|
||||
// Value for each property is in the range [-100, 100].
|
||||
// 0 is default, meaning neutral or no change.
|
||||
int values[MP_CSP_EQ_COUNT];
|
||||
};
|
||||
|
||||
void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
|
||||
const struct mp_csp_equalizer_opts *eq);
|
||||
|
||||
struct mpv_global;
|
||||
struct mp_csp_equalizer_state *mp_csp_equalizer_create(void *ta_parent,
|
||||
struct mpv_global *global);
|
||||
bool mp_csp_equalizer_state_changed(struct mp_csp_equalizer_state *state);
|
||||
void mp_csp_equalizer_state_get(struct mp_csp_equalizer_state *state,
|
||||
struct mp_csp_params *params);
|
||||
|
||||
struct mp_csp_col_xy {
|
||||
float x, y;
|
||||
};
|
||||
@ -233,13 +230,6 @@ struct mp_csp_primaries {
|
||||
struct mp_csp_col_xy red, green, blue, white;
|
||||
};
|
||||
|
||||
void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
|
||||
const struct mp_csp_equalizer *eq);
|
||||
int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property,
|
||||
int value);
|
||||
int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property,
|
||||
int *out_value);
|
||||
|
||||
enum mp_csp avcol_spc_to_mp_csp(int avcolorspace);
|
||||
enum mp_csp_levels avcol_range_to_mp_csp_levels(int avrange);
|
||||
enum mp_csp_prim avcol_pri_to_mp_csp_prim(int avpri);
|
||||
|
@ -141,15 +141,8 @@ struct vf_chain {
|
||||
void *wakeup_callback_ctx;
|
||||
};
|
||||
|
||||
typedef struct vf_seteq {
|
||||
const char *item;
|
||||
int value;
|
||||
} vf_equalizer_t;
|
||||
|
||||
enum vf_ctrl {
|
||||
VFCTRL_SEEK_RESET = 1, // reset on picture and PTS discontinuities
|
||||
VFCTRL_SET_EQUALIZER, // set color options (brightness,contrast etc)
|
||||
VFCTRL_GET_EQUALIZER, // get color options (brightness,contrast etc)
|
||||
#if HAVE_GPL
|
||||
VFCTRL_SET_DEINTERLACE, // Set deinterlacing status
|
||||
VFCTRL_GET_DEINTERLACE, // Get deinterlacing status
|
||||
|
@ -202,24 +202,6 @@ static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
|
||||
return dmpi;
|
||||
}
|
||||
|
||||
static int control(struct vf_instance *vf, int request, void *data)
|
||||
{
|
||||
struct mp_sws_context *sws = vf->priv->sws;
|
||||
|
||||
switch (request) {
|
||||
case VFCTRL_GET_EQUALIZER:
|
||||
if (mp_sws_get_vf_equalizer(sws, data) < 1)
|
||||
break;
|
||||
return CONTROL_TRUE;
|
||||
case VFCTRL_SET_EQUALIZER:
|
||||
if (mp_sws_set_vf_equalizer(sws, data) < 1)
|
||||
break;
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
static int query_format(struct vf_instance *vf, unsigned int fmt)
|
||||
{
|
||||
if (IMGFMT_IS_HWACCEL(fmt) || sws_isSupportedInput(imgfmt2pixfmt(fmt)) < 1)
|
||||
@ -236,7 +218,6 @@ static int vf_open(vf_instance_t *vf)
|
||||
vf->reconfig = reconfig;
|
||||
vf->filter = filter;
|
||||
vf->query_format = query_format;
|
||||
vf->control = control;
|
||||
vf->uninit = uninit;
|
||||
vf->priv->sws = mp_sws_alloc(vf);
|
||||
vf->priv->sws->log = vf->log;
|
||||
|
@ -242,7 +242,7 @@ struct gl_video {
|
||||
// state for configured scalers
|
||||
struct scaler scaler[SCALER_COUNT];
|
||||
|
||||
struct mp_csp_equalizer video_eq;
|
||||
struct mp_csp_equalizer_state *video_eq;
|
||||
|
||||
struct mp_rect src_rect; // displayed part of the source video
|
||||
struct mp_rect dst_rect; // video rectangle on output window
|
||||
@ -848,13 +848,6 @@ static void init_video(struct gl_video *p)
|
||||
|
||||
mp_image_params_guess_csp(&p->image_params);
|
||||
|
||||
int eq_caps = MP_CSP_EQ_CAPS_GAMMA;
|
||||
if (p->image_params.color.space != MP_CSP_BT_2020_C)
|
||||
eq_caps |= MP_CSP_EQ_CAPS_COLORMATRIX;
|
||||
if (p->image_params.color.space == MP_CSP_XYZ)
|
||||
eq_caps |= MP_CSP_EQ_CAPS_BRIGHTNESS;
|
||||
p->video_eq.capabilities = eq_caps;
|
||||
|
||||
av_lfg_init(&p->lfg, 1);
|
||||
|
||||
debug_check_gl(p, "before video texture creation");
|
||||
@ -2173,7 +2166,7 @@ static void pass_convert_yuv(struct gl_video *p)
|
||||
struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS;
|
||||
cparams.gray = p->is_gray;
|
||||
mp_csp_set_image_params(&cparams, &p->image_params);
|
||||
mp_csp_copy_equalizer_values(&cparams, &p->video_eq);
|
||||
mp_csp_equalizer_state_get(p->video_eq, &cparams);
|
||||
p->user_gamma = 1.0 / (cparams.gamma * p->opts.gamma);
|
||||
|
||||
pass_describe(p, "color conversion");
|
||||
@ -3582,6 +3575,7 @@ struct gl_video *gl_video_init(struct ra *ra, struct mp_log *log,
|
||||
.global = g,
|
||||
.log = log,
|
||||
.sc = gl_sc_create(ra, g, log),
|
||||
.video_eq = mp_csp_equalizer_create(p, g),
|
||||
.opts_cache = m_config_cache_alloc(p, g, &gl_video_conf),
|
||||
};
|
||||
// make sure this variable is initialized to *something*
|
||||
@ -3674,16 +3668,6 @@ void gl_video_configure_queue(struct gl_video *p, struct vo *vo)
|
||||
vo_set_queue_params(vo, 0, queue_size);
|
||||
}
|
||||
|
||||
struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p)
|
||||
{
|
||||
return &p->video_eq;
|
||||
}
|
||||
|
||||
// Call when the mp_csp_equalizer returned by gl_video_eq_ptr() was changed.
|
||||
void gl_video_eq_update(struct gl_video *p)
|
||||
{
|
||||
}
|
||||
|
||||
static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt,
|
||||
struct bstr name, struct bstr param)
|
||||
{
|
||||
@ -3758,7 +3742,6 @@ void gl_video_set_ambient_lux(struct gl_video *p, int lux)
|
||||
float gamma = gl_video_scale_ambient_lux(16.0, 64.0, 2.40, 1.961, lux);
|
||||
MP_VERBOSE(p, "ambient light changed: %dlux (gamma: %f)\n", lux, gamma);
|
||||
p->opts.gamma = MPMIN(1.0, 1.961 / gamma);
|
||||
gl_video_eq_update(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,9 +165,6 @@ void gl_video_resize(struct gl_video *p,
|
||||
void gl_video_set_fb_depth(struct gl_video *p, int fb_depth);
|
||||
struct voctrl_performance_data;
|
||||
void gl_video_perfdata(struct gl_video *p, struct voctrl_performance_data *out);
|
||||
struct mp_csp_equalizer;
|
||||
struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p);
|
||||
void gl_video_eq_update(struct gl_video *p);
|
||||
void gl_video_set_clear_color(struct gl_video *p, struct m_color color);
|
||||
void gl_video_set_osd_pts(struct gl_video *p, double pts);
|
||||
bool gl_video_check_osd_change(struct gl_video *p, struct mp_osd_res *osd,
|
||||
|
@ -228,6 +228,12 @@ static void update_opts(void *p)
|
||||
if (vo->driver->control)
|
||||
vo->driver->control(vo, VOCTRL_UPDATE_RENDER_OPTS, NULL);
|
||||
}
|
||||
|
||||
if (m_config_cache_update(vo->eq_opts_cache)) {
|
||||
// "Legacy" update of video equalizer related options.
|
||||
if (vo->driver->control)
|
||||
vo->driver->control(vo, VOCTRL_SET_EQUALIZER, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Does not include thread- and VO uninit.
|
||||
@ -238,6 +244,7 @@ static void dealloc_vo(struct vo *vo)
|
||||
// These must be free'd before vo->in->dispatch.
|
||||
talloc_free(vo->opts_cache);
|
||||
talloc_free(vo->gl_opts_cache);
|
||||
talloc_free(vo->eq_opts_cache);
|
||||
|
||||
pthread_mutex_destroy(&vo->in->lock);
|
||||
pthread_cond_destroy(&vo->in->wakeup);
|
||||
@ -291,6 +298,10 @@ static struct vo *vo_create(bool probing, struct mpv_global *global,
|
||||
update_opts, vo);
|
||||
#endif
|
||||
|
||||
vo->eq_opts_cache = m_config_cache_alloc(NULL, global, &mp_csp_equalizer_conf);
|
||||
m_config_cache_set_dispatch_change_cb(vo->eq_opts_cache, vo->in->dispatch,
|
||||
update_opts, vo);
|
||||
|
||||
mp_input_set_mouse_transform(vo->input_ctx, NULL, NULL);
|
||||
if (vo->driver->encode != !!vo->encode_lavc_ctx)
|
||||
goto error;
|
||||
|
@ -401,6 +401,7 @@ struct vo {
|
||||
struct m_config_cache *opts_cache; // cache for ->opts
|
||||
struct mp_vo_opts *opts;
|
||||
struct m_config_cache *gl_opts_cache;
|
||||
struct m_config_cache *eq_opts_cache;
|
||||
|
||||
bool want_redraw; // redraw as soon as possible
|
||||
|
||||
|
@ -185,7 +185,6 @@ typedef struct d3d_priv {
|
||||
D3DFORMAT osd_fmt_table[SUBBITMAP_COUNT];
|
||||
|
||||
D3DMATRIX d3d_colormatrix;
|
||||
struct mp_csp_equalizer video_eq;
|
||||
|
||||
struct osdpart *osd[MAX_OSD_PARTS];
|
||||
} d3d_priv;
|
||||
@ -1171,7 +1170,6 @@ static void update_colorspace(d3d_priv *priv)
|
||||
{
|
||||
struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
|
||||
mp_csp_set_image_params(&csp, &priv->params);
|
||||
mp_csp_copy_equalizer_values(&csp, &priv->video_eq);
|
||||
|
||||
if (priv->use_shaders) {
|
||||
csp.input_bits = priv->planes[0].bits_per_pixel;
|
||||
@ -1245,23 +1243,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
d3d_draw_frame(priv);
|
||||
return VO_TRUE;
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
if (!priv->use_shaders)
|
||||
break;
|
||||
struct voctrl_set_equalizer_args *args = data;
|
||||
if (mp_csp_equalizer_set(&priv->video_eq, args->name, args->value) < 0)
|
||||
return VO_NOTIMPL;
|
||||
update_colorspace(priv);
|
||||
vo->want_redraw = true;
|
||||
return VO_TRUE;
|
||||
}
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
if (!priv->use_shaders)
|
||||
break;
|
||||
struct voctrl_get_equalizer_args *args = data;
|
||||
return mp_csp_equalizer_get(&priv->video_eq, args->name, args->valueptr)
|
||||
>= 0 ? VO_TRUE : VO_NOTIMPL;
|
||||
}
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
calc_fs_rect(priv);
|
||||
priv->vo->want_redraw = true;
|
||||
|
@ -262,22 +262,9 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
resize(p);
|
||||
return VO_TRUE;
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
struct voctrl_get_equalizer_args *args = data;
|
||||
struct mp_csp_equalizer *eq = gl_video_eq_ptr(p->renderer);
|
||||
bool r = mp_csp_equalizer_get(eq, args->name, args->valueptr) >= 0;
|
||||
return r ? VO_TRUE : VO_NOTIMPL;
|
||||
}
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
struct voctrl_set_equalizer_args *args = data;
|
||||
struct mp_csp_equalizer *eq = gl_video_eq_ptr(p->renderer);
|
||||
if (mp_csp_equalizer_set(eq, args->name, args->value) >= 0) {
|
||||
gl_video_eq_update(p->renderer);
|
||||
case VOCTRL_SET_EQUALIZER:
|
||||
vo->want_redraw = true;
|
||||
return VO_TRUE;
|
||||
}
|
||||
return VO_NOTIMPL;
|
||||
}
|
||||
case VOCTRL_SCREENSHOT_WIN: {
|
||||
struct mp_image *screen = gl_read_fbo_contents(p->gl, p->glctx->main_fb,
|
||||
vo->dwidth, vo->dheight);
|
||||
|
@ -76,8 +76,6 @@ struct mpv_opengl_cb_context {
|
||||
bool force_update;
|
||||
bool imgfmt_supported[IMGFMT_END - IMGFMT_START];
|
||||
bool update_new_opts;
|
||||
bool eq_changed;
|
||||
struct mp_csp_equalizer eq;
|
||||
struct vo *active;
|
||||
|
||||
// --- This is only mutable while initialized=false, during which nothing
|
||||
@ -187,10 +185,6 @@ int mpv_opengl_cb_init_gl(struct mpv_opengl_cb_context *ctx, const char *exts,
|
||||
gl_video_set_hwdec(ctx->renderer, ctx->hwdec);
|
||||
|
||||
pthread_mutex_lock(&ctx->lock);
|
||||
// We don't know the exact caps yet - use a known superset
|
||||
ctx->eq.capabilities = MP_CSP_EQ_CAPS_GAMMA | MP_CSP_EQ_CAPS_BRIGHTNESS |
|
||||
MP_CSP_EQ_CAPS_COLORMATRIX;
|
||||
ctx->eq_changed = true;
|
||||
for (int n = IMGFMT_START; n < IMGFMT_END; n++) {
|
||||
ctx->imgfmt_supported[n - IMGFMT_START] =
|
||||
gl_video_check_format(ctx->renderer, n);
|
||||
@ -277,7 +271,6 @@ int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h)
|
||||
if (ctx->reconfigured) {
|
||||
gl_video_set_osd_source(ctx->renderer, vo ? vo->osd : NULL);
|
||||
gl_video_config(ctx->renderer, &ctx->img_params);
|
||||
ctx->eq_changed = true;
|
||||
}
|
||||
if (ctx->update_new_opts) {
|
||||
gl_video_update_options(ctx->renderer);
|
||||
@ -301,13 +294,6 @@ int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h)
|
||||
ctx->cur_frame->still = true;
|
||||
}
|
||||
|
||||
struct mp_csp_equalizer *eq = gl_video_eq_ptr(ctx->renderer);
|
||||
if (ctx->eq_changed) {
|
||||
memcpy(eq->values, ctx->eq.values, sizeof(eq->values));
|
||||
gl_video_eq_update(ctx->renderer);
|
||||
}
|
||||
ctx->eq_changed = false;
|
||||
|
||||
struct vo_frame *frame = ctx->next_frame;
|
||||
int64_t wait_present_count = ctx->present_count;
|
||||
if (frame) {
|
||||
@ -469,24 +455,9 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_PAUSE:
|
||||
vo->want_redraw = true;
|
||||
return VO_TRUE;
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
struct voctrl_get_equalizer_args *args = data;
|
||||
pthread_mutex_lock(&p->ctx->lock);
|
||||
bool r = mp_csp_equalizer_get(&p->ctx->eq, args->name, args->valueptr) >= 0;
|
||||
pthread_mutex_unlock(&p->ctx->lock);
|
||||
return r ? VO_TRUE : VO_NOTIMPL;
|
||||
}
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
struct voctrl_set_equalizer_args *args = data;
|
||||
pthread_mutex_lock(&p->ctx->lock);
|
||||
bool r = mp_csp_equalizer_set(&p->ctx->eq, args->name, args->value) >= 0;
|
||||
if (r) {
|
||||
p->ctx->eq_changed = true;
|
||||
update(p);
|
||||
}
|
||||
pthread_mutex_unlock(&p->ctx->lock);
|
||||
return r ? VO_TRUE : VO_NOTIMPL;
|
||||
}
|
||||
case VOCTRL_SET_EQUALIZER:
|
||||
vo->want_redraw = true;
|
||||
return VO_TRUE;
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
pthread_mutex_lock(&p->ctx->lock);
|
||||
p->ctx->force_update = true;
|
||||
@ -535,8 +506,6 @@ static int preinit(struct vo *vo)
|
||||
p->ctx->active = vo;
|
||||
p->ctx->reconfigured = true;
|
||||
p->ctx->update_new_opts = true;
|
||||
memset(p->ctx->eq.values, 0, sizeof(p->ctx->eq.values));
|
||||
p->ctx->eq_changed = true;
|
||||
pthread_mutex_unlock(&p->ctx->lock);
|
||||
|
||||
vo->hwdec_devs = p->ctx->hwdec_devs;
|
||||
|
@ -844,43 +844,10 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
struct priv *vc = vo->priv;
|
||||
|
||||
// decode brightness/contrast
|
||||
int color_add = 0;
|
||||
int color_mod = 255;
|
||||
int brightness = vc->brightness;
|
||||
int contrast = vc->contrast;
|
||||
|
||||
// only in this range it is possible to do brightness/contrast control
|
||||
// properly, using just additive render operations and color modding
|
||||
// (SDL2 provides no subtractive rendering, sorry)
|
||||
if (2 * brightness < contrast) {
|
||||
//brightness = (brightness + 2 * contrast) / 5; // closest point
|
||||
brightness = (brightness + contrast) / 3; // equal adjustment
|
||||
contrast = 2 * brightness;
|
||||
}
|
||||
|
||||
// convert to values SDL2 likes
|
||||
color_mod = ((contrast + 100) * 255 + 50) / 100;
|
||||
color_add = ((2 * brightness - contrast) * 255 + 100) / 200;
|
||||
|
||||
// clamp
|
||||
if (color_mod < 0)
|
||||
color_mod = 0;
|
||||
if (color_mod > 255)
|
||||
color_mod = 255;
|
||||
// color_add can't be < 0
|
||||
if (color_add > 255)
|
||||
color_add = 255;
|
||||
|
||||
// typically this runs in parallel with the following mp_image_copy call
|
||||
SDL_SetRenderDrawColor(vc->renderer, color_add, color_add, color_add, 255);
|
||||
SDL_SetRenderDrawColor(vc->renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(vc->renderer);
|
||||
|
||||
// use additive blending for the video texture only if the clear color is
|
||||
// not black (faster especially for the software renderer)
|
||||
if (color_add)
|
||||
SDL_SetTextureBlendMode(vc->tex, SDL_BLENDMODE_ADD);
|
||||
else
|
||||
SDL_SetTextureBlendMode(vc->tex, SDL_BLENDMODE_NONE);
|
||||
|
||||
if (mpi) {
|
||||
@ -909,15 +876,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
dst.w = vc->dst_rect.x1 - vc->dst_rect.x0;
|
||||
dst.h = vc->dst_rect.y1 - vc->dst_rect.y0;
|
||||
|
||||
// typically this runs in parallel with the following mp_image_copy call
|
||||
if (color_mod > 255) {
|
||||
SDL_SetTextureColorMod(vc->tex, color_mod / 2, color_mod / 2, color_mod / 2);
|
||||
SDL_RenderCopy(vc->renderer, vc->tex, &src, &dst);
|
||||
SDL_RenderCopy(vc->renderer, vc->tex, &src, &dst);
|
||||
} else {
|
||||
SDL_SetTextureColorMod(vc->tex, color_mod, color_mod, color_mod);
|
||||
SDL_RenderCopy(vc->renderer, vc->tex, &src, &dst);
|
||||
}
|
||||
|
||||
draw_osd(vo);
|
||||
}
|
||||
@ -938,36 +897,6 @@ static struct mp_image *get_window_screenshot(struct vo *vo)
|
||||
return image;
|
||||
}
|
||||
|
||||
static int set_eq(struct vo *vo, const char *name, int value)
|
||||
{
|
||||
struct priv *vc = vo->priv;
|
||||
|
||||
if (!strcmp(name, "brightness"))
|
||||
vc->brightness = value;
|
||||
else if (!strcmp(name, "contrast"))
|
||||
vc->contrast = value;
|
||||
else
|
||||
return VO_NOTIMPL;
|
||||
|
||||
vo->want_redraw = true;
|
||||
|
||||
return VO_TRUE;
|
||||
}
|
||||
|
||||
static int get_eq(struct vo *vo, const char *name, int *value)
|
||||
{
|
||||
struct priv *vc = vo->priv;
|
||||
|
||||
if (!strcmp(name, "brightness"))
|
||||
*value = vc->brightness;
|
||||
else if (!strcmp(name, "contrast"))
|
||||
*value = vc->contrast;
|
||||
else
|
||||
return VO_NOTIMPL;
|
||||
|
||||
return VO_TRUE;
|
||||
}
|
||||
|
||||
static int control(struct vo *vo, uint32_t request, void *data)
|
||||
{
|
||||
struct priv *vc = vo->priv;
|
||||
@ -982,14 +911,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
force_resize(vo);
|
||||
return VO_TRUE;
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
struct voctrl_set_equalizer_args *args = data;
|
||||
return set_eq(vo, args->name, args->value);
|
||||
}
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
struct voctrl_get_equalizer_args *args = data;
|
||||
return get_eq(vo, args->name, args->valueptr);
|
||||
}
|
||||
case VOCTRL_SCREENSHOT_WIN:
|
||||
*(struct mp_image **)data = get_window_screenshot(vo);
|
||||
return true;
|
||||
|
@ -434,103 +434,11 @@ static void draw_osd(struct vo *vo)
|
||||
osd_draw(vo->osd, *res, pts, 0, osd_formats, draw_osd_cb, p);
|
||||
}
|
||||
|
||||
static int get_displayattribtype(const char *name)
|
||||
{
|
||||
if (!strcmp(name, "brightness"))
|
||||
return VADisplayAttribBrightness;
|
||||
else if (!strcmp(name, "contrast"))
|
||||
return VADisplayAttribContrast;
|
||||
else if (!strcmp(name, "saturation"))
|
||||
return VADisplayAttribSaturation;
|
||||
else if (!strcmp(name, "hue"))
|
||||
return VADisplayAttribHue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 n;
|
||||
}
|
||||
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)
|
||||
{
|
||||
int index = get_display_attribute(p, name);
|
||||
if (index < 0)
|
||||
return VO_NOTIMPL;
|
||||
|
||||
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)
|
||||
{
|
||||
VAStatus status;
|
||||
int index = get_display_attribute(p, name);
|
||||
if (index < 0)
|
||||
return VO_NOTIMPL;
|
||||
|
||||
VADisplayAttribute *attr = &p->va_display_attrs[index];
|
||||
|
||||
if (!(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE))
|
||||
return VO_NOTIMPL;
|
||||
|
||||
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);
|
||||
|
||||
status = vaSetDisplayAttributes(p->display, attr, 1);
|
||||
if (!CHECK_VA_STATUS(p, "vaSetDisplayAttributes()"))
|
||||
return VO_FALSE;
|
||||
return VO_TRUE;
|
||||
}
|
||||
|
||||
static int control(struct vo *vo, uint32_t request, void *data)
|
||||
{
|
||||
struct priv *p = vo->priv;
|
||||
|
||||
switch (request) {
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
struct voctrl_set_equalizer_args *eq = data;
|
||||
return set_equalizer(p, eq->name, eq->value);
|
||||
}
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
struct voctrl_get_equalizer_args *eq = data;
|
||||
return get_equalizer(p, eq->name, eq->valueptr);
|
||||
}
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
p->output_surface = p->visible_surface;
|
||||
draw_osd(vo);
|
||||
|
@ -135,9 +135,6 @@ struct vdpctx {
|
||||
int render_count;
|
||||
int change_id;
|
||||
} osd_surfaces[MAX_OSD_PARTS];
|
||||
|
||||
// Video equalizer
|
||||
struct mp_csp_equalizer video_eq;
|
||||
};
|
||||
|
||||
static bool status_ok(struct vo *vo);
|
||||
@ -1026,6 +1023,7 @@ static int preinit(struct vo *vo)
|
||||
hwdec_devices_add(vo->hwdec_devs, &vc->mpvdp->hwctx);
|
||||
|
||||
vc->video_mixer = mp_vdpau_mixer_create(vc->mpvdp, vo->log);
|
||||
vc->video_mixer->video_eq = mp_csp_equalizer_create(vo, vo->global);
|
||||
|
||||
if (mp_vdpau_guess_if_emulated(vc->mpvdp)) {
|
||||
MP_WARN(vo, "VDPAU is most likely emulated via VA-API.\n"
|
||||
@ -1044,35 +1042,9 @@ static int preinit(struct vo *vo)
|
||||
vc->vdp->bitmap_surface_query_capabilities(vc->vdp_device, VDP_RGBA_FORMAT_A8,
|
||||
&vc->supports_a8, &(uint32_t){0}, &(uint32_t){0});
|
||||
|
||||
vc->video_eq.capabilities = MP_CSP_EQ_CAPS_COLORMATRIX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_equalizer(struct vo *vo, const char *name, int *value)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
|
||||
if (vc->rgb_mode)
|
||||
return false;
|
||||
|
||||
return mp_csp_equalizer_get(&vc->video_mixer->video_eq, name, value) >= 0 ?
|
||||
VO_TRUE : VO_NOTIMPL;
|
||||
}
|
||||
|
||||
static int set_equalizer(struct vo *vo, const char *name, int value)
|
||||
{
|
||||
struct vdpctx *vc = vo->priv;
|
||||
|
||||
if (vc->rgb_mode)
|
||||
return false;
|
||||
|
||||
if (mp_csp_equalizer_set(&vc->video_mixer->video_eq, name, value) < 0)
|
||||
return VO_NOTIMPL;
|
||||
vc->video_mixer->initialized = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void checked_resize(struct vo *vo)
|
||||
{
|
||||
if (!status_ok(vo))
|
||||
@ -1090,15 +1062,9 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
checked_resize(vo);
|
||||
return VO_TRUE;
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
case VOCTRL_SET_EQUALIZER:
|
||||
vo->want_redraw = true;
|
||||
struct voctrl_set_equalizer_args *args = data;
|
||||
return set_equalizer(vo, args->name, args->value);
|
||||
}
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
struct voctrl_get_equalizer_args *args = data;
|
||||
return get_equalizer(vo, args->name, args->valueptr);
|
||||
}
|
||||
return true;
|
||||
case VOCTRL_RESET:
|
||||
forget_frames(vo, true);
|
||||
return true;
|
||||
|
@ -878,15 +878,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
resize(vo);
|
||||
return VO_TRUE;
|
||||
case VOCTRL_SET_EQUALIZER: {
|
||||
vo->want_redraw = true;
|
||||
struct voctrl_set_equalizer_args *args = data;
|
||||
return xv_set_eq(vo, ctx->xv_port, args->name, args->value);
|
||||
}
|
||||
case VOCTRL_GET_EQUALIZER: {
|
||||
struct voctrl_get_equalizer_args *args = data;
|
||||
return xv_get_eq(vo, ctx->xv_port, args->name, args->valueptr);
|
||||
}
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
draw_image(vo, ctx->original_image);
|
||||
return true;
|
||||
|
@ -291,37 +291,6 @@ int mp_image_sw_blur_scale(struct mp_image *dst, struct mp_image *src,
|
||||
return res;
|
||||
}
|
||||
|
||||
int mp_sws_get_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
|
||||
{
|
||||
if (!sws->supports_csp)
|
||||
return 0;
|
||||
if (!strcmp(eq->item, "brightness"))
|
||||
eq->value = ((sws->brightness * 100) + (1 << 15)) >> 16;
|
||||
else if (!strcmp(eq->item, "contrast"))
|
||||
eq->value = (((sws->contrast * 100) + (1 << 15)) >> 16) - 100;
|
||||
else if (!strcmp(eq->item, "saturation"))
|
||||
eq->value = (((sws->saturation * 100) + (1 << 15)) >> 16) - 100;
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mp_sws_set_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
|
||||
{
|
||||
if (!sws->supports_csp)
|
||||
return 0;
|
||||
if (!strcmp(eq->item, "brightness"))
|
||||
sws->brightness = ((eq->value << 16) + 50) / 100;
|
||||
else if (!strcmp(eq->item, "contrast"))
|
||||
sws->contrast = MPMAX(1, (((eq->value + 100) << 16) + 50) / 100);
|
||||
else if (!strcmp(eq->item, "saturation"))
|
||||
sws->saturation = (((eq->value + 100) << 16) + 50) / 100;
|
||||
else
|
||||
return 0;
|
||||
|
||||
return mp_sws_reinit(sws) >= 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
static const int endian_swaps[][2] = {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if defined(AV_PIX_FMT_YA16) && defined(AV_PIX_FMT_RGBA64)
|
||||
|
@ -56,10 +56,6 @@ void mp_sws_set_from_cmdline(struct mp_sws_context *ctx, struct sws_opts *opts);
|
||||
int mp_sws_scale(struct mp_sws_context *ctx, struct mp_image *dst,
|
||||
struct mp_image *src);
|
||||
|
||||
struct vf_seteq;
|
||||
int mp_sws_set_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq);
|
||||
int mp_sws_get_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq);
|
||||
|
||||
struct mp_image *mp_img_swap_to_native(struct mp_image *img);
|
||||
|
||||
#endif /* MP_SWS_UTILS_H */
|
||||
|
@ -67,9 +67,6 @@ struct mp_vdpau_mixer *mp_vdpau_mixer_create(struct mp_vdpau_ctx *vdp_ctx,
|
||||
.ctx = vdp_ctx,
|
||||
.log = log,
|
||||
.video_mixer = VDP_INVALID_HANDLE,
|
||||
.video_eq = {
|
||||
.capabilities = MP_CSP_EQ_CAPS_COLORMATRIX,
|
||||
},
|
||||
};
|
||||
mp_vdpau_handle_preemption(mixer->ctx, &mixer->preemption_counter);
|
||||
return mixer;
|
||||
@ -201,7 +198,8 @@ static int create_vdp_mixer(struct mp_vdpau_mixer *mixer,
|
||||
|
||||
struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS;
|
||||
mp_csp_set_image_params(&cparams, &mixer->image_params);
|
||||
mp_csp_copy_equalizer_values(&cparams, &mixer->video_eq);
|
||||
if (mixer->video_eq)
|
||||
mp_csp_equalizer_state_get(mixer->video_eq, &cparams);
|
||||
mp_get_csp_matrix(&cparams, &yuv2rgb);
|
||||
|
||||
for (int r = 0; r < 3; r++) {
|
||||
@ -268,6 +266,9 @@ int mp_vdpau_mixer_render(struct mp_vdpau_mixer *mixer,
|
||||
if (mixer->video_mixer == VDP_INVALID_HANDLE)
|
||||
mixer->initialized = false;
|
||||
|
||||
if (mixer->video_eq && mp_csp_equalizer_state_changed(mixer->video_eq))
|
||||
mixer->initialized = false;
|
||||
|
||||
VdpChromaType s_chroma_type;
|
||||
uint32_t s_w, s_h;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "csputils.h"
|
||||
#include "mp_image.h"
|
||||
#include "vdpau.h"
|
||||
|
||||
@ -39,8 +40,7 @@ struct mp_vdpau_mixer {
|
||||
VdpChromaType current_chroma_type;
|
||||
int current_w, current_h;
|
||||
|
||||
// set initialized=false to force reinit when changed
|
||||
struct mp_csp_equalizer video_eq;
|
||||
struct mp_csp_equalizer_state *video_eq;
|
||||
|
||||
VdpVideoMixer video_mixer;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user