summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-06 17:34:29 +0100
committerwm4 <wm4@nowhere>2015-01-06 17:34:29 +0100
commitb5529707f5dfb8073a13bb376fe64010186b60cf (patch)
treebcacf577b17519c4b3afa4c72a62f44e55c1fafb /video
parent941eff85a64f1ac2178fcf5003fc652ee1e76cc2 (diff)
downloadmpv-b5529707f5dfb8073a13bb376fe64010186b60cf.tar.bz2
mpv-b5529707f5dfb8073a13bb376fe64010186b60cf.tar.xz
vo_opengl_cb: implement equalizer controls
This makes vo_opengl_cb respond to controls like "gamma" and "brightness". The commit includes an awkward refactor for vo_opengl to make it easier for vo_opengl_cb. One problem is a logical race condition. The set of supported controls depends on the pixelformat, which in turn is set by reconfig(). But the actual reconfig() call (on the renderer) happens asynchronously on the renderer thread. At the time it happens, the player most likely already tried to set some controls for command line options (see init_vo() in video.c). So setting this command line options will fail most of the time, though it could randomly succeed. This can't be fixed directly, because the player can't wait on the renderer thread, because the renderer thread might already wait on the player.
Diffstat (limited to 'video')
-rw-r--r--video/out/gl_video.c23
-rw-r--r--video/out/gl_video.h5
-rw-r--r--video/out/vo_opengl.c9
-rw-r--r--video/out/vo_opengl_cb.c30
4 files changed, 49 insertions, 18 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 88de5eeffb..12dc4d503a 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -2586,23 +2586,20 @@ void gl_video_get_colorspace(struct gl_video *p, struct mp_image_params *params)
*params = p->image_params; // supports everything
}
-bool gl_video_set_equalizer(struct gl_video *p, const char *name, int val)
+struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p)
{
- if (mp_csp_equalizer_set(&p->video_eq, name, val) >= 0) {
- if (!p->opts.gamma && p->video_eq.values[MP_CSP_EQ_GAMMA] != 0) {
- MP_VERBOSE(p, "Auto-enabling gamma.\n");
- p->opts.gamma = 1.0f;
- compile_shaders(p);
- }
- update_all_uniforms(p);
- return true;
- }
- return false;
+ return &p->video_eq;
}
-bool gl_video_get_equalizer(struct gl_video *p, const char *name, int *val)
+// Call when the mp_csp_equalizer returned by gl_video_eq_ptr() was changed.
+void gl_video_eq_update(struct gl_video *p)
{
- return mp_csp_equalizer_get(&p->video_eq, name, val) >= 0;
+ if (!p->opts.gamma && p->video_eq.values[MP_CSP_EQ_GAMMA] != 0) {
+ MP_VERBOSE(p, "Auto-enabling gamma.\n");
+ p->opts.gamma = 1.0f;
+ compile_shaders(p);
+ }
+ update_all_uniforms(p);
}
static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt,
diff --git a/video/out/gl_video.h b/video/out/gl_video.h
index c11fb51cab..1ee0ec9213 100644
--- a/video/out/gl_video.h
+++ b/video/out/gl_video.h
@@ -73,8 +73,9 @@ void gl_video_resize(struct gl_video *p, struct mp_rect *window,
struct mp_rect *src, struct mp_rect *dst,
struct mp_osd_res *osd, bool vflip);
void gl_video_get_colorspace(struct gl_video *p, struct mp_image_params *params);
-bool gl_video_set_equalizer(struct gl_video *p, const char *name, int val);
-bool gl_video_get_equalizer(struct gl_video *p, const char *name, int *val);
+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_debug(struct gl_video *p, bool enable);
void gl_video_resize_redraw(struct gl_video *p, int w, int h);
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index d9067d9567..b4e5ecd660 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -321,15 +321,18 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_GET_EQUALIZER: {
struct voctrl_get_equalizer_args *args = data;
mpgl_lock(p->glctx);
- bool r = gl_video_get_equalizer(p->renderer, args->name,
- args->valueptr);
+ struct mp_csp_equalizer *eq = gl_video_eq_ptr(p->renderer);
+ bool r = mp_csp_equalizer_get(eq, args->name, args->valueptr) >= 0;
mpgl_unlock(p->glctx);
return r ? VO_TRUE : VO_NOTIMPL;
}
case VOCTRL_SET_EQUALIZER: {
struct voctrl_set_equalizer_args *args = data;
mpgl_lock(p->glctx);
- bool r = gl_video_set_equalizer(p->renderer, args->name, args->value);
+ struct mp_csp_equalizer *eq = gl_video_eq_ptr(p->renderer);
+ bool r = mp_csp_equalizer_set(eq, args->name, args->value) >= 0;
+ if (r)
+ gl_video_eq_update(p->renderer);
mpgl_unlock(p->glctx);
if (r)
vo->want_redraw = true;
diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c
index 12a3aec46d..7785661ff8 100644
--- a/video/out/vo_opengl_cb.c
+++ b/video/out/vo_opengl_cb.c
@@ -71,6 +71,8 @@ struct mpv_opengl_cb_context {
bool update_new_opts;
struct vo_priv *new_opts; // use these options, instead of the VO ones
struct m_config *new_opts_cfg;
+ bool eq_changed;
+ struct mp_csp_equalizer eq;
// --- All of these can only be accessed from the thread where the host
// application's OpenGL context is current - i.e. only while the
@@ -165,7 +167,9 @@ int mpv_opengl_cb_init_gl(struct mpv_opengl_cb_context *ctx, const char *exts,
ctx->hwdec = gl_hwdec_load_api(ctx->log, ctx->gl, ctx->hwapi, &ctx->hwdec_info);
gl_video_set_hwdec(ctx->renderer, ctx->hwdec);
+
pthread_mutex_lock(&ctx->lock);
+ ctx->eq = *gl_video_eq_ptr(ctx->renderer);
for (int n = IMGFMT_START; n < IMGFMT_END; n++) {
ctx->imgfmt_supported[n - IMGFMT_START] =
gl_video_check_format(ctx->renderer, n);
@@ -252,6 +256,14 @@ int mpv_opengl_cb_render(struct mpv_opengl_cb_context *ctx, int fbo, int vp[4])
ctx->update_new_opts = false;
}
+ 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;
+ ctx->eq = *eq;
+
struct mp_image *mpi = ctx->next_frame;
ctx->next_frame = NULL;
@@ -363,6 +375,24 @@ static int control(struct vo *vo, uint32_t request, void *data)
switch (request) {
case VOCTRL_GET_PANSCAN:
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_REDRAW_FRAME:
pthread_mutex_lock(&p->ctx->lock);
update(p);