From 0ec6df2ddfc6eb22de3c4f98c78d291997a5e93d Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 27 Sep 2014 17:14:23 +0200 Subject: [PATCH] vf_lavfi: make chaining from other filters more flexible Some filters exists only to create a specific lavfi graph. Allow these filters to reset the graph exactly on reconfig, and allow them to modify some image parameters too. Also make vf_lw_update_graph() behave like vf_lw_set_graph() - they had a subtitle difference with filter==NULL. Useful for the following commit. --- video/filter/vf_gradfun.c | 11 +++++---- video/filter/vf_lavfi.c | 47 ++++++++++++++++++++++++--------------- video/filter/vf_lavfi.h | 13 +++++++---- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/video/filter/vf_gradfun.c b/video/filter/vf_gradfun.c index 6b98f38437..b352521001 100644 --- a/video/filter/vf_gradfun.c +++ b/video/filter/vf_gradfun.c @@ -43,16 +43,19 @@ struct vf_priv_s { .cfg_size = -1, }; -static void lavfi_recreate(struct vf_instance *vf) +static int lavfi_reconfig(struct vf_instance *vf, + struct mp_image_params *in, + struct mp_image_params *out) { struct vf_priv_s *p = vf_lw_old_priv(vf); - int w = vf->fmt_in.w; - int h = vf->fmt_in.h; + int w = in->w; + int h = in->h; p->radius = p->cfg_radius; if (p->cfg_size > -1) p->radius = (p->cfg_size / 100.0f) * sqrtf(w * w + h * h); p->radius = MPCLAMP((p->radius+1)&~1, 4, 32); vf_lw_update_graph(vf, "gradfun", "%f:%d", p->cfg_thresh, p->radius); + return 0; } static int vf_open(vf_instance_t *vf) @@ -72,7 +75,7 @@ static int vf_open(vf_instance_t *vf) if (vf_lw_set_graph(vf, vf->priv->lw_opts, "gradfun", "%f:4", vf->priv->cfg_thresh) >= 0) { - vf_lw_set_recreate_cb(vf, lavfi_recreate); + vf_lw_set_reconfig_cb(vf, lavfi_reconfig); return 1; } diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c index 0a14f94bbb..c806e17203 100644 --- a/video/filter/vf_lavfi.c +++ b/video/filter/vf_lavfi.c @@ -73,7 +73,9 @@ struct vf_priv_s { // for the lw wrapper void *old_priv; - void (*lw_recreate_cb)(struct vf_instance *vf); + int (*lw_reconfig_cb)(struct vf_instance *vf, + struct mp_image_params *in, + struct mp_image_params *out); // options char *cfg_graph; @@ -128,9 +130,6 @@ static bool recreate_graph(struct vf_instance *vf, int width, int height, struct vf_priv_s *p = vf->priv; AVFilterContext *in = NULL, *out = NULL, *f_format = NULL; - if (vf->priv->lw_recreate_cb) - vf->priv->lw_recreate_cb(vf); - if (bstr0(p->cfg_graph).len == 0) { MP_FATAL(vf, "lavfi: no filter graph set\n"); return false; @@ -227,14 +226,20 @@ static void reset(vf_instance_t *vf) recreate_graph(vf, f->w, f->h, f->d_w, f->d_h, f->imgfmt); } -static int config(struct vf_instance *vf, int width, int height, - int d_width, int d_height, unsigned int flags, - unsigned int fmt) +static int reconfig(struct vf_instance *vf, struct mp_image_params *in, + struct mp_image_params *out) { struct vf_priv_s *p = vf->priv; - if (!recreate_graph(vf, width, height, d_width, d_height, fmt)) - return 0; + *out = *in; // pass-through untouched flags + + if (vf->priv->lw_reconfig_cb) { + if (vf->priv->lw_reconfig_cb(vf, in, out) < 0) + return -1; + } + + if (!recreate_graph(vf, in->w, in->h, in->d_w, in->d_h, in->imgfmt)) + return -1; AVFilterLink *l_out = p->out->inputs[0]; AVFilterLink *l_in = p->in->outputs[0]; @@ -247,9 +252,12 @@ static int config(struct vf_instance *vf, int width, int height, int dw, dh; dar_from_sar_par(l_out->w, l_out->h, l_out->sample_aspect_ratio, &dw, &dh); - return vf_next_config(vf, l_out->w, l_out->h, dw, dh, flags, - pixfmt2imgfmt(l_out->format)); - + out->w = l_out->w; + out->h = l_out->h; + out->d_w = dw; + out->d_h = dh; + out->imgfmt = pixfmt2imgfmt(l_out->format); + return 0; } static int query_format(struct vf_instance *vf, unsigned int fmt) @@ -372,8 +380,8 @@ static void uninit(struct vf_instance *vf) static int vf_open(vf_instance_t *vf) { - vf->reconfig = NULL; - vf->config = config; + vf->reconfig = reconfig; + vf->config = NULL; vf->filter_ext = filter_ext; vf->filter_out = filter_out; vf->filter = NULL; @@ -519,13 +527,16 @@ void vf_lw_update_graph(struct vf_instance *vf, char *filter, char *opts, ...) va_start(ap, opts); char *s = talloc_vasprintf(vf, opts, ap); talloc_free(p->cfg_graph); - p->cfg_graph = talloc_asprintf(vf, "%s=%s", filter, s); + p->cfg_graph = filter ? talloc_asprintf(vf, "%s=%s", filter, s) + : talloc_strdup(vf, s); talloc_free(s); va_end(ap); } -void vf_lw_set_recreate_cb(struct vf_instance *vf, - void (*recreate)(struct vf_instance *vf)) +void vf_lw_set_reconfig_cb(struct vf_instance *vf, + int (*reconfig_)(struct vf_instance *vf, + struct mp_image_params *in, + struct mp_image_params *out)) { - vf->priv->lw_recreate_cb = recreate; + vf->priv->lw_reconfig_cb = reconfig_; } diff --git a/video/filter/vf_lavfi.h b/video/filter/vf_lavfi.h index ca811412f5..889129a8c2 100644 --- a/video/filter/vf_lavfi.h +++ b/video/filter/vf_lavfi.h @@ -17,8 +17,10 @@ int vf_lw_set_graph(struct vf_instance *vf, struct vf_lw_opts *lavfi_opts, void *vf_lw_old_priv(struct vf_instance *vf); void vf_lw_update_graph(struct vf_instance *vf, char *filter, char *opts, ...) PRINTF_ATTRIBUTE(3,4); -void vf_lw_set_recreate_cb(struct vf_instance *vf, - void (*recreate)(struct vf_instance *vf)); +void vf_lw_set_reconfig_cb(struct vf_instance *vf, + int (*reconfig)(struct vf_instance *vf, + struct mp_image_params *in, + struct mp_image_params *out)); #else static inline int vf_lw_set_graph(struct vf_instance *vf, struct vf_lw_opts *lavfi_opts, @@ -33,9 +35,12 @@ static void *vf_lw_old_priv(struct vf_instance *vf) static void vf_lw_update_graph(struct vf_instance *vf, char *filter, char *opts, ...) { } -static void vf_lw_set_recreate_cb(struct vf_instance *vf, - void (*recreate)(struct vf_instance *vf)) +void vf_lw_set_reconfig_cb(struct vf_instance *vf, + int (*reconfig)(struct vf_instance *vf, + struct mp_image_params *in, + struct mp_image_params *out)) { + return 0; } #include "options/m_option.h" static const struct m_sub_options vf_lw_conf = {0};