[FFmpeg-devel] [PATCH 1/2] avfilter: Dry run mode for list merging

Michael Niedermayer michaelni at gmx.at
Mon Jul 22 02:56:15 CEST 2013


Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavfilter/avfiltergraph.c |   18 +++++++++---------
 libavfilter/formats.c       |   44 ++++++++++++++++++++++++++-----------------
 libavfilter/formats.h       |    8 +++++---
 3 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 177ad4f..3c1b7c3 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -415,18 +415,18 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
             }
             MERGE_DISPATCH(formats,
                 if (!ff_merge_formats(link->in_formats, link->out_formats,
-                                      link->type))
+                                      link->type, 0))
                     convert_needed = 1;
             )
             if (link->type == AVMEDIA_TYPE_AUDIO) {
                 MERGE_DISPATCH(channel_layouts,
                     if (!ff_merge_channel_layouts(link->in_channel_layouts,
-                                                  link->out_channel_layouts))
+                                                  link->out_channel_layouts, 0))
                         convert_needed = 1;
                 )
                 MERGE_DISPATCH(samplerates,
                     if (!ff_merge_samplerates(link->in_samplerates,
-                                              link->out_samplerates))
+                                              link->out_samplerates, 0))
                         convert_needed = 1;
                 )
             }
@@ -484,20 +484,20 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
                 filter_query_formats(convert);
                 inlink  = convert->inputs[0];
                 outlink = convert->outputs[0];
-                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||
-                    !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
+                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type, 0) ||
+                    !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type, 0))
                     ret |= AVERROR(ENOSYS);
                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
                     (!ff_merge_samplerates(inlink->in_samplerates,
-                                           inlink->out_samplerates) ||
+                                           inlink->out_samplerates, 0) ||
                      !ff_merge_channel_layouts(inlink->in_channel_layouts,
-                                               inlink->out_channel_layouts)))
+                                               inlink->out_channel_layouts, 0)))
                     ret |= AVERROR(ENOSYS);
                 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
                     (!ff_merge_samplerates(outlink->in_samplerates,
-                                           outlink->out_samplerates) ||
+                                           outlink->out_samplerates, 0) ||
                      !ff_merge_channel_layouts(outlink->in_channel_layouts,
-                                               outlink->out_channel_layouts)))
+                                               outlink->out_channel_layouts, 0)))
                     ret |= AVERROR(ENOSYS);
 
                 if (ret < 0) {
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index ae8a456..a7627ab 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -34,8 +34,8 @@
 /**
  * Add all refs from a to ret and destroy a.
  */
-#define MERGE_REF(ret, a, fmts, type, fail)                                \
-do {                                                                       \
+#define MERGE_REF(ret, a, fmts, type, fail, dry_run)                       \
+do { if(!dry_run) {                                                        \
     type ***tmp;                                                           \
     int i;                                                                 \
                                                                            \
@@ -52,13 +52,13 @@ do {                                                                       \
     av_freep(&a->refs);                                                    \
     av_freep(&a->fmts);                                                    \
     av_freep(&a);                                                          \
-} while (0)
+}} while (0)
 
 /**
  * Add all formats common for a and b to ret, copy the refs and destroy
  * a and b.
  */
-#define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail)                          \
+#define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail, dry_run)                 \
 do {                                                                            \
     int i, j, k = 0, count = FFMIN(a->nb, b->nb);                               \
                                                                                 \
@@ -84,13 +84,17 @@ do {
     /* check that there was at least one common format */                       \
     if (!ret->nb)                                                               \
         goto fail;                                                              \
-                                                                                \
-    MERGE_REF(ret, a, fmts, type, fail);                                        \
-    MERGE_REF(ret, b, fmts, type, fail);                                        \
+    MERGE_REF(ret, a, fmts, type, fail, dry_run);                               \
+    MERGE_REF(ret, b, fmts, type, fail, dry_run);                               \
+    if (dry_run) {                                                              \
+        av_freep(&ret->fmts);                                                   \
+        av_freep(&ret);                                                         \
+        ret = a;                                                                \
+    }                                                                           \
 } while (0)
 
 AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
-                                  enum AVMediaType type)
+                                  enum AVMediaType type, int dry_run)
 {
     AVFilterFormats *ret = NULL;
     int i, j;
@@ -124,7 +128,7 @@ AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
     if (alpha2 > alpha1 || chroma2 > chroma1)
         return NULL;
 
-    MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
+    MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail, dry_run);
 
     return ret;
 fail:
@@ -137,19 +141,19 @@ fail:
 }
 
 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
-                                      AVFilterFormats *b)
+                                      AVFilterFormats *b, int dry_run)
 {
     AVFilterFormats *ret = NULL;
 
     if (a == b) return a;
 
     if (a->nb_formats && b->nb_formats) {
-        MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
+        MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail, dry_run);
     } else if (a->nb_formats) {
-        MERGE_REF(a, b, formats, AVFilterFormats, fail);
+        MERGE_REF(a, b, formats, AVFilterFormats, fail, dry_run);
         ret = a;
     } else {
-        MERGE_REF(b, a, formats, AVFilterFormats, fail);
+        MERGE_REF(b, a, formats, AVFilterFormats, fail, dry_run);
         ret = b;
     }
 
@@ -164,7 +168,8 @@ fail:
 }
 
 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
-                                                 AVFilterChannelLayouts *b)
+                                                 AVFilterChannelLayouts *b,
+                                                 int dry_run)
 {
     AVFilterChannelLayouts *ret = NULL;
     unsigned a_all = a->all_layouts + a->all_counts;
@@ -190,7 +195,7 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
                 return NULL;
             b->nb_channel_layouts = j;
         }
-        MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
+        MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail, dry_run);
         return b;
     }
 
@@ -238,8 +243,13 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
     ret->nb_channel_layouts = ret_nb;
     if (!ret->nb_channel_layouts)
         goto fail;
-    MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail);
-    MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail);
+    MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail, dry_run);
+    MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail, dry_run);
+    if (dry_run && ret) {
+        av_freep(&ret->channel_layouts);
+        av_freep(&ret);
+        ret = a;
+    }
     return ret;
 
 fail:
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index 468eac8..ce6290e 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -117,9 +117,11 @@ typedef struct AVFilterChannelLayouts {
  * is returned.
  */
 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
-                                                 AVFilterChannelLayouts *b);
+                                                 AVFilterChannelLayouts *b,
+                                                 int dry_run);
 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
-                                      AVFilterFormats *b);
+                                      AVFilterFormats *b,
+                                      int dry_run);
 
 /**
  * Construct an empty AVFilterChannelLayouts/AVFilterFormats struct --
@@ -219,7 +221,7 @@ AVFilterFormats *ff_planar_sample_fmts(void);
  * is returned.
  */
 AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
-                                  enum AVMediaType type);
+                                  enum AVMediaType type, int dry_run);
 
 /**
  * Add *ref as a new reference to formats.
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list