From 262e6f8430a821effb63af67e8f0bbbea9c3a754 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 28 Sep 2024 16:19:06 +0200 Subject: [PATCH] lavfi/avfilter: export AVFilter initialization state This will allow the AVOption code to detect setting non-runtime options after the filter has been initialized. --- libavfilter/avfilter.c | 8 +++++--- libavfilter/avfilter_internal.h | 5 ++--- libavfilter/graphparser.c | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 8a2a9e0593..dc06ebab4d 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -159,7 +159,8 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad, src->outputs[srcpad] || dst->inputs[dstpad]) return AVERROR(EINVAL); - if (!fffilterctx(src)->initialized || !fffilterctx(dst)->initialized) { + if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) || + !(fffilterctx(dst)->state_flags & AV_CLASS_STATE_INITIALIZED)) { av_log(src, AV_LOG_ERROR, "Filters must be initialized before linking.\n"); return AVERROR(EINVAL); } @@ -676,6 +677,7 @@ static const AVClass avfilter_class = { .child_next = filter_child_next, .child_class_iterate = filter_child_class_iterate, .option = avfilter_options, + .state_flags_offset = offsetof(FFFilterContext, state_flags), }; static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, @@ -909,7 +911,7 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) FFFilterContext *ctxi = fffilterctx(ctx); int ret = 0; - if (ctxi->initialized) { + if (ctxi->state_flags & AV_CLASS_STATE_INITIALIZED) { av_log(ctx, AV_LOG_ERROR, "Filter already initialized\n"); return AVERROR(EINVAL); } @@ -940,7 +942,7 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) return ret; } - ctxi->initialized = 1; + ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED; return 0; } diff --git a/libavfilter/avfilter_internal.h b/libavfilter/avfilter_internal.h index ec3933b1d1..9ba890a70c 100644 --- a/libavfilter/avfilter_internal.h +++ b/libavfilter/avfilter_internal.h @@ -100,9 +100,8 @@ typedef struct FFFilterContext { avfilter_execute_func *execute; - // 1 when avfilter_init_*() was successfully called on this filter - // 0 otherwise - int initialized; + // AV_CLASS_STATE_FLAG_* + unsigned state_flags; } FFFilterContext; static inline FFFilterContext *fffilterctx(AVFilterContext *ctx) diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index 912804ecd6..a23e26d2e3 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -627,7 +627,8 @@ int avfilter_graph_segment_init(AVFilterGraphSegment *seg, int flags) if (p->filter_name) return fail_creation_pending(seg, p->filter_name, __func__); - if (!p->filter || fffilterctx(p->filter)->initialized) + if (!p->filter || + (fffilterctx(p->filter)->state_flags & AV_CLASS_STATE_INITIALIZED)) continue; ret = avfilter_init_dict(p->filter, NULL);