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.rheinha...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".