diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 875789ca49880..d95c11d33fa1c 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -958,7 +958,7 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) int (*filter_frame)(AVFilterLink *, AVFrame *); AVFilterContext *dstctx = link->dst; AVFilterPad *dst = link->dstpad; - int ret; + int ret, needs_free = dst->flags & AVFILTERPAD_FLAG_GENERIC_FREE; if (!(filter_frame = dst->filter_frame)) filter_frame = default_filter_frame; @@ -973,9 +973,13 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) dstctx->is_disabled = !ff_inlink_evaluate_timeline_at_frame(link, frame); if (dstctx->is_disabled && - (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC)) + (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC)) { filter_frame = default_filter_frame; + needs_free = 0; + } ret = filter_frame(link, frame); + if (needs_free) + av_frame_free(&frame); link->frame_count_out++; return ret; diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 8b897217e1a5d..32a0fe7b5e23e 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -68,6 +68,14 @@ struct AVFilterPad { */ #define AVFILTERPAD_FLAG_NEEDS_WRITABLE (1 << 0) + /** + * AVFilterPad.filter_frame does not free its input frame at all + * and expects its caller to do so all the time. + * + * input pads only. + */ +#define AVFILTERPAD_FLAG_GENERIC_FREE (1 << 1) + /** * A combination of AVFILTERPAD_FLAG_* flags. */ @@ -97,7 +105,8 @@ struct AVFilterPad { * * @return >= 0 on success, a negative AVERROR on error. This function * must ensure that frame is properly unreferenced on error if it - * hasn't been passed on to another filter. + * hasn't been passed on to another filter unless the + * AVFILTERPAD_FLAG_GENERIC_FREE flag is set. */ int (*filter_frame)(AVFilterLink *link, AVFrame *frame);