Exmaple command: ffmpeg -h filters=overlay Output:
Filter overlay Overlay a video source on top of the input. slice threading supported Inputs: #0: main (video) [yuv420p, yuvj420p, yuva420p, nv12, nv21] #1: overlay (video) [yuva420p] Outputs: #0: default (video) [yuv420p, yuvj420p, yuva420p, nv12, nv21] overlay AVOptions: x [...] Signed-off-by: softworkz <softwo...@hotmail.com> --- fftools/cmdutils.c | 89 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index aa706c33ab..a112998574 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -33,6 +33,7 @@ #include "compat/va_copy.h" #include "libavformat/avformat.h" #include "libavfilter/avfilter.h" +#include <libavfilter/formats.h> #include "libavdevice/avdevice.h" #include "libswscale/swscale.h" #include "libswresample/swresample.h" @@ -1922,11 +1923,38 @@ static void show_help_muxer(const char *name) } #if CONFIG_AVFILTER +static void print_link_formats(enum AVMediaType mediaType, AVFilterFormats* formats) +{ + if (formats == NULL) + return; + + printf(" ["); + + for (unsigned i = 0; i < formats->nb_formats; i++) { + if (formats->formats[i] >= 0) { + if (i > 0) + printf(", "); + if (mediaType == AVMEDIA_TYPE_VIDEO) { + printf("%s", av_get_pix_fmt_name(formats->formats[i])); + } else if (mediaType == AVMEDIA_TYPE_AUDIO) { + printf("%s", av_get_sample_fmt_name(formats->formats[i])); + // TODO: Uncomment once subtitle filtering is added + ////} else if (mediaType == AVMEDIA_TYPE_SUBTITLE) { + //// printf("%s", av_get_subtitle_fmt_name(formats->formats[i])); + } + } + } + + printf("]"); +} + static void show_help_filter(const char *name) { #if CONFIG_AVFILTER const AVFilter *f = avfilter_get_by_name(name); - int i, count; + unsigned i, count; + int got_formats = 0; + AVFilterContext *filter_context; if (!name) { av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n"); @@ -1943,12 +1971,50 @@ static void show_help_filter(const char *name) if (f->flags & AVFILTER_FLAG_SLICE_THREADS) printf(" slice threading supported\n"); + filter_context = avfilter_alloc(f, "filter"); + if (!filter_context) { + av_log(NULL, AV_LOG_ERROR, "Failed create filtercontext\n"); + return; + } + + if (filter_context->nb_outputs == 0) { + filter_context->outputs= av_calloc(1, sizeof(AVFilterLink*)); + filter_context->outputs[0] = (AVFilterLink *)av_mallocz(sizeof(AVFilterLink)); + } + + if (filter_context->nb_inputs == 0) { + filter_context->inputs= av_calloc(1, sizeof(AVFilterLink*)); + filter_context->inputs[0] = (AVFilterLink *)av_mallocz(sizeof(AVFilterLink)); + } + + for (i = 0; i < filter_context->nb_inputs; i++) + filter_context->inputs[i] = (AVFilterLink *)av_mallocz(sizeof(AVFilterLink)); + + for (i = 0; i < filter_context->nb_outputs; i++) + filter_context->outputs[i] = (AVFilterLink *)av_mallocz(sizeof(AVFilterLink)); + + if (filter_context->filter->nb_inputs) + filter_context->inputs[0]->type = avfilter_pad_get_type(f->inputs, 0); + + if (filter_context->filter->nb_outputs) + filter_context->outputs[0]->type = avfilter_pad_get_type(f->outputs, 0); + + if (filter_context->nb_inputs > 0 || filter_context->nb_outputs > 0) + got_formats = !avfilter_query_formats(filter_context); + printf(" Inputs:\n"); count = avfilter_filter_pad_count(f, 0); for (i = 0; i < count; i++) { - printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i), - media_type_string(avfilter_pad_get_type(f->inputs, i))); + const enum AVMediaType media_type = avfilter_pad_get_type(f->inputs, i); + + printf(" #%d: %s (%s)", i, avfilter_pad_get_name(f->inputs, i), + media_type_string(media_type)); + + if (got_formats && (i < filter_context->nb_inputs)) + print_link_formats(media_type, filter_context->inputs[i]->outcfg.formats); + printf("\n"); } + if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS) printf(" dynamic (depending on the options)\n"); else if (!count) @@ -1957,8 +2023,13 @@ static void show_help_filter(const char *name) printf(" Outputs:\n"); count = avfilter_filter_pad_count(f, 1); for (i = 0; i < count; i++) { - printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i), - media_type_string(avfilter_pad_get_type(f->outputs, i))); + const enum AVMediaType media_type = avfilter_pad_get_type(f->outputs, i); + printf(" #%d: %s (%s)", i, avfilter_pad_get_name(f->outputs, i), + media_type_string(media_type)); + + if (got_formats && i < filter_context->nb_outputs) + print_link_formats(media_type, filter_context->outputs[i]->incfg.formats); + printf("\n"); } if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS) printf(" dynamic (depending on the options)\n"); @@ -1970,6 +2041,14 @@ static void show_help_filter(const char *name) AV_OPT_FLAG_AUDIO_PARAM); if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE) printf("This filter has support for timeline through the 'enable' option.\n"); + + if (filter_context->nb_inputs == 0) + filter_context->nb_inputs = 1; + if (filter_context->nb_outputs == 0) + filter_context->nb_outputs = 1; + + avfilter_free(filter_context); + #else av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; " "can not to satisfy request\n"); -- 2.30.2.windows.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".