[FFmpeg-devel] [PATCH 4/6] avfilter/avfilter: Allow to free non-static pads generically

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Tue Aug 17 04:53:56 EEST 2021


This can be enabled/disabled on a per-filter basis by setting
the new internal flags FF_FILTER_FLAG_FREE_(IN|OUT)PADS and
on a per-pad basis by setting the AVFILTERPAD_FLAG_FREE_NAME flag.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
I decided to combine both approaches: It has the advantage that
the marginal extra code for a filter all of whose inputs'/outputs'
names need to be freed is zero while making it easy to handle filters
that have some inputs/outputs whose names need to be freed.

 libavfilter/avfilter.c | 15 ++++++++++++++-
 libavfilter/internal.h | 20 ++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index c3382036d2..48727201f6 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -123,8 +123,11 @@ static int insert_pad(unsigned *count, AVFilterPad **pads,
         *pads  = newpads;
     if (newlinks)
         *links = newlinks;
-    if (!newpads || !newlinks)
+    if (!newpads || !newlinks) {
+        if (newpad->flags & AVFILTERPAD_FLAG_FREE_NAME)
+            av_freep(&newpad->name);
         return AVERROR(ENOMEM);
+    }
 
     memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
     (*links)[idx] = NULL;
@@ -136,11 +139,17 @@ static int insert_pad(unsigned *count, AVFilterPad **pads,
 
 int ff_insert_inpad(AVFilterContext *f, AVFilterPad *p)
 {
+    if (f->filter->flags_internal & FF_FILTER_FLAG_FREE_INPADS)
+        p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
+
     return insert_pad(&f->nb_inputs, &f->input_pads, &f->inputs, p);
 }
 
 int ff_insert_outpad(AVFilterContext *f, AVFilterPad *p)
 {
+    if (f->filter->flags_internal & FF_FILTER_FLAG_FREE_OUTPADS)
+        p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
+
     return insert_pad(&f->nb_outputs, &f->output_pads, &f->outputs, p);
 }
 
@@ -741,9 +750,13 @@ void avfilter_free(AVFilterContext *filter)
 
     for (i = 0; i < filter->nb_inputs; i++) {
         free_link(filter->inputs[i]);
+        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]);
+        if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
+            av_freep(&filter->output_pads[i].name);
     }
 
     if (filter->filter->priv_class)
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 8fe17a5433..0d0335bd1c 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -68,6 +68,11 @@ struct AVFilterPad {
      */
 #define AVFILTERPAD_FLAG_NEEDS_WRITABLE                  (1 << 0)
 
+    /**
+     * The pad's name is allocated and should be freed generically.
+     */
+#define AVFILTERPAD_FLAG_FREE_NAME                       (1 << 1)
+
     /**
      * A combination of AVFILTERPAD_FLAG_* flags.
      */
@@ -227,6 +232,11 @@ void ff_tlog_link(void *ctx, AVFilterLink *link, int end);
 
 /**
  * Append a new input/output pad to the filter's list of such pads.
+ *
+ * If the underlying AVFilter has the FF_FILTER_FLAG_FREE_INPADS
+ * set, the AVFILTERPAD_FLAG_FREE_NAME flag will be set for new inpads,
+ * ensuring that it will be freed generically (even on insertion error).
+ * Similarly for outpads.
  */
 int ff_insert_inpad (AVFilterContext *f, AVFilterPad *p);
 int ff_insert_outpad(AVFilterContext *f, AVFilterPad *p);
@@ -317,6 +327,16 @@ void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter
  */
 #define FF_FILTER_FLAG_HWFRAME_AWARE (1 << 0)
 
+/**
+ * The names of all input pads are allocated and should be freed generically.
+ */
+ #define FF_FILTER_FLAG_FREE_INPADS  (1 << 1)
+
+/**
+ * The names of all output pads are allocated and should be freed generically.
+ */
+ #define FF_FILTER_FLAG_FREE_OUTPADS (1 << 2)
+
 /**
  * Run one round of processing on a filter graph.
  */
-- 
2.30.2



More information about the ffmpeg-devel mailing list