summaryrefslogtreecommitdiffstats
path: root/filters
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-01-31 06:50:21 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-02-03 05:00:52 -0800
commitafb167cfd2521198539fbd23d772a252554221f0 (patch)
treedbd95c0f370734d94da5db9888b7e74ddd600431 /filters
parent174261450589d8a6ff21426c1cfc3f2508620583 (diff)
downloadmpv-afb167cfd2521198539fbd23d772a252554221f0.tar.bz2
mpv-afb167cfd2521198539fbd23d772a252554221f0.tar.xz
options: slightly improve filter help output for lavfi bridge
--vf=help will now list libavfilter filters, and e.g. --vf=yadif=help will list libavfilter filter options. The latter is rather bare, because the AVOption API is really awful (holy shit how is it so bad), and would require us to handle _every_ option type manually. Alternatively we could call av_opt_show2(), which ffmpeg uses for help output in its CLI tools and which is much more detailed. But it's rather foreign and forces output through av_log(), so I don't really want to use it.
Diffstat (limited to 'filters')
-rw-r--r--filters/f_lavfi.c51
-rw-r--r--filters/f_lavfi.h6
-rw-r--r--filters/user_filters.c26
3 files changed, 79 insertions, 4 deletions
diff --git a/filters/f_lavfi.c b/filters/f_lavfi.c
index b3f74b508b..745d1699a7 100644
--- a/filters/f_lavfi.c
+++ b/filters/f_lavfi.c
@@ -903,15 +903,58 @@ static bool is_usable(const AVFilter *filter, int media_type)
is_single_media_only(filter->outputs, media_type);
}
-static void print_help(struct mp_log *log, int mediatype, char *name, char *ex)
+static void dump_list(struct mp_log *log, int media_type)
{
- mp_info(log, "List of libavfilter filters:\n");
+ mp_info(log, "Available libavfilter filters:\n");
for (const AVFilter *filter = avfilter_next(NULL); filter;
filter = avfilter_next(filter))
{
- if (is_usable(filter, mediatype))
- mp_info(log, " %-16s %s\n", filter->name, filter->description);
+ if (is_usable(filter, media_type))
+ mp_info(log, " %-16s %s\n", filter->name, filter->description);
}
+}
+
+void print_lavfi_help(struct mp_log *log, const char *name, int media_type)
+{
+ const AVFilter *f = avfilter_get_by_name(name);
+ if (!f) {
+ mp_err(log, "Filter '%s' not found.\n", name);
+ return;
+ }
+ if (!is_usable(f, media_type)) {
+ mp_err(log, "Filter '%s' is not usable in this context (wrong media \n"
+ "types or wrong number of inputs/outputs).\n", name);
+ }
+ mp_info(log, "Options:\n\n");
+ const AVClass *class = f->priv_class;
+ // av_opt_next() requires this for some retarded incomprehensible reason.
+ const AVClass **c = &class;
+ int offset= -1;
+ int count = 0;
+ for (const AVOption *o = av_opt_next(c, 0); o; o = av_opt_next(c, o)) {
+ // This is how libavfilter (at the time) decided to assign positional
+ // options (called "shorthand" in the libavfilter code). So we
+ // duplicate it exactly.
+ if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
+ continue;
+ offset = o->offset;
+
+ mp_info(log, " %s\n", o->name);
+ count++;
+ }
+ mp_info(log, "\nTotal: %d options\n", count);
+}
+
+void print_lavfi_help_list(struct mp_log *log, int media_type)
+{
+ dump_list(log, media_type);
+ mp_info(log, "\nIf libavfilter filters clash with builtin mpv filters,\n"
+ "prefix them with lavfi- to select the libavfilter one.\n\n");
+}
+
+static void print_help(struct mp_log *log, int mediatype, char *name, char *ex)
+{
+ dump_list(log, mediatype);
mp_info(log, "\n"
"This lists %s->%s filters only. Refer to\n"
"\n"
diff --git a/filters/f_lavfi.h b/filters/f_lavfi.h
index 7efc96c3de..089d4aee1f 100644
--- a/filters/f_lavfi.h
+++ b/filters/f_lavfi.h
@@ -28,3 +28,9 @@ struct mp_lavfi *mp_lavfi_create_filter(struct mp_filter *parent,
enum mp_frame_type type, bool bidir,
char **graph_opts,
const char *filter, char **filter_opts);
+
+// Print libavfilter list for --vf/--af
+void print_lavfi_help_list(struct mp_log *log, int media_type);
+
+// Print libavfilter help for the given filter
+void print_lavfi_help(struct mp_log *log, const char *name, int media_type);
diff --git a/filters/user_filters.c b/filters/user_filters.c
index 30358a4a94..89d7743d53 100644
--- a/filters/user_filters.c
+++ b/filters/user_filters.c
@@ -1,3 +1,5 @@
+#include <libavutil/avutil.h>
+
#include "config.h"
#include "common/common.h"
@@ -36,11 +38,23 @@ static bool get_af_desc(struct m_obj_desc *dst, int index)
return get_desc_from(af_list, MP_ARRAY_SIZE(af_list), dst, index);
}
+static void print_af_help_list(struct mp_log *log)
+{
+ print_lavfi_help_list(log, AVMEDIA_TYPE_AUDIO);
+}
+
+static void print_af_lavfi_help(struct mp_log *log, const char *name)
+{
+ print_lavfi_help(log, name, AVMEDIA_TYPE_AUDIO);
+}
+
const struct m_obj_list af_obj_list = {
.get_desc = get_af_desc,
.description = "audio filters",
.allow_disable_entries = true,
.allow_unknown_entries = true,
+ .print_help_list = print_af_help_list,
+ .print_unknown_entry_help = print_af_lavfi_help,
};
// --vf option
@@ -72,11 +86,23 @@ 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);
}
+static void print_vf_help_list(struct mp_log *log)
+{
+ print_lavfi_help_list(log, AVMEDIA_TYPE_VIDEO);
+}
+
+static void print_vf_lavfi_help(struct mp_log *log, const char *name)
+{
+ print_lavfi_help(log, name, AVMEDIA_TYPE_VIDEO);
+}
+
const struct m_obj_list vf_obj_list = {
.get_desc = get_vf_desc,
.description = "video filters",
.allow_disable_entries = true,
.allow_unknown_entries = true,
+ .print_help_list = print_vf_help_list,
+ .print_unknown_entry_help = print_vf_lavfi_help,
};
// Create a bidir, single-media filter from command line arguments.