diff options
Diffstat (limited to 'filters/user_filters.c')
-rw-r--r-- | filters/user_filters.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/filters/user_filters.c b/filters/user_filters.c new file mode 100644 index 0000000000..f59dd22d76 --- /dev/null +++ b/filters/user_filters.c @@ -0,0 +1,119 @@ +#include "config.h" + +#include "common/common.h" +#include "common/msg.h" +#include "options/m_config.h" + +#include "f_lavfi.h" +#include "user_filters.h" + +static bool get_desc_from(const struct mp_user_filter_entry **list, int num, + struct m_obj_desc *dst, int index) +{ + if (index >= num) + return false; + const struct mp_user_filter_entry *entry = list[index]; + *dst = entry->desc; + dst->p = entry; + return true; +} + +// --vf option + +const struct mp_user_filter_entry *vf_list[] = { + &vf_format, + &vf_lavfi, + &vf_lavfi_bridge, + &vf_sub, +#if HAVE_VAPOURSYNTH_CORE && HAVE_VAPOURSYNTH + &vf_vapoursynth, +#endif +#if HAVE_VAPOURSYNTH_CORE && HAVE_VAPOURSYNTH_LAZY + &vf_vapoursynth_lazy, +#endif +#if HAVE_VDPAU + &vf_vdpaupp, +#endif +#if HAVE_VAAPI + &vf_vavpp, +#endif +#if HAVE_D3D_HWACCEL + &vf_d3d11vpp, +#endif +}; + +static bool get_vf_desc(struct m_obj_desc *dst, int index) +{ + return get_desc_from(vf_list, MP_ARRAY_SIZE(vf_list), dst, index); +} + +const struct m_obj_list vf_obj_list = { + .get_desc = get_vf_desc, + .description = "video filters", + .allow_disable_entries = true, + .allow_unknown_entries = true, +}; + +// Create a bidir, single-media filter from command line arguments. +struct mp_filter *mp_create_user_filter(struct mp_filter *parent, + enum mp_output_chain_type type, + const char *name, char **args) +{ + const struct m_obj_list *obj_list = NULL; + const char *defs_name = NULL; + enum mp_frame_type frame_type = 0; + if (type == MP_OUTPUT_CHAIN_VIDEO) { + frame_type = MP_FRAME_VIDEO; + obj_list = &vf_obj_list; + defs_name = "vf-defaults"; + } + assert(frame_type && obj_list); + + struct mp_filter *f = NULL; + + struct m_obj_desc desc; + if (!m_obj_list_find(&desc, obj_list, bstr0(name))) { + // Generic lavfi bridge. + if (strncmp(name, "lavfi-", 6) == 0) + name += 6; + struct mp_lavfi *l = + mp_lavfi_create_filter(parent, frame_type, true, NULL, name, args); + if (l) + f = l->f; + goto done; + } + + void *options = NULL; + if (desc.options) { + struct m_obj_settings *defs = NULL; + if (defs_name) { + mp_read_option_raw(parent->global, defs_name, + &m_option_type_obj_settings_list, &defs); + } + + struct m_config *config = + m_config_from_obj_desc_and_args(NULL, parent->log, parent->global, + &desc, name, defs, args); + + struct m_option dummy = {.type = &m_option_type_obj_settings_list}; + m_option_free(&dummy, &defs); + + if (!config) + goto done; + + options = config->optstruct; + // Free config when options is freed. + ta_set_parent(options, NULL); + ta_set_parent(config, options); + } + + const struct mp_user_filter_entry *entry = desc.p; + f = entry->create(parent, options); + +done: + if (!f) { + MP_ERR(parent, "Creating filter '%s' failed.\n", name); + return NULL; + } + return f; +} |