[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