Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing
@ 2025-02-18 12:46 Niklas Haas
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 2/4] avfilter/filters: keep track of AVFilterPad labels Niklas Haas
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Niklas Haas @ 2025-02-18 12:46 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

And use it to make the output format configurable.

I also added a "none" option to explicitly disable the behavior (in case a
previous command line argument was used to enable it). This has the added
benefit of giving the default "pretty" format the ID 1, allowing `-dumpgraph 1`
to continue working as expected.
---
 libavfilter/graphdump.c | 54 +++++++++++++++++++++++++++++++++++------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/libavfilter/graphdump.c b/libavfilter/graphdump.c
index 1bb59e4301..80cbda50f5 100644
--- a/libavfilter/graphdump.c
+++ b/libavfilter/graphdump.c
@@ -24,10 +24,33 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/bprint.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "filters.h"
 
+enum {
+    FMT_NONE = 0,
+    FMT_PRETTY,
+    FMT_NB,
+};
+
+typedef struct GraphDumpOptions {
+    const AVClass *class;
+
+    int format;
+} GraphDumpOptions;
+
+#define OFFSET(x) offsetof(GraphDumpOptions, x)
+static const AVOption graph_dump_options[] = {
+    { "format",     "set the output format", OFFSET(format), AV_OPT_TYPE_INT, { .i64 = FMT_NONE }, 0, FMT_NB - 1, .unit = "format" },
+    {     "none",   "don't produce any output",         0, AV_OPT_TYPE_CONST, {.i64 = FMT_NONE},    .unit = "format" },
+    {     "pretty", "pretty printed ASCII art graph",   0, AV_OPT_TYPE_CONST, {.i64 = FMT_PRETTY},  .unit = "format" },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(graph_dump);
+
 static int print_link_prop(AVBPrint *buf, AVFilterLink *link)
 {
     const char *format;
@@ -61,7 +84,7 @@ static int print_link_prop(AVBPrint *buf, AVFilterLink *link)
     return buf->len;
 }
 
-static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph)
+static void dump_pretty(AVBPrint *buf, AVFilterGraph *graph)
 {
     unsigned i, j, x, e;
 
@@ -157,13 +180,30 @@ char *avfilter_graph_dump(AVFilterGraph *graph, const char *options)
 {
     AVBPrint buf;
     char *dump = NULL;
+    int ret;
 
-    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_COUNT_ONLY);
-    avfilter_graph_dump_to_buf(&buf, graph);
-    dump = av_malloc(buf.len + 1);
-    if (!dump)
+    GraphDumpOptions opts = {
+        .class = &graph_dump_class,
+    };
+
+    static const char *shorthand[] = {
+        "format", NULL,
+    };
+
+    av_opt_set_defaults(&opts);
+    ret = av_opt_set_from_string(&opts, options, shorthand, "=", ":");
+    if (ret < 0)
         return NULL;
-    av_bprint_init_for_buffer(&buf, dump, buf.len + 1);
-    avfilter_graph_dump_to_buf(&buf, graph);
+
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    switch (opts.format) {
+    case FMT_NONE:
+        break;
+    case FMT_PRETTY:
+        dump_pretty(&buf, graph);
+        break;
+    }
+
+    av_bprint_finalize(&buf, &dump);
     return dump;
 }
-- 
2.47.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [FFmpeg-devel] [PATCH v2 2/4] avfilter/filters: keep track of AVFilterPad labels
  2025-02-18 12:46 [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
@ 2025-02-18 12:46 ` Niklas Haas
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 3/4] avfilter/graphdump: add complex format Niklas Haas
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Niklas Haas @ 2025-02-18 12:46 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

For use in diagnostic code e.g. avfilter_graph_dump().
---
 libavfilter/avfilter.c    | 2 ++
 libavfilter/filters.h     | 6 ++++++
 libavfilter/graphparser.c | 6 ++++++
 3 files changed, 14 insertions(+)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index e732556ffa..b434724694 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -825,11 +825,13 @@ void avfilter_free(AVFilterContext *filter)
 
     for (i = 0; i < filter->nb_inputs; i++) {
         free_link(filter->inputs[i]);
+        av_freep(&filter->input_pads[i].label);
         if (filter->input_pads[i].flags  & AVFILTERPAD_FLAG_FREE_NAME)
             av_freep(&filter->input_pads[i].name);
     }
     for (i = 0; i < filter->nb_outputs; i++) {
         free_link(filter->outputs[i]);
+        av_freep(&filter->output_pads[i].label);
         if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
             av_freep(&filter->output_pads[i].name);
     }
diff --git a/libavfilter/filters.h b/libavfilter/filters.h
index 654aed5c9e..751a125f52 100644
--- a/libavfilter/filters.h
+++ b/libavfilter/filters.h
@@ -43,6 +43,12 @@ struct AVFilterPad {
      */
     const char *name;
 
+    /**
+     * Parsed label for this filter pad in the filter graph, or NULL if
+     * anonymous or unknown.
+     */
+    const char *label;
+
     /**
      * AVFilterPad type.
      */
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index a23e26d2e3..9f8dd3190a 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -564,6 +564,12 @@ int avfilter_graph_segment_create_filters(AVFilterGraphSegment *seg, int flags)
                 }
             }
 
+            /* Set all filter pad labels to their corresponding parsed labels */
+            for (size_t i = 0; i < FFMIN(p->nb_inputs, p->filter->nb_inputs); i++)
+                p->filter->input_pads[i].label = av_strdup(p->inputs[i]->label);
+            for (size_t i = 0; i < FFMIN(p->nb_outputs, p->filter->nb_outputs); i++)
+                p->filter->output_pads[i].label = av_strdup(p->outputs[i]->label);
+
             av_freep(&p->filter_name);
             av_freep(&p->instance_name);
 
-- 
2.47.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [FFmpeg-devel] [PATCH v2 3/4] avfilter/graphdump: add complex format
  2025-02-18 12:46 [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 2/4] avfilter/filters: keep track of AVFilterPad labels Niklas Haas
@ 2025-02-18 12:46 ` Niklas Haas
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option Niklas Haas
  2025-02-18 12:50 ` [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
  3 siblings, 0 replies; 7+ messages in thread
From: Niklas Haas @ 2025-02-18 12:46 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

As an example, the following filter graph (taken from FATE):

  sws_flags=+accurate_rnd+bitexact;
  split [main][over];
  [over] scale=88:72, pad=96:80:4:4 [overf];
  [main][overf] overlay=240:16:format=yuv422

Results in this output:

Filter graph:
  [L0] split=thread_type=0x00000000 [L1] [over];
  [over] scale=w=88:width=88:h=72:height=72:flags=+accurate_rnd+bitexact:thread_type=0x00000000 [L3];
  [L3] pad=width=96:w=96:height=80:h=80:x=4:y=4:thread_type=0x00000000 [overf];
  [main] [overf] overlay=x=240:y=16:format=2 [L6];
  buffer=width=352:video_size=352x288:height=288:pix_fmt=yuv420p:time_base=1/25:frame_rate=25/1:range=1:thread_type=0x00000000 [L0];
  [L6] buffersink=pixel_formats=:colorspaces=:colorranges=:thread_type=0x00000000;
  [L1] scale=w=iw:width=iw:h=ih:height=ih:flags=+accurate_rnd+bitexact:thread_type=0x00000000 [main];
Filter links:
  [L0: buffer -> split] yuv420p 352x288 [SAR 0:1] csp:unknown range:tv
  [L1: split -> scale] yuv420p 352x288 [SAR 0:1] csp:unknown range:tv
  [over: split -> scale] yuv420p 352x288 [SAR 0:1] csp:unknown range:tv
  [L3: scale -> pad] yuva422p 88x72 [SAR 0:1] csp:unknown range:tv
  [overf: pad -> overlay] yuva422p 96x80 [SAR 0:1] csp:unknown range:tv
  [main: scale -> overlay] yuva422p 352x288 [SAR 0:1] csp:unknown range:tv
  [L6: overlay -> buffersink] yuva422p 352x288 [SAR 0:1] csp:unknown range:tv

This format is intended to be more useful for logging, post-processing or
otherwise reusing the dumpled filter graph, since it can be directly ingested
again by `-filter_complex`.
---
 libavfilter/graphdump.c | 124 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/libavfilter/graphdump.c b/libavfilter/graphdump.c
index 80cbda50f5..e81ea0c001 100644
--- a/libavfilter/graphdump.c
+++ b/libavfilter/graphdump.c
@@ -32,6 +32,7 @@
 enum {
     FMT_NONE = 0,
     FMT_PRETTY,
+    FMT_COMPLEX,
     FMT_NB,
 };
 
@@ -46,6 +47,7 @@ static const AVOption graph_dump_options[] = {
     { "format",     "set the output format", OFFSET(format), AV_OPT_TYPE_INT, { .i64 = FMT_NONE }, 0, FMT_NB - 1, .unit = "format" },
     {     "none",   "don't produce any output",         0, AV_OPT_TYPE_CONST, {.i64 = FMT_NONE},    .unit = "format" },
     {     "pretty", "pretty printed ASCII art graph",   0, AV_OPT_TYPE_CONST, {.i64 = FMT_PRETTY},  .unit = "format" },
+    {     "complex","complex filter graph",             0, AV_OPT_TYPE_CONST, {.i64 = FMT_COMPLEX}, .unit = "format" },
     { NULL },
 };
 
@@ -176,6 +178,121 @@ static void dump_pretty(AVBPrint *buf, AVFilterGraph *graph)
     }
 }
 
+/* Assign a unique ID to each link by keeping track of them in an array */
+static int get_link_id(AVFilterLink ***links, int *nb_links, AVFilterLink *link)
+{
+    int ret;
+    for (int i = 0; i < *nb_links; i++) {
+        if ((*links)[i] == link)
+            return i;
+    }
+
+    ret = av_dynarray_add_nofree(links, nb_links, link);
+    return ret ? ret : *nb_links - 1;
+}
+
+static const char *get_filter_name(const AVFilterContext *filter)
+{
+    /* Reuse the filter instance name if present */
+    return strchr(filter->name, '@') ? filter->name : filter->filter->name;
+}
+
+static void print_link_label(AVBPrint *buf, AVFilterLink *link, int id)
+{
+    if (link->srcpad->label)
+        av_bprintf(buf, "%s", link->srcpad->label);
+    else if (link->dstpad->label)
+        av_bprintf(buf, "%s", link->dstpad->label);
+    else
+        av_bprintf(buf, "L%d", id);
+}
+
+static int dump_complex(AVBPrint *buf, AVFilterGraph *graph)
+{
+    /* Keep track of seen filter links to assign a unique ID to each */
+    AVFilterLink **links = NULL;
+    int nb_links = 0;
+    int ret = AVERROR(ENOMEM);
+    char *filter_opts = NULL;
+
+    for (int i = 0; i < graph->nb_filters; i++) {
+        AVFilterContext *filter = graph->filters[i];
+        if (i == 0)
+            av_bprintf(buf, "Filter graph:\n");
+
+        ret = av_opt_serialize(filter, AV_OPT_FLAG_FILTERING_PARAM,
+                               AV_OPT_SERIALIZE_SKIP_DEFAULTS |
+                               AV_OPT_SERIALIZE_SEARCH_CHILDREN,
+                               &filter_opts, '=', ':');
+        if (ret < 0)
+            goto fail;
+
+        av_bprintf(buf, "  ");
+        for (int j = 0; j < filter->nb_inputs; j++) {
+            AVFilterLink *link = filter->inputs[j];
+            ret = get_link_id(&links, &nb_links, link);
+            if (ret < 0)
+                goto fail;
+            av_bprintf(buf, "[");
+            print_link_label(buf, link, ret);
+            av_bprintf(buf, "] ");
+        }
+
+        av_bprintf(buf, "%s", get_filter_name(filter));
+        if (filter_opts && filter_opts[0])
+            av_bprintf(buf, "=%s", filter_opts);
+        av_freep(&filter_opts);
+
+        for (int j = 0; j < filter->nb_outputs; j++) {
+            AVFilterLink *link = filter->outputs[j];
+            ret = get_link_id(&links, &nb_links, link);
+            if (ret < 0)
+                goto fail;
+            av_bprintf(buf, " [");
+            print_link_label(buf, link, ret);
+            av_bprintf(buf, "]");
+        }
+        av_bprintf(buf, ";\n");
+    }
+
+    /* Dump a summary of all seen links */
+    for (int i = 0; i < nb_links; i++) {
+        AVFilterLink *link = links[i];
+        if (i == 0)
+            av_bprintf(buf, "Filter links:\n");
+        av_bprintf(buf, "  [");
+        print_link_label(buf, link, i);
+        av_bprintf(buf, ": %s -> %s] ", get_filter_name(link->src),
+                   get_filter_name(link->dst));
+
+        switch (link->type) {
+        case AVMEDIA_TYPE_VIDEO:
+            av_bprintf(buf, "%s %dx%d [SAR %d:%d] csp:%s range:%s\n",
+                       av_get_pix_fmt_name(link->format), link->w, link->h,
+                       link->sample_aspect_ratio.num, link->sample_aspect_ratio.den,
+                       av_color_space_name(link->colorspace),
+                       av_color_range_name(link->color_range));
+            break;
+        case AVMEDIA_TYPE_AUDIO:
+            av_bprintf(buf, "%s %dHz ",
+                       av_get_sample_fmt_name(link->format), link->sample_rate);
+            av_channel_layout_describe_bprint(&link->ch_layout, buf);
+            av_bprintf(buf, "\n");
+            break;
+        default:
+            av_bprintf(buf, "unknown\n");
+            continue;
+        }
+    }
+
+    ret = 0;
+fail:
+    av_free(links);
+    av_free(filter_opts);
+    return ret;
+}
+
+
 char *avfilter_graph_dump(AVFilterGraph *graph, const char *options)
 {
     AVBPrint buf;
@@ -202,6 +319,13 @@ char *avfilter_graph_dump(AVFilterGraph *graph, const char *options)
     case FMT_PRETTY:
         dump_pretty(&buf, graph);
         break;
+    case FMT_COMPLEX:
+        ret = dump_complex(&buf, graph);
+        if (ret < 0) {
+            av_bprint_finalize(&buf, NULL);
+            return NULL;
+        }
+        break;
     }
 
     av_bprint_finalize(&buf, &dump);
-- 
2.47.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option
  2025-02-18 12:46 [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 2/4] avfilter/filters: keep track of AVFilterPad labels Niklas Haas
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 3/4] avfilter/graphdump: add complex format Niklas Haas
@ 2025-02-18 12:46 ` Niklas Haas
  2025-02-18 16:43   ` epirat07
  2025-02-18 12:50 ` [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
  3 siblings, 1 reply; 7+ messages in thread
From: Niklas Haas @ 2025-02-18 12:46 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Debugging option to dump the filter graph after insertion of auto-filters.
Named such to avoid clashing with the existing -dumpgraph option on lavfi
devices.
---
 doc/ffmpeg.texi             | 18 ++++++++++++++++++
 fftools/ffmpeg.h            |  1 +
 fftools/ffmpeg_filter.c     | 13 +++++++++++++
 fftools/ffmpeg_opt.c        |  4 ++++
 libavfilter/vf_libplacebo.c |  2 +-
 5 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index da6549f043..298c736b47 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -2768,6 +2768,24 @@ filter (scale, aresample) in the graph.
 On by default, to explicitly disable it you need to specify
 @code{-noauto_conversion_filters}.
 
+@item -dump_filter_graph
+Print out the fully settled filter graph, after all automatic conversion
+and format restriction filters have been inserted. Accepts a key/value list of
+suboptions to influnce the output.
+@table @option
+@item format
+Choose the output format. Possible values are:
+
+@table @option
+@item none
+Don't print anything.
+@item pretty
+Pretty-print an ASCII art graph. This is the default.
+@item complex
+Print in a format suitable for consumption by @option{-filter_complex}.
+@end table
+@end table
+
 @item -bits_per_raw_sample[:@var{stream_specifier}] @var{value} (@emph{output,per-stream})
 Declare the number of bits per raw sample in the given output stream to be
 @var{value}. Note that this option sets the information provided to the
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 6cc0da05a0..d6be3df539 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -715,6 +715,7 @@ extern char *filter_nbthreads;
 extern int filter_complex_nbthreads;
 extern int vstats_version;
 extern int auto_conversion_filters;
+extern char *dump_filter_graph;
 
 extern const AVIOInterruptCB int_cb;
 
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 800e2a3f06..5aa871c8ad 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -23,6 +23,7 @@
 #include "ffmpeg.h"
 
 #include "libavfilter/avfilter.h"
+#include "libavfilter/filters.h"
 #include "libavfilter/buffersink.h"
 #include "libavfilter/buffersrc.h"
 
@@ -1986,6 +1987,18 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
     if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
         goto fail;
 
+    /* Print the generated filter graph after insertion of auto filters */
+    if (dump_filter_graph) {
+        char *graph = avfilter_graph_dump(fgt->graph, dump_filter_graph);
+        if (graph)
+            av_log(NULL, AV_LOG_INFO, "%s", graph);
+        else
+            av_log(NULL, AV_LOG_ERROR, "Failed dumping filtergraph!\n");
+    }
+
+    avfilter_inout_free(&inputs);
+    avfilter_inout_free(&outputs);
+
     fgp->is_meta = graph_is_meta(fgt->graph);
 
     /* limit the lists of allowed formats to the ones selected, to
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 3c0c682594..aa8a6508ab 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -76,6 +76,7 @@ char *filter_nbthreads;
 int filter_complex_nbthreads = 0;
 int vstats_version = 2;
 int auto_conversion_filters = 1;
+char *dump_filter_graph;
 int64_t stats_period = 500000;
 
 
@@ -1733,6 +1734,9 @@ const OptionDef options[] = {
     { "auto_conversion_filters", OPT_TYPE_BOOL, OPT_EXPERT,
         { &auto_conversion_filters },
         "enable automatic conversion filters globally" },
+    { "dump_filter_graph", OPT_TYPE_STRING, OPT_EXPERT,
+        { &dump_filter_graph },
+        "dump filter graph after insertion of auto-filters" },
     { "stats",               OPT_TYPE_BOOL, 0,
         { &print_stats },
         "print progress report during encoding", },
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index e1c6629f6d..20f5c2cf75 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -1288,7 +1288,7 @@ static const AVOption libplacebo_options[] = {
     { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, STATIC },
     { "normalize_sar", "force SAR normalization to 1:1 by adjusting pos_x/y/w/h", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
     { "pad_crop_ratio", "ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)", OFFSET(pad_crop_ratio), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0, DYNAMIC },
-    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = DYNAMIC },
+    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black@0.0"}, .flags = DYNAMIC },
     { "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
     { "extra_opts", "Pass extra libplacebo-specific options using a :-separated list of key=value pairs", OFFSET(extra_opts), AV_OPT_TYPE_DICT, .flags = DYNAMIC },
 
-- 
2.47.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing
  2025-02-18 12:46 [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
                   ` (2 preceding siblings ...)
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option Niklas Haas
@ 2025-02-18 12:50 ` Niklas Haas
  3 siblings, 0 replies; 7+ messages in thread
From: Niklas Haas @ 2025-02-18 12:50 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

On Tue, 18 Feb 2025 13:46:00 +0100 Niklas Haas <ffmpeg@haasn.xyz> wrote:
> From: Niklas Haas <git@haasn.dev>
>
> And use it to make the output format configurable.
>
> I also added a "none" option to explicitly disable the behavior (in case a
> previous command line argument was used to enable it). This has the added
> benefit of giving the default "pretty" format the ID 1, allowing `-dumpgraph 1`
> to continue working as expected.

Should address all of the issues brought up in the previous review.

One difference in this implementation is that we now print buffer/buffersink
filters as well, because I couldn't justify omitting them from an implementation
that has nothing to do with ffmpeg.c.

This does unfortunately mean that the output can't *directly* be reused as an
input to -filter_complex without first removing the buffer* entries. In theory
we could add an option to explicitly drop them, but I'm not sold on the idea.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option
  2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option Niklas Haas
@ 2025-02-18 16:43   ` epirat07
  2025-02-19 17:36     ` Niklas Haas
  0 siblings, 1 reply; 7+ messages in thread
From: epirat07 @ 2025-02-18 16:43 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On 18 Feb 2025, at 13:46, Niklas Haas wrote:

> From: Niklas Haas <git@haasn.dev>
>
> Debugging option to dump the filter graph after insertion of auto-filters.
> Named such to avoid clashing with the existing -dumpgraph option on lavfi
> devices.
> ---
>  doc/ffmpeg.texi             | 18 ++++++++++++++++++
>  fftools/ffmpeg.h            |  1 +
>  fftools/ffmpeg_filter.c     | 13 +++++++++++++
>  fftools/ffmpeg_opt.c        |  4 ++++
>  libavfilter/vf_libplacebo.c |  2 +-
>  5 files changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
> index da6549f043..298c736b47 100644
> --- a/doc/ffmpeg.texi
> +++ b/doc/ffmpeg.texi
> @@ -2768,6 +2768,24 @@ filter (scale, aresample) in the graph.
>  On by default, to explicitly disable it you need to specify
>  @code{-noauto_conversion_filters}.
>
> +@item -dump_filter_graph
> +Print out the fully settled filter graph, after all automatic conversion
> +and format restriction filters have been inserted. Accepts a key/value list of
> +suboptions to influnce the output.
> +@table @option
> +@item format
> +Choose the output format. Possible values are:
> +
> +@table @option
> +@item none
> +Don't print anything.
> +@item pretty
> +Pretty-print an ASCII art graph. This is the default.
> +@item complex
> +Print in a format suitable for consumption by @option{-filter_complex}.
> +@end table
> +@end table
> +
>  @item -bits_per_raw_sample[:@var{stream_specifier}] @var{value} (@emph{output,per-stream})
>  Declare the number of bits per raw sample in the given output stream to be
>  @var{value}. Note that this option sets the information provided to the
> diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> index 6cc0da05a0..d6be3df539 100644
> --- a/fftools/ffmpeg.h
> +++ b/fftools/ffmpeg.h
> @@ -715,6 +715,7 @@ extern char *filter_nbthreads;
>  extern int filter_complex_nbthreads;
>  extern int vstats_version;
>  extern int auto_conversion_filters;
> +extern char *dump_filter_graph;
>
>  extern const AVIOInterruptCB int_cb;
>
> diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
> index 800e2a3f06..5aa871c8ad 100644
> --- a/fftools/ffmpeg_filter.c
> +++ b/fftools/ffmpeg_filter.c
> @@ -23,6 +23,7 @@
>  #include "ffmpeg.h"
>
>  #include "libavfilter/avfilter.h"
> +#include "libavfilter/filters.h"
>  #include "libavfilter/buffersink.h"
>  #include "libavfilter/buffersrc.h"
>
> @@ -1986,6 +1987,18 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
>      if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
>          goto fail;
>
> +    /* Print the generated filter graph after insertion of auto filters */
> +    if (dump_filter_graph) {
> +        char *graph = avfilter_graph_dump(fgt->graph, dump_filter_graph);
> +        if (graph)
> +            av_log(NULL, AV_LOG_INFO, "%s", graph);
> +        else
> +            av_log(NULL, AV_LOG_ERROR, "Failed dumping filtergraph!\n");
> +    }
> +
> +    avfilter_inout_free(&inputs);
> +    avfilter_inout_free(&outputs);
> +
>      fgp->is_meta = graph_is_meta(fgt->graph);
>
>      /* limit the lists of allowed formats to the ones selected, to
> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
> index 3c0c682594..aa8a6508ab 100644
> --- a/fftools/ffmpeg_opt.c
> +++ b/fftools/ffmpeg_opt.c
> @@ -76,6 +76,7 @@ char *filter_nbthreads;
>  int filter_complex_nbthreads = 0;
>  int vstats_version = 2;
>  int auto_conversion_filters = 1;
> +char *dump_filter_graph;
>  int64_t stats_period = 500000;
>
>
> @@ -1733,6 +1734,9 @@ const OptionDef options[] = {
>      { "auto_conversion_filters", OPT_TYPE_BOOL, OPT_EXPERT,
>          { &auto_conversion_filters },
>          "enable automatic conversion filters globally" },
> +    { "dump_filter_graph", OPT_TYPE_STRING, OPT_EXPERT,
> +        { &dump_filter_graph },
> +        "dump filter graph after insertion of auto-filters" },
>      { "stats",               OPT_TYPE_BOOL, 0,
>          { &print_stats },
>          "print progress report during encoding", },
> diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> index e1c6629f6d..20f5c2cf75 100644
> --- a/libavfilter/vf_libplacebo.c
> +++ b/libavfilter/vf_libplacebo.c
> @@ -1288,7 +1288,7 @@ static const AVOption libplacebo_options[] = {
>      { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, STATIC },
>      { "normalize_sar", "force SAR normalization to 1:1 by adjusting pos_x/y/w/h", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
>      { "pad_crop_ratio", "ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)", OFFSET(pad_crop_ratio), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0, DYNAMIC },
> -    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = DYNAMIC },
> +    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black@0.0"}, .flags = DYNAMIC },

Seems this is a leftover from your other patch that accidentally got in here.

>      { "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
>      { "extra_opts", "Pass extra libplacebo-specific options using a :-separated list of key=value pairs", OFFSET(extra_opts), AV_OPT_TYPE_DICT, .flags = DYNAMIC },
>
> -- 
> 2.47.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option
  2025-02-18 16:43   ` epirat07
@ 2025-02-19 17:36     ` Niklas Haas
  0 siblings, 0 replies; 7+ messages in thread
From: Niklas Haas @ 2025-02-19 17:36 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Tue, 18 Feb 2025 17:43:35 +0100 epirat07@gmail.com wrote:
>
>
> On 18 Feb 2025, at 13:46, Niklas Haas wrote:
>
> > From: Niklas Haas <git@haasn.dev>
> >
> > Debugging option to dump the filter graph after insertion of auto-filters.
> > Named such to avoid clashing with the existing -dumpgraph option on lavfi
> > devices.
> > ---
> >  doc/ffmpeg.texi             | 18 ++++++++++++++++++
> >  fftools/ffmpeg.h            |  1 +
> >  fftools/ffmpeg_filter.c     | 13 +++++++++++++
> >  fftools/ffmpeg_opt.c        |  4 ++++
> >  libavfilter/vf_libplacebo.c |  2 +-
> >  5 files changed, 37 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
> > index da6549f043..298c736b47 100644
> > --- a/doc/ffmpeg.texi
> > +++ b/doc/ffmpeg.texi
> > @@ -2768,6 +2768,24 @@ filter (scale, aresample) in the graph.
> >  On by default, to explicitly disable it you need to specify
> >  @code{-noauto_conversion_filters}.
> >
> > +@item -dump_filter_graph
> > +Print out the fully settled filter graph, after all automatic conversion
> > +and format restriction filters have been inserted. Accepts a key/value list of
> > +suboptions to influnce the output.
> > +@table @option
> > +@item format
> > +Choose the output format. Possible values are:
> > +
> > +@table @option
> > +@item none
> > +Don't print anything.
> > +@item pretty
> > +Pretty-print an ASCII art graph. This is the default.
> > +@item complex
> > +Print in a format suitable for consumption by @option{-filter_complex}.
> > +@end table
> > +@end table
> > +
> >  @item -bits_per_raw_sample[:@var{stream_specifier}] @var{value} (@emph{output,per-stream})
> >  Declare the number of bits per raw sample in the given output stream to be
> >  @var{value}. Note that this option sets the information provided to the
> > diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> > index 6cc0da05a0..d6be3df539 100644
> > --- a/fftools/ffmpeg.h
> > +++ b/fftools/ffmpeg.h
> > @@ -715,6 +715,7 @@ extern char *filter_nbthreads;
> >  extern int filter_complex_nbthreads;
> >  extern int vstats_version;
> >  extern int auto_conversion_filters;
> > +extern char *dump_filter_graph;
> >
> >  extern const AVIOInterruptCB int_cb;
> >
> > diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
> > index 800e2a3f06..5aa871c8ad 100644
> > --- a/fftools/ffmpeg_filter.c
> > +++ b/fftools/ffmpeg_filter.c
> > @@ -23,6 +23,7 @@
> >  #include "ffmpeg.h"
> >
> >  #include "libavfilter/avfilter.h"
> > +#include "libavfilter/filters.h"
> >  #include "libavfilter/buffersink.h"
> >  #include "libavfilter/buffersrc.h"
> >
> > @@ -1986,6 +1987,18 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
> >      if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
> >          goto fail;
> >
> > +    /* Print the generated filter graph after insertion of auto filters */
> > +    if (dump_filter_graph) {
> > +        char *graph = avfilter_graph_dump(fgt->graph, dump_filter_graph);
> > +        if (graph)
> > +            av_log(NULL, AV_LOG_INFO, "%s", graph);
> > +        else
> > +            av_log(NULL, AV_LOG_ERROR, "Failed dumping filtergraph!\n");
> > +    }
> > +
> > +    avfilter_inout_free(&inputs);
> > +    avfilter_inout_free(&outputs);
> > +
> >      fgp->is_meta = graph_is_meta(fgt->graph);
> >
> >      /* limit the lists of allowed formats to the ones selected, to
> > diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
> > index 3c0c682594..aa8a6508ab 100644
> > --- a/fftools/ffmpeg_opt.c
> > +++ b/fftools/ffmpeg_opt.c
> > @@ -76,6 +76,7 @@ char *filter_nbthreads;
> >  int filter_complex_nbthreads = 0;
> >  int vstats_version = 2;
> >  int auto_conversion_filters = 1;
> > +char *dump_filter_graph;
> >  int64_t stats_period = 500000;
> >
> >
> > @@ -1733,6 +1734,9 @@ const OptionDef options[] = {
> >      { "auto_conversion_filters", OPT_TYPE_BOOL, OPT_EXPERT,
> >          { &auto_conversion_filters },
> >          "enable automatic conversion filters globally" },
> > +    { "dump_filter_graph", OPT_TYPE_STRING, OPT_EXPERT,
> > +        { &dump_filter_graph },
> > +        "dump filter graph after insertion of auto-filters" },
> >      { "stats",               OPT_TYPE_BOOL, 0,
> >          { &print_stats },
> >          "print progress report during encoding", },
> > diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> > index e1c6629f6d..20f5c2cf75 100644
> > --- a/libavfilter/vf_libplacebo.c
> > +++ b/libavfilter/vf_libplacebo.c
> > @@ -1288,7 +1288,7 @@ static const AVOption libplacebo_options[] = {
> >      { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, STATIC },
> >      { "normalize_sar", "force SAR normalization to 1:1 by adjusting pos_x/y/w/h", OFFSET(normalize_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, STATIC },
> >      { "pad_crop_ratio", "ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)", OFFSET(pad_crop_ratio), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0, DYNAMIC },
> > -    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black"}, .flags = DYNAMIC },
> > +    { "fillcolor", "Background fill color", OFFSET(fillcolor), AV_OPT_TYPE_STRING, {.str = "black@0.0"}, .flags = DYNAMIC },
>
> Seems this is a leftover from your other patch that accidentally got in here.

Indeed. Fixed locally.

>
> >      { "corner_rounding", "Corner rounding radius", OFFSET(corner_rounding), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 1.0, .flags = DYNAMIC },
> >      { "extra_opts", "Pass extra libplacebo-specific options using a :-separated list of key=value pairs", OFFSET(extra_opts), AV_OPT_TYPE_DICT, .flags = DYNAMIC },
> >
> > --
> > 2.47.0
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-02-19 17:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-18 12:46 [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas
2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 2/4] avfilter/filters: keep track of AVFilterPad labels Niklas Haas
2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 3/4] avfilter/graphdump: add complex format Niklas Haas
2025-02-18 12:46 ` [FFmpeg-devel] [PATCH v2 4/4] fftools/ffmpeg_filter: add -dump_filter_graph option Niklas Haas
2025-02-18 16:43   ` epirat07
2025-02-19 17:36     ` Niklas Haas
2025-02-18 12:50 ` [FFmpeg-devel] [PATCH v2 1/4] avfilter/graphdump: implement options parsing Niklas Haas

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git