[FFmpeg-devel] [PATCH 2/5] fftools/cmdutils: Print filter input/output formats in help output
Soft Works
softworkz at hotmail.com
Wed Oct 13 07:49:57 EEST 2021
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 <softworkz at 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
More information about the ffmpeg-devel
mailing list