[FFmpeg-devel] [PATCH] avfilter: add option to end filtering on first EOF in filter sink

Paul B Mahol onemda at gmail.com
Sun Oct 31 13:01:35 EET 2021


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 fftools/ffmpeg.h            | 1 +
 fftools/ffmpeg_filter.c     | 1 +
 fftools/ffmpeg_opt.c        | 3 +++
 libavfilter/avfilter.h      | 1 +
 libavfilter/avfiltergraph.c | 7 +++++--
 5 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 545ff1c8e7..f3b003cd6a 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -633,6 +633,7 @@ extern char *videotoolbox_pixfmt;
 
 extern char *filter_nbthreads;
 extern int filter_complex_nbthreads;
+extern int filter_shortest;
 extern int vstats_version;
 extern int auto_conversion_filters;
 
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index b798459946..d67f4d5528 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1028,6 +1028,7 @@ int configure_filtergraph(FilterGraph *fg)
         av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
     } else {
         fg->graph->nb_threads = filter_complex_nbthreads;
+        fg->graph->shortest = filter_shortest;
     }
 
     if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 601db2b827..1bc2df37d4 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -171,6 +171,7 @@ int frame_bits_per_raw_sample = 0;
 float max_error_rate  = 2.0/3;
 char *filter_nbthreads;
 int filter_complex_nbthreads = 0;
+int filter_shortest = 0;
 int vstats_version = 2;
 int auto_conversion_filters = 1;
 int64_t stats_period = 500000;
@@ -3638,6 +3639,8 @@ const OptionDef options[] = {
         "create a complex filtergraph", "graph_description" },
     { "filter_complex_threads", HAS_ARG | OPT_INT,                   { &filter_complex_nbthreads },
         "number of threads for -filter_complex" },
+    { "filter_shortest", OPT_BOOL | OPT_INT,                         { &filter_shortest },
+        "ends filtering on shortest sink" },
     { "lavfi",          HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
         "create a complex filtergraph", "graph_description" },
     { "filter_complex_script", HAS_ARG | OPT_EXPERT,                 { .func_arg = opt_filter_complex_script },
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index f7208754a7..c00e70774e 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -909,6 +909,7 @@ typedef struct AVFilterGraph {
     int sink_links_count;
 
     unsigned disable_auto_convert;
+    int shortest;
 } AVFilterGraph;
 
 /**
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index b8b432e98b..3c87d42e49 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -57,6 +57,8 @@ static const AVOption filtergraph_options[] = {
         AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|V },
     {"aresample_swr_opts"   , "default aresample filter options"    , OFFSET(aresample_swr_opts)    ,
         AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|A },
+    {"shortest", "ends filtering with shortest sink"                , OFFSET(shortest)              ,
+        AV_OPT_TYPE_BOOL,   {.i64 = 0}, 0, 1, F|V|A },
     { NULL },
 };
 
@@ -77,6 +79,7 @@ int ff_graph_thread_init(AVFilterGraph *graph)
 {
     graph->thread_type = 0;
     graph->nb_threads  = 1;
+    graph->shortest    = 0;
     return 0;
 }
 #endif
@@ -1298,7 +1301,7 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph)
         } else {
             r = ff_request_frame(oldest);
         }
-        if (r != AVERROR_EOF)
+        if (r != AVERROR_EOF || graph->shortest)
             break;
         av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
                oldest->dst->name,
@@ -1309,7 +1312,7 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph)
                              oldest->age_index);
         oldest->age_index = -1;
     }
-    if (!graph->sink_links_count)
+    if (!graph->sink_links_count || (r == AVERROR_EOF && graph->shortest))
         return AVERROR_EOF;
     av_assert1(!oldest->dst->filter->activate);
     av_assert1(oldest->age_index >= 0);
-- 
2.33.0



More information about the ffmpeg-devel mailing list