[FFmpeg-cvslog] avfilter: Dont partially merge lists

Michael Niedermayer git at videolan.org
Tue Jul 23 19:22:44 CEST 2013


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Mon Jul 22 02:31:04 2013 +0200| [fe328f0807687ab5d418ff164b389f953102912f] | committer: Michael Niedermayer

avfilter: Dont partially merge lists

This prevents the unneeded insertion of multiple aresample filters in some cases

The format merging is moved to avoid having to call the channel layout
merge twice. The channel layout merge code uses different structures and
is not compatible with the added dry run wrappers.

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fe328f0807687ab5d418ff164b389f953102912f
---

 libavfilter/avfiltergraph.c |   68 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 6 deletions(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 177ad4f..c594a4f 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -360,6 +360,47 @@ static int formats_declared(AVFilterContext *f)
     return 1;
 }
 
+static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg)
+{
+    AVFilterFormats *a = av_memdup(arg, sizeof(*arg));
+    if (a) {
+        a->refcount = 0;
+        a->refs     = NULL;
+        a->formats  = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats);
+        if (!a->formats && arg->formats)
+            av_freep(&a);
+    }
+    return a;
+}
+
+static int can_merge_formats(AVFilterFormats *a_arg,
+                             AVFilterFormats *b_arg,
+                             enum AVMediaType type,
+                             int is_sample_rate)
+{
+    AVFilterFormats *a, *b, *ret;
+    if (a == b)
+        return 1;
+    a = clone_filter_formats(a_arg);
+    b = clone_filter_formats(b_arg);
+    if (is_sample_rate) {
+        ret = ff_merge_samplerates(a, b);
+    } else {
+        ret = ff_merge_formats(a, b, type);
+    }
+    if (ret) {
+        av_freep(&ret->formats);
+        av_freep(&ret);
+        return 1;
+    } else {
+        av_freep(&a->formats);
+        av_freep(&b->formats);
+        av_freep(&a);
+        av_freep(&b);
+        return 0;
+    }
+}
+
 /**
  * Perform one round of query_formats() and merging formats lists on the
  * filter graph.
@@ -404,20 +445,30 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
             if (!link)
                 continue;
 
+            if (link->in_formats != link->out_formats
+                && link->in_formats && link->out_formats)
+                if (!can_merge_formats(link->in_formats, link->out_formats,
+                                      link->type, 0))
+                    convert_needed = 1;
+            if (link->type == AVMEDIA_TYPE_AUDIO) {
+                if (link->in_samplerates != link->out_samplerates
+                    && link->in_samplerates && link->out_samplerates)
+                    if (!can_merge_formats(link->in_samplerates,
+                                           link->out_samplerates,
+                                           0, 1))
+                        convert_needed = 1;
+            }
+
 #define MERGE_DISPATCH(field, statement)                                     \
             if (!(link->in_ ## field && link->out_ ## field)) {              \
                 count_delayed++;                                             \
             } else if (link->in_ ## field == link->out_ ## field) {          \
                 count_already_merged++;                                      \
-            } else {                                                         \
+            } else if (!convert_needed) {                                                         \
                 count_merged++;                                              \
                 statement                                                    \
             }
-            MERGE_DISPATCH(formats,
-                if (!ff_merge_formats(link->in_formats, link->out_formats,
-                                      link->type))
-                    convert_needed = 1;
-            )
+
             if (link->type == AVMEDIA_TYPE_AUDIO) {
                 MERGE_DISPATCH(channel_layouts,
                     if (!ff_merge_channel_layouts(link->in_channel_layouts,
@@ -430,6 +481,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
                         convert_needed = 1;
                 )
             }
+            MERGE_DISPATCH(formats,
+                if (!ff_merge_formats(link->in_formats, link->out_formats,
+                                      link->type))
+                    convert_needed = 1;
+            )
 #undef MERGE_DISPATCH
 
             if (convert_needed) {



More information about the ffmpeg-cvslog mailing list